Commit 6b28cb0909a for nodejs
commit 6b28cb0909afbeb8d95dc5956673633fc22a273b
Author: Joyee Cheung <joyeec9h3@gmail.com>
Date: Mon Oct 5 15:32:30 2026 +0200
deps: update V8 to 15.5.35.20
Signed-off-by: Joyee Cheung <joyeec9h3@gmail.com>
PR-URL: https://github.com/nodejs/node/pull/66537
Reviewed-By: Richard Lau <richard.lau@ibm.com>
Reviewed-By: Chengzhong Wu <legendecas@gmail.com>
Reviewed-By: Filip Skokan <panva.ip@gmail.com>
Reviewed-By: Yagiz Nizipli <yagiz@nizipli.com>
diff --git a/deps/v8/.gitignore b/deps/v8/.gitignore
index d7f3cb65e11..c9cbb930c22 100644
--- a/deps/v8/.gitignore
+++ b/deps/v8/.gitignore
@@ -35,6 +35,7 @@
.gclient_entries
.gdb_history
.gemini
+.github
.idea
.jetskicli
.jslint-cache
diff --git a/deps/v8/.gn b/deps/v8/.gn
index 8b788bd1772..fcc0c855322 100644
--- a/deps/v8/.gn
+++ b/deps/v8/.gn
@@ -7,9 +7,13 @@ import("//build/dotfile_settings.gni")
# The location of the build configuration file.
buildconfig = "//build/config/BUILDCONFIG.gn"
-# The python interpreter to use by default. On Windows, this will look
-# for python3.exe and python3.bat.
-script_executable = "python3"
+# The hermetic Python interpreter to use by default. Platforms without a
+# hermetic CPython CIPD package fallback to the system python3 on $PATH.
+if (host_cpu == "s390x" || host_cpu == "ppc64" || host_os == "zos") {
+ script_executable = "python3"
+} else {
+ script_executable = "//third_party/cpython3/host/bin/python3"
+}
# These are the targets to check headers for by default. The files in targets
# matching these patterns (see "gn help label_pattern" for format) will have
diff --git a/deps/v8/.vpython3 b/deps/v8/.vpython3
deleted file mode 100644
index 8551fa2f7a1..00000000000
--- a/deps/v8/.vpython3
+++ /dev/null
@@ -1,107 +0,0 @@
-# This is a vpython "spec" file.
-#
-# It describes patterns for python wheel dependencies of the python scripts in
-# the chromium repo, particularly for dependencies that have compiled components
-# (since pure-python dependencies can be easily vendored into third_party).
-#
-# When vpython is invoked, it finds this file and builds a python VirtualEnv,
-# containing all of the dependencies described in this file, fetching them from
-# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`,
-# this never requires the end-user machine to have a working python extension
-# compilation environment. All of these packages are built using:
-# https://chromium.googlesource.com/infra/infra/+/main/infra/tools/dockerbuild/
-#
-# All python scripts in the repo share this same spec, to avoid dependency
-# fragmentation.
-#
-# If you have depot_tools installed in your $PATH, you can invoke python scripts
-# in this repo by running them as you normally would run them, except
-# substituting `vpython` instead of `python` on the command line, e.g.:
-# vpython path/to/script.py some --arguments
-#
-# Read more about `vpython` and how to modify this file here:
-# https://chromium.googlesource.com/infra/infra/+/main/doc/users/vpython.md
-
-python_version: "3.11"
-
-# The default set of platforms vpython checks does not yet include mac-arm64.
-# Setting `verify_pep425_tag` to the list of platforms we explicitly must support
-# allows us to ensure that vpython specs stay mac-arm64-friendly
-verify_pep425_tag: [
- {python: "cp311", abi: "cp311", platform: "manylinux1_x86_64"},
- {python: "cp311", abi: "cp311", platform: "linux_arm64"},
-
- {python: "cp311", abi: "cp311", platform: "macosx_10_10_intel"},
- {python: "cp311", abi: "cp311", platform: "macosx_11_0_arm64"},
-
- {python: "cp311", abi: "cp311", platform: "win32"},
- {python: "cp311", abi: "cp311", platform: "win_amd64"}
-]
-
-# TODO(https://crbug.com/898348): Add in necessary wheels as Python3 versions
-# become available.
-wheel: <
- name: "infra/python/wheels/six-py2_py3"
- version: "version:1.15.0"
->
-
-wheel: <
- name: "infra/python/wheels/coverage/${vpython_platform}"
- version: "version:7.3.1"
->
-
-wheel: <
- name: "infra/python/wheels/pbr-py2_py3"
- version: "version:3.0.0"
->
-
-wheel: <
- name: "infra/python/wheels/filecheck-py2_py3"
- version: "version:1.0.1"
->
-
-wheel: <
- name: "infra/python/wheels/funcsigs-py2_py3"
- version: "version:1.0.2"
->
-
-wheel: <
- name: "infra/python/wheels/mock-py2_py3"
- version: "version:2.0.0"
->
-
-wheel: <
- name: "infra/python/wheels/numpy/${vpython_platform}"
- version: "version:1.23.5.chromium.4"
->
-
-wheel: <
- name: "infra/python/wheels/protobuf-py3"
- version: "version:3.19.3"
->
-
-# requests and its dependencies.
-wheel: <
- name: "infra/python/wheels/requests-py3"
- version: "version:2.31.0"
->
-wheel: <
- name: "infra/python/wheels/urllib3-py2_py3"
- version: "version:1.26.6"
->
-wheel: <
- name: "infra/python/wheels/idna-py2_py3"
- version: "version:2.8"
->
-wheel: <
- name: "infra/python/wheels/certifi-py2_py3"
- version: "version:2020.11.8"
->
-wheel: <
- name: "infra/python/wheels/charset_normalizer-py3"
- version: "version:2.0.4"
->
-wheel: <
- name: "infra/python/wheels/pyfakefs-py3"
- version: "version:5.7.3"
->
diff --git a/deps/v8/AUTHORS b/deps/v8/AUTHORS
index e3c97a9fdf3..39f1bbd70a1 100644
--- a/deps/v8/AUTHORS
+++ b/deps/v8/AUTHORS
@@ -67,6 +67,7 @@ Amos Lim <eui-sang.lim@samsung.com>
Andreas Anyuru <andreas.anyuru@gmail.com>
Andrei Kashcha <anvaka@gmail.com>
Andreu Botella <andreu@andreubotella.com>
+Andrew Gaul <andrew@gaul.org>
Andrew Paprocki <andrew@ishiboo.com>
Anna Henningsen <anna@addaleax.net>
Antoine du Hamel <duhamelantoine1995@gmail.com>
@@ -106,10 +107,12 @@ Christopher Nady <nady.christopher@gmail.com>
Colin Ihrig <cjihrig@gmail.com>
Cong Zuo <zckevinzc@gmail.com>
Craig Schlenter <craig.schlenter@gmail.com>
+Cristiano Moraes <cris.moraes.ds@gmail.com>
Daniel Andersson <kodandersson@gmail.com>
Daniel Bevenius <daniel.bevenius@gmail.com>
Daniel Dromboski <dandromb@gmail.com>
Daniel James <dnljms@gmail.com>
+Daniel Kocielinski <daniel.koc@gmail.com>
Daniel Shelton <d1.shelton@samsung.com>
Daniil Bakin <bd.bakin@gmail.com>
Danylo Boiko <danielboyko02@gmail.com>
@@ -129,7 +132,6 @@ Douglas Crosher <dtc-v8@scieneer.com>
Dusan Milosavljevic <dusan.m.milosavljevic@gmail.com>
Eden Wang <nedenwang@tencent.com>
Edoardo Marangoni <edoardo@wasmer.io>
-Eliau Elkouby <eliau.elkouby@gmail.com>
Elisha Hollander <just4now666666@gmail.com>
Eric Rannaud <eric.rannaud@gmail.com>
Erich Ocean <erich.ocean@me.com>
@@ -181,6 +183,7 @@ Jay Freeman <saurik@saurik.com>
Jeroen Bobbeldijk <jerbob92@gmail.com>
Jérôme Vouillon <jerome.vouillon@gmail.com>
Jesper van den Ende <jespertheend@gmail.com>
+Jesse Wright <jmwright.045@gmail.com>
Ji Qiu <qiuji@iscas.ac.cn>
Jiawen Geng <technicalcute@gmail.com>
Jiaxun Yang <jiaxun.yang@flygoat.com>
@@ -207,6 +210,7 @@ Keyhan Vakil <kvakil@googlecontrib.kvakil.me>
Kris Selden <kris.selden@gmail.com>
Krishna Ravishankar <krishna.ravi732@gmail.com>
Kyounga Ra <kyounga@alticast.com>
+Leo Camus <leo.camus23@gmail.com>
Levi Zim <rsworktech@outlook.com>
LN Liberda <lauren@selfisekai.rocks>
Loo Rong Jie <loorongjie@gmail.com>
@@ -287,10 +291,12 @@ Ruben Bridgewater <ruben@bridgewater.de>
Ryan Dahl <ry@tinyclouds.org>
Sahil Shaikh <shaikhsahil4883@gmail.com>
Sakthipriyan Vairamani (thefourtheye) <thechargingvolcano@gmail.com>
+Samuel Attard <samuel.r.attard@gmail.com>
Sander Mathijs van Veen <sander@leaningtech.com>
Sandro Santilli <strk@keybit.net>
Sanjoy Das <sanjoy@playingwithpointers.com>
Sam James <sam@gentoo.org>
+Samuel Attard <samuel.r.attard@gmail.com>
Sébastien Doeraene <sjrdoeraene@gmail.com>
Seo Sanghyeon <sanxiyn@gmail.com>
Sergey Markelov <sergionso@gmail.com>
@@ -303,13 +309,13 @@ Stefan Penner <stefan.penner@gmail.com>
Stefan Stojanovic <stefko.stojanovic@gmail.com>
Stephan Hartmann <stha09@googlemail.com>
Stephen Belanger <stephen.belanger@datadoghq.com>
-Steven R. Loomis <srl295@gmail.com>
Sylvestre Ledru <sledru@mozilla.com>
Takeshi Yoneda <takeshi@tetrate.io>
Taketoshi Aono <brn@b6n.ch>
Tao Liqiang <taolq@outlook.com>
Tao Wang <tao.wang.2261@gmail.com>
Teddy Katz <teddy.katz@gmail.com>
+Temiloluwa Yusuf <ytemiloluwa@gmail.com>
Thomas Young <wenzhang5800@gmail.com>
Tiancheng "Timothy" Gu <timothygu99@gmail.com>
Tianping Yang <yangtianping@oppo.com>
@@ -359,6 +365,7 @@ Zhaojun Meng <zhaojun.meng@gmail.com>
Zheng Liu <i6122f@gmail.com>
Zhongqi Wang <wzq2253675767@gmail.com>
Zhongping Wang <kewpie.w.zp@gmail.com>
+Zuyao Chen <zuyaocat@gmail.com>
柳荣一 <admin@web-tinker.com>
Yang Xiang <xiangyangemail@gmail.com>
Kotaro Ohsugi <dec4m4rk@gmail.com>
diff --git a/deps/v8/BUILD.bazel b/deps/v8/BUILD.bazel
index 49a7613604d..2350f14126e 100644
--- a/deps/v8/BUILD.bazel
+++ b/deps/v8/BUILD.bazel
@@ -9,6 +9,7 @@ load("@rules_python//python:defs.bzl", "py_binary", "py_test")
load("@v8_python_deps//:requirements.bzl", "requirement")
load(
"@v8//:bazel/defs.bzl",
+ "metagen_instance_types",
"v8_binary",
"v8_build_config",
"v8_config",
@@ -47,7 +48,6 @@ load(":bazel/v8-non-pointer-compression.bzl", "v8_binary_non_pointer_compression
# v8_enable_local_off_stack_check
# v8_enable_ignition_dispatch_counting
# v8_enable_builtins_optimization
-# v8_enable_builtins_profiling
# v8_enable_builtins_profiling_verbose
# v8_builtins_profiling_log_file
# v8_enable_builtins_reordering
@@ -94,11 +94,6 @@ v8_flag(name = "v8_annotate_torque_ir")
v8_flag(name = "v8_code_comments")
-v8_flag(
- name = "v8_cppgc_microtask_queue",
- default = False,
-)
-
v8_flag(
name = "v8_deprecation_warnings",
default = True,
@@ -111,6 +106,8 @@ v8_flag(
v8_flag(name = "v8_enable_backtrace")
+v8_flag(name = "v8_enable_builtins_profiling")
+
v8_flag(name = "v8_enable_debug_code")
v8_flag(name = "v8_enable_disassembler")
@@ -146,14 +143,19 @@ v8_flag(name = "v8_enable_snapshot_code_comments")
v8_flag(name = "v8_enable_snapshot_native_code_counters")
v8_flag(
- name = "v8_enable_static_roots",
- default = True,
+ name = "v8_enable_static_roots",
+ default = True,
)
v8_flag(name = "v8_enable_trace_maps")
v8_flag(name = "v8_enable_v8_checks")
+v8_flag(
+ name = "v8_disallow_js_in_api_interrupts_is_checked",
+ default = True,
+)
+
v8_flag(name = "v8_enable_verify_csa")
v8_flag(name = "v8_enable_verify_heap")
@@ -176,6 +178,14 @@ v8_flag(
v8_flag(name = "v8_enable_experimental_tq_to_tsa")
+# Mirrors the GN arg of the same name: selects which instance-type
+# generator's output V8 compiles in, metagen or Torque's emission. When
+# off, the metagen action is not part of the build graph.
+v8_flag(
+ name = "v8_use_metagen_instance_types",
+ default = False,
+)
+
v8_flag(
name = "v8_use_host_cpu_arm_features",
default = True,
@@ -506,10 +516,11 @@ v8_config(
conditional_defines = {
"v8_android_log_stdout": "V8_ANDROID_LOG_STDOUT",
"v8_code_comments": "V8_CODE_COMMENTS",
- "v8_cppgc_microtask_queue": "V8_CPPGC_MICROTASK_QUEUE",
"v8_deprecation_warnings": "V8_DEPRECATION_WARNINGS",
+ "v8_disallow_js_in_api_interrupts_is_checked": "V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED",
"v8_imminent_deprecation_warnings": "V8_IMMINENT_DEPRECATION_WARNINGS",
"v8_enable_debug_code": "V8_ENABLE_DEBUG_CODE",
+ "v8_enable_builtins_profiling": "V8_ENABLE_BUILTINS_PROFILING",
"v8_enable_disassembler": "ENABLE_DISASSEMBLER",
"v8_enable_global_handle_zapping": "ENABLE_GLOBAL_HANDLE_ZAPPING",
"v8_enable_local_handle_zapping": "ENABLE_LOCAL_HANDLE_ZAPPING",
@@ -544,22 +555,27 @@ v8_config(
"V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA",
"V8_TLS_USED_IN_LIBRARY",
] + select({
+ ":is_not_v8_use_metagen_instance_types": [
+ "V8_USE_METAGEN_INSTANCE_TYPES=0",
+ ],
+ "//conditions:default": [],
+ }) + select({
"@v8//bazel/config:is_debug": [
"DEBUG",
"V8_ENABLE_CHECKS",
],
"//conditions:default": [],
}) + select({
- "@v8//bazel/config:asan_enabled" : [ "V8_USE_ADDRESS_SANITIZER" ],
+ "@v8//bazel/config:asan_enabled": ["V8_USE_ADDRESS_SANITIZER"],
"//conditions:default": [],
}) + select({
- "@v8//bazel/config:hwasan_enabled" : [ "V8_USE_HWADDRESS_SANITIZER" ],
+ "@v8//bazel/config:hwasan_enabled": ["V8_USE_HWADDRESS_SANITIZER"],
"//conditions:default": [],
}) + select({
- "@v8//bazel/config:msan_enabled" : [ "V8_USE_MEMORY_SANITIZER" ],
+ "@v8//bazel/config:msan_enabled": ["V8_USE_MEMORY_SANITIZER"],
"//conditions:default": [],
}) + select({
- "@v8//bazel/config:ubsan_enabled" : [ "V8_USE_UNDEFINED_BEHAVIOR_SANITIZER" ],
+ "@v8//bazel/config:ubsan_enabled": ["V8_USE_UNDEFINED_BEHAVIOR_SANITIZER"],
"//conditions:default": [],
}) + select(
{
@@ -578,7 +594,7 @@ v8_config(
"V8_ENABLE_SPARKPLUG_PLUS",
],
"@v8//bazel/config:v8_target_s390x": [
- "V8_TARGET_ARCH_S390X"
+ "V8_TARGET_ARCH_S390X",
],
"@v8//bazel/config:v8_target_riscv64": [
# NOTE: Bazel rules for riscv64 weren't tested on a real system.
@@ -587,7 +603,7 @@ v8_config(
],
"@v8//bazel/config:v8_target_ppc64le": [
# NOTE: Bazel rules for ppc64le weren't tested on a real system.
- "V8_TARGET_ARCH_PPC64"
+ "V8_TARGET_ARCH_PPC64",
],
},
no_match_error = "Please specify a target cpu supported by v8",
@@ -657,11 +673,10 @@ v8_config(
"//conditions:default": [],
}) + select({
"v8_drumbrake_bounds_checks": [
- "V8_DRUMBRAKE_BOUNDS_CHECKS"
+ "V8_DRUMBRAKE_BOUNDS_CHECKS",
],
"//conditions:default": [],
}),
-
deps = [":default"],
)
@@ -813,13 +828,11 @@ filegroup(
filegroup(
name = "v8_flags",
srcs = [
+ "src/flags/feature-flags.h",
"src/flags/flag-definitions.h",
"src/flags/flags-impl.h",
"src/flags/flags.h",
- ] + select({
- "is_v8_enable_webassembly": ["src/wasm/wasm-feature-flags.h"],
- "//conditions:default": [],
- }),
+ ],
)
filegroup(
@@ -1284,6 +1297,7 @@ filegroup(
# "src/objects/js-temporal-objects.tq",
"src/objects/js-weak-refs.tq",
"src/objects/literal-objects.tq",
+ "src/objects/managed.tq",
"src/objects/map.tq",
"src/objects/megadom-handler.tq",
"src/objects/microtask.tq",
@@ -1326,7 +1340,7 @@ filegroup(
"src/wasm/wasm-objects.tq",
],
":is_v8_enable_drumbrake": [
- "src/wasm/wasm-interpreter-objects.tq"
+ "src/wasm/wasm-interpreter-objects.tq",
],
"//conditions:default": [],
}),
@@ -1623,8 +1637,6 @@ filegroup(
"src/common/ptr-compr-inl.h",
"src/common/thread-local-storage.h",
"src/common/scoped-modification.h",
- "src/common/segmented-table.h",
- "src/common/segmented-table-inl.h",
"src/common/simd128.h",
"src/common/synchronization-point-support.cc",
"src/common/synchronization-point-support.h",
@@ -1650,6 +1662,8 @@ filegroup(
"src/debug/debug-interface.h",
"src/debug/debug-property-iterator.cc",
"src/debug/debug-property-iterator.h",
+ "src/debug/debug-scope-info.cc",
+ "src/debug/debug-scope-info.h",
"src/debug/debug-scope-iterator.cc",
"src/debug/debug-scope-iterator.h",
"src/debug/debug-scopes.cc",
@@ -1657,10 +1671,6 @@ filegroup(
"src/debug/debug-stack-trace-iterator.cc",
"src/debug/debug-stack-trace-iterator.h",
"src/debug/interface-types.h",
- "src/debug/liveedit.cc",
- "src/debug/liveedit.h",
- "src/debug/liveedit-diff.cc",
- "src/debug/liveedit-diff.h",
"src/deoptimizer/deoptimize-reason.cc",
"src/deoptimizer/deoptimize-reason.h",
"src/deoptimizer/deoptimized-frame-info.cc",
@@ -2097,6 +2107,7 @@ filegroup(
"src/objects/abstract-code.h",
"src/objects/abstract-code-inl.h",
"src/objects/all-objects-inl.h",
+ "src/objects/all-objects.h",
"src/objects/allocation-site.h",
"src/objects/allocation-site-inl.h",
"src/objects/allocation-site-scopes.h",
@@ -2196,6 +2207,7 @@ filegroup(
"src/objects/instance-type.h",
"src/objects/instance-type-checker.h",
"src/objects/instance-type-inl.h",
+ "src/objects/instance-types-gen.h",
"src/objects/internal-index.h",
"src/objects/instruction-stream.cc",
"src/objects/instruction-stream.h",
@@ -2270,6 +2282,7 @@ filegroup(
"src/objects/managed.cc",
"src/objects/managed.h",
"src/objects/managed-inl.h",
+ "src/objects/managed-type-id.h",
"src/objects/map.cc",
"src/objects/map.h",
"src/objects/map-inl.h",
@@ -2296,6 +2309,7 @@ filegroup(
"src/objects/object-macros-undef.h",
"src/objects/object-type.cc",
"src/objects/object-type.h",
+ "src/objects/object-conversions-inl.h",
"src/objects/object-predicates.h",
"src/objects/object-predicates-inl.h",
"src/objects/oddball-predicates.h",
@@ -2627,6 +2641,9 @@ filegroup(
"src/sandbox/sandbox-malloc.h",
"src/sandbox/sandboxed-pointer.h",
"src/sandbox/sandboxed-pointer-inl.h",
+ "src/sandbox/segmented-table.cc",
+ "src/sandbox/segmented-table.h",
+ "src/sandbox/segmented-table-inl.h",
"src/sandbox/tagged-payload.h",
"src/sandbox/testing.cc",
"src/sandbox/testing.h",
@@ -3269,7 +3286,6 @@ filegroup(
"src/wasm/wasm-value.h",
"src/wasm/well-known-imports.cc",
"src/wasm/well-known-imports.h",
-
"src/wasm/wasm-wrapper-cache-inl.h",
"third_party/utf8-decoder/generalized-utf8-decoder.h",
],
@@ -4021,10 +4037,10 @@ filegroup(
"//conditions:default": [],
}) + select({
":enable_drumbrake_x64": [
- "src/wasm/interpreter/x64/interpreter-builtins-x64.cc"
+ "src/wasm/interpreter/x64/interpreter-builtins-x64.cc",
],
":enable_drumbrake_arm64": [
- "src/wasm/interpreter/arm64/interpreter-builtins-arm64.cc"
+ "src/wasm/interpreter/arm64/interpreter-builtins-arm64.cc",
],
"//conditions:default": [],
}),
@@ -4171,27 +4187,27 @@ filegroup(
)
v8_library(
- name = "lib_dragonbox",
- srcs = ["third_party/dragonbox/src/include/dragonbox/dragonbox.h"],
- hdrs = [
- "third_party/dragonbox/src/include/dragonbox/dragonbox.h",
- ],
- includes = [
- "third_party/dragonbox/src/include",
- ],
+ name = "lib_dragonbox",
+ srcs = ["third_party/dragonbox/src/include/dragonbox/dragonbox.h"],
+ hdrs = [
+ "third_party/dragonbox/src/include/dragonbox/dragonbox.h",
+ ],
+ includes = [
+ "third_party/dragonbox/src/include",
+ ],
)
v8_library(
- name = "lib_fp16",
- srcs = ["third_party/fp16/src/include/fp16.h"],
- hdrs = [
- "third_party/fp16/src/include/fp16/fp16.h",
- "third_party/fp16/src/include/fp16/bitcasts.h",
- "third_party/fp16/src/include/fp16/macros.h",
- ],
- includes = [
- "third_party/fp16/src/include",
- ],
+ name = "lib_fp16",
+ srcs = ["third_party/fp16/src/include/fp16.h"],
+ hdrs = [
+ "third_party/fp16/src/include/fp16/fp16.h",
+ "third_party/fp16/src/include/fp16/bitcasts.h",
+ "third_party/fp16/src/include/fp16/macros.h",
+ ],
+ includes = [
+ "third_party/fp16/src/include",
+ ],
)
filegroup(
@@ -4448,6 +4464,8 @@ v8_torque_files(
"class-forward-declarations.h",
# "debug-macros.cc",
# "debug-macros.h",
+ "debug-reader-classes-list.h",
+ "instance-type-checker-lists.h",
"instance-types.h",
"interface-descriptors.inc",
],
@@ -4455,6 +4473,185 @@ v8_torque_files(
noicu_srcs = [":noicu/torque_files"],
)
+# Metagen: libclang-driven IT generator. Produces gen/metagen/instance-types.h
+# which `src/objects/instance-types-gen.h` includes when
+# V8_USE_METAGEN_INSTANCE_TYPES is on. :v8_libshared reaches the targets
+# below only under that flag.
+filegroup(
+ name = "metagen_python_sources",
+ srcs = [
+ "tools/metagen/__init__.py",
+ "tools/metagen/clang_bootstrap.py",
+ "tools/metagen/compile_flags.py",
+ "tools/metagen/cpp_hier.py",
+ "tools/metagen/extract.py",
+ "tools/metagen/instance_types.py",
+ "tools/metagen/metagen.py",
+ ],
+)
+
+# V8 headers staged into the metagen action's sandbox so libclang can
+# resolve transitive #includes. Globbed wide on purpose: cheaper than
+# enumerating the transitive set, and the extra files only cost sandbox
+# materialization.
+filegroup(
+ name = "metagen_sandbox_headers",
+ srcs = glob([
+ "include/**/*.h",
+ "src/**/*.h",
+ "src/**/*.inc",
+ # Vendored third_party headers reached from V8's own (e.g.
+ # src/strings/unicode.h -> utf8-decoder.h). Enumerated rather
+ # than a blanket third_party/**, which would also stage the
+ # large gclient trees.
+ "third_party/utf8-decoder/**/*.h",
+ "third_party/simdutf/**/*.h",
+ "third_party/rapidhash-v8/**/*.h",
+ "third_party/fp16/**/*.h",
+ "third_party/wasm-api/**/*.h",
+ "third_party/siphash/**/*.h",
+ "third_party/vtune/**/*.h",
+ ]),
+)
+
+# Libclang runtime files: the Python bindings + host native library, both
+# from the llvm-libclang package (version-locked together). This filegroup
+# is consumed in the exec configuration, so the select follows the host
+# that runs metagen rather than the V8 target platform.
+filegroup(
+ name = "metagen_libclang_files",
+ srcs = [
+ "third_party/llvm-libclang/bindings/python/clang/__init__.py",
+ "third_party/llvm-libclang/bindings/python/clang/cindex.py",
+ ] + select({
+ "@v8//bazel/config:is_macos": [
+ "third_party/llvm-libclang/lib/libclang.dylib",
+ ],
+ "@v8//bazel/config:is_windows": [
+ "third_party/llvm-libclang/bin/libclang.dll",
+ ],
+ "//conditions:default": [
+ "third_party/llvm-libclang/lib/libclang.so",
+ ],
+ }),
+)
+
+# Clang's builtin headers (stddef.h, stdarg.h, the arch intrinsics).
+# Kept separate from the libclang files above because they are a
+# different input to the rule: metagen takes their directory explicitly
+# and passes it as -isystem. The llvm-libclang package ships the library
+# and the C API headers but no builtin headers, so these come from the
+# clang toolchain, which rolls from the same LLVM revision and therefore
+# matches the parsing library.
+filegroup(
+ name = "metagen_clang_builtin_headers",
+ srcs = glob([
+ "third_party/llvm-build/Release+Asserts/lib/clang/*/include/**",
+ ]),
+)
+
+# The harvest's checked-in C++ driver, shared with GN and metagen.py. It
+# includes src/objects/all-objects.h, whose feature-conditional groups
+# are selected by the normal V8 feature defines. Bazel always defines
+# V8_ENABLE_WEBASSEMBLY via :define_flags; V8_INTL_SUPPORT is added only by
+# the icu-prefixed action. Temporal is disabled because temporal_rs is not a
+# Bazel dependency.
+#
+# The headers themselves reach the action through the
+# `metagen_sandbox_headers` glob below, which already covers src/**.
+filegroup(
+ name = "metagen_driver",
+ srcs = ["tools/metagen/harvest-driver.cc"],
+)
+
+py_binary(
+ name = "metagen_tool",
+ srcs = [
+ "tools/metagen/__init__.py",
+ "tools/metagen/clang_bootstrap.py",
+ "tools/metagen/compile_flags.py",
+ "tools/metagen/cpp_hier.py",
+ "tools/metagen/extract.py",
+ "tools/metagen/instance_types.py",
+ "tools/metagen/metagen.py",
+ ],
+ # tools/metagen/ is a Python package, so the scripts import each
+ # other as `from metagen import ...`, which needs the package's
+ # parent -- tools/ -- on sys.path rather than the package dir
+ # itself. metagen.py arranges that itself when run as a script,
+ # rather than through the `imports` attribute, which not every
+ # py_binary rule this file is built with supports.
+ main = "tools/metagen/metagen.py",
+)
+
+metagen_instance_types(
+ name = "metagen_instance_types_h",
+ driver = ":metagen_driver",
+ clang_builtin_headers = [":metagen_clang_builtin_headers"],
+ libclang_files = [":metagen_libclang_files"],
+ python_srcs = [":metagen_python_sources"],
+ # V8 source-tree headers transitively #include'd from the input
+ # headers. The cc_compilation_context_from CcInfo only covers
+ # :v8_libbase and :define_flags, which doesn't reach src/objects,
+ # src/handles, src/wasm, etc. The natural target that would
+ # (:v8_libshared) depends on this rule's output, so we ship the
+ # headers as raw files in the action sandbox instead.
+ extra_sandbox_files = [":metagen_sandbox_headers"],
+ tool = ":metagen_tool",
+ # Source of the cflags fed to libclang: `:define_flags` carries V8's
+ # arch/feature defines, `:v8_libbase` the source-root / include/ /
+ # libc++ context, the cc toolchain the rest.
+ #
+ # The third_party libs need CcInfo rather than the sandbox glob
+ # because their includes resolve through the lib's own -I, which a
+ # glob cannot supply: abseil is included as absl/..., and fp16.h
+ # does #include "fp16/bitcasts.h". The rest are included by full
+ # path, resolve via -I., and the glob suffices.
+ cc_compilation_context_from = [
+ ":define_flags",
+ ":v8_libbase",
+ ":lib_fp16",
+ ":simdutf",
+ "@abseil-cpp//absl/container:btree",
+ "@abseil-cpp//absl/container:flat_hash_map",
+ "@abseil-cpp//absl/container:flat_hash_set",
+ "@abseil-cpp//absl/container:node_hash_set",
+ "@abseil-cpp//absl/functional:function_ref",
+ "@abseil-cpp//absl/functional:overload",
+ "@abseil-cpp//absl/numeric:int128",
+ "@abseil-cpp//absl/strings:str_format",
+ "@abseil-cpp//absl/synchronization",
+ ],
+ # The icu variant of v8_library compiles with V8_INTL_SUPPORT (via
+ # ENABLE_I18N_SUPPORT_DEFINES copts, invisible to CcInfo) and the
+ # intl object sources, so its IT enum must include the intl types:
+ # the icu-prefixed harvest additionally parses the intl headers,
+ # with the same defines and with ICU's headers + include paths.
+ icu_cc_compilation_context_from = ["//external:icu"],
+ icu_extra_defines = [
+ "V8_INTL_SUPPORT",
+ "ICU_UTIL_DATA_IMPL=ICU_UTIL_DATA_STATIC",
+ "UNISTR_FROM_CHAR_EXPLICIT=",
+ ],
+)
+
+# Header-only library wrapping the metagen output. strip_include_prefix
+# rewrites the include path so `#include "metagen/instance-types.h"`
+# resolves against the gen dir.
+cc_library(
+ name = "icu/metagen_instance_types_headers",
+ hdrs = [":icu/metagen_instance_types_h"],
+ copts = ["-Wno-implicit-fallthrough"],
+ strip_include_prefix = "icu",
+)
+
+cc_library(
+ name = "noicu/metagen_instance_types_headers",
+ hdrs = [":noicu/metagen_instance_types_h"],
+ copts = ["-Wno-implicit-fallthrough"],
+ strip_include_prefix = "noicu",
+)
+
py_binary(
name = "code_generator",
srcs = [
@@ -4571,6 +4768,9 @@ genrule(
v8_mksnapshot(
name = "generated_snapshot_files",
args = select({
+ ":is_v8_enable_builtins_profiling": ["--turbo-profiling"],
+ "//conditions:default": [],
+ }) + select({
":is_v8_enable_verify_heap": ["--verify-heap"],
"//conditions:default": [],
}) + select({
@@ -4661,11 +4861,11 @@ cc_library(
)
cc_library(
- name = "simdutf",
- srcs = ["third_party/simdutf/simdutf.cpp"],
- hdrs = ["third_party/simdutf/simdutf.h"],
- strip_include_prefix = "third_party/simdutf",
- copts = select({
+ name = "simdutf",
+ srcs = ["third_party/simdutf/simdutf.cpp"],
+ hdrs = ["third_party/simdutf/simdutf.h"],
+ strip_include_prefix = "third_party/simdutf",
+ copts = select({
"@v8//bazel/config:is_clang": ["-std=c++20"],
"@v8//bazel/config:is_gcc": ["-std=gnu++2a"],
"@v8//bazel/config:is_windows": ["/std:c++20"],
@@ -4688,18 +4888,34 @@ v8_library(
icu_deps = [
":icu/generated_torque_definitions_headers",
"//external:icu",
- ],
+ ] + select({
+ ":is_v8_use_metagen_instance_types": [
+ ":icu/metagen_instance_types_headers",
+ ],
+ "//conditions:default": [],
+ }),
icu_srcs = [
":generated_regexp_special_case",
":icu/generated_torque_definitions",
":icu/v8_base_without_compiler_files",
- ],
+ ] + select({
+ ":is_v8_use_metagen_instance_types": [":icu/metagen_instance_types_h"],
+ "//conditions:default": [],
+ }),
noicu_deps = [
":noicu/generated_torque_definitions_headers",
- ],
+ ] + select({
+ ":is_v8_use_metagen_instance_types": [
+ ":noicu/metagen_instance_types_headers",
+ ],
+ "//conditions:default": [],
+ }),
noicu_srcs = [
":noicu/generated_torque_definitions",
- ],
+ ] + select({
+ ":is_v8_use_metagen_instance_types": [":noicu/metagen_instance_types_h"],
+ "//conditions:default": [],
+ }),
deps = [
":lib_dragonbox",
"//third_party/fast_float/src:fast_float",
diff --git a/deps/v8/BUILD.gn b/deps/v8/BUILD.gn
index 72163489956..c6132807ff6 100644
--- a/deps/v8/BUILD.gn
+++ b/deps/v8/BUILD.gn
@@ -7,6 +7,7 @@
import("//build/config/android/config.gni")
import("//build/config/arm.gni")
import("//build/config/c++/c++.gni")
+import("//build/config/clang/clang.gni")
import("//build/config/coverage/coverage.gni")
import("//build/config/dcheck_always_on.gni")
import("//build/config/host_byteorder.gni")
@@ -24,6 +25,11 @@ if (is_clang) {
import("//build/config/clang/clang.gni")
}
+if (is_win && v8_use_metagen_instance_types) {
+ # For the SDK include flags, see `metagen_instance_types_h`.
+ import("//build/toolchain/win/win_toolchain_data.gni")
+}
+
if (v8_enable_temporal_support) {
import("//build/config/rust.gni")
}
@@ -43,6 +49,16 @@ declare_args() {
# Print to stdout on Android.
v8_android_log_stdout = false
+ # Native libclang for the metagen instance-type harvest, for platforms
+ # that have no prebuilt llvm-libclang package (currently ppc64 and s390x).
+ # Both are absolute paths, and both must be set or both left empty.
+ # v8_metagen_libclang_so: the native libclang shared library.
+ # v8_metagen_libclang_bindings_dir: the directory holding the matching
+ # clang/cindex.py bindings (i.e. the
+ # dir that contains the clang/ package).
+ v8_metagen_libclang_so = ""
+ v8_metagen_libclang_bindings_dir = ""
+
# Dynamically set an additional dependency from v8/custom_deps.
v8_custom_deps = ""
@@ -71,6 +87,13 @@ declare_args() {
# Enable compiler warnings when using V8_DEPRECATED apis.
v8_deprecation_warnings = true
+ # Check that executing JavaScript inside API interrupt callbacks is
+ # disallowed.
+ # TODO(40067940): Ensure this does not break DevTools.
+ # TODO(node): Upstream issue https://github.com/nodejs/node/pull/65028
+ v8_disallow_js_in_api_interrupts_is_checked =
+ !(defined(build_with_node) && build_with_node)
+
# Enable compiler warnings when using V8_DEPRECATE_SOON apis.
v8_imminent_deprecation_warnings = true
@@ -104,6 +127,9 @@ declare_args() {
# Sets -DV8_ENABLE_APX_F.
v8_enable_apx_f = false
+ # Sets -DV8_ENABLE_AVX10_1.
+ v8_enable_avx10_1 = false
+
# Sets -DENABLE_HUGEPAGE
v8_enable_hugepage = false
@@ -135,7 +161,9 @@ declare_args() {
v8_enable_slow_dchecks = false
# Enable fast mksnapshot runs.
- v8_enable_fast_mksnapshot = false
+ v8_enable_fast_mksnapshot =
+ build_with_chromium && (is_debug || dcheck_always_on) &&
+ !is_official_build
# Enable using multiple threads to build builtins in mksnapshot.
v8_enable_concurrent_mksnapshot = true
@@ -531,6 +559,13 @@ declare_args() {
v8_logging_level = ""
}
+# The native-libclang args are a matched pair: a .so with no bindings (or
+# vice versa) is always a misconfiguration, so fail early rather than at the
+# metagen action. Both being empty is the normal, bundled-package case.
+assert(v8_metagen_libclang_so == "" == (v8_metagen_libclang_bindings_dir == ""),
+ "v8_metagen_libclang_so and v8_metagen_libclang_bindings_dir must be " +
+ "set together or left empty together.")
+
# Derived defaults.
if (v8_logging_level == "") {
if (v8_enable_verification_features || v8_dcheck_always_on) {
@@ -656,7 +691,8 @@ if (v8_enable_sparkplug == "") {
v8_enable_sparkplug = !v8_jitless
}
v8_enable_sparkplug_plus = v8_enable_sparkplug && (v8_current_cpu == "x64" ||
- v8_current_cpu == "arm64")
+ v8_current_cpu == "arm64" ||
+ v8_current_cpu == "loong64")
if (v8_enable_maglev == "") {
v8_enable_maglev =
v8_enable_turbofan &&
@@ -1059,11 +1095,11 @@ external_v8_defines = [
"V8_COMPRESS_ZONES",
"V8_ENABLE_SANDBOX",
"V8_DEPRECATION_WARNINGS",
+ "V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED",
"V8_IMMINENT_DEPRECATION_WARNINGS",
"V8_USE_PERFETTO",
"V8_USE_PERFETTO_JSON_EXPORT",
"V8_USE_PERFETTO_SDK",
- "V8_CPPGC_MICROTASK_QUEUE",
"V8_MAP_PACKING",
"V8_IS_TSAN",
"V8_ENABLE_DIRECT_HANDLE",
@@ -1110,6 +1146,10 @@ if (v8_enable_sandbox) {
if (v8_deprecation_warnings) {
enabled_external_v8_defines += [ "V8_DEPRECATION_WARNINGS" ]
}
+if (v8_disallow_js_in_api_interrupts_is_checked) {
+ enabled_external_v8_defines +=
+ [ "V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED" ]
+}
if (v8_imminent_deprecation_warnings) {
enabled_external_v8_defines += [ "V8_IMMINENT_DEPRECATION_WARNINGS" ]
}
@@ -1122,9 +1162,7 @@ if (v8_use_perfetto_json_export) {
if (v8_use_perfetto_sdk) {
enabled_external_v8_defines += [ "V8_USE_PERFETTO_SDK" ]
}
-if (v8_cppgc_microtask_queue) {
- enabled_external_v8_defines += [ "V8_CPPGC_MICROTASK_QUEUE" ]
-}
+
if (v8_enable_map_packing) {
enabled_external_v8_defines += [ "V8_MAP_PACKING" ]
}
@@ -1277,6 +1315,13 @@ config("features") {
"V8_LOGGING_LEVEL=${v8_logging_level}",
]
+ # Selects metagen vs Torque instance-type output (see
+ # src/objects/instance-types-gen.h). The header defaults to metagen
+ # when this is undefined, so only the off case needs a define.
+ if (!v8_use_metagen_instance_types) {
+ defines += [ "V8_USE_METAGEN_INSTANCE_TYPES=0" ]
+ }
+
configs = [
":v8_header_features",
":cppgc_header_features",
@@ -1340,6 +1385,9 @@ config("features") {
if (v8_enable_apx_f) {
defines += [ "V8_ENABLE_APX_F" ]
}
+ if (v8_enable_avx10_1) {
+ defines += [ "V8_ENABLE_AVX10_1" ]
+ }
if (v8_enable_hugepage) {
defines += [ "ENABLE_HUGEPAGE" ]
}
@@ -1391,9 +1439,6 @@ config("features") {
if (v8_enable_temporal_support) {
defines += [ "V8_TEMPORAL_SUPPORT" ]
}
- if (v8_enable_temporal_systemicu) {
- defines += [ "V8_ENABLE_TEMPORAL_SYSTEMICU" ]
- }
if (v8_enable_local_handle_zapping) {
defines += [ "ENABLE_LOCAL_HANDLE_ZAPPING" ]
}
@@ -1463,6 +1508,9 @@ config("features") {
if (v8_fuzzilli) {
defines += [ "V8_FUZZILLI" ]
}
+ if (v8_enable_builtins_profiling) {
+ defines += [ "V8_ENABLE_BUILTINS_PROFILING" ]
+ }
if (use_chromium_fuzzilli) {
defines += [ "USE_CHROMIUM_FUZZILLI" ]
}
@@ -1484,6 +1532,9 @@ config("features") {
v8_current_cpu == "x64") {
defines += [ "V8_BUILTINS_GEARBOX" ]
}
+ if (v8_enable_builtins_optimization) {
+ defines += [ "V8_ENABLE_BUILTINS_OPTIMIZATION" ]
+ }
if (v8_enable_short_builtin_calls) {
defines += [ "V8_SHORT_BUILTIN_CALLS" ]
}
@@ -1724,16 +1775,7 @@ config("toolchain") {
if (v8_current_cpu == "ppc64") {
defines += [ "V8_TARGET_ARCH_PPC64" ]
cflags += [ "-ffp-contract=off" ]
- if (current_os == "aix" && !is_clang) {
- cflags += [
- # Work around AIX ceil, trunc and round oddities.
- "-mcpu=power5+",
- "-mfprnd",
-
- # Work around AIX assembler popcntb bug.
- "-mno-popcntb",
- ]
- } else if (!v8_target_is_simulator) {
+ if (!v8_target_is_simulator) {
cflags += [ "-mcpu=pwr9" ]
}
}
@@ -1957,10 +1999,10 @@ config("strict_warnings") {
v8_current_cpu == "mips64el" || v8_current_cpu == "riscv64") {
cflags += [ "-Wshorten-64-to-32" ]
}
- cflags += [ "-Wmissing-field-initializers" ]
- if (v8_current_cpu != "ppc64" && v8_current_cpu != "s390x") {
- cflags += [ "-Wunnecessary-virtual-specifier" ]
- }
+ cflags += [
+ "-Wmissing-field-initializers",
+ "-Wunnecessary-virtual-specifier",
+ ]
}
}
@@ -2016,9 +2058,17 @@ if (v8_postmortem_support) {
script = "tools/gen-postmortem-metadata.py"
+ if (v8_use_metagen_instance_types) {
+ _instance_types_header = "$target_gen_dir/metagen/instance-types.h"
+ } else {
+ _instance_types_header =
+ "$target_gen_dir/torque-generated/instance-types.h"
+ }
+
# NOSORT
inputs = [
- "$target_gen_dir/torque-generated/instance-types.h",
+ _instance_types_header,
+ "$target_gen_dir/torque-generated/debug-reader-classes-list.h",
"src/objects/allocation-site.h",
"src/objects/allocation-site-inl.h",
"src/objects/cell.h",
@@ -2124,6 +2174,9 @@ if (v8_postmortem_support) {
rebase_path(inputs, root_build_dir)
deps = [ ":run_torque" ]
+ if (v8_use_metagen_instance_types) {
+ deps += [ ":metagen_instance_types_h" ]
+ }
}
}
@@ -2324,6 +2377,7 @@ torque_files = [
"src/objects/js-struct.tq",
"src/objects/js-weak-refs.tq",
"src/objects/literal-objects.tq",
+ "src/objects/managed.tq",
"src/objects/map.tq",
"src/objects/megadom-handler.tq",
"src/objects/microtask.tq",
@@ -2395,6 +2449,178 @@ if (v8_enable_webassembly) {
}
}
+if (v8_use_metagen_instance_types) {
+ # The checked-in translation unit metagen parses. It includes
+ # src/objects/all-objects.h, whose feature-specific groups use the same
+ # defines as their V8 sources.
+ _metagen_driver_file = "tools/metagen/harvest-driver.cc"
+ _metagen_out_dir = "$target_gen_dir/metagen"
+
+ # metagen's libclang Python bindings and native library, declared as
+ # inputs so a package roll re-runs the harvest.
+ #
+ # The `//` prefix is load-bearing: llvm-libclang lives in the checkout
+ # root's third_party in both layouts (v8/ standalone, src/ under
+ # Chromium), whereas a relative path would anchor at //v8/ in Chromium.
+ if (v8_metagen_libclang_so != "") {
+ # System libclang + separately-staged bindings: the bundled package files
+ # do not exist on this platform, so declare none of them as inputs.
+ _metagen_libclang_files = []
+ } else {
+ _metagen_libclang_files = [
+ "//third_party/llvm-libclang/bindings/python/clang/cindex.py",
+ "//third_party/llvm-libclang/bindings/python/clang/__init__.py",
+ ]
+ if (host_os == "mac") {
+ _metagen_libclang_files +=
+ [ "//third_party/llvm-libclang/lib/libclang.dylib" ]
+ } else if (host_os == "win") {
+ _metagen_libclang_files +=
+ [ "//third_party/llvm-libclang/bin/libclang.dll" ]
+ } else {
+ _metagen_libclang_files +=
+ [ "//third_party/llvm-libclang/lib/libclang.so" ]
+ }
+ }
+
+ # The clang toolchain's resource dir contains builting headers
+ # include/{stddef.h,stdarg.h,...}.
+ _metagen_clang_resource_dir = "$clang_base_path/lib/clang/$clang_version"
+ _metagen_flags_target = ":v8_base_without_compiler"
+ _metagen_flags_target_ninja =
+ get_label_info(_metagen_flags_target, "target_out_dir") +
+ "/v8_base_without_compiler.ninja"
+
+ action("metagen_instance_types_h") {
+ visibility = [
+ ":*",
+ "tools/debug_helper/:*",
+ ]
+
+ script = "tools/metagen/metagen.py"
+
+ # The script obtains the parse flags through `gn desc`, so make the build
+ # configuration an explicit input. In particular, changing a feature define
+ # must re-run the driver even though the action command is unchanged.
+ deps = [ ":v8_dump_build_config" ]
+
+ if (v8_generate_external_defines_header) {
+ # v8config.h includes the generated v8-gn.h in this configuration.
+ deps += [ ":gen_v8_gn" ]
+ }
+
+ # No deps on V8's own generators: every generated header the harvested set
+ # reaches short-circuits to empty under V8_METAGEN_GENERATION_PASS
+ # (see builtins-definitions.h and factory-base.h), so the harvest runs
+ # independently of Torque and the bytecode-builtins-list generator.
+ # Perfetto's generated headers are kept out of the parse the same way, by
+ # undefining V8_USE_PERFETTO for it (see metagen.py).
+
+ # `inputs`, not `sources`: these headers belong to the V8 targets that
+ # compile them; this action only reads them.
+ inputs = [
+ "tools/metagen/clang_bootstrap.py",
+ "tools/metagen/compile_flags.py",
+ "tools/metagen/cpp_hier.py",
+ "tools/metagen/extract.py",
+ "tools/metagen/instance_types.py",
+ "tools/metagen/metagen.py",
+ _metagen_driver_file,
+ "$root_out_dir/v8_build_config.json",
+
+ # Proxy for the whole builtin-header directory, which has no
+ # GN glob: a toolchain roll rewrites stddef.h along with the
+ # rest, and the harvest cannot parse without it.
+ "$_metagen_clang_resource_dir/include/stddef.h",
+ ] + _metagen_libclang_files
+
+ outputs = [ "$_metagen_out_dir/instance-types.h" ]
+
+ # The files the harvest read a fact out of, reported by the script.
+ # `inputs` above declares only the driver, so this is what re-runs the
+ # harvest when a class declaration or a marker changes.
+ #
+ # Binds to the first output, so output order matters if one is added.
+ depfile = "$_metagen_out_dir/instance-types.h.d"
+
+ args = [
+ "--depfile",
+ rebase_path(depfile, root_build_dir),
+ "--driver",
+ rebase_path(_metagen_driver_file, root_build_dir),
+ "--v8-root",
+ rebase_path(".", root_build_dir),
+ "--build-dir",
+ ".", # The action runs with cwd=root_build_dir.
+
+ # metagen cannot find this by walking up from the build dir: on
+ # ChromeOS the build dir sits outside the checkout entirely.
+ "--source-root",
+ rebase_path("//", root_build_dir),
+ "--out",
+ rebase_path(_metagen_out_dir, root_build_dir),
+
+ # Representative compiled target whose flags metagen harvests via
+ # `gn desc`: its TUs include the headers metagen parses, so its
+ # config is the right one. Passed as a string, not a dep, to avoid a
+ # cycle with the targets that consume instance-types.h.
+ # Pass the current_toolchain so cross-compiles are handled correctly.
+ # It travels in its own argument because GN would not quote the
+ # parentheses of a qualified label on a Windows command line.
+ "--flags-from-target",
+ get_label_info(_metagen_flags_target, "label_no_toolchain"),
+ "--flags-toolchain",
+ current_toolchain,
+
+ # GN does not allow its generated ninja files as explicit action inputs.
+ # Have metagen add the file containing the queried flags to its depfile.
+ "--flags-dependency",
+ rebase_path(_metagen_flags_target_ninja, root_build_dir),
+
+ # We pass a resource dir, not an include dir, so the driver decides where
+ # the builtin headers sit: behind libc++, ahead of the Windows SDK's
+ # copies of stddef.h and the intrinsics. See tools/metagen/metagen.py.
+ "--clang-resource-dir",
+ rebase_path(_metagen_clang_resource_dir, root_build_dir),
+ ]
+
+ if (v8_metagen_libclang_so != "") {
+ # No prebuilt llvm-libclang for this platform: point metagen at the
+ # system libclang and the separately-staged cindex bindings. The two
+ # args are validated as a pair at the top of this file.
+ args += [
+ "--libclang-so",
+ v8_metagen_libclang_so,
+ "--libclang-bindings-dir",
+ v8_metagen_libclang_bindings_dir,
+
+ # The toolchain major, so metagen can warn if the loaded libclang is
+ # out of step with the clang whose builtin headers it parses against.
+ "--expect-libclang-major",
+ clang_version,
+ ]
+ } else {
+ # Package root, so metagen need not guess the checkout layout.
+ args += [
+ "--libclang-dir",
+ rebase_path("//third_party/llvm-libclang", root_build_dir),
+ ]
+ }
+
+ if (is_win) {
+ # The SDK/UCRT include dirs never show up in `gn desc`: the toolchain
+ # interpolates them into its tool command template instead of into
+ # cflags. Pass the build's own resolved flags, the way
+ # build/modules/BUILD.gn does, so an SDK roll reruns the harvest.
+ # `--extra-flag=` attaches the value because the flags start with a
+ # dash (-imsvc<dir>) and argparse would take them for options.
+ foreach(flag, current_win_toolchain_data.include_flags_imsvc_list) {
+ args += [ "--extra-flag=$flag" ]
+ }
+ }
+ }
+}
+
if (v8_enable_experimental_tq_to_tsa) {
template("run_torque_to_tsa") {
if (target_name == "") {
@@ -2508,9 +2734,11 @@ template("run_torque") {
"$destination_folder/csa-types.h",
"$destination_folder/debug-macros.cc",
"$destination_folder/debug-macros.h",
+ "$destination_folder/debug-reader-classes-list.h",
"$destination_folder/enum-verifiers.cc",
"$destination_folder/exported-macros-assembler.cc",
"$destination_folder/exported-macros-assembler.h",
+ "$destination_folder/instance-type-checker-lists.h",
"$destination_folder/instance-types.h",
"$destination_folder/interface-descriptors.inc",
]
@@ -2606,6 +2834,7 @@ group("v8_simdutf") {
visibility = [ "./*" ]
}
+
config("simdutf_include_config") {
include_dirs = [ "//third_party/simdutf" ]
}
@@ -2767,6 +2996,7 @@ template("run_mksnapshot") {
} else {
suffix = "_$name"
}
+
action("run_mksnapshot_" + name) {
deps = [ ":mksnapshot($v8_snapshot_toolchain)" ]
if (v8_verify_deterministic_mksnapshot) {
@@ -3051,6 +3281,7 @@ if (v8_verify_builtins_compatibility) {
# This specifies a separate mksnapshot target for each of:
# x86, x64, arm, arm64.
hashes = "builtins_hashes_$v8_current_cpu"
+
run_mksnapshot("dump_$v8_current_cpu") {
args = [
"--dump-builtins-hashes-to-file",
@@ -3071,6 +3302,7 @@ if (v8_verify_builtins_compatibility) {
profile_toolchain = "//build/toolchain/linux:clang_${profile_arch}"
target_toolchain =
"//build/toolchain/linux:clang_${profile_arch}_v8_${target_arch}"
+
action("compare_builtins_$target_name") {
deps = [
":run_mksnapshot_dump_${profile_arch}($profile_toolchain)",
@@ -3207,7 +3439,6 @@ action("v8_dump_build_config") {
"wasm_random_fuzzers=$v8_wasm_random_fuzzers",
"memory_corruption_api=$v8_enable_memory_corruption_api",
"lower_limits_mode=$v8_lower_limits_mode",
- "cppgc_microtask_queue=$v8_cppgc_microtask_queue",
"test_only_sync_points=$v8_enable_test_only_sync_points",
# Please add new switches also in `build_config_content` in `bazel/defs.bzl`
@@ -3229,6 +3460,8 @@ generated_file("v8_generate_features_json") {
output_conversion = "json"
contents = {
v8_deprecation_warnings = v8_deprecation_warnings
+ v8_disallow_js_in_api_interrupts_is_checked =
+ v8_disallow_js_in_api_interrupts_is_checked
v8_enable_31bit_smis_on_64bit_arch = v8_enable_31bit_smis_on_64bit_arch
v8_enable_direct_handle = v8_enable_direct_handle
v8_enable_extensible_ro_snapshot = v8_enable_extensible_ro_snapshot
@@ -3236,7 +3469,6 @@ generated_file("v8_generate_features_json") {
v8_enable_hugepage = v8_enable_hugepage
v8_enable_i18n_support = v8_enable_i18n_support
v8_enable_temporal_support = v8_enable_temporal_support
- v8_enable_temporal_systemicu = v8_enable_temporal_systemicu
v8_enable_javascript_promise_hooks = v8_enable_javascript_promise_hooks
v8_enable_lite_mode = v8_enable_lite_mode
v8_enable_map_packing = v8_enable_map_packing
@@ -3253,7 +3485,6 @@ generated_file("v8_generate_features_json") {
v8_optimized_debug = v8_optimized_debug
v8_random_seed = v8_random_seed
v8_use_perfetto = v8_use_perfetto
- v8_cppgc_microtask_queue = v8_cppgc_microtask_queue
v8_use_siphash = v8_use_siphash
v8_use_default_hasher_secret = v8_use_default_hasher_secret
}
@@ -3691,6 +3922,7 @@ v8_header_set("v8_flags") {
configs = [ ":internal_config" ]
sources = [
+ "src/flags/feature-flags.h",
"src/flags/flag-definitions.h",
"src/flags/flags-impl.h",
"src/flags/flags.h",
@@ -3829,8 +4061,6 @@ v8_header_set("v8_internal_headers") {
"src/common/ptr-compr-inl.h",
"src/common/ptr-compr.h",
"src/common/scoped-modification.h",
- "src/common/segmented-table-inl.h",
- "src/common/segmented-table.h",
"src/common/simd128.h",
"src/common/synchronization-point-support.h",
"src/common/thread-local-storage.h",
@@ -4077,13 +4307,12 @@ v8_header_set("v8_internal_headers") {
"src/debug/debug-frames.h",
"src/debug/debug-interface.h",
"src/debug/debug-property-iterator.h",
+ "src/debug/debug-scope-info.h",
"src/debug/debug-scope-iterator.h",
"src/debug/debug-scopes.h",
"src/debug/debug-stack-trace-iterator.h",
"src/debug/debug.h",
"src/debug/interface-types.h",
- "src/debug/liveedit-diff.h",
- "src/debug/liveedit.h",
"src/deoptimizer/deoptimize-reason.h",
"src/deoptimizer/deoptimized-frame-info.h",
"src/deoptimizer/deoptimizer.h",
@@ -4346,6 +4575,7 @@ v8_header_set("v8_internal_headers") {
"src/numbers/ieee754.h",
"src/numbers/math-random.h",
"src/objects/all-objects-inl.h",
+ "src/objects/all-objects.h",
"src/objects/allocation-site-inl.h",
"src/objects/allocation-site-scopes-inl.h",
"src/objects/allocation-site-scopes.h",
@@ -4473,6 +4703,7 @@ v8_header_set("v8_internal_headers") {
"src/objects/lookup-inl.h",
"src/objects/lookup.h",
"src/objects/managed-inl.h",
+ "src/objects/managed-type-id.h",
"src/objects/managed.h",
"src/objects/map-inl.h",
"src/objects/map-updater.h",
@@ -4489,6 +4720,7 @@ v8_header_set("v8_internal_headers") {
"src/objects/module.h",
"src/objects/name-inl.h",
"src/objects/name.h",
+ "src/objects/object-conversions-inl.h",
"src/objects/object-list-macros.h",
"src/objects/object-macros-undef.h",
"src/objects/object-macros.h",
@@ -4693,6 +4925,8 @@ v8_header_set("v8_internal_headers") {
"src/sandbox/sandboxable-thread.h",
"src/sandbox/sandboxed-pointer-inl.h",
"src/sandbox/sandboxed-pointer.h",
+ "src/sandbox/segmented-table-inl.h",
+ "src/sandbox/segmented-table.h",
"src/sandbox/tagged-payload.h",
"src/sandbox/testing.h",
"src/sandbox/trusted-pointer-scope.h",
@@ -4987,7 +5221,6 @@ v8_header_set("v8_internal_headers") {
"src/wasm/wasm-engine.h",
"src/wasm/wasm-export-wrapper-cache.h",
"src/wasm/wasm-external-refs.h",
- "src/wasm/wasm-feature-flags.h",
"src/wasm/wasm-features.h",
"src/wasm/wasm-import-wrapper-cache.h",
"src/wasm/wasm-init-expr.h",
@@ -5028,8 +5261,6 @@ v8_header_set("v8_internal_headers") {
if (v8_enable_wasm_simd256_revec) {
sources += [
- "src/compiler/linear-scheduler.h",
- "src/compiler/revectorizer.h",
"src/compiler/turboshaft/wasm-revec-phase.h",
"src/compiler/turboshaft/wasm-revec-reducer.h",
]
@@ -5485,6 +5716,9 @@ v8_header_set("v8_internal_headers") {
if (v8_enable_experimental_tq_to_tsa) {
deps += [ ":run_torque_to_tsa" ]
}
+ if (v8_use_metagen_instance_types) {
+ deps += [ ":metagen_instance_types_h" ]
+ }
}
v8_compiler_sources = [
@@ -5783,8 +6017,6 @@ if (v8_enable_webassembly) {
if (v8_enable_wasm_simd256_revec) {
v8_compiler_sources += [
- "src/compiler/linear-scheduler.cc",
- "src/compiler/revectorizer.cc",
"src/compiler/turboshaft/wasm-revec-phase.cc",
"src/compiler/turboshaft/wasm-revec-reducer.cc",
]
@@ -6032,12 +6264,11 @@ v8_cluster_source_set("v8_base_without_compiler") {
"src/debug/debug-frames.cc",
"src/debug/debug-interface.cc",
"src/debug/debug-property-iterator.cc",
+ "src/debug/debug-scope-info.cc",
"src/debug/debug-scope-iterator.cc",
"src/debug/debug-scopes.cc",
"src/debug/debug-stack-trace-iterator.cc",
"src/debug/debug.cc",
- "src/debug/liveedit-diff.cc",
- "src/debug/liveedit.cc",
"src/deoptimizer/deoptimize-reason.cc",
"src/deoptimizer/deoptimized-frame-info.cc",
"src/deoptimizer/deoptimizer.cc",
@@ -6370,6 +6601,7 @@ v8_cluster_source_set("v8_base_without_compiler") {
"src/sandbox/js-dispatch-table.cc",
"src/sandbox/sandbox.cc",
"src/sandbox/sandboxable-thread.cc",
+ "src/sandbox/segmented-table.cc",
"src/sandbox/testing.cc",
"src/sandbox/trap-fuzzer.cc",
"src/sandbox/trusted-pointer-scope.cc",
@@ -7926,6 +8158,7 @@ if (v8_check_header_includes) {
# This file will be generated by tools/generate-header-include-checks.py
# if the "check_v8_header_includes" gclient variable is set.
import("check-header-includes/sources.gni")
+
v8_source_set("check_headers") {
configs = [ ":internal_config" ]
sources = check_header_includes_sources
@@ -7965,6 +8198,7 @@ if (v8_monolithic) {
# Using external startup data would produce separate files.
assert(!v8_use_external_startup_data,
"Set `v8_use_external_startup_data = false` for v8_monolithic.")
+
v8_static_library("v8_monolith") {
deps = [
":v8",
@@ -8229,7 +8463,10 @@ group("gn_all") {
}
group("v8_python_base") {
- data = [ ".vpython3" ]
+ data = [
+ "vpython.toml",
+ "vpython.toml.uv.lock",
+ ]
}
# Enable fallbacks for files that might be hard to access on Clusterfuzz.
@@ -8872,6 +9109,7 @@ if (v8_enable_webassembly) {
template("v8_wasm_fuzzer") {
forward_variables_from(invoker, "*")
+
v8_fuzzer(target_name) {
deps = [ ":wasm_test_common" ]
}
diff --git a/deps/v8/COMMON_OWNERS b/deps/v8/COMMON_OWNERS
index d789357ca67..998869969e6 100644
--- a/deps/v8/COMMON_OWNERS
+++ b/deps/v8/COMMON_OWNERS
@@ -1,5 +1,6 @@
ahaas@chromium.org
alexschulze@chromium.org
+arashk@chromium.org
bikineev@chromium.org
bmeurer@chromium.org
cbruni@chromium.org
diff --git a/deps/v8/DEPS b/deps/v8/DEPS
index 30d59efdb80..67ee185a5af 100644
--- a/deps/v8/DEPS
+++ b/deps/v8/DEPS
@@ -76,6 +76,9 @@ vars = {
# Fetch the internal agents repository.
'checkout_agents_internal': False,
+ # CPython 3 CIPD package version for Siso hermetic toolchain.
+ 'cpython3_version': 'version:3@3.11.9.chromium.38',
+
# reclient CIPD package version
'reclient_version': 're_client_version:0.185.0.db415f21-gomaip',
@@ -96,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:641ace93dd9560e75e7add0d08f77b446fbb3b78',
+ 'gn_version': 'git_revision:a99d46a9d04c770d6bb87387058e1d7b151758ce',
# 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:78c72819a5567e09f4b3083b04c6b15d11bb345b',
+ 'siso_version': 'git_revision:efbbe7f1892211b5e9512576843a3c247b6a6d7c',
# 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:32.20260723.5.1',
+ 'fuchsia_version': 'version:33.20260824.1.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': '66df8ef636795eff70efc52a47d8f62612800054',
+ 'partition_alloc_version': 'c029851c21b7e1154fa3964e08c97710adc92cc7',
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling android_sdk_build-tools_version
@@ -138,15 +141,15 @@ vars = {
# Three lines of non-changing comments so that
# the commit queue can handle CLs rolling jetstream_3.0-custom_revision
# and whatever else without interference from each other.
- 'jetstream_3.0-custom_revision': '91552391bf2f429a2b7102c5c02d6f2cb82b4bcf',
+ 'jetstream_3.0-custom_revision': 'ffde597c189c9c781986a6247a5844b1c04e4a8a',
# 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': '21c25488408500557636122892d27dda39a0f922',
+ 'agents_internal_revision': 'd2d5adf5a243d90aba25902a46fc32e7a4f5ab99',
# 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': '559f135fc214d637f85174c6be7010804e31f1e5',
+ 'agents_public_revision': '4e0a8bacdfcc6b6303540aa466b05a508f349486',
}
deps = {
@@ -158,9 +161,9 @@ deps = {
'condition': 'checkout_agents_internal',
},
'build':
- Var('chromium_url') + '/chromium/src/build.git' + '@' + 'fab0ea1e4e8033be4088e2478d58cfac471b76ca',
+ Var('chromium_url') + '/chromium/src/build.git' + '@' + '8ca8a372cab9ff143072204053d30fbc2c17bd7a',
'buildtools':
- Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '0d8a204ff274ee12fa9ace5e3ffd8e5fbcb54926',
+ Var('chromium_url') + '/chromium/src/buildtools.git' + '@' + '6f6a5dbf04b734214f3b1f386567d101ec9d607e',
'buildtools/linux64': {
'packages': [
{
@@ -215,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' + '@' + '9e61c12835c5e4a3bdba93850427e6742c4f64c4',
+ Var('chromium_url') + '/external/github.com/tc39/test262.git' + '@' + '72faf8ec1445c55149615e8b35187830783aba1a',
'third_party/android_platform': {
'url': Var('chromium_url') + '/chromium/src/third_party/android_platform.git' + '@' + 'e3919359f2387399042d31401817db4a02d756ec',
'condition': 'checkout_android',
@@ -257,11 +260,11 @@ deps = {
'dep_type': 'cipd',
},
'third_party/catapult': {
- 'url': Var('chromium_url') + '/catapult.git' + '@' + '74513188f5cd39f9edb16236ea3a49ed5b3cb3c6',
+ 'url': Var('chromium_url') + '/catapult.git' + '@' + '50c971fc0958d8c1fb0adcc97f41b90042fa7c87',
'condition': 'checkout_android',
},
'third_party/clang-format/script':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git' + '@' + '6eddfb5ec5f92127a531eda66c568d3a11e7ec11',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/clang/tools/clang-format.git' + '@' + '70510081984cfcdb14a15b3e08dfe9776dc7ed37',
'third_party/colorama/src': {
'url': Var('chromium_url') + '/external/colorama.git' + '@' + '3de9f013df4b470069d03d250224062e8cf15c49',
'condition': 'checkout_android',
@@ -275,7 +278,7 @@ deps = {
'condition': 'checkout_android',
},
'third_party/depot_tools':
- Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'f394ab2c993283e94680ca13db98b99927868e98',
+ Var('chromium_url') + '/chromium/tools/depot_tools.git' + '@' + 'cb70c994a656601dc6a0d423f49ff57503bd70bc',
'third_party/dragonbox/src':
Var('chromium_url') + '/external/github.com/jk-jeon/dragonbox.git' + '@' + 'beeeef91cf6fef89a4d4ba5e95d47ca64ccb3a44',
'third_party/fp16/src':
@@ -283,7 +286,7 @@ deps = {
'third_party/fast_float/src':
Var('chromium_url') + '/external/github.com/fastfloat/fast_float.git' + '@' + '34164f547b7df3f5d794ff67e9f885c36819ebfc',
'third_party/fuchsia-gn-sdk': {
- 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '4f34a41435a29fbf91cb3c6e0bcaffff6598c190',
+ 'url': Var('chromium_url') + '/chromium/src/third_party/fuchsia-gn-sdk.git' + '@' + '740d23bfe5b137c2c387a4b421f120f6126845de',
'condition': 'checkout_fuchsia',
},
'third_party/simdutf':
@@ -307,17 +310,17 @@ deps = {
'url': Var('chromium_url') + '/external/github.com/google/benchmark.git' + '@' + '8abf1e701fbd88c8170f48fe0558247e2e5f8e7d',
},
'third_party/fuzztest':
- Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + 'cc30588369ddfd00e2098229ea8050a8ebe1cf58',
+ Var('chromium_url') + '/chromium/src/third_party/fuzztest.git' + '@' + 'f0f143db954fb311d4e7ba39972d2dab9ba47e2a',
'third_party/fuzztest/src':
- Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '073bf2392bf11e22d456036a8f7d286bc9a6d346',
+ Var('chromium_url') + '/external/github.com/google/fuzztest.git' + '@' + '846bda6f291e26b7f8fb33c8de23796129bffd12',
'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' + '@' + 'd578f2e8b7bd5938e21cfb6bf15c079e0aa5b738',
+ Var('chromium_url') + '/chromium/deps/icu.git' + '@' + '6ebb40c594776cc2c21ea14df85a2a89a328b364',
'third_party/instrumented_libs': {
- 'url': Var('chromium_url') + '/chromium/third_party/instrumented_libraries.git' + '@' + 'e8cb570a9a2ee9128e2214c73417ad2a3c47780b',
+ 'url': Var('chromium_url') + '/chromium/third_party/instrumented_libraries.git' + '@' + 'd15c278eed5d38d9acf2d8054cf37baba93cef8e',
'condition': 'checkout_instrumented_libraries',
},
'third_party/ittapi': {
@@ -329,175 +332,182 @@ deps = {
'third_party/jinja2':
Var('chromium_url') + '/chromium/src/third_party/jinja2.git' + '@' + 'c3027d884967773057bf74b957e3fea87e5df4d7',
'third_party/jsoncpp/source':
- Var('chromium_url') + '/external/github.com/open-source-parsers/jsoncpp.git'+ '@' + 'edc01ab10f52135ec80e3589b6b4e0a9c65b27fd',
+ Var('chromium_url') + '/external/github.com/open-source-parsers/jsoncpp.git'+ '@' + '3347a4b86bb914cb565f0cbda19c06e109513300',
'third_party/libc++/src':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxx.git' + '@' + 'b16984ce99c702355a5b2b4c52574e82cec41fb9',
+ 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' + '@' + '8f11bb1d4438d0239d0dfc1bd9456a9f31629dda',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libcxxabi.git' + '@' + 'fc1897a2c12aa27e703c3ed48b62eba8abf4ce19',
'third_party/libpfm4':
Var('chromium_url') + '/chromium/src/third_party/libpfm4.git' + '@' + '4a112befd93f8d90a9b6894b2ec4d320310e1178',
'third_party/libpfm4/src':
Var('chromium_url') + '/external/git.code.sf.net/p/perfmon2/libpfm4.git' + '@' + '6870a9f00412830ceaa7e4384bb92ee323e2a28f',
'third_party/libunwind/src':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '1fd455816c724182cf8736811182bf0c37b03035',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libunwind.git' + '@' + '45120ee2331193c3650acc9c427ed267fab31d62',
'third_party/llvm-libc/src':
- Var('chromium_url') + '/external/github.com/llvm/llvm-project/libc.git' + '@' + '75ae50cd48c8a9d70f552ccff040029968778da9',
+ Var('chromium_url') + '/external/github.com/llvm/llvm-project/libc.git' + '@' + '43a9a99ce4b5a04954090f8a0e74bf2786f59379',
'third_party/llvm-build/Release+Asserts': {
'dep_type': 'gcs',
'bucket': 'chromium-browser-clang',
'objects': [
{
- 'object_name': 'Linux_x64/clang-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': 'e22e06c05fe1657f48f988b15804b8226e691addb00abba5b984a5c99ac98c42',
- 'size_bytes': 59093892,
- 'generation': 1781627382446731,
+ 'object_name': 'Linux_x64/clang-android-runtime-library-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '780597375163e78615a307a73ec66346b54c58ea3164aa6fbedf24eae85382fc',
+ 'size_bytes': 6210856,
+ 'generation': 1787607008868327,
+ 'condition': 'checkout_android',
+ },
+ {
+ 'object_name': 'Linux_x64/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '565f7d980b31411e76d9478731cf3f0ac907a46f274d289ea7f03d9137354053',
+ 'size_bytes': 56894668,
+ 'generation': 1787607001504676,
'condition': 'host_os == "linux"',
},
{
- 'object_name': 'Linux_x64/clang-tidy-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '96da04c2fff4e580ac81b840405edfa292108d0b593927a10750c0a1d8599c0a',
- 'size_bytes': 14808648,
- 'generation': 1781627382496605,
+ 'object_name': 'Linux_x64/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '4290664a4fa8aa11fd1e6b2d3ff4965d26b41cca1a4950f9835ff19115c2384f',
+ 'size_bytes': 14877500,
+ 'generation': 1787607001575317,
'condition': 'host_os == "linux" and checkout_clang_tidy',
},
{
- 'object_name': 'Linux_x64/clangd-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '1e6b6918bb270659ef517a3e8f80af8f371bc79a9d942241978db8faea22f152',
- 'size_bytes': 15001372,
- 'generation': 1781627382490030,
+ 'object_name': 'Linux_x64/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '9db50937915608c466da28ba4166cfa69a5f6bcad346233e47807f532cc3075b',
+ 'size_bytes': 15049952,
+ 'generation': 1787607001603946,
'condition': 'host_os == "linux" and checkout_clangd',
},
{
- 'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': 'bb63e33c20329c344a9dfa958f3742b316c0b9dd602647190fb0037d8d53a7e6',
- 'size_bytes': 2332356,
- 'generation': 1781627382888550,
+ 'object_name': 'Linux_x64/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '34747a8e113c399daa36f75a5a0a4c0963871ceafbce7c49a3b5133f81a63bae',
+ 'size_bytes': 2352288,
+ 'generation': 1787607001865886,
'condition': 'host_os == "linux" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Linux_x64/llvmobjdump-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': 'e43b98bce71d58bbe1b456f7b62997c4d017cf8362a0367592428ac5a7512f41',
- 'size_bytes': 5875704,
- 'generation': 1781627382574869,
+ 'object_name': 'Linux_x64/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'cc8a621ec8cc3c48471c90cf4ed88dcc56bfb403824eda10f8b55796abaec280',
+ 'size_bytes': 5912568,
+ 'generation': 1787607001713199,
'condition': '(checkout_linux or checkout_mac or checkout_android) and host_os == "linux"',
},
{
- 'object_name': 'Mac/clang-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '84b3934db2fb3c2e657d4a783a83ca6d2facaf598991490ae8ab712fcb03224b',
- 'size_bytes': 56083264,
- 'generation': 1781627385112611,
+ 'object_name': 'Mac/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'ba2b707d83f7a19d81b9403b4ebe8e999d41ae35fead00a142f02b67e197fe2f',
+ 'size_bytes': 56420628,
+ 'generation': 1787607010939621,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac/clang-mac-runtime-library-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '5079e2ac3f0fa76e8b0218bf99a65a5439e8dcf6a750f886a355a66df34c69c1',
- 'size_bytes': 1010816,
- 'generation': 1781627394919334,
+ 'object_name': 'Mac/clang-mac-runtime-library-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'da06337f54ba4b36c79e0d379557832bf82b9c7e85fe8ef78a5b953567d98de1',
+ 'size_bytes': 1012348,
+ 'generation': 1787607018227451,
'condition': 'checkout_mac and not host_os == "mac"',
},
{
- 'object_name': 'Mac/clang-tidy-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '1ca3dc160992d8c27765adaffcc8115aed34cdf7645a5354820e8c8b16b75dcd',
- 'size_bytes': 14790996,
- 'generation': 1781627384977799,
+ 'object_name': 'Mac/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'ae5cbec1362517b6928162fddb9b160bd1c75e8fd90789718393e1cadf1342ae',
+ 'size_bytes': 14882308,
+ 'generation': 1787607010909866,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_tidy',
},
{
- 'object_name': 'Mac/clangd-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '4920275e6050dffbb81ba0210a627a61a20faa896aa50f5ecc2d765522790526',
- 'size_bytes': 16720488,
- 'generation': 1781627385229783,
+ 'object_name': 'Mac/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '73f5de0f007f8c588593d824147963ec770b66d487a707d1c377a06e34952d89',
+ 'size_bytes': 16779464,
+ 'generation': 1787607010899287,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clangd',
},
{
- 'object_name': 'Mac/llvm-code-coverage-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '07e8bf3354e0c086e420ab8f1f376e48c8b6207788cf30b56d1b0ad1fd4b0f12',
- 'size_bytes': 2372720,
- 'generation': 1781627385661382,
+ 'object_name': 'Mac/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'c47eb37873d3290cc95ba5f9027337895eeeaa199c3f70e63c5d09b710faf250',
+ 'size_bytes': 2411184,
+ 'generation': 1787607011184644,
'condition': 'host_os == "mac" and host_cpu == "x64" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Mac/llvmobjdump-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '9b286eecf04996dfa82cd1434bceb19612fa0754e4390649ba8dcd846dca9c1e',
- 'size_bytes': 5797028,
- 'generation': 1781627385345493,
+ 'object_name': 'Mac/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '4ddefa96f6aaa04ac502610fc736528f65dc3e1b997fc4a5380081937f6ffb1a',
+ 'size_bytes': 5874672,
+ 'generation': 1787607011035157,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac_arm64/clang-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': 'e96c5e31ddc2a6e841bcb0f7278ae82b3a581799904276e6f7673213c9748c27',
- 'size_bytes': 47058068,
- 'generation': 1781627397208650,
+ 'object_name': 'Mac_arm64/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '264d803970f9b58ddbdc90464ad82e54cef642c58ec371ba5356dfa7342ece4d',
+ 'size_bytes': 47226204,
+ 'generation': 1787607020088085,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Mac_arm64/clang-tidy-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '27eff49b49d393c903246d5e17ba620f62f493a8a39cb6dbdd2e3f5f06c592a2',
- 'size_bytes': 12835944,
- 'generation': 1781627397575694,
+ 'object_name': 'Mac_arm64/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '3e02eae391e05018fb4e95d3c90b270688a5e3d5f5b31df6c59512e602478f36',
+ 'size_bytes': 12960456,
+ 'generation': 1787607020070956,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_tidy',
},
{
- 'object_name': 'Mac_arm64/clangd-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '9519e51006f45a797a351b616d92bff319793ab976eeb59df60901d6181f3c18',
- 'size_bytes': 13205948,
- 'generation': 1781627397237653,
+ 'object_name': 'Mac_arm64/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'a56514d09cfcb216efa297e5fecd51a2e248faf7db6edd2d444cfe78e0e219d3',
+ 'size_bytes': 13320572,
+ 'generation': 1787607020209265,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clangd',
},
{
- 'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '62084a5523a1c3b140166c2ed5a21bc110ceb65503f2759272a9f1feb00b503e',
- 'size_bytes': 2000216,
- 'generation': 1781627397451117,
+ 'object_name': 'Mac_arm64/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'b593c509e8f4269cf4a16272f6eddcea0f9dd47f6f3fe39b9813041d0f96d4e3',
+ 'size_bytes': 2031112,
+ 'generation': 1787607020489366,
'condition': 'host_os == "mac" and host_cpu == "arm64" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Mac_arm64/llvmobjdump-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': 'b6c6c0b1b4147ba4d51603713d3ed21f88ee2f506ff07fb432b3444f1d323295',
- 'size_bytes': 5548680,
- 'generation': 1781627397409118,
+ 'object_name': 'Mac_arm64/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': 'c67f5dba316d6367be8c153ede456fdbef0dfffad4da10aaf597ff967c07378c',
+ 'size_bytes': 5610096,
+ 'generation': 1787607020228775,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Win/clang-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '9e3894b94d0d5e3d5904a559f590f12bd53aa5d1d9b6a902de2acb957825de46',
- 'size_bytes': 51306328,
- 'generation': 1781627409675428,
+ 'object_name': 'Win/clang-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '166437ede456b3d7cf0d9317287511e47714f91da547dbde02992261aeef7174',
+ 'size_bytes': 51467544,
+ 'generation': 1787607030157700,
'condition': 'host_os == "win"',
},
{
- 'object_name': 'Win/clang-tidy-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '8fa52c3d1707e73d0689aaa3c8d3789f13e85526bef029d942baf44ed980b442',
- 'size_bytes': 14867152,
- 'generation': 1781627409620988,
+ 'object_name': 'Win/clang-tidy-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '13cae70dfa207c9ec27e294f38b732b5c820ef637f48d24cc8b97f5f3a96e220',
+ 'size_bytes': 15134360,
+ 'generation': 1787607030186388,
'condition': 'host_os == "win" and checkout_clang_tidy',
},
{
- 'object_name': 'Win/clang-win-runtime-library-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': 'f925c30e1f63291662b2ad91103592208ecc4354f669c98a07e35360d2561a13',
- 'size_bytes': 2623388,
- 'generation': 1781627419134531,
+ 'object_name': 'Win/clang-win-runtime-library-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '4ff9a06f5fc4a711103cd890e724ae4448d67873de438542f3ac6772e68d3c63',
+ 'size_bytes': 2638196,
+ 'generation': 1787607037249082,
'condition': 'checkout_win and not host_os == "win"',
},
{
- 'object_name': 'Win/clangd-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '54042464918d992a19efed3a5f2a170e6fc2e4551884b4870650e3a3a6a03b41',
- 'size_bytes': 15262064,
- 'generation': 1781627409708803,
+ 'object_name': 'Win/clangd-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '17f1d575127724051099a778d77e609f650702248cf4e7ff3ec33b377053edd9',
+ 'size_bytes': 15444040,
+ 'generation': 1787607030301504,
'condition': 'host_os == "win" and checkout_clangd',
},
{
- 'object_name': 'Win/llvm-code-coverage-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '7c4fbafcf2741a036d1f4058fc31b52cb5b0951e617561fc3d51b7fbe0a3044b',
- 'size_bytes': 2496336,
- 'generation': 1781627409916932,
+ 'object_name': 'Win/llvm-code-coverage-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '78aa6b2b9cf057077be6705b76e43ffed83e46e17ee86da1ab699340129b1aca',
+ 'size_bytes': 2512968,
+ 'generation': 1787607030493491,
'condition': 'host_os == "win" and checkout_clang_coverage_tools',
},
{
- 'object_name': 'Win/llvmobjdump-llvmorg-23-init-19482-g53d18800-1.tar.xz',
- 'sha256sum': '7ea19d03f21ef59d2e511af8d9cccff20ea72deb54923557173bb46a64244fa7',
- 'size_bytes': 5934284,
- 'generation': 1781627409787893,
+ 'object_name': 'Win/llvmobjdump-llvmorg-24-init-3796-g20e97c4b-4.tar.xz',
+ 'sha256sum': '4b899193da883a447c75f057e3a94f5e7ab93e5df5724ad94cbd6bf82ea792b4',
+ 'size_bytes': 5994644,
+ 'generation': 1787607030276791,
'condition': '(checkout_linux or checkout_mac or checkout_android) and host_os == "win"',
},
],
@@ -521,9 +531,9 @@ deps = {
'condition': 'not build_with_chromium',
},
'third_party/perfetto':
- Var('chromium_url') + '/external/github.com/google/perfetto.git' + '@' + 'bd153cb9c843f35cce632e2f21b8cd04b551576e',
+ Var('chromium_url') + '/external/github.com/google/perfetto.git' + '@' + '5dbeaad4ceb91470a835426b52e0cb43a3e5ef10',
'third_party/protobuf':
- Var('chromium_url') + '/chromium/src/third_party/protobuf.git' + '@' + 'f4b110307a4845dfe04c4fc5458d514eb8fc7d66',
+ Var('chromium_url') + '/chromium/src/third_party/protobuf.git' + '@' + '5f8c379d1fc89fe8eee16ae560dd5e514a4608da',
'third_party/re2/src':
Var('chromium_url') + '/external/github.com/google/re2.git' + '@' + '972a15cedd008d846f1a39b2e88ce48d7f166cbd',
'third_party/requests': {
@@ -531,41 +541,84 @@ deps = {
'condition': 'checkout_android',
},
'tools/rust':
- Var('chromium_url') + '/chromium/src/tools/rust' + '@' + '9c007b63f883469648cd95ca8bbd88dd8f35a1b4',
+ Var('chromium_url') + '/chromium/src/tools/rust' + '@' + '54d1148695dbbbfc3e00dfd05aff502acaa602e3',
'tools/win':
- Var('chromium_url') + '/chromium/src/tools/win' + '@' + '45843c2c1e993427751e2a07f904db069dc26ad6',
+ Var('chromium_url') + '/chromium/src/tools/win' + '@' + '13cb6e5d223dc49eadd082d3aef4c2a5b0e4c0a0',
'third_party/rust':
- Var('chromium_url') + '/chromium/src/third_party/rust' + '@' + 'afbc96607d0e659715d803cc099607dd1737fc41',
+ Var('chromium_url') + '/chromium/src/third_party/rust' + '@' + '4dec6f65bcb34c4c289736b0e6fd571b35c6c665',
'third_party/rust-toolchain': {
'dep_type': 'gcs',
'bucket': 'chromium-browser-clang',
'objects': [
{
- 'object_name': 'Linux_x64/rust-toolchain-b998449636a48e2c4a362809085b600a0174e1f2-5-llvmorg-23-init-19482-g53d18800.tar.xz',
- 'sha256sum': '1753392d6fe791a5ce743bfc70f45e151ee27bcccede516fb221b023f2c06a05',
- 'size_bytes': 274786408,
- 'generation': 1783367871911099,
+ 'object_name': 'Linux_x64/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
+ 'sha256sum': '4b131e81d157a97bcf454ad0fbb71bc2063b2a3708c858410c04201ef06134e5',
+ 'size_bytes': 276314860,
+ 'generation': 1786821088882867,
'condition': 'host_os == "linux"',
},
{
- 'object_name': 'Mac/rust-toolchain-b998449636a48e2c4a362809085b600a0174e1f2-5-llvmorg-23-init-19482-g53d18800.tar.xz',
- 'sha256sum': '6925151e70efd917156f3d50925c5bd416b9adf4ff42ca4bf73b4a6610d785d2',
- 'size_bytes': 262413648,
- 'generation': 1783367875702343,
+ 'object_name': 'Mac/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
+ 'sha256sum': '12ca849195c27495073ba52ae7126d8a4a9a5807cd7a0dc6ba6b6fa612302a6d',
+ 'size_bytes': 264031896,
+ 'generation': 1786821092536805,
'condition': 'host_os == "mac" and host_cpu == "x64"',
},
{
- 'object_name': 'Mac_arm64/rust-toolchain-b998449636a48e2c4a362809085b600a0174e1f2-5-llvmorg-23-init-19482-g53d18800.tar.xz',
- 'sha256sum': '1765d9be3b30726f5f5ad60d8bc50ee66501220bc942019782cf423de3f7114e',
- 'size_bytes': 246837492,
- 'generation': 1783367879712419,
+ 'object_name': 'Mac_arm64/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
+ 'sha256sum': 'fe128475561d7a51c797d1cb3ccea6f94fd770b167c8e0cc33bf75e7c25d8225',
+ 'size_bytes': 248465344,
+ 'generation': 1786821096222521,
'condition': 'host_os == "mac" and host_cpu == "arm64"',
},
{
- 'object_name': 'Win/rust-toolchain-b998449636a48e2c4a362809085b600a0174e1f2-5-llvmorg-23-init-19482-g53d18800.tar.xz',
- 'sha256sum': 'dfa5db1cef7e75fd4d3ea5827f0c5eff3543d55d9d9982f806154e8d6b05950a',
- 'size_bytes': 415992772,
- 'generation': 1783367883448269,
+ 'object_name': 'Win/rust-toolchain-0913b18e489ac1011b580e31fa5559654be12bfc-2-llvmorg-24-init-3796-g20e97c4b.tar.xz',
+ 'sha256sum': '14bc9cea5e00cb191f58204ef44d68a6794f856a76f885c50298a12d052035bc',
+ 'size_bytes': 414479372,
+ 'generation': 1786821099612317,
+ 'condition': 'host_os == "win"',
+ },
+ ],
+ },
+ # libclang + Python bindings, for the tools/metagen harvest. Built from
+ # the same LLVM revision as the clang and rust packages, so it stays in
+ # step with the toolchain metagen borrows its resource-dir from; bump
+ # this pin along with the clang/rust roll.
+ #
+ # The GCS object is named rust-libclang-*, but the entry uses the name
+ # Chromium gives it (src/third_party/llvm-libclang, maintained there by
+ # tools/clang/scripts/sync_deps.py) so //third_party/llvm-libclang
+ # resolves in both trees.
+ 'third_party/llvm-libclang': {
+ 'dep_type': 'gcs',
+ '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,
+ '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,
+ '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,
+ '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,
'condition': 'host_os == "win"',
},
],
@@ -580,14 +633,36 @@ deps = {
'dep_type': 'cipd',
'condition': 'not build_with_chromium and host_cpu != "s390x" and host_os != "zos" and host_cpu != "ppc64"',
},
+ # Always download Linux x64 package regardless of host OS for RBE workers.
+ 'third_party/cpython3/linux-amd64': {
+ 'packages': [
+ {
+ 'package': 'infra/3pp/tools/cpython3/linux-amd64',
+ 'version': Var('cpython3_version'),
+ }
+ ],
+ 'condition': 'not build_with_chromium and host_cpu != "s390x" and host_os != "zos" and host_cpu != "ppc64"',
+ 'dep_type': 'cipd',
+ },
+ # Host platform package.
+ 'third_party/cpython3/host': {
+ 'packages': [
+ {
+ 'package': 'infra/3pp/tools/cpython3/${{platform}}',
+ 'version': Var('cpython3_version'),
+ }
+ ],
+ 'condition': 'not build_with_chromium and host_cpu != "s390x" and host_os != "zos" and host_cpu != "ppc64"',
+ 'dep_type': 'cipd',
+ },
'third_party/zlib':
- Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '42c2f19a14d33b4ed327ab898fe7b652013aa740',
+ Var('chromium_url') + '/chromium/src/third_party/zlib.git'+ '@' + '285e94b8fa95ad3b7d16b80798ec8dce6febb8c8',
'tools/clang':
- Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '56a7ab321b6840e949e3acf5f4528dadc6cb05bc',
+ Var('chromium_url') + '/chromium/src/tools/clang.git' + '@' + '450d823868eaee61e2b2cb986e19aec287f16d58',
'tools/protoc_wrapper':
- Var('chromium_url') + '/chromium/src/tools/protoc_wrapper.git' + '@' + '418c65786fdf6fc5f10cb008c252c2b12c4713a6',
+ 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' + '@' + 'ff6e8ce3e932c16cebd1611c8fc42c45080a0e55',
+ 'url': Var('chromium_url') + '/chromium/src/third_party/abseil-cpp.git' + '@' + '435e7d977fb36fb47854a4c552c0706dad0bd7cf',
'condition': 'not build_with_chromium',
},
'third_party/fadec/src': {
@@ -828,7 +903,7 @@ hooks = [
'name': 'vpython3_common',
'pattern': '.',
'action': [ 'vpython3',
- '-vpython-spec', '.vpython3',
+ '-vpython-spec', 'vpython.toml',
'-vpython-tool', 'install',
],
},
diff --git a/deps/v8/MODULE.bazel b/deps/v8/MODULE.bazel
index 00ad66496a5..9f3b298b0b1 100644
--- a/deps/v8/MODULE.bazel
+++ b/deps/v8/MODULE.bazel
@@ -118,8 +118,7 @@ def _impl(ctx):
"{WORKSPACE_ROOT}/third_party/libc++abi/src/include",
"{WORKSPACE_ROOT}/third_party/libc++/src/src",
"{WORKSPACE_ROOT}/third_party/llvm-libc/src",
- "{WORKSPACE_ROOT}/third_party/llvm-build/Release+Asserts/lib/clang/22/include",
- "{WORKSPACE_ROOT}/third_party/llvm-build/Release+Asserts/lib/clang/23/include",
+ "{WORKSPACE_ROOT}/third_party/llvm-build/Release+Asserts/lib/clang/24/include",
"{WORKSPACE_ROOT}/build/linux/debian_bullseye_amd64-sysroot/usr/include",
"{WORKSPACE_ROOT}/build/linux/debian_bullseye_amd64-sysroot/usr/local/include",
],
diff --git a/deps/v8/OWNERS b/deps/v8/OWNERS
index 265bcceab8d..3bf23b9f9fb 100644
--- a/deps/v8/OWNERS
+++ b/deps/v8/OWNERS
@@ -2,6 +2,7 @@
# Disagreement among owners should be escalated to eng reviewers.
file:ENG_REVIEW_OWNERS
+per-file vpython.toml*=file:INFRA_OWNERS
per-file .*=file:INFRA_OWNERS
per-file .bazelrc=file:COMMON_OWNERS
per-file .mailmap=file:COMMON_OWNERS
diff --git a/deps/v8/PRESUBMIT.py b/deps/v8/PRESUBMIT.py
index 3e25c400395..335f2333e0b 100644
--- a/deps/v8/PRESUBMIT.py
+++ b/deps/v8/PRESUBMIT.py
@@ -436,7 +436,7 @@ def _CheckNoProductionCodeUsingTestOnlyFunctions(input_api, output_api):
r'//.*({})'.format(base_function_pattern))
exclusion_pattern = input_api.re.compile(
r'::[A-Za-z0-9_]+({})|({})[^;]+'.format(base_function_pattern,
- base_function_pattern) + '\{')
+ base_function_pattern) + r'\{')
def FilterFile(affected_file):
files_to_skip = (_EXCLUDED_PATHS +
@@ -679,6 +679,7 @@ def _CommonChecks(input_api, output_api):
_CheckNoInlineHeaderIncludesInNormalHeaders,
_CheckInlineHeadersIncludeNonInlineHeadersFirst,
_CheckJSONFiles,
+ _CheckMetagenHeaders,
_CheckNoexceptAnnotations,
_CheckBannedCpp,
_RunTestsWithVPythonSpec,
@@ -747,6 +748,8 @@ def _CheckLandOnChromiumBranch(input_api, output_api):
target_branch = 'refs/heads/%s' % target_branch
if not target_branch.startswith('refs/heads/chromium/'):
return []
+ if '_' in target_branch: # Allow merges to mini branches.
+ return []
description = input_api.change.FullDescriptionText()
if input_api.re.search(r'^LAND_ON_CHROMIUM_BRANCH=.+', description,
@@ -844,6 +847,82 @@ def _CheckNoexceptAnnotations(input_api, output_api):
return []
+def _CheckMetagenHeaders(input_api, output_api):
+ """Check that tools/metagen's driver still reaches every heap object.
+
+ 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.
+ """
+ import subprocess
+ v8_root = input_api.PresubmitLocalPath()
+ join = input_api.os_path.join
+
+ # A header takes part in the harvest if it declares a V8_OBJECT /
+ # V8_ABSTRACT_OBJECT class or carries a `V8_IT_<name>` marker, which is
+ # a member of the class body. Leading whitespace is allowed for both;
+ # requiring the marker at the start of its line is what keeps a
+ # comment that mentions a marker out. object-macros.h matches
+ # structurally because it defines the markers themselves; exclude it.
+ marker_regex = (
+ r"^[[:space:]]*V8_(ABSTRACT_)?OBJECT|^[[:space:]]*V8_IT_[A-Z_]+")
+ try:
+ res = subprocess.run([
+ "git", "grep", "-lE", marker_regex, "--", "src/**/*.h",
+ ":!src/objects/object-macros.h"
+ ],
+ cwd=v8_root,
+ capture_output=True,
+ text=True,
+ check=True)
+ except (subprocess.CalledProcessError, FileNotFoundError) as e:
+ return [
+ output_api.PresubmitNotifyResult(
+ f"_CheckMetagenHeaders: skipping (git grep failed: {e})")
+ ]
+ 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))
+
+ missing = sorted(live - reached)
+ 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" {h}" for h in missing] + [
+ "Add them to src/objects/all-objects.h.",
+ ]))
+ ]
+
+
def _CheckBannedCpp(input_api, output_api):
# We only check for a single pattern right now; feel free to add more, but
# potentially change the logic for files_to_skip then (and skip individual
diff --git a/deps/v8/agents/.vpython3 b/deps/v8/agents/.vpython3
index c9d6c30b553..9a55b6ba5af 100644
--- a/deps/v8/agents/.vpython3
+++ b/deps/v8/agents/.vpython3
@@ -99,6 +99,10 @@ 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"
diff --git a/deps/v8/agents/PRESUBMIT.py b/deps/v8/agents/PRESUBMIT.py
new file mode 100644
index 00000000000..7cf5428231c
--- /dev/null
+++ b/deps/v8/agents/PRESUBMIT.py
@@ -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.
+
+USE_PYTHON3 = True
+
+
+def _CommonChecks(input_api, output_api):
+ return input_api.RunTests(
+ input_api.canned_checks.GetUnitTestsInDirectory(
+ input_api,
+ output_api,
+ 'scripts',
+ files_to_check=[r'.+_test\.py$'],
+ run_on_python2=False))
+
+
+def CheckChangeOnCommit(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
+
+
+def CheckChangeOnUpload(input_api, output_api):
+ return _CommonChecks(input_api, output_api)
diff --git a/deps/v8/agents/README.md b/deps/v8/agents/README.md
index 762a42e13bd..2d4e4f31732 100644
--- a/deps/v8/agents/README.md
+++ b/deps/v8/agents/README.md
@@ -26,6 +26,10 @@ To use them, you need to run the appropriate installation script from the
generate the subagent files in `.gemini/agents/`.
- **For Jetski**: Run `vpython3 scripts/install_for_jetski.py` to create
symlinks in `.agents/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/`,
+ and expose compatible V8 skills in `.github/skills/`.
## Contributing
diff --git a/deps/v8/agents/scripts/create_worktree.sh b/deps/v8/agents/scripts/create_worktree.sh
index 506446e3c59..81ee1049c50 100755
--- a/deps/v8/agents/scripts/create_worktree.sh
+++ b/deps/v8/agents/scripts/create_worktree.sh
@@ -51,8 +51,14 @@ WORKTREE_PATH="$V8_ROOT/worktrees/$BRANCH_NAME"
mkdir -p "$V8_ROOT/worktrees"
-git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" origin/main > /dev/null 2>&1
+if ! git worktree add -b "$BRANCH_NAME" "$WORKTREE_PATH" origin/main; then
+ echo "Error: Failed to create git worktree at $WORKTREE_PATH" >&2
+ exit 1
+fi
-python3 "$V8_ROOT/tools/dev/setup_worktree_build.py" "$V8_ROOT" "$WORKTREE_PATH" > /dev/null 2>&1
+if ! python3 "$V8_ROOT/tools/dev/setup_worktree_build.py" "$V8_ROOT" "$WORKTREE_PATH"; then
+ echo "Error: Failed to set up dependencies for $WORKTREE_PATH" >&2
+ exit 1
+fi
echo "$WORKTREE_PATH"
diff --git a/deps/v8/agents/scripts/install_for_copilot_cli.py b/deps/v8/agents/scripts/install_for_copilot_cli.py
new file mode 100644
index 00000000000..63d2182d27d
--- /dev/null
+++ b/deps/v8/agents/scripts/install_for_copilot_cli.py
@@ -0,0 +1,362 @@
+#!/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.
+"""Install local GitHub Copilot CLI adapters for V8 agent files.
+
+Generated files are ignored by Git. Pass --force to refresh files created by a
+previous run without replacing user-managed files.
+"""
+
+from __future__ import annotations
+
+import argparse
+import os
+from pathlib import Path
+import re
+import stat
+import sys
+import yaml
+
+FILE_PATH = Path(__file__).resolve()
+GENERATED_MARKER = (
+ "<!-- Generated by agents/scripts/install_for_copilot_cli.py. -->")
+# Copilot only reads instruction files that carry this suffix.
+RULE_ADAPTER_SUFFIX = ".instructions.md"
+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",
+}
+COPILOT_INCOMPATIBLE_SKILLS = {
+ # Requires client-specific approval suppression and agent lifecycle controls
+ # not mapped by this adapter.
+ "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",
+ # Mixes client-neutral tool setup with Jetski-specific .agents, MCP, and
+ # settings guidance; exclude it until split or adapted.
+ "v8-setup",
+}
+
+
+def _path_entry_exists(path: Path) -> bool:
+ try:
+ path.lstat()
+ except FileNotFoundError:
+ return False
+ return True
+
+
+def _path_entry_is_reparse_point(path: Path) -> bool:
+ path_stat = path.lstat()
+ if stat.S_ISLNK(path_stat.st_mode):
+ return True
+ file_attributes = getattr(path_stat, "st_file_attributes", 0)
+ reparse_attribute = getattr(stat, "FILE_ATTRIBUTE_REPARSE_POINT", 0)
+ return bool(file_attributes & reparse_attribute)
+
+
+class CopilotInstaller:
+ """Installs Copilot CLI adapters for one V8 checkout."""
+
+ def __init__(self, repo_root: Path):
+ self.repo_root = repo_root
+ self.agents_dir = repo_root / "agents"
+ self.skills_dir = self.agents_dir / "skills"
+ self.rules_dir = self.agents_dir / "rules"
+ self.github_dir = repo_root / ".github"
+ self.copilot_instructions = self.github_dir / "copilot-instructions.md"
+ self.github_skills_dir = self.github_dir / "skills"
+ self.github_instructions_dir = self.github_dir / "instructions"
+
+ def _repo_path(self, path: Path) -> str:
+ return path.relative_to(self.repo_root).as_posix()
+
+ def _frontmatter(self, markdown_file: Path) -> tuple[dict[str, str], str]:
+ """Return parsed YAML frontmatter and its original Markdown block."""
+ match = FRONTMATTER_PATTERN.match(markdown_file.read_text(encoding="utf-8"))
+ if not match:
+ return {}, ""
+ metadata = yaml.safe_load(match.group("yaml")) or {}
+ if not isinstance(metadata, dict):
+ metadata = {}
+ return metadata, match.group("block")
+
+ def _write_generated_file(self, path: Path, content: str) -> bool:
+ if path.is_symlink():
+ print(f"Skipping {path}: existing path is a symlink")
+ return False
+ if _path_entry_exists(path):
+ try:
+ existing = path.read_text(encoding="utf-8")
+ except UnicodeDecodeError:
+ # Destinations under .github/ are user territory, so skip undecodable
+ # files instead of aborting the install part-way through.
+ print(f"Skipping {path}: existing file is not UTF-8 text")
+ return False
+ if GENERATED_MARKER not in existing:
+ print(f"Skipping {path}: existing file is not generated")
+ return False
+
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(content, encoding="utf-8", newline="\n")
+ print(f"Wrote {path}")
+ return True
+
+ def _rule_apply_to(self, metadata: dict[str, str]) -> str | None:
+ """Return the Copilot `applyTo` glob for a rule.
+
+ `None` means Copilot has no equivalent trigger and the rule is only
+ advertised in the instructions.
+ """
+ trigger = str(metadata.get("trigger", ""))
+ if trigger == "always_on":
+ # Copilot has no always-on trigger, but `**` matches every file.
+ return "**"
+ if trigger == "glob":
+ return str(metadata.get("globs", "")) or None
+ # Some rules carry the glob in the trigger field instead of `globs`.
+ if "*" in trigger:
+ return trigger
+ return None
+
+ def _compatible_rules(self):
+ """Yield `(rule_file, metadata, apply_to)` for each compatible rule."""
+ if not self.rules_dir.is_dir():
+ return
+ for rule_file in sorted(self.rules_dir.glob("*.md")):
+ if rule_file.name in COPILOT_INCOMPATIBLE_RULES:
+ continue
+ metadata, _ = self._frontmatter(rule_file)
+ yield rule_file, metadata, self._rule_apply_to(metadata)
+
+ def _rule_source_for(self, adapter_name: str) -> Path:
+ stem = adapter_name
+ if stem.endswith(RULE_ADAPTER_SUFFIX):
+ stem = stem[:-len(RULE_ADAPTER_SUFFIX)]
+ return self.rules_dir / f"{stem}.md"
+
+ def _enumerate_rules(self) -> str:
+ """List rules that Copilot cannot trigger on its own."""
+ entries = []
+ for rule_file, metadata, apply_to in self._compatible_rules():
+ if apply_to is not None:
+ continue
+ entry = f"- `{self._repo_path(rule_file)}`"
+ description = metadata.get("description", "")
+ if description:
+ entry += f": {description}"
+ entries.append(entry)
+
+ if not entries:
+ return ""
+ return ("\n## Optional rules\n\n"
+ "Copilot cannot trigger these rules automatically. Read one when "
+ "its description matches the current task:\n\n" +
+ "\n".join(entries) + "\n")
+
+ def _instructions(self) -> str:
+ return f"""{GENERATED_MARKER}
+# V8 GitHub Copilot Instructions
+
+The canonical V8 agent knowledge lives under `agents/`. Update those checked-in
+files rather than this generated adapter.
+
+## Canonical context
+
+Rules install as Copilot instruction files under `.github/instructions/`, which
+Copilot applies on its own. Load compatible V8 skills on demand through
+`.github/skills/`; their canonical content and supporting resources remain in
+`agents/skills/`. When a rule or skill names another agent's tool, use the
+Copilot CLI equivalent.
+{self._enumerate_rules()}"""
+
+ def _generated_markdown(self, path: Path) -> bool:
+ if not path.is_file():
+ return False
+ try:
+ return GENERATED_MARKER in path.read_text(encoding="utf-8")
+ except UnicodeDecodeError:
+ # A file this script cannot decode is not one it generated.
+ return False
+
+ def _generated_link(self, path: Path, source: Path) -> bool:
+ if not path.is_symlink():
+ return False
+ try:
+ return os.readlink(path) == os.path.relpath(source, start=path.parent)
+ except OSError:
+ return False
+
+ def _remove_generated_adapter(self, path: Path, source: Path) -> bool:
+ """Remove an adapter this script generated, keeping user files intact."""
+ if self._generated_link(path, source):
+ path.unlink()
+ return True
+ if path.is_symlink() or _path_entry_is_reparse_point(path):
+ return False
+ if path.is_file():
+ if not self._generated_markdown(path):
+ return False
+ path.unlink()
+ return True
+ if path.is_dir() and self._generated_markdown(path / "SKILL.md"):
+ (path / "SKILL.md").unlink()
+ if not any(path.iterdir()):
+ path.rmdir()
+ return True
+ return False
+
+ def _skill_wrapper(self, skill_dir: Path) -> str:
+ skill_file = skill_dir / "SKILL.md"
+ metadata, frontmatter = self._frontmatter(skill_file)
+ name = metadata.get("name", skill_dir.name)
+ if not frontmatter:
+ frontmatter = (
+ "---\n"
+ f"name: {skill_dir.name}\n"
+ f"description: Adapter for the canonical V8 {skill_dir.name} skill.\n"
+ "---")
+ canonical_path = self._repo_path(skill_file)
+ base_path = self._repo_path(skill_dir)
+ return f"""{frontmatter}
+{GENERATED_MARKER}
+
+# {name}
+
+Read and follow the canonical skill at `{canonical_path}`.
+Treat `{base_path}/` as the skill's base directory when resolving relative
+paths and supporting resources.
+"""
+
+ def _write_skill_wrapper(self, skill_dir: Path, dest: Path) -> None:
+ self._write_generated_file(dest / "SKILL.md",
+ self._skill_wrapper(skill_dir))
+
+ def _rule_wrapper(self, rule_file: Path, apply_to: str) -> str:
+ """Render a rule as an instruction file Copilot can act on.
+
+ The canonical frontmatter is dropped rather than passed through, because
+ its `trigger` vocabulary means nothing to Copilot.
+ """
+ _, frontmatter = self._frontmatter(rule_file)
+ body = rule_file.read_text(encoding="utf-8")[len(frontmatter):]
+ return (f"---\napplyTo: \"{apply_to}\"\n---\n"
+ f"{GENERATED_MARKER}\n\n{body.lstrip()}")
+
+ def _remove_stale_adapters(self, adapters_dir: Path, current: set[str],
+ source_for) -> None:
+ if not adapters_dir.is_dir():
+ return
+ for dest in adapters_dir.iterdir():
+ if dest.name in current:
+ continue
+ if self._remove_generated_adapter(dest, source_for(dest.name)):
+ print(f"Removed stale adapter {dest}")
+
+ def _install_skill(self, skill_dir: Path, force: bool) -> None:
+ """Link the skill into `.github/`, falling back to a generated wrapper."""
+ dest = self.github_skills_dir / skill_dir.name
+ if _path_entry_exists(dest):
+ if not force:
+ print(f"Skipping {dest}: already exists")
+ return
+ if not self._remove_generated_adapter(dest, skill_dir):
+ print(f"Skipping {dest}: existing path is not generated")
+ return
+ if _path_entry_exists(dest):
+ self._write_skill_wrapper(skill_dir, dest)
+ return
+
+ dest.parent.mkdir(parents=True, exist_ok=True)
+ target = Path(os.path.relpath(skill_dir, start=dest.parent))
+ try:
+ dest.symlink_to(target, target_is_directory=True)
+ print(f"Symlinked {dest} -> {target}")
+ except OSError as exc:
+ if _path_entry_exists(dest):
+ print(f"Skipping {dest}: failed to create a clean adapter: {exc}")
+ return
+ print(f"Could not symlink {dest}: {exc}; writing a wrapper instead")
+ self._write_skill_wrapper(skill_dir, dest)
+
+ def _install_rule(self, rule_file: Path, apply_to: str) -> None:
+ # A rule cannot be linked the way a skill is, because Copilot needs an
+ # `applyTo` header that the canonical file does not carry.
+ dest = self.github_instructions_dir / (rule_file.stem + RULE_ADAPTER_SUFFIX)
+ self._write_generated_file(dest, self._rule_wrapper(rule_file, apply_to))
+
+ def install(self, force: bool) -> int:
+ if not self.skills_dir.is_dir():
+ print(f"Missing skills directory: {self.skills_dir}", file=sys.stderr)
+ return 1
+
+ for destination in (self.github_dir, self.github_skills_dir,
+ self.github_instructions_dir):
+ if (_path_entry_exists(destination) and
+ _path_entry_is_reparse_point(destination)):
+ print(
+ f"Unsafe adapter destination: {destination} is a symlink or "
+ "reparse point",
+ file=sys.stderr)
+ return 1
+
+ self._write_generated_file(self.copilot_instructions, self._instructions())
+
+ self.github_skills_dir.mkdir(parents=True, exist_ok=True)
+
+ current_skills = sorted(
+ path for path in self.skills_dir.iterdir()
+ if (path.is_dir() and (path / "SKILL.md").is_file() and
+ path.name not in COPILOT_INCOMPATIBLE_SKILLS))
+ current_rules = [(rule_file, apply_to)
+ for rule_file, _, apply_to in self._compatible_rules()
+ if apply_to is not None]
+ # Stale adapters are dropped even without `--force`: reclaiming a path
+ # this script generated is not the same as overwriting a user's file, and
+ # leaving one behind keeps a rule active after it stops being compatible.
+ self._remove_stale_adapters(self.github_skills_dir,
+ {path.name for path in current_skills},
+ lambda name: self.skills_dir / name)
+ self._remove_stale_adapters(
+ self.github_instructions_dir,
+ {path.stem + RULE_ADAPTER_SUFFIX for path, _ in current_rules},
+ self._rule_source_for)
+ for skill_dir in current_skills:
+ self._install_skill(skill_dir, force)
+ for rule_file, apply_to in current_rules:
+ self._install_rule(rule_file, apply_to)
+
+ print("GitHub Copilot CLI adapter installation complete.")
+ print("Restart or resume your Copilot CLI session to pick up the changes.")
+ return 0
+
+
+def main(argv: list[str] | None = None) -> int:
+ parser = argparse.ArgumentParser(description=__doc__)
+ parser.add_argument(
+ "--force",
+ action="store_true",
+ help="replace adapters generated by a previous run")
+ args = parser.parse_args(argv)
+ return CopilotInstaller(FILE_PATH.parents[2]).install(args.force)
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/deps/v8/agents/scripts/install_for_copilot_cli_test.py b/deps/v8/agents/scripts/install_for_copilot_cli_test.py
new file mode 100644
index 00000000000..bdb3198cfc0
--- /dev/null
+++ b/deps/v8/agents/scripts/install_for_copilot_cli_test.py
@@ -0,0 +1,651 @@
+#!/usr/bin/env python3
+# 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.
+
+import io
+import os
+from pathlib import Path
+import shutil
+import stat
+import subprocess
+import tempfile
+import unittest
+from unittest import mock
+
+from install_for_copilot_cli import CopilotInstaller
+from install_for_copilot_cli import COPILOT_INCOMPATIBLE_RULES
+from install_for_copilot_cli import COPILOT_INCOMPATIBLE_SKILLS
+from install_for_copilot_cli import GENERATED_MARKER
+
+REPO_ROOT = Path(__file__).resolve().parents[2]
+
+
+class CopilotInstallerTest(unittest.TestCase):
+
+ def setUp(self):
+ self.temp_dir = tempfile.TemporaryDirectory()
+ self.repo_root = Path(self.temp_dir.name)
+ self.skills_dir = self.repo_root / "agents" / "skills"
+ self.rules_dir = self.repo_root / "agents" / "rules"
+ self.skills_dir.mkdir(parents=True)
+ self.rules_dir.mkdir()
+ self.installer = CopilotInstaller(self.repo_root)
+
+ def tearDown(self):
+ self.temp_dir.cleanup()
+
+ def _write(self, path: Path, content: str) -> None:
+ path.parent.mkdir(parents=True, exist_ok=True)
+ path.write_text(content, encoding="utf-8")
+
+ def _add_skill(self, name: str, body: str = "Original instructions.\n"):
+ skill_dir = self.skills_dir / name
+ self._write(skill_dir / "SKILL.md",
+ f"---\nname: {name}\ndescription: Test skill.\n---\n\n{body}")
+ self._write(skill_dir / "scripts" / "helper.py", "print('helper')\n")
+ return skill_dir
+
+ def _add_rule(self,
+ name: str,
+ trigger: str = "",
+ globs: str = "",
+ description: str = "",
+ body: str = "Rule body.\n") -> Path:
+ frontmatter = [f"name: {name}"]
+ if trigger:
+ frontmatter.append(f"trigger: {trigger}")
+ if globs:
+ frontmatter.append(f"globs: {globs}")
+ if description:
+ frontmatter.append(f"description: {description}")
+ rule_file = self.rules_dir / f"{name}.md"
+ self._write(rule_file, "---\n{}\n---\n\n{}".format("\n".join(frontmatter),
+ body))
+ return rule_file
+
+ def _rule_adapter(self, name: str) -> Path:
+ return self.installer.github_instructions_dir / f"{name}.instructions.md"
+
+ # Junctions need neither elevation nor developer mode, so failures are real.
+ def _create_junction(self, junction: Path, target: Path) -> None:
+ subprocess.run(
+ ["cmd.exe", "/d", "/c", "mklink", "/J",
+ str(junction),
+ str(target)],
+ check=True,
+ capture_output=True,
+ text=True)
+
+ def _is_junction(self, junction: Path) -> bool:
+ return bool(junction.lstat().st_file_attributes
+ & stat.FILE_ATTRIBUTE_REPARSE_POINT)
+
+ def _remove_junction(self, junction: Path) -> None:
+ # Tolerate a missing junction so cleanup cannot mask an assertion failure.
+ try:
+ is_junction = self._is_junction(junction)
+ except FileNotFoundError:
+ return
+ if is_junction:
+ os.rmdir(junction)
+
+ def _symlink_or_skip(self,
+ link: Path,
+ target: Path,
+ is_directory: bool = True) -> None:
+ try:
+ link.symlink_to(target, target_is_directory=is_directory)
+ except OSError as exc:
+ self.skipTest(f"Symlinks are unavailable: {exc}")
+
+ def _require_symlinks(self) -> None:
+ probe = self.repo_root / "symlink-probe"
+ self._symlink_or_skip(probe, self.repo_root)
+ probe.unlink()
+
+ def _without_symlink_support(self):
+ return mock.patch.object(
+ Path, "symlink_to", side_effect=OSError("unsupported"))
+
+ def _file_snapshot(self, root: Path) -> dict[Path, bytes]:
+ return {
+ path.relative_to(root): path.read_bytes()
+ for path in root.rglob("*")
+ if path.is_file()
+ }
+
+ def test_wrapper_fallback_points_to_canonical_skill(self):
+ self._add_skill("test-skill",
+ "Run [the helper](../../scripts/create_worktree.sh).\n")
+ self._add_rule("always", trigger="always_on")
+ for rule_name in COPILOT_INCOMPATIBLE_RULES:
+ self._add_rule(Path(rule_name).stem, trigger="always_on")
+
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=False))
+
+ instructions = self.installer.copilot_instructions.read_text(
+ encoding="utf-8")
+ self.assertIn(GENERATED_MARKER, instructions)
+ self.assertIn(".github/instructions/", instructions)
+ self.assertIn("Load compatible V8 skills on demand", instructions)
+ # The generated file points at canonical knowledge instead of restating
+ # it, and does not rely on `@` imports being expanded, so neither an
+ # import line nor duplicated build guidance may appear here.
+ self.assertNotIn("@agents/rules/", instructions)
+ self.assertNotIn("tools/dev/gm.py", instructions)
+ for rule_name in COPILOT_INCOMPATIBLE_RULES:
+ self.assertNotIn(f"agents/rules/{rule_name}", instructions)
+ self.assertFalse(self._rule_adapter(Path(rule_name).stem).exists())
+
+ installed = self.installer.github_skills_dir / "test-skill"
+ wrapper = (installed / "SKILL.md").read_text(encoding="utf-8")
+ self.assertIn(GENERATED_MARKER, wrapper)
+ self.assertIn("agents/skills/test-skill/SKILL.md", wrapper)
+ self.assertIn(
+ "Treat `agents/skills/test-skill/` as the skill's base directory",
+ wrapper)
+ self.assertFalse((installed / "scripts" / "helper.py").exists())
+
+ def test_symlinked_skill_resolves_to_canonical_resources(self):
+ self._require_symlinks()
+ self._add_skill("test-skill")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ installed = self.installer.github_skills_dir / "test-skill"
+ self.assertTrue(installed.is_symlink())
+ self.assertEqual(
+ os.path.join("..", "..", "agents", "skills", "test-skill"),
+ os.readlink(installed))
+ self.assertIn("Original instructions.",
+ (installed / "SKILL.md").read_text(encoding="utf-8"))
+ self.assertTrue((installed / "scripts" / "helper.py").is_file())
+
+ def test_stale_symlinked_adapter_is_removed(self):
+ self._require_symlinks()
+ stale_skill = self._add_skill("stale-skill")
+ self.assertEqual(0, self.installer.install(force=False))
+ installed = self.installer.github_skills_dir / "stale-skill"
+ self.assertTrue(installed.is_symlink())
+
+ shutil.rmtree(stale_skill)
+ self.assertEqual(0, self.installer.install(force=False))
+
+ self.assertFalse(installed.is_symlink())
+ self.assertFalse(installed.exists())
+
+ def test_force_upgrades_wrapper_to_symlink(self):
+ self._require_symlinks()
+ self._add_skill("test-skill")
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=False))
+ installed = self.installer.github_skills_dir / "test-skill"
+ self.assertFalse(installed.is_symlink())
+
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertTrue(installed.is_symlink())
+
+ def test_always_on_rule_applies_to_every_file(self):
+ self._add_rule("always", trigger="always_on", body="Always body.\n")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ adapter = self._rule_adapter("always")
+ self.assertFalse(adapter.is_symlink())
+ wrapper = adapter.read_text(encoding="utf-8")
+ self.assertTrue(wrapper.startswith('---\napplyTo: "**"\n---\n'))
+ self.assertIn(GENERATED_MARKER, wrapper)
+ self.assertIn("Always body.", wrapper)
+
+ def test_rule_adapters_drop_the_canonical_frontmatter(self):
+ self._add_rule("always", trigger="always_on")
+ self._add_rule("conditional", trigger="glob", globs="src/**/*.tq")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ for name in ("always", "conditional"):
+ with self.subTest(rule=name):
+ wrapper = self._rule_adapter(name).read_text(encoding="utf-8")
+ # Scope reaches Copilot through the generated `applyTo` header, so
+ # V8's own frontmatter is dropped rather than passed through.
+ self.assertNotIn("trigger:", wrapper)
+ self.assertNotIn("always_on", wrapper)
+ self.assertNotIn("globs:", wrapper)
+ self.assertNotIn(f"name: {name}", wrapper)
+
+ def test_glob_rule_wrapper_carries_apply_to(self):
+ self._add_rule(
+ "conditional",
+ trigger="glob",
+ globs="src/**/*.tq",
+ body="Torque body.\n")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ adapter = self._rule_adapter("conditional")
+ self.assertFalse(adapter.is_symlink())
+ wrapper = adapter.read_text(encoding="utf-8")
+ self.assertTrue(wrapper.startswith('---\napplyTo: "src/**/*.tq"\n---\n'))
+ self.assertIn(GENERATED_MARKER, wrapper)
+ self.assertIn("Torque body.", wrapper)
+
+ def test_glob_rule_wrapper_refreshes_without_force(self):
+ rule_file = self._add_rule(
+ "conditional", trigger="glob", globs="src/**/*.tq", body="First.\n")
+ self.assertEqual(0, self.installer.install(force=False))
+ self._write(
+ rule_file, "---\nname: conditional\ntrigger: glob\n"
+ "globs: src/**/*.tq\n---\n\nSecond.\n")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ wrapper = self._rule_adapter("conditional").read_text(encoding="utf-8")
+ self.assertIn("Second.", wrapper)
+ self.assertNotIn("First.", wrapper)
+
+ def test_glob_written_in_the_trigger_field_is_used_as_apply_to(self):
+ self._add_rule("writing-skills", trigger="agents/**/*")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ self.assertIn(
+ 'applyTo: "agents/**/*"',
+ self._rule_adapter("writing-skills").read_text(encoding="utf-8"))
+
+ def test_rules_without_a_copilot_trigger_are_listed_only(self):
+ self._add_rule(
+ "chooseable", trigger="model_decision", description="Use for CLs.")
+ self._add_rule("missing-trigger")
+ self._add_rule("unknown-trigger", trigger="unsupported")
+ self._add_rule("empty-glob", trigger="glob")
+ for rule_name in COPILOT_INCOMPATIBLE_RULES:
+ self._add_rule(Path(rule_name).stem, trigger="always_on")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ instructions = self.installer.copilot_instructions.read_text(
+ encoding="utf-8")
+ self.assertIn("## Optional rules", instructions)
+ self.assertIn("- `agents/rules/chooseable.md`: Use for CLs.", instructions)
+ for name in ("missing-trigger", "unknown-trigger", "empty-glob"):
+ self.assertIn(f"- `agents/rules/{name}.md`", instructions)
+ for name in ("chooseable", "missing-trigger", "unknown-trigger",
+ "empty-glob"):
+ self.assertFalse(self._rule_adapter(name).exists())
+ for rule_name in COPILOT_INCOMPATIBLE_RULES:
+ self.assertNotIn(f"agents/rules/{rule_name}", instructions)
+
+ def test_stale_rule_adapters_are_removed(self):
+ always = self._add_rule("stale-always", trigger="always_on")
+ conditional = self._add_rule(
+ "stale-glob", trigger="glob", globs="src/**/*.tq")
+ self.assertEqual(0, self.installer.install(force=False))
+ for name in ("stale-always", "stale-glob"):
+ self.assertTrue(self._rule_adapter(name).is_file())
+
+ always.unlink()
+ conditional.unlink()
+ self.assertEqual(0, self.installer.install(force=False))
+
+ for name in ("stale-always", "stale-glob"):
+ self.assertFalse(self._rule_adapter(name).exists())
+
+ def test_force_preserves_user_managed_rule_adapters(self):
+ self._add_rule("always", trigger="always_on")
+ self._add_rule("conditional", trigger="glob", globs="src/**/*.tq")
+ for name in ("always", "conditional"):
+ self._write(self._rule_adapter(name), "User rule.\n")
+
+ self.assertEqual(0, self.installer.install(force=True))
+
+ for name in ("always", "conditional"):
+ self.assertEqual("User rule.\n",
+ self._rule_adapter(name).read_text(encoding="utf-8"))
+
+ def test_rejects_instructions_symlink_before_mutating_anything(self):
+ self._add_rule("always", trigger="always_on")
+ with tempfile.TemporaryDirectory() as external_temp_dir:
+ external = Path(external_temp_dir) / "external-instructions"
+ self._write(external / "keep.txt", "External tree sentinel.\n")
+ self.installer.github_dir.mkdir(parents=True)
+ self._symlink_or_skip(self.installer.github_instructions_dir, external)
+ try:
+ with mock.patch("sys.stderr", new_callable=io.StringIO) as stderr:
+ self.assertEqual(1, self.installer.install(force=True))
+
+ self.assertIn("is a symlink or reparse point", stderr.getvalue())
+ self.assertFalse(self.installer.copilot_instructions.exists())
+ self.assertEqual(["keep.txt"], [p.name for p in external.iterdir()])
+ finally:
+ if self.installer.github_instructions_dir.is_symlink():
+ self.installer.github_instructions_dir.unlink()
+
+ def test_frontmatter_uses_yaml_and_preserves_original_block(self):
+ markdown_file = self.repo_root / "frontmatter.md"
+ frontmatter = ("---\n"
+ 'name: "name: with colon"\n'
+ "description: >-\n"
+ " Folded description.\n"
+ "---")
+ self._write(markdown_file, f"{frontmatter}\n\nBody.\n")
+
+ metadata, block = self.installer._frontmatter(markdown_file)
+
+ self.assertEqual("name: with colon", metadata["name"])
+ self.assertEqual("Folded description.", metadata["description"])
+ self.assertEqual(frontmatter, block)
+
+ def test_force_refreshes_generated_wrapper(self):
+ skill_dir = self._add_skill("test-skill")
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=False))
+ self._write(
+ skill_dir / "SKILL.md",
+ "---\nname: test-skill\ndescription: Updated description.\n---\n")
+ self.assertEqual(0, self.installer.install(force=True))
+
+ installed = self.installer.github_skills_dir / "test-skill" / "SKILL.md"
+ self.assertIn("description: Updated description.",
+ installed.read_text(encoding="utf-8"))
+
+ def test_stale_generated_wrapper_is_removed(self):
+ stale_skill = self._add_skill("stale-skill")
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=False))
+ installed = self.installer.github_skills_dir / "stale-skill"
+ self._write(installed / "user-notes.md", "Keep me.\n")
+ shutil.rmtree(stale_skill)
+ self.assertEqual(0, self.installer.install(force=False))
+
+ self.assertTrue(installed.is_dir())
+ self.assertFalse((installed / "SKILL.md").exists())
+ self.assertEqual("Keep me.\n",
+ (installed / "user-notes.md").read_text(encoding="utf-8"))
+
+ def test_force_preserves_user_files_beside_generated_wrapper(self):
+ self._add_skill("test-skill")
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=False))
+ installed = self.installer.github_skills_dir / "test-skill"
+ self._write(installed / "user-notes.md", "Keep me.\n")
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertTrue((installed / "SKILL.md").is_file())
+ self.assertEqual("Keep me.\n",
+ (installed / "user-notes.md").read_text(encoding="utf-8"))
+
+ def test_incompatible_skills_are_not_installed(self):
+ for skill_name in COPILOT_INCOMPATIBLE_SKILLS:
+ self._add_skill(skill_name)
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ for skill_name in COPILOT_INCOMPATIBLE_SKILLS:
+ self.assertFalse((self.installer.github_skills_dir / skill_name).exists())
+
+ def test_incompatible_adapter_sources_exist_in_checkout(self):
+ for rule_name in COPILOT_INCOMPATIBLE_RULES:
+ with self.subTest(rule=rule_name):
+ self.assertTrue((REPO_ROOT / "agents" / "rules" / rule_name).is_file())
+ for skill_name in COPILOT_INCOMPATIBLE_SKILLS:
+ with self.subTest(skill=skill_name):
+ self.assertTrue((REPO_ROOT / "agents" / "skills" / skill_name /
+ "SKILL.md").is_file())
+
+ def test_file_system_errors_propagate(self):
+ generated_file = self.installer.copilot_instructions
+ self._write(generated_file, GENERATED_MARKER)
+ with mock.patch.object(
+ Path, "read_text", side_effect=OSError("unreadable")):
+ with self.assertRaisesRegex(OSError, "unreadable"):
+ self.installer._write_generated_file(generated_file, "new contents")
+
+ def test_force_preserves_user_managed_files(self):
+ self._add_skill("test-skill")
+ self._write(self.installer.copilot_instructions, "User instructions.\n")
+ installed = self.installer.github_skills_dir / "test-skill"
+ self._write(installed / "SKILL.md", "User skill.\n")
+
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertEqual(
+ "User instructions.\n",
+ self.installer.copilot_instructions.read_text(encoding="utf-8"))
+ self.assertEqual("User skill.\n",
+ (installed / "SKILL.md").read_text(encoding="utf-8"))
+
+ @unittest.skipUnless(os.name == "nt", "Directory junctions require Windows")
+ def test_rejects_github_junction_before_mutation(self):
+ self._add_skill("test-skill")
+ with tempfile.TemporaryDirectory() as external_temp_dir:
+ external_github = Path(external_temp_dir) / "external-github"
+ self._write(external_github / "copilot-instructions.md",
+ f"{GENERATED_MARKER}\n\nExternal instructions sentinel.\n")
+ self._write(external_github / "skills" / "stale-skill" / "SKILL.md",
+ f"{GENERATED_MARKER}\n\nExternal skill sentinel.\n")
+ self._write(external_github / "keep.txt", "External tree sentinel.\n")
+ original_files = self._file_snapshot(external_github)
+
+ self._create_junction(self.installer.github_dir, external_github)
+ original_target = os.readlink(self.installer.github_dir)
+ try:
+ with mock.patch("sys.stderr", new_callable=io.StringIO) as stderr:
+ self.assertEqual(1, self.installer.install(force=True))
+
+ self.assertIn(
+ f"Unsafe adapter destination: {self.installer.github_dir}",
+ stderr.getvalue())
+ self.assertEqual(original_target,
+ os.readlink(self.installer.github_dir))
+ self.assertEqual(original_files, self._file_snapshot(external_github))
+ self.assertFalse((external_github / "skills" / "test-skill").exists())
+ finally:
+ self._remove_junction(self.installer.github_dir)
+
+ @unittest.skipUnless(os.name == "nt", "Directory junctions require Windows")
+ def test_rejects_skills_junction_before_mutation(self):
+ self._add_skill("test-skill")
+ self._write(self.installer.copilot_instructions,
+ "User instructions sentinel.\n")
+ original_instructions = self.installer.copilot_instructions.read_bytes()
+ with tempfile.TemporaryDirectory() as external_temp_dir:
+ external_skills = Path(external_temp_dir) / "external-skills"
+ self._write(external_skills / "test-skill" / "SKILL.md",
+ f"{GENERATED_MARKER}\n\nExternal skill sentinel.\n")
+ self._write(external_skills / "keep.txt", "External tree sentinel.\n")
+ original_files = self._file_snapshot(external_skills)
+
+ self._create_junction(self.installer.github_skills_dir, external_skills)
+ original_target = os.readlink(self.installer.github_skills_dir)
+ try:
+ with mock.patch("sys.stderr", new_callable=io.StringIO) as stderr:
+ self.assertEqual(1, self.installer.install(force=True))
+
+ self.assertIn(
+ f"Unsafe adapter destination: {self.installer.github_skills_dir}",
+ stderr.getvalue())
+ self.assertEqual(original_instructions,
+ self.installer.copilot_instructions.read_bytes())
+ self.assertEqual(original_target,
+ os.readlink(self.installer.github_skills_dir))
+ self.assertEqual(original_files, self._file_snapshot(external_skills))
+ finally:
+ self._remove_junction(self.installer.github_skills_dir)
+
+ def test_rejects_github_symlink_before_mutation(self):
+ self._add_skill("test-skill")
+ with tempfile.TemporaryDirectory() as external_temp_dir:
+ external_github = Path(external_temp_dir) / "external-github"
+ self._write(external_github / "keep.txt", "External tree sentinel.\n")
+ self._symlink_or_skip(self.installer.github_dir, external_github)
+ try:
+ with mock.patch("sys.stderr", new_callable=io.StringIO) as stderr:
+ self.assertEqual(1, self.installer.install(force=True))
+
+ self.assertIn("is a symlink or reparse point", stderr.getvalue())
+ self.assertTrue(self.installer.github_dir.is_symlink())
+ self.assertEqual("External tree sentinel.\n",
+ (external_github /
+ "keep.txt").read_text(encoding="utf-8"))
+ self.assertFalse((external_github / "copilot-instructions.md").exists())
+ self.assertFalse((external_github / "skills").exists())
+ finally:
+ if self.installer.github_dir.is_symlink():
+ self.installer.github_dir.unlink()
+
+ def test_rejects_skills_symlink_before_mutation(self):
+ self._add_skill("test-skill")
+ self._write(self.installer.copilot_instructions,
+ "User instructions sentinel.\n")
+ original_instructions = self.installer.copilot_instructions.read_bytes()
+ with tempfile.TemporaryDirectory() as external_temp_dir:
+ external_skills = Path(external_temp_dir) / "external-skills"
+ self._write(external_skills / "keep.txt", "External tree sentinel.\n")
+ self._symlink_or_skip(self.installer.github_skills_dir, external_skills)
+ try:
+ with mock.patch("sys.stderr", new_callable=io.StringIO) as stderr:
+ self.assertEqual(1, self.installer.install(force=True))
+
+ self.assertIn("is a symlink or reparse point", stderr.getvalue())
+ self.assertEqual(original_instructions,
+ self.installer.copilot_instructions.read_bytes())
+ self.assertTrue(self.installer.github_skills_dir.is_symlink())
+ self.assertEqual("External tree sentinel.\n",
+ (external_skills /
+ "keep.txt").read_text(encoding="utf-8"))
+ self.assertFalse((external_skills / "test-skill").exists())
+ finally:
+ if self.installer.github_skills_dir.is_symlink():
+ self.installer.github_skills_dir.unlink()
+
+ def test_force_does_not_follow_user_managed_symlink(self):
+ skill_dir = self._add_skill("test-skill")
+ external_skill = self.repo_root / "external-skill"
+ self._write(external_skill / "SKILL.md",
+ f"{GENERATED_MARKER}\n\nUser-managed target.\n")
+ installed = self.installer.github_skills_dir / "test-skill"
+ installed.parent.mkdir(parents=True)
+ self._symlink_or_skip(installed, external_skill)
+
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertTrue(installed.is_symlink())
+ self.assertEqual(f"{GENERATED_MARKER}\n\nUser-managed target.\n",
+ (external_skill / "SKILL.md").read_text(encoding="utf-8"))
+ self.assertNotEqual(
+ installed.resolve(strict=False), skill_dir.resolve(strict=False))
+
+ @unittest.skipUnless(os.name == "nt", "Directory junctions require Windows")
+ def test_force_does_not_follow_user_managed_junction(self):
+ self._add_skill("test-skill")
+ external_skill = self.repo_root / "junction-target"
+ target_contents = (
+ f"{GENERATED_MARKER}\r\n\r\nUser-managed junction target.\r\n")
+ self._write(external_skill / "SKILL.md", target_contents)
+ installed = self.installer.github_skills_dir / "test-skill"
+ installed.parent.mkdir(parents=True)
+ self._create_junction(installed, external_skill)
+
+ original_contents = (external_skill / "SKILL.md").read_bytes()
+ try:
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertEqual(original_contents,
+ (external_skill / "SKILL.md").read_bytes())
+ self.assertTrue(self._is_junction(installed))
+ finally:
+ self._remove_junction(installed)
+
+ @unittest.skipUnless(os.name == "nt", "Directory junctions require Windows")
+ def test_force_preserves_dangling_user_managed_junction(self):
+ self._add_skill("test-skill")
+ installed = self.installer.github_skills_dir / "test-skill"
+ installed.parent.mkdir(parents=True)
+
+ with tempfile.TemporaryDirectory() as external_temp_dir:
+ external_skill = Path(external_temp_dir) / "junction-target"
+ moved_skill = Path(external_temp_dir) / "moved-target"
+ target_contents = (
+ f"{GENERATED_MARKER}\r\n\r\nUser-managed junction target.\r\n")
+ self._write(external_skill / "SKILL.md", target_contents)
+ self._create_junction(installed, external_skill)
+
+ original_target = os.readlink(installed)
+ original_contents = (external_skill / "SKILL.md").read_bytes()
+ try:
+ external_skill.rename(moved_skill)
+ self.assertFalse(external_skill.exists())
+ self.assertFalse(installed.exists())
+
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertEqual(original_target, os.readlink(installed))
+ self.assertEqual(original_contents,
+ (moved_skill / "SKILL.md").read_bytes())
+ self.assertTrue(self._is_junction(installed))
+ finally:
+ self._remove_junction(installed)
+
+ def test_non_utf8_user_files_are_skipped(self):
+ self._add_skill("test-skill")
+ installed = self.installer.github_skills_dir / "test-skill"
+ installed.mkdir(parents=True)
+ self.installer.copilot_instructions.write_bytes(b"\xe9 user notes\n")
+ (installed / "SKILL.md").write_bytes(b"\xe9 user skill\n")
+
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertEqual(b"\xe9 user notes\n",
+ self.installer.copilot_instructions.read_bytes())
+ self.assertEqual(b"\xe9 user skill\n",
+ (installed / "SKILL.md").read_bytes())
+
+ def test_generated_file_symlink_is_not_followed(self):
+ external = self.repo_root / "shared-instructions.md"
+ self._write(external, f"{GENERATED_MARKER}\n\nShared checkout content.\n")
+ self.installer.github_dir.mkdir(parents=True)
+ self._symlink_or_skip(
+ self.installer.copilot_instructions, external, is_directory=False)
+ original = external.read_bytes()
+
+ self.assertEqual(0, self.installer.install(force=True))
+
+ self.assertEqual(original, external.read_bytes())
+ self.assertTrue(self.installer.copilot_instructions.is_symlink())
+
+ def test_without_force_existing_adapters_are_left_alone(self):
+ skill_dir = self._add_skill("test-skill")
+ with self._without_symlink_support():
+ self.assertEqual(0, self.installer.install(force=False))
+ installed = self.installer.github_skills_dir / "test-skill" / "SKILL.md"
+ original = installed.read_bytes()
+
+ self._write(skill_dir / "SKILL.md",
+ "---\nname: test-skill\ndescription: Updated.\n---\n")
+ self.assertEqual(0, self.installer.install(force=False))
+
+ self.assertEqual(original, installed.read_bytes())
+
+ def test_stale_removal_preserves_user_managed_adapters(self):
+ self._add_skill("test-skill")
+ user_rule = self.installer.github_instructions_dir / "mine.instructions.md"
+ user_skill = self.installer.github_skills_dir / "mine" / "SKILL.md"
+ self._write(user_rule, "User rule.\n")
+ self._write(user_skill, "User skill.\n")
+
+ self.assertEqual(0, self.installer.install(force=False))
+
+ self.assertEqual("User rule.\n", user_rule.read_text(encoding="utf-8"))
+ self.assertEqual("User skill.\n", user_skill.read_text(encoding="utf-8"))
+
+ def test_missing_skills_directory_fails(self):
+ missing_root = self.repo_root / "missing"
+ self.assertEqual(1, CopilotInstaller(missing_root).install(force=False))
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/deps/v8/agents/skills/ecmascript-evaluation/SKILL.md b/deps/v8/agents/skills/ecmascript-evaluation/SKILL.md
index 1845f2da738..020e5c21062 100644
--- a/deps/v8/agents/skills/ecmascript-evaluation/SKILL.md
+++ b/deps/v8/agents/skills/ecmascript-evaluation/SKILL.md
@@ -88,30 +88,45 @@ your answers:
### I. Navigation & Grammar Extraction
-- `ecma262_get_operation(name)`: **[RECOMMENDED]** Use this to directly fetch
- the algorithm for an abstract operation by name (e.g., `ToObject`, `GetValue`,
- `CreateMutableBinding`). **Try this FIRST** whenever you know the name of the
- operation you need, as it bypasses search-then-fetch and saves steps.
-- `ecma262_get_evaluation(production_name)`: **[RECOMMENDED]** Use this to
- directly fetch the evaluation rules for a specific grammar production (e.g.,
- `VariableStatement`). This saves steps and is much faster than searching.
-- `ecma262_search(query)`: Use this to locate the exact section ID for a syntax
- node (e.g., `VariableStatement`) or when you don't know the exact name of the
- operation.
-- `ecma262_signature(name)` / `ecma262_dependencies(id)`: Use these to map out
- the call graph before writing out an evaluation. This ensures you know which
- operations you will need to invoke.
-- `ecma262_section(id)`: Fetch the actual algorithm steps. Treat these steps as
- law.
-- `ecma262_lookup(id)`: Resolves the ancestry (parent chain) of a given section
- ID, helping to understand its context in the specification hierarchy.
-- `ecma262_sections(ids)`: Fetch full HTML content for multiple section IDs at
- once to reduce tool calls.
-- `ecma262_production(symbol)`: Use this to fetch Syntactic or Lexical grammar
- rules (e.g., `StringNumericLiteral` or `AssignmentExpression`) to explain
- parsing edge cases.
-
-### II. State Alteration (JSON Scratchpad)
+- `ecma262_get_operation(name, proposal=None)`: **[RECOMMENDED]** Use this to
+ directly fetch the algorithm for an abstract operation by name (e.g.,
+ `ToObject`, `GetValue`, `CreateMutableBinding`, `PrivateFieldAdd`). Steps that
+ can invoke JavaScript user code (getters, setters, Proxy traps,
+ `Symbol.toPrimitive`, etc.) are annotated with `⚡`.
+- `ecma262_get_evaluation(production_name, proposal=None)`: **[RECOMMENDED]**
+ Use this to directly fetch the evaluation rules for a specific grammar
+ production (e.g., `VariableStatement`). This saves steps and is much faster
+ than searching.
+- `ecma262_callers(name, proposal=None)`: Find all algorithm steps across the
+ specification (or active TC39 proposal) that call or reference a given
+ operation (e.g., `IsExtensible`, `HostEnsureCanAddPrivateElement`).
+- `ecma262_search(query, proposal=None)`: Use this to locate the exact section
+ ID for a syntax node (e.g., `VariableStatement`) or when you don't know the
+ exact name of the operation.
+- `ecma262_signature(name, proposal=None)`: Fetch the formal type signature of
+ an abstract operation.
+- `ecma262_section(id, proposal=None)`: Fetch the rendered Markdown content of a
+ specific section ID.
+- `ecma262_sections(ids, proposal=None)`: Fetch content for multiple section IDs
+ at once.
+- `ecma262_lookup(id, proposal=None)`: Resolves the ancestry (parent chain) of a
+ given section ID, helping to understand its context in the specification
+ hierarchy.
+
+### II. TC39 Proposal Research & Diffing
+
+- `ecma262_load_proposal(name)`: Fetch and index an official TC39 proposal
+ (e.g., `defer-import-eval`, `explicit-resource-management`, `temporal`,
+ `decorators`, `shadowrealm`) and set it as the active context.
+- `ecma262_list_proposals()`: List all loaded proposals and see which
+ specification context is currently active.
+- `ecma262_use_proposal(name)`: Switch the active specification context between
+ Base ECMA-262 (`"base"`) and any loaded proposal.
+- `ecma262_diff(name, proposal=None)`: Compare an abstract operation or clause
+ between Base ECMA-262 and a TC39 proposal, displaying `<ins>` additions and
+ `<del>` deletions side-by-side.
+
+### III. State Alteration (JSON Scratchpad)
You **MUST** use the following tools to maintain the abstract machine state.
Call `init()` at the start of evaluation. The tool will automatically generate a
diff --git a/deps/v8/bazel/defs.bzl b/deps/v8/bazel/defs.bzl
index 1b1234b02db..68f283bcfc3 100644
--- a/deps/v8/bazel/defs.bzl
+++ b/deps/v8/bazel/defs.bzl
@@ -8,6 +8,7 @@ This module contains helper functions to compile V8.
load("@rules_cc//cc:cc_library.bzl", "cc_library")
load("@rules_cc//cc:cc_binary.bzl", "cc_binary")
+load("@rules_cc//cc:find_cc_toolchain.bzl", "find_cc_toolchain", "use_cc_toolchain")
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
@@ -140,6 +141,7 @@ def _default_args():
"-Wno-invalid-offsetof",
"-Wno-deprecated-this-capture",
"-Wno-deprecated-declarations",
+ "-Wno-deprecated-attributes",
"-std=c++20",
],
"@v8//bazel/config:is_gcc": [
@@ -590,7 +592,6 @@ def build_config_content(cpu, icu):
("local_off_stack_check", "false"),
("lower_limits_mode", "false"),
("memory_corruption_api", "false"),
- ("cppgc_microtask_queue", "false"),
("mips_arch_variant", '""'),
("mips_use_msa", "false"),
("msan", "false"),
@@ -621,6 +622,296 @@ def build_config_content(cpu, icu):
("write_barriers", "false"),
])
+# =============================================================================
+# Metagen: libclang-driven instance-type generator.
+#
+# Produces gen/metagen/instance-types.h, the file `src/objects/instance-types-
+# gen.h` includes when V8_USE_METAGEN_INSTANCE_TYPES=1, i.e. under
+# --//:v8_use_metagen_instance_types.
+#
+# The generator runs tools/metagen/metagen.py, which uses libclang to parse
+# V8_OBJECT-annotated C++ headers and emits the IT enum macros. We feed it
+# a compile_commands.json synthesized from cc_common: the defines / includes
+# come from the cc_libraries passed via `cc_compilation_context_from`, the
+# toolchain bits (libc++ -isystem, sysroot, target triple, ...) come from
+# the active cc toolchain, and metagen-specific cflags (-std=c++20,
+# -fno-rtti, -fno-exceptions, -fsyntax-only) come from a small list below.
+# =============================================================================
+
+# Metagen-specific cflags that don't propagate via CcInfo (they're copts on
+# v8_library, not on the `:define_flags` we depend on). Kept tiny on
+# purpose -- everything else comes from the toolchain or CcInfo.
+_METAGEN_USER_COPTS = [
+ "-std=c++20",
+ "-fno-rtti",
+ "-fno-exceptions",
+]
+
+def _metagen_instance_types_impl(ctx):
+ v8root = ctx.label.workspace_root
+ if v8root == "":
+ v8root = "."
+
+ out_h = ctx.actions.declare_file(
+ ctx.attr.prefix + "/metagen/instance-types.h",
+ )
+ out_dir = out_h.dirname
+
+ # Merge CcInfo from all cc_compilation_context_from targets -- this is
+ # where V8's defines (`:define_flags`), the libc++ system include path
+ # (`@libcxx//:libc++`), and the V8 source-root include come from.
+ cc_infos = [d[CcInfo] for d in ctx.attr.cc_compilation_context_from]
+ merged_cc_info = cc_common.merge_cc_infos(cc_infos = cc_infos)
+ cc_context = merged_cc_info.compilation_context
+
+ cc_toolchain = find_cc_toolchain(ctx)
+ feature_configuration = cc_common.configure_features(
+ ctx = ctx,
+ cc_toolchain = cc_toolchain,
+ requested_features = ctx.features,
+ unsupported_features = ctx.disabled_features + ["module_maps"],
+ )
+
+ # -I dirs for the generated headers (torque, bytecode_builtins).
+ # None of these live in a cc_library CcInfo so they're added directly.
+ extra_quote_includes = [
+ ctx.bin_dir.path + "/" + v8root,
+ ctx.bin_dir.path + "/" + v8root + "/" + ctx.attr.prefix,
+ # V8 source root: needed because `is_posix` copts include
+ # `-isystem .` and that's a copt, not propagated via CcInfo.
+ ".",
+ ]
+
+ compile_variables = cc_common.create_compile_variables(
+ feature_configuration = feature_configuration,
+ cc_toolchain = cc_toolchain,
+ source_file = "tools/metagen/probe.cc",
+ user_compile_flags = _METAGEN_USER_COPTS,
+ include_directories = cc_context.includes,
+ quote_include_directories = depset(
+ extra_quote_includes,
+ transitive = [cc_context.quote_includes],
+ ),
+ system_include_directories = cc_context.system_includes,
+ framework_include_directories = cc_context.framework_includes,
+ preprocessor_defines = depset(
+ ctx.attr.extra_defines,
+ transitive = [
+ cc_context.defines,
+ cc_context.local_defines,
+ ],
+ ),
+ )
+
+ cc_cmd_line = cc_common.get_memory_inefficient_command_line(
+ feature_configuration = feature_configuration,
+ action_name = "c++-compile",
+ variables = compile_variables,
+ )
+ cc_binary = cc_common.get_tool_for_action(
+ feature_configuration = feature_configuration,
+ action_name = "c++-compile",
+ )
+
+ # Synthesize a one-entry compile_commands.json for metagen. (The GN
+ # side instead harvests flags via `gn desc`; this is the Bazel path.)
+ # The `directory` is the action's cwd (execroot); the bogus
+ # `probe.cc` file + `-c`/`-o` args are filtered out by metagen.
+ compile_db = ctx.actions.declare_file(
+ ctx.attr.prefix + "/metagen-compile-commands.json",
+ )
+ ctx.actions.write(
+ output = compile_db,
+ content = json.encode([{
+ "directory": ".",
+ "file": "tools/metagen/probe.cc",
+ "arguments": [cc_binary] + cc_cmd_line,
+ }]),
+ )
+
+ args = ctx.actions.args()
+ args.add("--v8-root", v8root)
+ args.add("--compile-commands", compile_db.path)
+ args.add("--driver", ctx.file.driver.path)
+ args.add("--out", out_dir)
+
+ # Where libclang comes from. Both modes are explicit, so a mismatch
+ # is an analysis-time error rather than a harvest that quietly parses
+ # with the wrong library.
+ if ctx.attr.libclang_from_python_env:
+ if ctx.files.libclang_files:
+ fail("libclang_from_python_env = True, but libclang_files is " +
+ "non-empty. In this mode the bindings come from the tool's " +
+ "Python deps; drop libclang_files or unset the flag.")
+ args.add("--libclang-from-python-env")
+ else:
+ if not ctx.files.libclang_files:
+ fail("libclang_files is empty. Pass the llvm-libclang package " +
+ "files, or set libclang_from_python_env = True to take the " +
+ "bindings from the tool's Python deps instead.")
+
+ # The llvm-libclang package root, as an execroot-relative path:
+ # metagen resolves it against the action's cwd. The files get
+ # there as action inputs (:metagen_libclang_files below), which
+ # is why the tool needs no runfiles copy of them. This mirrors
+ # what the GN action passes for //third_party/llvm-libclang.
+ args.add("--libclang-dir", v8root + "/third_party/llvm-libclang")
+
+ # Clang's builtin headers. Find the directory via stddef.h rather
+ # than files[0].dirname: the staged set contains subdirectories
+ # (sanitizer/, cuda_wrappers/, ...), so element 0 sits at the include
+ # root only by luck of ordering, and a dir one level too deep fails
+ # as a wall of parse errors rather than a build error.
+ builtin_headers_dir = None
+ for f in ctx.files.clang_builtin_headers:
+ if f.basename == "stddef.h":
+ builtin_headers_dir = f.dirname
+ break
+ if builtin_headers_dir == None:
+ fail("clang_builtin_headers contains no stddef.h, so the clang " +
+ "builtin-header directory cannot be located. Pass the target " +
+ "that stages clang's builtin headers (lib/Headers).")
+ args.add("--clang-builtin-headers-dir", builtin_headers_dir)
+
+ all_inputs = depset(
+ direct = [compile_db, ctx.file.driver],
+ transitive = [
+ depset(ctx.files.libclang_files),
+ depset(ctx.files.clang_builtin_headers),
+ depset(ctx.files.python_srcs),
+ depset(ctx.files.extra_sandbox_files),
+ cc_context.headers,
+ cc_toolchain.all_files,
+ ],
+ )
+
+ ctx.actions.run(
+ outputs = [out_h],
+ inputs = all_inputs,
+ executable = ctx.executable.tool,
+ arguments = [args],
+ mnemonic = "MetagenInstanceTypes",
+ progress_message = "Generating metagen/instance-types.h",
+ )
+
+ return [DefaultInfo(files = depset([out_h]))]
+
+# The harvest is a host tool that must reason about the target build, so
+# this rule's inputs fall into two groups -- the same split GN gets from
+# v8_generator_toolchain (see gni/snapshot_toolchain.gni), where the
+# generator is a host binary compiled with the target's V8 configuration:
+#
+# exec-configured the parsing machinery: the tool, libclang, and
+# clang's builtin headers. These are host-only
+# artifacts; a build that constrains targets by
+# platform will reject them for a non-host target
+# unless they are exec-configured.
+#
+# target-configured what we parse and how: `headers`,
+# `cc_compilation_context_from`, `extra_defines`, and
+# `extra_sandbox_files` (V8's own source headers).
+# These must reflect the TARGET build -- exec-
+# configuring them would harvest the host's defines,
+# which today changes nothing but would silently emit
+# host object layout once metagen generates layout.
+_metagen_instance_types = rule(
+ implementation = _metagen_instance_types_impl,
+ attrs = {
+ "prefix": attr.string(mandatory = True),
+ # The checked-in C++ driver, passed straight through as --driver. Its
+ # direct includes are staged by extra_sandbox_files, not by this attr.
+ "driver": attr.label(allow_single_file = True, mandatory = True),
+ "libclang_files": attr.label_list(allow_files = True, cfg = "exec"),
+ # Clang's builtin headers (stddef.h etc.), staged into the action
+ # sandbox and passed to metagen as -isystem. Separate from
+ # extra_sandbox_files because this is host toolchain material:
+ # it needs cfg = "exec", whereas V8's own headers must not have it.
+ "clang_builtin_headers": attr.label_list(
+ allow_files = True,
+ cfg = "exec",
+ mandatory = True,
+ ),
+ # Selects where libclang comes from; see the impl. Explicit rather
+ # than inferred from libclang_files being empty, so no call site
+ # can end up in environment mode by forgetting an argument.
+ "libclang_from_python_env": attr.bool(default = False),
+ "python_srcs": attr.label_list(allow_files = True, cfg = "exec"),
+ # Additional files that need to live in the action sandbox so
+ # libclang's transitive #include resolution succeeds, but that
+ # should NOT be directly included by the driver.
+ # Bazel hermetic sandboxing makes this necessary: header files
+ # only reach the sandbox via declared inputs, and the CcInfo of
+ # :v8_libbase / :define_flags doesn't reach into src/objects,
+ # src/handles, src/wasm etc. v8_libshared (which would) depends
+ # on this rule's output, so a CcInfo-based propagation cycles.
+ # V8's own headers, so target-configured; host-toolchain material
+ # goes in clang_builtin_headers instead.
+ "extra_sandbox_files": attr.label_list(allow_files = True),
+ # cc_library / v8_library / v8_config labels whose CcInfo merged
+ # compilation_context supplies the defines, includes, and libc++
+ # paths that V8 normally compiles with.
+ "cc_compilation_context_from": attr.label_list(
+ providers = [CcInfo],
+ mandatory = True,
+ ),
+ # Additional -D defines for the harvest that do not propagate
+ # via CcInfo (v8_library applies them as per-variant copts,
+ # e.g. V8_INTL_SUPPORT on the icu prefix).
+ "extra_defines": attr.string_list(),
+ "tool": attr.label(
+ executable = True,
+ cfg = "exec",
+ mandatory = True,
+ ),
+ },
+ fragments = ["cpp"],
+ # use_cc_toolchain() rather than a literal @bazel_tools label: the
+ # helper resolves to whichever cc toolchain type the surrounding
+ # build defines, and find_cc_toolchain() reads it back out of
+ # ctx.toolchains. Spelling the label directly makes the rule
+ # unusable in builds that do not have a @bazel_tools repository.
+ toolchains = use_cc_toolchain(),
+)
+
+def metagen_instance_types(name, driver,
+ python_srcs, tool,
+ cc_compilation_context_from,
+ clang_builtin_headers,
+ libclang_files = [],
+ libclang_from_python_env = False,
+ extra_sandbox_files = [],
+ icu_extra_defines = [],
+ icu_cc_compilation_context_from = []):
+ """Emit gen/metagen/instance-types.h for both icu/ and noicu/ prefixes.
+
+ Mirrors the v8_torque_files double-emission pattern so each consumer
+ library can include the correctly-prefixed copy. The two harvests
+ differ: v8_library compiles the icu variant with V8_INTL_SUPPORT
+ (via copts, invisible to CcInfo) and the intl object sources, so
+ the icu emission additionally enables the driver's i18n includes with the
+ intl defines and ICU's compilation context.
+
+ Pass either `libclang_files` (the bundled llvm-libclang package) or
+ `libclang_from_python_env = True` (bindings supplied through `tool`'s
+ Python deps) -- exactly one, enforced by the rule.
+ """
+ for prefix in ("noicu", "icu"):
+ is_icu = prefix == "icu"
+ _metagen_instance_types(
+ name = prefix + "/" + name,
+ prefix = prefix,
+ driver = driver,
+ libclang_files = libclang_files,
+ libclang_from_python_env = libclang_from_python_env,
+ clang_builtin_headers = clang_builtin_headers,
+ python_srcs = python_srcs,
+ tool = tool,
+ cc_compilation_context_from = cc_compilation_context_from +
+ (icu_cc_compilation_context_from if is_icu else []),
+ extra_defines = icu_extra_defines if is_icu else [],
+ extra_sandbox_files = extra_sandbox_files,
+ )
+
# TODO(victorgomes): Create a rule (instead of a macro), that can
# dynamically populate the build config.
def v8_build_config(name, arch):
diff --git a/deps/v8/bazel/toolchain/libcxx_repository.bzl b/deps/v8/bazel/toolchain/libcxx_repository.bzl
index 60aca4bf91d..b60ea9be615 100644
--- a/deps/v8/bazel/toolchain/libcxx_repository.bzl
+++ b/deps/v8/bazel/toolchain/libcxx_repository.bzl
@@ -28,11 +28,13 @@ load("@rules_cc//cc:defs.bzl", "cc_library")
package(default_visibility = ["//visibility:public"])
LIBCXX_COPTS = [
- "-std=c++23",
+ "-std=c++26",
"-fPIC",
"-fstrict-aliasing",
"-fexceptions",
"-frtti",
+ "-Wno-pragma-clang-attribute",
+ "-Wno-ignored-attributes",
"-D_LIBCPP_BUILDING_LIBRARY",
"-D_LIBCPP_HARDENING_MODE_DEFAULT=_LIBCPP_HARDENING_MODE_NONE",
"-DLIBC_NAMESPACE=__llvm_libc_cr",
diff --git a/deps/v8/docs/runtime/tiering.md b/deps/v8/docs/runtime/tiering.md
index 98fcb9af9ae..21e1c8a3430 100644
--- a/deps/v8/docs/runtime/tiering.md
+++ b/deps/v8/docs/runtime/tiering.md
@@ -62,7 +62,7 @@ When the budget is exceeded, V8 calls into the C++ runtime. Each tier has its ow
* **Ignition**: `Runtime::kBytecodeBudgetInterruptWithStackCheck_Ignition` and `Runtime::kBytecodeBudgetInterrupt_Ignition`.
* **Sparkplug**: `Runtime::kBytecodeBudgetInterruptWithStackCheck_Sparkplug` and `Runtime::kBytecodeBudgetInterrupt_Sparkplug`.
-* **Maglev**: `Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev` and `Runtime::kBytecodeBudgetInterrupt_Maglev`.
+* **Maglev**: `Runtime::kBytecodeBudgetLoopInterrupt_Maglev` and `Runtime::kBytecodeBudgetInterrupt_Maglev`.
The "WithStackCheck" variants are typically used at loop back-edges to handle both interrupts (e.g., GC requests, debugging pauses) and stack limit checks simultaneously.
diff --git a/deps/v8/docs/security/triaging.md b/deps/v8/docs/security/triaging.md
index 3a293aecae2..86ead358de9 100644
--- a/deps/v8/docs/security/triaging.md
+++ b/deps/v8/docs/security/triaging.md
@@ -22,6 +22,8 @@ It is okay to just set to the current stable or extended stable milestone if unk
- **Introduced In**: Should point to the milestone this was introduced.
It is okay to be conservative if unknown, e.g., to assume that the bug was present when a feature was launched.
+Triage is based on available information; initial classifications (such as type, severity, impact) may be revised as expert analysis or new evidence emerges.
+
### Sandbox bypasses
V8 Sandbox bypasses are included in Chrome’s VRP.
@@ -117,6 +119,14 @@ Invalid ("bogus") `DCHECK`s should still be fixed or removed.
Note: `CHECK`s must not be behind special builds or phases, such as `--verify-*`.
+### Leaking _Hole_ values into JavaScript
+
+Fields: **Type=Bug**, **[Security_Impact-None][hl-impact-none]**
+
+Rationale: V8 uses internal sentinel _Hole_ values.
+While leaking them historically enabled type confusion, _Hole_ sentinels are now immutable in read-only space, segregated by type (preventing cross-subsystem confusion), and have unmapped payloads (since M146) that deterministically crash on access.
+Leaks are therefore triaged as functional bugs unless exploitability is demonstrated.
+
### Breakage through directly invoking internal runtime functions with `%`-syntax
Runtime functions like `%IterableForEach()` are directly visible to JavaScript programs via `--allow-natives-syntax`.
diff --git a/deps/v8/gni/v8.gni b/deps/v8/gni/v8.gni
index b54c2d74057..aee7c82b486 100644
--- a/deps/v8/gni/v8.gni
+++ b/deps/v8/gni/v8.gni
@@ -34,6 +34,12 @@ declare_args() {
# Turns on compiler optimizations in V8 in Debug build.
v8_optimized_debug = true
+ # Selects which instance-type generator's output V8 compiles in:
+ # metagen (tools/metagen/) or Torque's emission. When off, the metagen
+ # action is out of the build graph entirely, so nothing depends on the
+ # llvm-libclang package. Sets -DV8_USE_METAGEN_INSTANCE_TYPES=0 when off.
+ v8_use_metagen_instance_types = true
+
# Support for backtrace_symbols on linux.
v8_enable_backtrace = ""
@@ -42,6 +48,7 @@ declare_args() {
v8_use_external_startup_data = ""
# Includes profiles to optimize builtins.
+ # Sets -DV8_ENABLE_BUILTINS_OPTIMIZATION.
v8_enable_builtins_optimization = ""
# Turns on all V8 debug features. Enables running V8 in a pseudo debug mode
@@ -62,10 +69,6 @@ declare_args() {
# Furthermore, some architectures don't have Rust toolchains in Chromium
v8_enable_temporal_support = !(defined(build_with_node) && build_with_node)
- # by default, don't enable compiling Temporal with a system ICU4C
- # (assume private headers are available)
- v8_enable_temporal_systemicu = false
-
# Use static libraries instead of source_sets.
v8_static_library = false
@@ -87,7 +90,9 @@ declare_args() {
v8_expose_symbols = false
# Implement tracing using Perfetto (https://perfetto.dev).
- v8_use_perfetto = false
+ # Chromium is configured to use the perfetto client library, v8 should also
+ # use perfetto for tracing.
+ v8_use_perfetto = build_with_chromium && !use_fuzzing_engine
# Use Perfetto JSON Export.
v8_use_perfetto_json_export = ""
@@ -95,12 +100,6 @@ declare_args() {
# Use Perfetto SDK headers.
v8_use_perfetto_sdk = false
- # Enable definition of v8::MicrotaskQueue as a cppgc object.
- # TODO(https://crbug.com/515252150): remove this flag once the old
- # v8::MicrotaskQueue::New() returning std::unique_ptr<> gets through
- # the V8 API deprecation process.
- v8_cppgc_microtask_queue = true
-
# Override global symbol level setting for v8.
v8_symbol_level = symbol_level
@@ -314,12 +313,6 @@ if (v8_use_perfetto_sdk) {
v8_use_perfetto = true
}
-# Chromium is configured to use the perfetto client library, v8 should also
-# use perfetto for tracing.
-if (build_with_chromium && !use_fuzzing_engine) {
- v8_use_perfetto = true
-}
-
# Enable JSON export by default when using perfetto but not the SDK.
if (v8_use_perfetto_json_export == "") {
v8_use_perfetto_json_export = v8_use_perfetto && !v8_use_perfetto_sdk
@@ -463,6 +456,7 @@ template("v8_source_set") {
} else {
link_target_type = "source_set"
}
+
target(link_target_type, target_name) {
forward_variables_from(invoker,
"*",
diff --git a/deps/v8/include/OWNERS b/deps/v8/include/OWNERS
index c0e3a1f767b..c0b23e355e5 100644
--- a/deps/v8/include/OWNERS
+++ b/deps/v8/include/OWNERS
@@ -1,6 +1,7 @@
cbruni@chromium.org
leszeks@chromium.org
mlippautz@chromium.org
+olivf@chromium.org
verwaest@chromium.org
yangguo@chromium.org
diff --git a/deps/v8/include/cppgc/explicit-management.h b/deps/v8/include/cppgc/explicit-management.h
index 0290328dccb..d7f1dcde656 100644
--- a/deps/v8/include/cppgc/explicit-management.h
+++ b/deps/v8/include/cppgc/explicit-management.h
@@ -90,8 +90,11 @@ template <typename T>
bool Resize(T& object, AdditionalBytes additional_bytes) {
static_assert(IsGarbageCollectedTypeV<T>,
"Object must be of type GarbageCollected.");
- return internal::ExplicitManagementImpl::Resize(
- &object, sizeof(T) + additional_bytes.value);
+ const size_t new_object_size = sizeof(T) + additional_bytes.value;
+ if (new_object_size < sizeof(T)) {
+ return false;
+ }
+ return internal::ExplicitManagementImpl::Resize(&object, new_object_size);
}
} // namespace subtle
diff --git a/deps/v8/include/js_protocol.pdl b/deps/v8/include/js_protocol.pdl
index bc86332d869..99905a48ca7 100644
--- a/deps/v8/include/js_protocol.pdl
+++ b/deps/v8/include/js_protocol.pdl
@@ -143,6 +143,12 @@ 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.
+ # Only present if true.
+ # Empty scopes are retained in the scope chain because
+ # they can be targeted via `evaluateOnCallFrame` (using `scopeNumber`) or
+ # matched against scopes in source maps.
+ experimental optional boolean empty
# Search match for resource.
type SearchMatch extends object
@@ -212,6 +218,8 @@ domain Debugger
optional boolean throwOnSideEffect
# Terminate execution after timing out (number of milliseconds).
experimental optional Runtime.TimeDelta timeout
+ # Specifies the scope number to evaluate the expression in (default: 0, innermost scope).
+ experimental optional integer scopeNumber
returns
# Object wrapper for the evaluation result.
Runtime.RemoteObject result
@@ -485,14 +493,8 @@ domain Debugger
# New return value.
Runtime.CallArgument newValue
- # Edits JavaScript source live.
- #
- # In general, functions that are currently on the stack can not be edited with
- # a single exception: If the edited function is the top-most stack frame and
- # that is the only activation of that function on the stack. In this case
- # the live edit will be successful and a `Debugger.restartFrame` for the
- # top-most function is automatically triggered.
- command setScriptSource
+ # Live edit is no longer supported and this command always fails with a "no longer available" error.
+ deprecated command setScriptSource
parameters
# Id of the script to edit.
Runtime.ScriptId scriptId
@@ -1142,6 +1144,7 @@ domain Runtime
dataview
webassemblymemory
wasmvalue
+ deferredmodule
# blink's subtypes.
trustedtype
# Object class (constructor) name. Specified for `object` type values only.
@@ -1205,6 +1208,7 @@ domain Runtime
dataview
webassemblymemory
wasmvalue
+ deferredmodule
# blink's subtypes.
trustedtype
# String representation of the object.
@@ -1256,6 +1260,7 @@ domain Runtime
dataview
webassemblymemory
wasmvalue
+ deferredmodule
# blink's subtypes.
trustedtype
diff --git a/deps/v8/include/v8-container.h b/deps/v8/include/v8-container.h
index 380999e5ee4..213e38d6204 100644
--- a/deps/v8/include/v8-container.h
+++ b/deps/v8/include/v8-container.h
@@ -76,17 +76,8 @@ class V8_EXPORT Array : public Object {
* This function will typically be faster than calling {Get()} repeatedly.
* As a consequence of being optimized for low overhead, the provided
* callback must adhere to the following restrictions:
- * - It must not allocate any V8 objects and continue iterating; it may
- * allocate (e.g. an error message/object) and then immediately terminate
- * the iteration.
* - It must not modify the array being iterated.
- * - It must not call back into V8 (unless it can guarantee that such a
- * call does not violate the above restrictions, which is difficult).
- * - The {Local<Value> element} must not "escape", i.e. must not be assigned
- * to any other {Local}. Creating a {Global} from it, or updating a
- * v8::TypecheckWitness with it, is safe.
- * These restrictions may be lifted in the future if use cases arise that
- * justify a slower but more robust implementation.
+ * - It must not call back into V8 to execute JavaScript.
*
* Returns {Nothing} on exception; use a {TryCatch} to catch and handle this
* exception.
diff --git a/deps/v8/include/v8-context.h b/deps/v8/include/v8-context.h
index a91bae448a0..02b6f5c855d 100644
--- a/deps/v8/include/v8-context.h
+++ b/deps/v8/include/v8-context.h
@@ -9,6 +9,7 @@
#include <vector>
+#include "cppgc/type-traits.h" // NOLINT(build/include_directory)
#include "v8-data.h" // NOLINT(build/include_directory)
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-maybe.h" // NOLINT(build/include_directory)
@@ -316,39 +317,22 @@ class V8_EXPORT Context : public Data {
*/
V8_INLINE void* GetAlignedPointerFromEmbedderData(Isolate* isolate, int index,
EmbedderDataTypeTag tag);
- V8_INLINE void* GetAlignedPointerFromEmbedderData(int index,
- EmbedderDataTypeTag tag);
-
- V8_DEPRECATED(
- "Use GetAlignedPointerFromEmbedderData with EmbedderDataTypeTag "
- "parameter instead.")
- V8_INLINE void* GetAlignedPointerFromEmbedderData(Isolate* isolate,
- int index) {
- return GetAlignedPointerFromEmbedderData(isolate, index,
- kEmbedderDataTypeTagDefault);
- }
-
- V8_DEPRECATED(
- "Use GetAlignedPointerFromEmbedderData with EmbedderDataTypeTag "
- "parameter instead.")
- V8_INLINE void* GetAlignedPointerFromEmbedderData(int index) {
- return GetAlignedPointerFromEmbedderData(index,
- kEmbedderDataTypeTagDefault);
- }
+ void* GetAlignedPointerFromEmbedderData(int index,
+ EmbedderDataTypeTag tag);
+ template <typename T>
+ requires cppgc::IsGarbageCollectedTypeV<T>
+ V8_INLINE T* GetAlignedPointerFromEmbedderData(Isolate* isolate, int index,
+ CppHeapPointerTag tag);
void SetAlignedPointerInEmbedderData(int index, void* value,
EmbedderDataTypeTag tag);
- /**
- * Sets a 2-byte-aligned native pointer in the embedder data with the given
- * index, growing the data as needed. Note that index 0 currently has a
- * special meaning for Chrome's debugger.
- */
- V8_DEPRECATED(
- "Use SetAlignedPointerInEmbedderData with EmbedderDataTypeTag parameter "
- "instead.")
- void SetAlignedPointerInEmbedderData(int index, void* value) {
- SetAlignedPointerInEmbedderData(index, value, kEmbedderDataTypeTagDefault);
+ template <typename T>
+ requires cppgc::IsGarbageCollectedTypeV<T>
+ void SetAlignedPointerInEmbedderData(int index, T* value,
+ CppHeapPointerTag tag) {
+ SetAlignedPointerInEmbedderDataInternal(index, static_cast<void*>(value),
+ tag);
}
/**
@@ -477,8 +461,9 @@ class V8_EXPORT Context : public Data {
size_t index);
Local<Value> SlowGetEmbedderData(int index);
Local<Data> SlowGetEmbedderDataV2(int index);
- void* SlowGetAlignedPointerFromEmbedderData(int index,
- EmbedderDataTypeTag tag);
+ void* SlowGetAlignedPointerFromEmbedderData(int index, CppHeapPointerTag tag);
+ void SetAlignedPointerInEmbedderDataInternal(int index, void* value,
+ CppHeapPointerTag tag);
};
// --- Implementation ---
@@ -529,26 +514,15 @@ V8_INLINE Local<Data> Context::GetEmbedderDataV2(int index) {
#endif
}
-void* Context::GetAlignedPointerFromEmbedderData(Isolate* isolate, int index,
- EmbedderDataTypeTag tag) {
-#if !defined(V8_ENABLE_CHECKS)
- using A = internal::Address;
- using I = internal::Internals;
- A ctx = internal::ValueHelper::ValueAsAddress(this);
- A embedder_data =
- I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
- int value_offset = I::kEmbedderDataArrayHeaderSize +
- (I::kEmbedderDataSlotSize * index) +
- I::kEmbedderDataSlotExternalPointerOffset;
- return reinterpret_cast<void*>(I::ReadExternalPointerField(
- isolate, embedder_data, value_offset, ToExternalPointerTag(tag)));
-#else
- return SlowGetAlignedPointerFromEmbedderData(index, tag);
-#endif
+V8_INLINE void* Context::GetAlignedPointerFromEmbedderData(
+ Isolate* isolate, int index, EmbedderDataTypeTag tag) {
+ return GetAlignedPointerFromEmbedderData(index, tag);
}
-void* Context::GetAlignedPointerFromEmbedderData(int index,
- EmbedderDataTypeTag tag) {
+template <typename T>
+ requires cppgc::IsGarbageCollectedTypeV<T>
+T* Context::GetAlignedPointerFromEmbedderData(Isolate* isolate, int index,
+ CppHeapPointerTag tag) {
#if !defined(V8_ENABLE_CHECKS)
using A = internal::Address;
using I = internal::Internals;
@@ -557,12 +531,11 @@ void* Context::GetAlignedPointerFromEmbedderData(int index,
I::ReadTaggedPointerField(ctx, I::kNativeContextEmbedderDataOffset);
int value_offset = I::kEmbedderDataArrayHeaderSize +
(I::kEmbedderDataSlotSize * index) +
- I::kEmbedderDataSlotExternalPointerOffset;
- Isolate* isolate = I::GetCurrentIsolateForSandbox();
- return reinterpret_cast<void*>(I::ReadExternalPointerField(
- isolate, embedder_data, value_offset, ToExternalPointerTag(tag)));
+ I::kEmbedderDataSlotCppHeapPointerOffset;
+ return internal::ReadCppHeapPointerField<T>(
+ isolate, embedder_data, value_offset, CppHeapPointerTagRange(tag, tag));
#else
- return SlowGetAlignedPointerFromEmbedderData(index, tag);
+ return static_cast<T*>(SlowGetAlignedPointerFromEmbedderData(index, tag));
#endif
}
diff --git a/deps/v8/include/v8-cppgc.h b/deps/v8/include/v8-cppgc.h
index 9dc6ee5e617..2bb82aa6f2c 100644
--- a/deps/v8/include/v8-cppgc.h
+++ b/deps/v8/include/v8-cppgc.h
@@ -86,15 +86,6 @@ class V8_EXPORT CppHeap {
*/
cppgc::HeapHandle& GetHeapHandle();
- /**
- * Terminate clears all roots and performs multiple garbage collections to
- * reclaim potentially newly created objects in destructors.
- *
- * After this call, object allocation is prohibited.
- */
- V8_DEPRECATED("Terminate gets automatically called in the CppHeap destructor")
- void Terminate();
-
/**
* \param detail_level specifies whether should return detailed
* statistics or only brief summary statistics.
@@ -136,6 +127,28 @@ class V8_EXPORT CppHeap {
void CollectGarbageInYoungGenerationForTesting(
cppgc::EmbedderStackState stack_state);
+ /**
+ * Controls whether forced garbage collections sweep atomically.
+ *
+ * A forced garbage collection (including
+ * `Isolate::RequestGarbageCollectionForTesting()`) normally sweeps
+ * atomically, so finalizers have already run by the time the collection
+ * returns. When this is enabled, forced collections instead sweep according
+ * to the heap's sweeping support, leaving finalization deferred as it would
+ * be in a natural garbage collection. This lets a test observe an object in
+ * the window between being discovered unreachable and being finalized.
+ *
+ * Note that sweeping may then be concurrent; pass `--single-threaded-gc` for
+ * sweeping that only makes progress on the main thread, and use
+ * `FinishSweepingForTesting()` to close the window deterministically.
+ */
+ void SetForceIncrementalSweepingForTesting(bool value);
+
+ /**
+ * Finishes any in-progress sweeping, running the finalizers it discovers.
+ */
+ void FinishSweepingForTesting();
+
private:
CppHeap() = default;
diff --git a/deps/v8/include/v8-exception.h b/deps/v8/include/v8-exception.h
index f240d9a609e..74f57311a52 100644
--- a/deps/v8/include/v8-exception.h
+++ b/deps/v8/include/v8-exception.h
@@ -276,6 +276,14 @@ class V8_EXPORT TryCatch {
void ResetInternal();
+ /**
+ * Set whether or not this TryCatch is internal.
+ * Internal TryCatch blocks are not treated as external handlers for the
+ * purposes of the debugger.
+ */
+ void SetIsInternal(bool value);
+ bool IsInternal() const;
+
// Helper methods for internal::Isolate.
bool capture_message() const;
void set_can_continue(bool value);
diff --git a/deps/v8/include/v8-function-callback.h b/deps/v8/include/v8-function-callback.h
index aeac5e557bd..e0708430f61 100644
--- a/deps/v8/include/v8-function-callback.h
+++ b/deps/v8/include/v8-function-callback.h
@@ -243,9 +243,6 @@ class PropertyCallbackInfo {
* would return the global proxy.
*/
V8_INLINE Local<Object> Holder() const;
- // TODO(http://crbug.com/333672197): deprecate and remove.
- V8_DEPRECATED("Use Holder().")
- V8_INLINE Local<Object> HolderV2() const;
/**
* \return The return value of the callback.
@@ -688,10 +685,6 @@ template <typename T>
Local<Object> PropertyCallbackInfo<T>::Holder() const {
return Local<Object>::FromSlot(&args_[kHolderIndex]);
}
-template <typename T>
-Local<Object> PropertyCallbackInfo<T>::HolderV2() const {
- return Holder();
-}
template <typename T>
ReturnValue<T> PropertyCallbackInfo<T>::GetReturnValue() const {
diff --git a/deps/v8/include/v8-internal.h b/deps/v8/include/v8-internal.h
index 4ce3e6e3055..43b598c4a0c 100644
--- a/deps/v8/include/v8-internal.h
+++ b/deps/v8/include/v8-internal.h
@@ -467,14 +467,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 +523,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
}
@@ -582,37 +575,42 @@ struct TagRange {
Tag last;
};
+enum class ManagedTypeId : uint32_t {
+ kBackingStore,
+ kTestDeleteCounter,
+ kTestDeleteNative,
+ kWasmStreaming,
+ kWasmFuncData,
+ kWasmManagedData,
+ kWasmNativeModule,
+ kIcuBreakIterator,
+ kIcuBreakIteratorWithText,
+ kIcuLocale,
+ kIcuSimpleDateFormat,
+ kIcuDateIntervalFormat,
+ kIcuRelativeDateTimeFormatter,
+ kIcuListFormatter,
+ kIcuCollator,
+ kIcuPluralRules,
+ kIcuLocalizedNumberFormatter,
+ kTemporalDuration,
+ kTemporalInstant,
+ kTemporalPlainDate,
+ kTemporalPlainTime,
+ kTemporalPlainDateTime,
+ kTemporalPlainYearMonth,
+ kTemporalPlainMonthDay,
+ kTemporalZonedDateTime,
+ kDisplayNamesInternal,
+ kD8Worker,
+ kD8ModuleEmbedderData,
+ kD8AsyncHooksWrap,
+};
+
#define SHARED_MANAGED_TAG_LIST(V) V(WasmFutexManagedObjectWaitListTag)
-#define MANAGED_TAG_LIST(V) \
- SHARED_MANAGED_TAG_LIST(V) \
- V(GenericManagedTag) \
- V(WasmWasmStreamingTag) \
- V(WasmFuncDataTag) \
- V(WasmManagedDataTag) \
- V(WasmNativeModuleTag) \
- V(BackingStoreTag) \
- V(IcuBreakIteratorTag) \
- V(IcuListFormatterTag) \
- V(IcuLocaleTag) \
- V(IcuSimpleDateFormatTag) \
- V(IcuDateIntervalFormatTag) \
- V(IcuRelativeDateTimeFormatterTag) \
- V(IcuLocalizedNumberFormatterTag) \
- V(IcuPluralRulesTag) \
- V(IcuCollatorTag) \
- V(IcuBreakIteratorWithTextTag) \
- V(TemporalDurationTag) \
- V(TemporalInstantTag) \
- V(TemporalPlainDateTag) \
- V(TemporalPlainTimeTag) \
- V(TemporalPlainDateTimeTag) \
- V(TemporalPlainYearMonthTag) \
- V(TemporalPlainMonthDayTag) \
- V(TemporalZonedDateTimeTag) \
- V(DisplayNamesInternalTag) \
- V(D8WorkerTag) \
- V(D8ModuleEmbedderDataTag)
+#define MANAGED_TAG_LIST(V) \
+ SHARED_MANAGED_TAG_LIST(V)
#define FOREIGN_TAG_LIST(V) \
V(GenericForeignTag) \
@@ -1005,12 +1003,8 @@ class Internals {
#endif // !V8_COMPRESS_POINTERS
static const int kFixedArrayHeaderSize = 2 * kApiTaggedSize;
static const int kEmbedderDataArrayHeaderSize = 2 * kApiTaggedSize;
- static const int kEmbedderDataSlotSize = kApiSystemPointerSize;
-#ifdef V8_ENABLE_SANDBOX
- static const int kEmbedderDataSlotExternalPointerOffset = kApiTaggedSize;
-#else
- static const int kEmbedderDataSlotExternalPointerOffset = 0;
-#endif
+ static const int kEmbedderDataSlotSize = 2 * kApiTaggedSize;
+ static const int kEmbedderDataSlotCppHeapPointerOffset = kApiTaggedSize;
static const int kNativeContextEmbedderDataOffset = 6 * kApiTaggedSize;
static const int kStringRepresentationAndEncodingMask = 0x0f;
static const int kStringEncodingMask = 0x8;
@@ -1038,10 +1032,7 @@ class Internals {
// ExternalPointerTable, CppHeapPointerTable and TrustedPointerTable layout
// guarantees.
static const int kExternalEntityTableBasePointerOffset = 0;
- static const int kSegmentedTableSegmentPoolSize = 4;
- static const int kExternalEntityTableSize =
- 4 * kApiSystemPointerSize +
- kSegmentedTableSegmentPoolSize * sizeof(uint32_t);
+ static const int kExternalEntityTableSize = 4 * kApiSystemPointerSize;
// IsolateData layout guarantees.
static const int kIsolateCageBaseOffset = 0;
diff --git a/deps/v8/include/v8-isolate.h b/deps/v8/include/v8-isolate.h
index f8395c96f14..50c87b78de5 100644
--- a/deps/v8/include/v8-isolate.h
+++ b/deps/v8/include/v8-isolate.h
@@ -665,6 +665,10 @@ class V8_EXPORT Isolate {
kOBSOLETE_WasmResizableBuffers = 183,
kInvalidatedArrayBufferMutableProtector = 184,
kHoleyArrayReadthrough = 185,
+ kWasmGCAllocation = 186,
+ kModuleNamespaceMissingDefaultWithStarExport = 187,
+ kRegExpMatcherFlagsMismatch = 188,
+ kRegExpCustomSpecies = 189,
// 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
@@ -971,18 +975,19 @@ class V8_EXPORT Isolate {
V8_INLINE MaybeLocal<T> GetDataFromSnapshotOnce(size_t index);
/**
- * Returns the value that was set or restored by
- * SetContinuationPreservedEmbedderData(), if any.
+ * Returns the value set by `SetContinuationPreservedEmbedderData()` or
+ * restored during microtask execution for the currently running continuation,
+ * if any. Returns undefiend if no continuation preserved embedder data was
+ * set.
*/
- V8_DEPRECATED("Use GetContinuationPreservedEmbedderDataV2 instead")
- Local<Value> GetContinuationPreservedEmbedderData();
+ Local<Data> GetContinuationPreservedEmbedderData();
/**
- * Sets a value that will be stored on continuations and reset while the
- * continuation runs.
+ * Sets a value that will be stored on continuations and restored while the
+ * continuation runs. If `data` is empty, the continuation preserved embedder
+ * data is set to undefined.
*/
- V8_DEPRECATED("Use SetContinuationPreservedEmbedderDataV2 instead")
- void SetContinuationPreservedEmbedderData(Local<Value> data);
+ void SetContinuationPreservedEmbedderData(Local<Data> data);
/**
* Returns the value set by `SetContinuationPreservedEmbedderDataV2()` or
@@ -1509,7 +1514,7 @@ class V8_EXPORT Isolate {
* The optional parameter |dependant_context| specifies whether the disposed
* context was depending on state from other contexts or not.
*/
- V8_DEPRECATE_SOON("Use version that passes ContextDependants.")
+ V8_DEPRECATED("Use version that passes ContextDependants.")
int ContextDisposedNotification(bool dependant_context = true);
/**
diff --git a/deps/v8/include/v8-microtask-queue.h b/deps/v8/include/v8-microtask-queue.h
index b99a734aa6f..de58638c85d 100644
--- a/deps/v8/include/v8-microtask-queue.h
+++ b/deps/v8/include/v8-microtask-queue.h
@@ -9,16 +9,13 @@
#include <memory>
+#include "cppgc/garbage-collected.h"
#include "cppgc/macros.h"
+#include "cppgc/name-provider.h"
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-microtask.h" // NOLINT(build/include_directory)
#include "v8config.h" // NOLINT(build/include_directory)
-#ifdef V8_CPPGC_MICROTASK_QUEUE
-#include "cppgc/garbage-collected.h"
-#include "cppgc/name-provider.h"
-#endif // V8_CPPGC_MICROTASK_QUEUE
-
namespace v8 {
class Function;
@@ -43,27 +40,15 @@ class MicrotaskQueue;
* other synchronously. E.g. for Web embedding, use the same instance for all
* origins that share the same URL scheme and eTLD+1.
*/
-class V8_EXPORT MicrotaskQueue
-#ifdef V8_CPPGC_MICROTASK_QUEUE
- : public cppgc::GarbageCollected<MicrotaskQueue>,
- public cppgc::NameProvider
-#endif // V8_CPPGC_MICROTASK_QUEUE
-{
+class V8_EXPORT MicrotaskQueue : public cppgc::GarbageCollected<MicrotaskQueue>,
+ public cppgc::NameProvider {
public:
/**
* Creates an empty MicrotaskQueue instance.
*/
-#ifdef V8_CPPGC_MICROTASK_QUEUE
static MicrotaskQueue* New(Isolate* isolate,
MicrotasksPolicy policy = MicrotasksPolicy::kAuto);
virtual void Trace(cppgc::Visitor* visitor) const {}
-#else
- V8_DEPRECATE_SOON(
- "Use MicrotaskQueue allocated in cppgc, "
- "see gn flag: v8_cppgc_microtask_queue.")
- static std::unique_ptr<MicrotaskQueue> New(
- Isolate* isolate, MicrotasksPolicy policy = MicrotasksPolicy::kAuto);
-#endif // V8_CPPGC_MICROTASK_QUEUE
virtual ~MicrotaskQueue() = default;
diff --git a/deps/v8/include/v8-object.h b/deps/v8/include/v8-object.h
index f66c5a97f5c..1dd2eb91124 100644
--- a/deps/v8/include/v8-object.h
+++ b/deps/v8/include/v8-object.h
@@ -202,9 +202,10 @@ using AccessorNameSetterCallbackV2 =
void (*)(Local<Name> property, Local<Value> value,
const PropertyCallbackInfo<Boolean>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using AccessorNameSetterCallback =
- void (*)(Local<Name> property, Local<Value> value,
- const PropertyCallbackInfo<void>& info);
+using AccessorNameSetterCallback //
+ V8_DEPRECATE_SOON("Use AccessorNameSetterCallbackV2 instead.") =
+ void (*)(Local<Name> property, Local<Value> value,
+ const PropertyCallbackInfo<void>& info);
/**
* Property filter bits. They can be or'ed to build a composite filter.
@@ -406,30 +407,11 @@ class V8_EXPORT Object : public Value {
*/
V8_WARN_UNUSED_RESULT Maybe<bool> SetNativeDataProperty(
Local<Context> context, Local<Name> name,
- AccessorNameGetterCallback getter, AccessorNameSetterCallbackV2 setter,
- Local<Value> data = Local<Value>(), PropertyAttribute attributes = None,
- SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
- SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
- V8_DEPRECATED("Use AccessorNameSetterCallbackV2 setter instead")
- V8_WARN_UNUSED_RESULT Maybe<bool> SetNativeDataProperty(
- Local<Context> context, Local<Name> name,
- AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
+ AccessorNameGetterCallback getter,
+ AccessorNameSetterCallbackV2 setter = nullptr,
Local<Value> data = Local<Value>(), PropertyAttribute attributes = None,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
- // TODO(https://crbug.com/348660658): remove once AccessorNameSetterCallback
- // is removed.
- V8_WARN_UNUSED_RESULT Maybe<bool> SetNativeDataProperty(
- Local<Context> context, Local<Name> name,
- AccessorNameGetterCallback getter, std::nullptr_t setter = nullptr,
- Local<Value> data = Local<Value>(), PropertyAttribute attributes = None,
- SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
- SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect) {
- return SetNativeDataProperty(
- context, name, getter,
- static_cast<AccessorNameSetterCallbackV2>(setter), data, attributes,
- getter_side_effect_type, setter_side_effect_type);
- }
/**
* Attempts to create a property with the given name which behaves like a data
@@ -494,9 +476,6 @@ class V8_EXPORT Object : public Value {
* This does not consult the security handler.
*/
Local<Value> GetPrototype();
- // TODO(http://crbug.com/333672197): deprecate and remove.
- V8_DEPRECATED("Use GetPrototype().")
- inline Local<Value> GetPrototypeV2() { return GetPrototype(); }
/**
* Set the prototype object (same as calling Object.setPrototypeOf(..)).
@@ -504,12 +483,6 @@ class V8_EXPORT Object : public Value {
*/
V8_WARN_UNUSED_RESULT Maybe<bool> SetPrototype(Local<Context> context,
Local<Value> prototype);
- // TODO(http://crbug.com/333672197): deprecate and remove.
- V8_DEPRECATED("Use SetPrototype().")
- V8_WARN_UNUSED_RESULT Maybe<bool> SetPrototypeV2(Local<Context> context,
- Local<Value> prototype) {
- return SetPrototype(context, prototype);
- }
/**
* Finds an instance of the given function template in the prototype
@@ -837,6 +810,8 @@ class V8_EXPORT Object : public Value {
void* GetAlignedPointerFromEmbedderDataInCreationContext(
int index, EmbedderDataTypeTag tag);
+ void* GetAlignedPointerFromEmbedderDataInCreationContext(
+ v8::Isolate* isolate, int index, CppHeapPointerTag tag);
/**
* Checks whether a callback is set by the
* ObjectTemplate::SetCallAsFunctionHandler method.
@@ -968,44 +943,11 @@ Local<Data> Object::GetInternalField(int index) {
void* Object::GetAlignedPointerFromInternalField(v8::Isolate* isolate,
int index,
EmbedderDataTypeTag tag) {
-#if !defined(V8_ENABLE_CHECKS)
- using A = internal::Address;
- using I = internal::Internals;
- A obj = internal::ValueHelper::ValueAsAddress(this);
- // Fast path: If the object is a plain JSObject, which is the common case, we
- // know where to find the internal fields and can return the value directly.
- auto instance_type = I::GetInstanceType(obj);
- if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
- int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
- (I::kEmbedderDataSlotSize * index) +
- I::kEmbedderDataSlotExternalPointerOffset;
- A value = I::ReadExternalPointerField(isolate, obj, offset,
- ToExternalPointerTag(tag));
- return reinterpret_cast<void*>(value);
- }
-#endif
return SlowGetAlignedPointerFromInternalField(isolate, index, tag);
}
void* Object::GetAlignedPointerFromInternalField(int index,
EmbedderDataTypeTag tag) {
-#if !defined(V8_ENABLE_CHECKS)
- using A = internal::Address;
- using I = internal::Internals;
- A obj = internal::ValueHelper::ValueAsAddress(this);
- // Fast path: If the object is a plain JSObject, which is the common case, we
- // know where to find the internal fields and can return the value directly.
- auto instance_type = I::GetInstanceType(obj);
- if (V8_LIKELY(I::CanHaveInternalField(instance_type))) {
- int offset = I::kJSAPIObjectWithEmbedderSlotsHeaderSize +
- (I::kEmbedderDataSlotSize * index) +
- I::kEmbedderDataSlotExternalPointerOffset;
- Isolate* isolate = I::GetCurrentIsolateForSandbox();
- A value = I::ReadExternalPointerField(isolate, obj, offset,
- ToExternalPointerTag(tag));
- return reinterpret_cast<void*>(value);
- }
-#endif
return SlowGetAlignedPointerFromInternalField(index, tag);
}
diff --git a/deps/v8/include/v8-sandbox.h b/deps/v8/include/v8-sandbox.h
index be31584ac3e..2cda25eb958 100644
--- a/deps/v8/include/v8-sandbox.h
+++ b/deps/v8/include/v8-sandbox.h
@@ -62,6 +62,8 @@ enum class CppHeapPointerTag : uint16_t {
kInspectorTaskInfoTag,
kMicrotaskQueueTag,
kWasmMemoryMapDescriptorTag,
+ kCppGCManagedTag,
+ kEmbedderDataSlotTag,
kLastV8InternalTag,
#if !V8_ENABLE_SANDBOX
diff --git a/deps/v8/include/v8-script.h b/deps/v8/include/v8-script.h
index 456831b0b2b..c6b0585cb11 100644
--- a/deps/v8/include/v8-script.h
+++ b/deps/v8/include/v8-script.h
@@ -280,7 +280,7 @@ class V8_EXPORT Module : public Data {
*
* If IsGraphAsync() is false, the returned Promise is settled.
*/
- V8_WARN_UNUSED_RESULT MaybeLocal<Value> Evaluate(Local<Context> context);
+ V8_WARN_UNUSED_RESULT MaybeLocal<Promise> Evaluate(Local<Context> context);
/**
* Evaluates async dependencies of a module and defer its evaluation
@@ -292,7 +292,7 @@ class V8_EXPORT Module : public Data {
* modules that are going to be evaluated. This module and its sync
* dependencies are not going to be evaluated.
*/
- V8_WARN_UNUSED_RESULT MaybeLocal<Value> EvaluateForImportDefer(
+ V8_WARN_UNUSED_RESULT MaybeLocal<Promise> EvaluateForImportDefer(
Local<Context> context);
/**
@@ -351,6 +351,15 @@ class V8_EXPORT Module : public Data {
* (where an exception was thrown).
*/
using SyntheticModuleEvaluationSteps =
+ MaybeLocal<Promise> (*)(Local<Context> context, Local<Module> module);
+
+ /*
+ * Deprecated version of SyntheticModuleEvaluationSteps: the returned value is
+ * still required to be a Promise, but that is only enforced at runtime.
+ */
+ // TODO(https://crbug.com/545375591): Remove once all embedders return a
+ // MaybeLocal<Promise>.
+ using LegacySyntheticModuleEvaluationSteps =
MaybeLocal<Value> (*)(Local<Context> context, Local<Module> module);
/**
@@ -366,6 +375,17 @@ class V8_EXPORT Module : public Data {
SyntheticModuleEvaluationSteps evaluation_steps,
Local<Data> host_defined_options = Local<Data>());
+ // TODO(https://crbug.com/545375591): Advance to V8_DEPRECATED and then remove
+ // this overload once all embedders have been migrated to the one above.
+ V8_DEPRECATE_SOON(
+ "Use the CreateSyntheticModule overload whose evaluation_steps return a "
+ "MaybeLocal<Promise>")
+ static Local<Module> CreateSyntheticModule(
+ Isolate* isolate, Local<String> module_name,
+ const std::span<const Local<String>>& export_names,
+ LegacySyntheticModuleEvaluationSteps evaluation_steps,
+ Local<Data> host_defined_options = Local<Data>());
+
/**
* Returns the host defined options set during CreateSyntheticModule().
* Must only be called on SyntheticModules.
diff --git a/deps/v8/include/v8-template.h b/deps/v8/include/v8-template.h
index 8c51703b8f3..182293f05bd 100644
--- a/deps/v8/include/v8-template.h
+++ b/deps/v8/include/v8-template.h
@@ -103,29 +103,10 @@ class V8_EXPORT Template : public Data {
*/
void SetNativeDataProperty(
Local<Name> name, AccessorNameGetterCallback getter,
- AccessorNameSetterCallbackV2 setter, Local<Value> data = Local<Value>(),
- PropertyAttribute attribute = None,
- SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
- SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
- V8_DEPRECATED("Use AccessorNameSetterCallbackV2 setter instead")
- void SetNativeDataProperty(
- Local<Name> name, AccessorNameGetterCallback getter,
- AccessorNameSetterCallback setter, Local<Value> data = Local<Value>(),
- PropertyAttribute attribute = None,
+ AccessorNameSetterCallbackV2 setter = nullptr,
+ Local<Value> data = Local<Value>(), PropertyAttribute attribute = None,
SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect);
- // TODO(https://crbug.com/348660658): remove once AccessorNameSetterCallback
- // is removed.
- void SetNativeDataProperty(
- Local<Name> name, AccessorNameGetterCallback getter,
- std::nullptr_t setter = nullptr, Local<Value> data = Local<Value>(),
- PropertyAttribute attribute = None,
- SideEffectType getter_side_effect_type = SideEffectType::kHasSideEffect,
- SideEffectType setter_side_effect_type = SideEffectType::kHasSideEffect) {
- SetNativeDataProperty(
- name, getter, static_cast<AccessorNameSetterCallbackV2>(setter), data,
- attribute, getter_side_effect_type, setter_side_effect_type);
- }
/**
* Like SetNativeDataProperty, but V8 will replace the native data property
@@ -236,9 +217,10 @@ using NamedPropertySetterCallbackV2 =
Intercepted (*)(Local<Name> property, Local<Value> value,
const PropertyCallbackInfo<Boolean>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using NamedPropertySetterCallback =
- Intercepted (*)(Local<Name> property, Local<Value> value,
- const PropertyCallbackInfo<void>& info);
+using NamedPropertySetterCallback //
+ V8_DEPRECATE_SOON("Use NamedPropertySetterCallbackV2 instead.") =
+ Intercepted (*)(Local<Name> property, Local<Value> value,
+ const PropertyCallbackInfo<void>& info);
/**
* Intercepts all requests that query the attributes of the property,
@@ -335,9 +317,10 @@ using NamedPropertyDefinerCallbackV2 =
Intercepted (*)(Local<Name> property, const PropertyDescriptor& desc,
const PropertyCallbackInfo<Boolean>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using NamedPropertyDefinerCallback =
- Intercepted (*)(Local<Name> property, const PropertyDescriptor& desc,
- const PropertyCallbackInfo<void>& info);
+using NamedPropertyDefinerCallback //
+ V8_DEPRECATE_SOON("Use NamedPropertyDefinerCallbackV2 instead.") =
+ Intercepted (*)(Local<Name> property, const PropertyDescriptor& desc,
+ const PropertyCallbackInfo<void>& info);
/**
* Interceptor for [[GetOwnProperty]] requests on an object.
@@ -369,7 +352,9 @@ using NamedPropertyDescriptorCallback = Intercepted (*)(
using IndexedPropertyGetterCallback =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using IndexedPropertyGetterCallbackV2 = IndexedPropertyGetterCallback;
+using IndexedPropertyGetterCallbackV2 //
+ V8_DEPRECATE_SOON("Use IndexedPropertyGetterCallback instead.") =
+ IndexedPropertyGetterCallback;
/**
* See `v8::NamedPropertySetterCallback`.
@@ -378,8 +363,10 @@ using IndexedPropertySetterCallback =
Intercepted (*)(uint32_t index, Local<Value> value,
const PropertyCallbackInfo<Boolean>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using IndexedPropertySetterCallbackV2 = Intercepted (*)(
- uint32_t index, Local<Value> value, const PropertyCallbackInfo<void>& info);
+using IndexedPropertySetterCallbackV2 //
+ V8_DEPRECATE_SOON("Use IndexedPropertySetterCallback instead.") =
+ Intercepted (*)(uint32_t index, Local<Value> value,
+ const PropertyCallbackInfo<void>& info);
/**
* See `v8::NamedPropertyQueryCallback`.
@@ -387,7 +374,9 @@ using IndexedPropertySetterCallbackV2 = Intercepted (*)(
using IndexedPropertyQueryCallback =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Integer>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using IndexedPropertyQueryCallbackV2 = IndexedPropertyQueryCallback;
+using IndexedPropertyQueryCallbackV2 //
+ V8_DEPRECATE_SOON("Use IndexedPropertyQueryCallback instead.") =
+ IndexedPropertyQueryCallback;
/**
* See `v8::NamedPropertyDeleterCallback`.
@@ -395,7 +384,9 @@ using IndexedPropertyQueryCallbackV2 = IndexedPropertyQueryCallback;
using IndexedPropertyDeleterCallback =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Boolean>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using IndexedPropertyDeleterCallbackV2 = IndexedPropertyDeleterCallback;
+using IndexedPropertyDeleterCallbackV2 //
+ V8_DEPRECATE_SOON("Use IndexedPropertyDeleterCallback instead.") =
+ IndexedPropertyDeleterCallback;
/**
* Returns an array containing the indices of the properties the indexed
@@ -413,9 +404,10 @@ using IndexedPropertyDefinerCallback =
Intercepted (*)(uint32_t index, const PropertyDescriptor& desc,
const PropertyCallbackInfo<Boolean>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using IndexedPropertyDefinerCallbackV2 =
- Intercepted (*)(uint32_t index, const PropertyDescriptor& desc,
- const PropertyCallbackInfo<void>& info);
+using IndexedPropertyDefinerCallbackV2 //
+ V8_DEPRECATE_SOON("Use IndexedPropertyDefinerCallback instead.") =
+ Intercepted (*)(uint32_t index, const PropertyDescriptor& desc,
+ const PropertyCallbackInfo<void>& info);
/**
* See `v8::NamedPropertyDescriptorCallback`.
@@ -423,7 +415,9 @@ using IndexedPropertyDefinerCallbackV2 =
using IndexedPropertyDescriptorCallback =
Intercepted (*)(uint32_t index, const PropertyCallbackInfo<Value>& info);
// TODO(https://crbug.com/348660658): deprecate and remove.
-using IndexedPropertyDescriptorCallbackV2 = IndexedPropertyDescriptorCallback;
+using IndexedPropertyDescriptorCallbackV2 //
+ V8_DEPRECATE_SOON("Use IndexedPropertyDescriptorCallback instead.") =
+ IndexedPropertyDescriptorCallback;
/**
* Experimental API, do not use!
@@ -762,69 +756,37 @@ struct NamedPropertyHandlerConfiguration {
PropertyHandlerFlags::kInternalNewCallbacksSignatures));
}
- static NamedPropertySetterCallbackV2 ConvertSetter(std::nullptr_t) {
- return nullptr;
- }
- static NamedPropertySetterCallbackV2 ConvertSetter(
- NamedPropertySetterCallbackV2 value) {
- return value;
- }
-
- static NamedPropertyDefinerCallbackV2 ConvertDefiner(std::nullptr_t) {
- return nullptr;
- }
- static NamedPropertyDefinerCallbackV2 ConvertDefiner(
- NamedPropertyDefinerCallbackV2 value) {
- return value;
- }
-
public:
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // NamedPropertySetterCallbackV2/NamedPropertyDefinerCallbackV2 is done.
- template <typename TSetter = std::nullptr_t,
- typename TDefiner = std::nullptr_t>
- requires((std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, NamedPropertySetterCallback> ||
- std::is_same_v<TSetter, NamedPropertySetterCallbackV2>) &&
- (std::is_same_v<TDefiner, std::nullptr_t> ||
- std::is_same_v<TDefiner, NamedPropertyDefinerCallback> ||
- std::is_same_v<TDefiner, NamedPropertyDefinerCallbackV2>))
NamedPropertyHandlerConfiguration(
NamedPropertyGetterCallback getter, //
- TSetter setter, //
+ NamedPropertySetterCallbackV2 setter, //
NamedPropertyQueryCallback query, //
NamedPropertyDeleterCallback deleter, //
NamedPropertyEnumeratorCallback enumerator, //
- TDefiner definer, //
+ NamedPropertyDefinerCallbackV2 definer, //
NamedPropertyDescriptorCallback descriptor, //
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
- definer(ConvertDefiner(definer)),
+ definer(definer),
descriptor(descriptor),
data(data),
flags(flags) {}
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // NamedPropertySetterCallbackV2/NamedPropertyDefinerCallbackV2 is done.
- template <typename TSetter = std::nullptr_t>
- requires(std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, NamedPropertySetterCallback> ||
- std::is_same_v<TSetter, NamedPropertySetterCallbackV2>)
explicit NamedPropertyHandlerConfiguration(
NamedPropertyGetterCallback getter, //
- TSetter setter = nullptr, //
+ NamedPropertySetterCallbackV2 setter = nullptr, //
NamedPropertyQueryCallback query = nullptr, //
NamedPropertyDeleterCallback deleter = nullptr, //
NamedPropertyEnumeratorCallback enumerator = nullptr, //
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
@@ -833,31 +795,21 @@ struct NamedPropertyHandlerConfiguration {
data(data),
flags(flags) {}
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // NamedPropertySetterCallbackV2/NamedPropertyDefinerCallbackV2 is done.
- template <typename TSetter = std::nullptr_t,
- typename TDefiner = std::nullptr_t>
- requires((std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, NamedPropertySetterCallback> ||
- std::is_same_v<TSetter, NamedPropertySetterCallbackV2>) &&
- (std::is_same_v<TDefiner, std::nullptr_t> ||
- std::is_same_v<TDefiner, NamedPropertyDefinerCallback> ||
- std::is_same_v<TDefiner, NamedPropertyDefinerCallbackV2>))
NamedPropertyHandlerConfiguration(
NamedPropertyGetterCallback getter, //
- TSetter setter, //
+ NamedPropertySetterCallbackV2 setter, //
NamedPropertyDescriptorCallback descriptor, //
NamedPropertyDeleterCallback deleter, //
NamedPropertyEnumeratorCallback enumerator, //
- TDefiner definer, //
+ NamedPropertyDefinerCallbackV2 definer, //
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(nullptr),
deleter(deleter),
enumerator(enumerator),
- definer(ConvertDefiner(definer)),
+ definer(definer),
descriptor(descriptor),
data(data),
flags(flags) {}
@@ -883,69 +835,37 @@ struct IndexedPropertyHandlerConfiguration {
PropertyHandlerFlags::kInternalNewCallbacksSignatures));
}
- static IndexedPropertySetterCallback ConvertSetter(std::nullptr_t) {
- return nullptr;
- }
- static IndexedPropertySetterCallback ConvertSetter(
- IndexedPropertySetterCallback value) {
- return value;
- }
-
- static IndexedPropertyDefinerCallback ConvertDefiner(std::nullptr_t) {
- return nullptr;
- }
- static IndexedPropertyDefinerCallback ConvertDefiner(
- IndexedPropertyDefinerCallback value) {
- return value;
- }
-
public:
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // IndexedPropertySetterCallback/IndexedPropertyDefinerCallback is done.
- template <typename TSetter = std::nullptr_t,
- typename TDefiner = std::nullptr_t>
- requires((std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallback> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallbackV2>) &&
- (std::is_same_v<TDefiner, std::nullptr_t> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallback> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallbackV2>))
IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter, //
- TSetter setter, //
+ IndexedPropertySetterCallback setter, //
IndexedPropertyQueryCallback query, //
IndexedPropertyDeleterCallback deleter, //
IndexedPropertyEnumeratorCallback enumerator, //
- TDefiner definer, //
+ IndexedPropertyDefinerCallback definer, //
IndexedPropertyDescriptorCallback descriptor, //
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
- definer(ConvertDefiner(definer)),
+ definer(definer),
descriptor(descriptor),
data(data),
flags(flags) {}
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // IndexedPropertySetterCallback/IndexedPropertyDefinerCallback is done.
- template <typename TSetter = std::nullptr_t>
- requires(std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallback> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallbackV2>)
explicit IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter = nullptr, //
- TSetter setter = nullptr, //
+ IndexedPropertySetterCallback setter = nullptr, //
IndexedPropertyQueryCallback query = nullptr, //
IndexedPropertyDeleterCallback deleter = nullptr, //
IndexedPropertyEnumeratorCallback enumerator = nullptr, //
Local<Value> data = Local<Value>(), //
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
@@ -954,98 +874,68 @@ struct IndexedPropertyHandlerConfiguration {
data(data),
flags(flags) {}
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // IndexedPropertySetterCallback/IndexedPropertyDefinerCallback is done.
- template <typename TSetter = std::nullptr_t,
- typename TDefiner = std::nullptr_t>
- requires((std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallback> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallbackV2>) &&
- (std::is_same_v<TDefiner, std::nullptr_t> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallback> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallbackV2>))
IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter, //
- TSetter setter, //
+ IndexedPropertySetterCallback setter, //
IndexedPropertyDescriptorCallback descriptor, //
IndexedPropertyDeleterCallback deleter, //
IndexedPropertyEnumeratorCallback enumerator, //
- TDefiner definer, //
+ IndexedPropertyDefinerCallback definer, //
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(nullptr),
deleter(deleter),
enumerator(enumerator),
- definer(ConvertDefiner(definer)),
+ definer(definer),
descriptor(descriptor),
data(data),
flags(flags) {}
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // IndexedPropertySetterCallback/IndexedPropertyDefinerCallback is done.
- template <typename TSetter = std::nullptr_t,
- typename TDefiner = std::nullptr_t>
- requires((std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallback> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallbackV2>) &&
- (std::is_same_v<TDefiner, std::nullptr_t> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallback> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallbackV2>))
V8_DEPRECATE_SOON(
"Use IndexedPropertyHandlerConfiguration with iterable_to_list")
IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter, //
- TSetter setter, //
+ IndexedPropertySetterCallback setter, //
IndexedPropertyQueryCallback query, //
IndexedPropertyDeleterCallback deleter, //
IndexedPropertyEnumeratorCallback enumerator, //
- TDefiner definer, //
+ IndexedPropertyDefinerCallback definer, //
IndexedPropertyDescriptorCallback descriptor, //
IndexedPropertyIndexOfCallback index_of, //
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
- definer(ConvertDefiner(definer)),
+ definer(definer),
descriptor(descriptor),
index_of(index_of),
iterable_to_list(nullptr),
data(data),
flags(flags) {}
- // TODO(https://crbug.com/348660658): cleanup once migration to
- // IndexedPropertySetterCallback/IndexedPropertyDefinerCallback is done.
- template <typename TSetter = std::nullptr_t,
- typename TDefiner = std::nullptr_t>
- requires((std::is_same_v<TSetter, std::nullptr_t> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallback> ||
- std::is_same_v<TSetter, IndexedPropertySetterCallbackV2>) &&
- (std::is_same_v<TDefiner, std::nullptr_t> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallback> ||
- std::is_same_v<TDefiner, IndexedPropertyDefinerCallbackV2>))
IndexedPropertyHandlerConfiguration(
IndexedPropertyGetterCallback getter, //
- TSetter setter, //
+ IndexedPropertySetterCallback setter, //
IndexedPropertyQueryCallback query, //
IndexedPropertyDeleterCallback deleter, //
IndexedPropertyEnumeratorCallback enumerator, //
- TDefiner definer, //
+ IndexedPropertyDefinerCallback definer, //
IndexedPropertyDescriptorCallback descriptor, //
IndexedPropertyIndexOfCallback index_of, //
IndexedPropertyIterableToListCallback iterable_to_list,
Local<Value> data = Local<Value>(),
PropertyHandlerFlags flags = PropertyHandlerFlags::kNone)
: getter(getter),
- setter(ConvertSetter(setter)),
+ setter(setter),
query(query),
deleter(deleter),
enumerator(enumerator),
- definer(ConvertDefiner(definer)),
+ definer(definer),
descriptor(descriptor),
index_of(index_of),
iterable_to_list(iterable_to_list),
diff --git a/deps/v8/include/v8-value-serializer.h b/deps/v8/include/v8-value-serializer.h
index 0cb3e045bc4..731965722fb 100644
--- a/deps/v8/include/v8-value-serializer.h
+++ b/deps/v8/include/v8-value-serializer.h
@@ -10,6 +10,7 @@
#include <memory>
#include <utility>
+#include <vector>
#include "v8-local-handle.h" // NOLINT(build/include_directory)
#include "v8-maybe.h" // NOLINT(build/include_directory)
@@ -18,6 +19,7 @@
namespace v8 {
class ArrayBuffer;
+class BackingStore;
class Isolate;
class Object;
class SharedArrayBuffer;
@@ -150,8 +152,18 @@ class V8_EXPORT ValueSerializer {
virtual void FreeBufferMemory(void* buffer);
};
- explicit ValueSerializer(Isolate* isolate);
- ValueSerializer(Isolate* isolate, Delegate* delegate);
+ enum class SharedImmutableArrayBufferMode {
+ kDisabled,
+ kEnabled,
+ };
+
+ explicit ValueSerializer(
+ Isolate* isolate,
+ SharedImmutableArrayBufferMode share_immutable_array_buffer =
+ SharedImmutableArrayBufferMode::kDisabled);
+ ValueSerializer(Isolate* isolate, Delegate* delegate,
+ SharedImmutableArrayBufferMode share_immutable_array_buffer =
+ SharedImmutableArrayBufferMode::kDisabled);
~ValueSerializer();
/**
@@ -190,6 +202,18 @@ class V8_EXPORT ValueSerializer {
*/
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
+ /**
+ * Returns the backing stores of all immutable JSArrayBuffers that were
+ * serialized without copying.
+ *
+ * When SharedImmutableArrayBufferMode::kEnabled is passed to the constructor,
+ * the embedder MUST call this method after serialization and transmit these
+ * backing stores to the receiver, where they must be passed to
+ * ValueDeserializer::SetSharedImmutableBackingStores.
+ */
+ std::vector<std::shared_ptr<v8::BackingStore>>
+ ReleaseSharedImmutableBackingStores();
+
/**
* Write raw data in various common formats to the buffer.
* Note that integer types are written in base-128 varint format, not with a
@@ -277,6 +301,12 @@ class V8_EXPORT ValueDeserializer {
void TransferSharedArrayBuffer(uint32_t id,
Local<SharedArrayBuffer> shared_array_buffer);
+ /**
+ * Accepts shared immutable backing stores from ValueSerializer.
+ */
+ void SetSharedImmutableBackingStores(
+ std::vector<std::shared_ptr<v8::BackingStore>> backing_stores);
+
/**
* Must be called before ReadHeader to enable support for reading the legacy
* wire format (i.e., which predates this being shipped).
diff --git a/deps/v8/include/v8-value.h b/deps/v8/include/v8-value.h
index c2fd021ed23..4757dcc4185 100644
--- a/deps/v8/include/v8-value.h
+++ b/deps/v8/include/v8-value.h
@@ -366,6 +366,13 @@ class V8_EXPORT Value : public Data {
*/
bool IsModuleNamespaceObject() const;
+ /**
+ * Returns true if the value is a Deferred Module Namespace Object, i.e. the
+ * namespace object created by `import defer * as ns from ...`. Note that
+ * IsModuleNamespaceObject() is also true for such values.
+ */
+ bool IsDeferredModuleNamespaceObject() const;
+
/**
* Returns true if the value is a primitive.
*/
diff --git a/deps/v8/include/v8-version.h b/deps/v8/include/v8-version.h
index 3862105d3f1..d3a60cfe29e 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 2
-#define V8_BUILD_NUMBER 124
-#define V8_PATCH_LEVEL 38
+#define V8_MINOR_VERSION 5
+#define V8_BUILD_NUMBER 35
+#define V8_PATCH_LEVEL 20
// 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 b78624ec00a..4d0158bd29d 100644
--- a/deps/v8/include/v8-wasm.h
+++ b/deps/v8/include/v8-wasm.h
@@ -9,6 +9,7 @@
#include <memory>
#include <span>
#include <string>
+#include <string_view>
#include <variant>
#include "v8-internal.h" // NOLINT(build/include_directory)
@@ -108,11 +109,11 @@ class V8_EXPORT WasmModuleObject : public Object {
CompiledWasmModule GetCompiledModule();
/**
- * Compile-time imports that influence how a Wasm module is compiled. These
- * mirror the options accepted by the JS `WebAssembly.Module` constructor
- * (`{ builtins, importedStringConstants }`).
+ * Options that influence how a Wasm module is compiled. The compile-time
+ * import options mirror those accepted by the JS `WebAssembly.Module`
+ * constructor (`{ builtins, importedStringConstants }`).
*/
- struct CompileTimeImports {
+ struct CompileOptions {
// Builtin compile-time imports, mirroring the strings accepted in the
// `builtins` array of the JS `WebAssembly.Module` constructor options.
// Combine values with bitwise-or to enable multiple builtins.
@@ -126,8 +127,13 @@ class V8_EXPORT WasmModuleObject : public Object {
int builtins = Builtins::kNone;
// If non-null, enable imported string constants from the named module
// (e.g. "wasm:js/string-constants"). The string must be null-terminated and
- // remain valid for the duration of this call.
+ // remain valid for the duration of the compile call.
const char* imported_string_constants_module = nullptr;
+ // If non-empty, associated with the module's script as its source URL, for
+ // use in stack traces and developer tooling. If a script already exists in
+ // the isolate for the same module, its existing URL is retained. The
+ // string must remain valid for the duration of the compile call.
+ std::string_view source_url = {};
};
/**
@@ -138,11 +144,11 @@ class V8_EXPORT WasmModuleObject : public Object {
/**
* Compile a Wasm module from the provided uncompiled bytes, applying the
- * given compile-time imports.
+ * given compile options.
*/
static MaybeLocal<WasmModuleObject> Compile(
Isolate* isolate, std::span<const uint8_t> wire_bytes,
- const CompileTimeImports& compile_imports);
+ const CompileOptions& options);
V8_INLINE static WasmModuleObject* Cast(Value* value) {
#ifdef V8_ENABLE_CHECKS
@@ -163,8 +169,8 @@ class V8_EXPORT WasmModuleObject : public Object {
*/
class V8_EXPORT WasmStreaming final {
public:
- static constexpr internal::ExternalPointerTag kManagedTag =
- internal::kWasmWasmStreamingTag;
+ static constexpr internal::ManagedTypeId kTypeID =
+ internal::ManagedTypeId::kWasmStreaming;
class WasmStreamingImpl;
class ModuleCachingInterface {
@@ -236,9 +242,9 @@ class V8_EXPORT WasmStreaming final {
void SetUrl(const char* url, size_t length);
/**
- * Unpacks a {WasmStreaming} object wrapped in a {Managed} for the embedder.
- * Since the embedder is on the other side of the API, it cannot unpack the
- * {Managed} itself.
+ * Unpacks a {WasmStreaming} object wrapped in a {CppGCManaged} for the
+ * embedder. Since the embedder is on the other side of the API, it cannot
+ * unpack the {CppGCManaged} itself.
*/
static std::shared_ptr<WasmStreaming> Unpack(Isolate* isolate,
Local<Value> value);
@@ -256,13 +262,15 @@ class V8_EXPORT WasmStreaming final {
class V8_EXPORT WasmModuleCompilation final {
public:
using ModuleCachingCallback = WasmStreaming::ModuleCachingCallback;
+ using CompileOptions = WasmModuleObject::CompileOptions;
/**
- * Start an asynchronous module compilation. This can be called on any thread.
+ * Start an asynchronous module compilation, applying the given compile
+ * options. This can be called on any thread. Providing
+ * {CompileOptions::source_url} is equivalent to calling {SetUrl}.
* TODO(clemensb): Add some way to pass enabled features.
- * TODO(clemensb): Add some way to pass compile time imports.
*/
- WasmModuleCompilation();
+ explicit WasmModuleCompilation(const CompileOptions& options = {});
~WasmModuleCompilation();
diff --git a/deps/v8/include/v8config.h b/deps/v8/include/v8config.h
index 7a60288c673..b36169f1f77 100644
--- a/deps/v8/include/v8config.h
+++ b/deps/v8/include/v8config.h
@@ -602,15 +602,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 da5db1f882a..0efde3556e7 100644
--- a/deps/v8/infra/mb/mb_config.pyl
+++ b/deps/v8/infra/mb/mb_config.pyl
@@ -120,6 +120,8 @@
'V8 Linux64 - runtime call stats - builder': 'release_x64_runtime_call_stats',
'V8 Linux64 - debug - single generation - builder': 'debug_x64_single_generation',
'V8 Linux64 - dumpling - builder': 'release_x64_dumpling',
+ 'V8 Linux64 - no metagen - debug builder':
+ 'debug_x64_no_metagen',
'V8 Linux64 - no pointer compression - builder': 'release_x64_no_pointer_compression',
'V8 Linux64 - sticky mark bits - debug builder': 'debug_x64_sticky_mark_bits',
'V8 Linux64 - undefined double - debug builder': 'debug_x64_undefined_double',
@@ -305,6 +307,8 @@
'v8_linux64_fyi_compile_rel': 'release_x64_test_features_trybot',
'v8_linux64_nodcheck_compile_rel': 'release_x64',
'v8_linux64_perfetto_compile_dbg': 'debug_x64_perfetto',
+ 'v8_linux64_no_metagen_compile_dbg':
+ 'debug_x64_no_metagen',
'v8_linux64_no_pointer_compression_compile_rel': 'release_x64_no_pointer_compression',
'v8_linux64_compile_rel': 'release_x64_test_features_gcmole_trybot',
'v8_linux64_no_sandbox_compile_rel': 'release_x64_no_sandbox',
@@ -753,6 +757,8 @@
'debug_bot', 'x64', 'non_default_cppgc'],
'debug_x64_perfetto': [
'debug_bot', 'x64', 'perfetto'],
+ 'debug_x64_no_metagen': [
+ 'debug_bot', 'x64', 'v8_disable_metagen_instance_types'],
'debug_x64_no_sandbox': [
'debug_bot', 'x64', 'no_sandbox'],
'debug_x64_sandbox_hardware_support': [
@@ -1178,6 +1184,9 @@
'gn_args': 'v8_dict_property_const_tracking=true',
},
+ 'v8_disable_metagen_instance_types': {
+ 'gn_args': 'v8_use_metagen_instance_types=false',
+ },
'v8_disable_pointer_compression': {
'gn_args': 'v8_enable_pointer_compression=false',
},
diff --git a/deps/v8/infra/testing/builders.pyl b/deps/v8/infra/testing/builders.pyl
index 127ce4abf06..c7ea3073b91 100644
--- a/deps/v8/infra/testing/builders.pyl
+++ b/deps/v8/infra/testing/builders.pyl
@@ -321,7 +321,7 @@
'os': 'Ubuntu-22.04',
},
'tests': [
- {'name': 'v8testing', 'shards': 5},
+ {'name': 'v8testing', 'shards': 7},
],
},
'v8_linux64_css_dbg': {
@@ -329,7 +329,7 @@
'os': 'Ubuntu-22.04',
},
'tests': [
- {'name': 'v8testing', 'shards': 5},
+ {'name': 'v8testing', 'shards': 7},
{'name': 'benchmarks', 'shards': 5},
{'name': 'mozilla', 'shards': 5},
{'name': 'test262', 'shards': 12},
@@ -347,16 +347,16 @@
{'name': 'mozilla', 'variant': 'extra'},
{'name': 'test262', 'variant': 'default', 'shards': 4},
{'name': 'test262', 'variant': 'future', 'shards': 4},
- {'name': 'v8testing', 'shards': 8},
+ {'name': 'v8testing', 'shards': 9},
{'name': 'v8testing', 'variant': 'extra', 'shards': 6},
{'name': 'v8testing', 'variant': 'minor_ms', 'shards': 2},
- {'name': 'v8testing', 'variant': 'conservative_stack_scanning', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'conservative_stack_scanning', 'shards': 3},
{'name': 'v8testing', 'variant': 'no_lfa', 'shards': 2},
{'name': 'v8testing', 'variant': 'stress_instruction_scheduling', 'shards': 2},
{'name': 'v8testing', 'variant': 'stress_concurrent_allocation', 'shards': 2},
{'name': 'v8testing', 'variant': 'stress_concurrent_inlining','shards': 2},
{'name': 'v8testing', 'variant': 'turbofan_random_rescheduling', 'shards': 2},
- {'name': 'v8testing', 'variant': 'scavenger_chaos_mode', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'scavenger_chaos_mode', 'shards': 3},
{'name': 'mjsunit', 'variant': 'stress_maglev_tests_with_turbofan', 'shards': 2},
# Maglev -- move to extra once more architectures are supported.
{'name': 'v8testing', 'variant': 'maglev', 'shards': 2},
@@ -371,13 +371,13 @@
{'name': 'benchmarks', 'variant': 'code_serializer', 'shards': 1},
{'name': 'd8testing', 'variant': 'code_serializer', 'shards': 2},
{'name': 'mozilla', 'variant': 'code_serializer', 'shards': 1},
- {'name': 'test262', 'variant': 'code_serializer', 'shards': 6},
+ {'name': 'test262', 'variant': 'code_serializer', 'shards': 8},
# GC stress
{
'name': 'd8testing',
'suffix': 'gc-stress',
'test_args': ['--gc-stress'],
- 'shards': 9,
+ 'shards': 10,
},
# Jit fuzzing.
{'name': 'mjsunit', 'variant': 'jit_fuzzing'},
@@ -610,6 +610,15 @@
{'name': 'v8testing', 'shards': 8},
],
},
+ 'v8_linux64_no_metagen_dbg': {
+ 'swarming_dimensions' : {
+ 'os': 'Ubuntu-22.04',
+ 'cpu': 'x86-64',
+ },
+ 'tests': [
+ {'name': 'v8testing', 'shards': 7},
+ ],
+ },
'v8_linux64_no_pointer_compression_rel': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
@@ -1284,7 +1293,7 @@
{
'name': 'd8testing',
'test_args': ['--gc-stress'],
- 'shards': 5,
+ 'shards': 8,
},
{
'name': 'mjsunit',
@@ -1442,7 +1451,7 @@
'os': 'Ubuntu-22.04',
},
'tests': [
- {'name': 'mjsunit', 'test_args': ['--no-harness'], 'shards': 2},
+ {'name': 'mjsunit', 'test_args': ['--no-harness'], 'shards': 4},
],
},
'V8 Linux64 - debug': {
@@ -1457,28 +1466,28 @@
{'name': 'mozilla', 'variant': 'extra'},
{'name': 'optimize_for_size'},
{'name': 'test262', 'shards': 16},
- {'name': 'test262', 'variant': 'extra', 'shards': 10},
- {'name': 'v8testing', 'shards': 5},
+ {'name': 'test262', 'variant': 'extra', 'shards': 12},
+ {'name': 'v8testing', 'shards': 7},
{'name': 'v8testing', 'variant': 'extra', 'shards': 4},
- {'name': 'v8testing', 'variant': 'minor_ms'},
- {'name': 'v8testing', 'variant': 'conservative_stack_scanning'},
- {'name': 'v8testing', 'variant': 'no_lfa'},
- {'name': 'v8testing', 'variant': 'slow_path'},
- {'name': 'v8testing', 'variant': 'stress_instruction_scheduling'},
- {'name': 'v8testing', 'variant': 'stress_concurrent_allocation'},
+ {'name': 'v8testing', 'variant': 'minor_ms', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'conservative_stack_scanning', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'no_lfa', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'slow_path', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'stress_instruction_scheduling', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'stress_concurrent_allocation', 'shards': 2},
{'name': 'v8testing', 'variant': 'stress_concurrent_inlining', 'shards': 2},
- {'name': 'v8testing', 'variant': 'turbofan_random_rescheduling'},
- {'name': 'v8testing', 'variant': 'scavenger_chaos_mode'},
- {'name': 'mjsunit', 'variant': 'stress_maglev_tests_with_turbofan'},
+ {'name': 'v8testing', 'variant': 'turbofan_random_rescheduling', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'scavenger_chaos_mode', 'shards': 2},
+ {'name': 'mjsunit', 'variant': 'stress_maglev_tests_with_turbofan', 'shards': 2},
# Maglev -- move to extra once more architectures are supported.
- {'name': 'v8testing', 'variant': 'maglev'},
- {'name': 'v8testing', 'variant': 'maglev_future'},
- {'name': 'v8testing', 'variant': 'stress_maglev'},
- {'name': 'v8testing', 'variant': 'stress_maglev_non_eager_inlining'},
- {'name': 'v8testing', 'variant': 'stress_maglev_future'},
- {'name': 'v8testing', 'variant': 'turbolev'},
- {'name': 'v8testing', 'variant': 'stress_turbolev_future'},
- {'name': 'v8testing', 'variant': 'verify_turboshaft'},
+ {'name': 'v8testing', 'variant': 'maglev', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'maglev_future', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'stress_maglev', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'stress_maglev_non_eager_inlining', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'stress_maglev_future', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'turbolev', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'stress_turbolev_future', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'verify_turboshaft', 'shards': 2},
# Noavx.
{
'name': 'v8testing',
@@ -1490,7 +1499,7 @@
{'name': 'benchmarks', 'variant': 'code_serializer', 'shards': 1},
{'name': 'd8testing', 'variant': 'code_serializer', 'shards': 1},
{'name': 'mozilla', 'variant': 'code_serializer', 'shards': 1},
- {'name': 'test262', 'variant': 'code_serializer', 'shards': 4},
+ {'name': 'test262', 'variant': 'code_serializer', 'shards': 6},
# Jit fuzzing.
{'name': 'mjsunit', 'variant': 'jit_fuzzing'},
{'name': 'mjsunit', 'variant': 'jit_fuzzing_maglev'},
@@ -1549,7 +1558,7 @@
'os': 'Ubuntu-22.04',
},
'tests': [
- {'name': 'v8testing', 'shards': 5},
+ {'name': 'v8testing', 'shards': 7},
],
},
'V8 Linux64 - debug - perfetto': {
@@ -1645,7 +1654,7 @@
{
'name': 'd8testing',
'test_args': ['--gc-stress'],
- 'shards': 7,
+ 'shards': 8,
},
{
'name': 'mjsunit',
@@ -1708,6 +1717,15 @@
{'name': 'v8testing', 'shards': 6},
],
},
+ 'V8 Linux64 - no metagen - debug': {
+ 'swarming_dimensions' : {
+ 'os': 'Ubuntu-22.04',
+ 'cpu': 'x86-64',
+ },
+ 'tests': [
+ {'name': 'v8testing', 'shards': 7},
+ ],
+ },
'V8 Linux64 - no pointer compression': {
'swarming_dimensions' : {
'os': 'Ubuntu-22.04',
@@ -1791,7 +1809,7 @@
'os': 'Ubuntu-22.04',
},
'tests': [
- {'name': 'v8testing', 'shards': 2},
+ {'name': 'v8testing', 'shards': 3},
],
},
'V8 Linux64 ASAN': {
@@ -1810,10 +1828,10 @@
'os': 'Ubuntu-22.04',
},
'tests': [
- {'name': 'v8testing', 'shards': 5},
+ {'name': 'v8testing', 'shards': 7},
{'name': 'benchmarks', 'shards': 5},
{'name': 'mozilla', 'shards': 5},
- {'name': 'test262', 'shards': 12},
+ {'name': 'test262', 'shards': 16},
],
},
'V8 Linux64 GC Stress - custom snapshot': {
@@ -1824,7 +1842,7 @@
{
'name': 'mjsunit',
'test_args': ['--gc-stress', '--no-harness'],
- 'shards': 5,
+ 'shards': 8,
},
],
},
@@ -2117,9 +2135,9 @@
{'name': 'test262', 'variant': 'default', 'shards': 4},
{'name': 'v8testing', 'shards': 4},
{'name': 'v8testing', 'variant': 'extra', 'shards': 3},
- {'name': 'v8testing', 'variant': 'minor_ms'},
- {'name': 'v8testing', 'variant': 'conservative_stack_scanning'},
- {'name': 'v8testing', 'variant': 'scavenger_chaos_mode'},
+ {'name': 'v8testing', 'variant': 'minor_ms', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'conservative_stack_scanning', 'shards': 2},
+ {'name': 'v8testing', 'variant': 'scavenger_chaos_mode', 'shards': 2},
{'name': 'benchmarks', 'variant': 'validate_generated_code', 'shards': 2},
{'name': 'd8testing', 'variant': 'validate_generated_code', 'shards': 2},
],
diff --git a/deps/v8/src/DEPS b/deps/v8/src/DEPS
index af82a07ba9d..54108a8f1af 100644
--- a/deps/v8/src/DEPS
+++ b/deps/v8/src/DEPS
@@ -88,6 +88,7 @@ include_rules = [
"-src/libplatform",
"-include/libplatform",
"+builtins-generated",
+ "+metagen",
"+torque-generated",
"+starboard",
]
diff --git a/deps/v8/src/api/api-arguments-inl.h b/deps/v8/src/api/api-arguments-inl.h
index 8cbda85dc65..dbfae8ec545 100644
--- a/deps/v8/src/api/api-arguments-inl.h
+++ b/deps/v8/src/api/api-arguments-inl.h
@@ -354,10 +354,11 @@ v8::Intercepted PropertyCallbackArguments::CallNamedSetter(
set_property_key(*name);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
- NamedPropertySetterCallback f = reinterpret_cast<NamedPropertySetterCallback>(
- interceptor->named_setter(isolate));
+ NamedPropertySetterCallbackV2 f =
+ reinterpret_cast<NamedPropertySetterCallbackV2>(
+ interceptor->named_setter(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
- PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
+ PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, has_side_effects,
ExceptionContext::kNamedSetter);
v8::Intercepted intercepted =
f(v8::Utils::ToLocal(name), v8::Utils::ToLocal(value), callback_info);
@@ -373,11 +374,11 @@ v8::Intercepted PropertyCallbackArguments::CallNamedDefiner(
set_property_key(*name);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
- NamedPropertyDefinerCallback f =
- reinterpret_cast<NamedPropertyDefinerCallback>(
+ NamedPropertyDefinerCallbackV2 f =
+ reinterpret_cast<NamedPropertyDefinerCallbackV2>(
interceptor->named_definer(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
- PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
+ PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, has_side_effects,
ExceptionContext::kNamedDefiner);
v8::Intercepted intercepted =
f(v8::Utils::ToLocal(name), desc, callback_info);
@@ -425,8 +426,8 @@ DirectHandle<Object> PropertyCallbackArguments::CallIndexedQuery(
set_property_key(index);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(Smi::FromInt(v8::None));
- IndexedPropertyQueryCallbackV2 f =
- reinterpret_cast<IndexedPropertyQueryCallbackV2>(
+ IndexedPropertyQueryCallback f =
+ reinterpret_cast<IndexedPropertyQueryCallback>(
interceptor->indexed_query(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Integer, interceptor,
ExceptionContext::kIndexedQuery);
@@ -444,8 +445,8 @@ DirectHandle<JSAny> PropertyCallbackArguments::CallIndexedGetter(
set_property_key(index);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
- IndexedPropertyGetterCallbackV2 f =
- reinterpret_cast<IndexedPropertyGetterCallbackV2>(
+ IndexedPropertyGetterCallback f =
+ reinterpret_cast<IndexedPropertyGetterCallback>(
interceptor->indexed_getter(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor,
ExceptionContext::kIndexedGetter);
@@ -463,8 +464,8 @@ Handle<JSAny> PropertyCallbackArguments::CallIndexedDescriptor(
set_property_key(index);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).undefined_value());
- IndexedPropertyDescriptorCallbackV2 f =
- reinterpret_cast<IndexedPropertyDescriptorCallbackV2>(
+ IndexedPropertyDescriptorCallback f =
+ reinterpret_cast<IndexedPropertyDescriptorCallback>(
interceptor->indexed_descriptor(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Value, interceptor,
ExceptionContext::kIndexedDescriptor);
@@ -482,11 +483,11 @@ v8::Intercepted PropertyCallbackArguments::CallIndexedSetter(
set_property_key(index);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
- IndexedPropertySetterCallbackV2 f =
- reinterpret_cast<IndexedPropertySetterCallbackV2>(
+ IndexedPropertySetterCallback f =
+ reinterpret_cast<IndexedPropertySetterCallback>(
interceptor->indexed_setter(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
- PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
+ PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, has_side_effects,
ExceptionContext::kIndexedSetter);
v8::Intercepted intercepted =
f(index, v8::Utils::ToLocal(value), callback_info);
@@ -502,11 +503,11 @@ v8::Intercepted PropertyCallbackArguments::CallIndexedDefiner(
set_property_key(index);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
- IndexedPropertyDefinerCallbackV2 f =
- reinterpret_cast<IndexedPropertyDefinerCallbackV2>(
+ IndexedPropertyDefinerCallback f =
+ reinterpret_cast<IndexedPropertyDefinerCallback>(
interceptor->indexed_definer(isolate));
DirectHandle<InterceptorInfo> has_side_effects;
- PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, void, has_side_effects,
+ PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, has_side_effects,
ExceptionContext::kIndexedDefiner);
v8::Intercepted intercepted = f(index, desc, callback_info);
return intercepted;
@@ -521,8 +522,8 @@ v8::Intercepted PropertyCallbackArguments::CallIndexedDeleter(
set_property_key(index);
slot_at(kCallbackInfoIndex).store(*interceptor);
slot_at(kReturnValueIndex).store(ReadOnlyRoots(isolate).true_value());
- IndexedPropertyDeleterCallbackV2 f =
- reinterpret_cast<IndexedPropertyDeleterCallbackV2>(
+ IndexedPropertyDeleterCallback f =
+ reinterpret_cast<IndexedPropertyDeleterCallback>(
interceptor->indexed_deleter(isolate));
PREPARE_CALLBACK_INFO_INTERCEPTOR(isolate, f, v8::Boolean, interceptor,
ExceptionContext::kIndexedDeleter);
diff --git a/deps/v8/src/api/api-inl.h b/deps/v8/src/api/api-inl.h
index a85ad8c4798..b5be783c231 100644
--- a/deps/v8/src/api/api-inl.h
+++ b/deps/v8/src/api/api-inl.h
@@ -17,7 +17,7 @@
#include "src/heap/heap-inl.h"
#include "src/logging/runtime-call-stats.h"
#include "src/objects/foreign-inl.h"
-#include "src/objects/objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
namespace v8 {
@@ -203,10 +203,13 @@ class V8_NODISCARD CallDepthScope {
bool CheckKeptObjectsClearedAfterMicrotaskCheckpoint(
i::MicrotaskQueue* microtask_queue) {
bool did_perform_microtask_checkpoint =
- isolate_->thread_local_top()->CallDepthIsZero() && do_callback &&
+ do_callback && isolate_->thread_local_top()->CallDepthIsZero() &&
microtask_queue &&
microtask_queue->microtasks_policy() == MicrotasksPolicy::kAuto &&
- !isolate_->is_execution_terminating();
+ !isolate_->is_execution_terminating() &&
+ microtask_queue->ShouldPerformCheckpoint(
+ reinterpret_cast<v8::Isolate*>(isolate_));
+
return !did_perform_microtask_checkpoint ||
IsUndefined(isolate_->heap()->weak_refs_keep_during_job());
}
diff --git a/deps/v8/src/api/api-natives.cc b/deps/v8/src/api/api-natives.cc
index 36bcf476d56..68ba61b7cbc 100644
--- a/deps/v8/src/api/api-natives.cc
+++ b/deps/v8/src/api/api-natives.cc
@@ -443,9 +443,7 @@ MaybeHandle<JSFunction> InstantiateFunction(
if (!info->needs_access_check() &&
IsUndefined(info->GetNamedPropertyHandler()) &&
IsUndefined(info->GetIndexedPropertyHandler())) {
- function_type = v8_flags.experimental_embedder_instance_types
- ? info->GetInstanceType()
- : JS_API_OBJECT_TYPE;
+ function_type = JS_API_OBJECT_TYPE;
DCHECK(InstanceTypeChecker::IsJSApiObject(function_type));
}
@@ -735,6 +733,13 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
if (immutable_proto) map->set_is_immutable_proto(true);
JSFunction::SetInitialMap(isolate, result, map, Cast<JSObject>(prototype));
+ if (map->supports_fast_iterable_to_list()) {
+ // %CheckFastIterableToListPrototype() relies on the constness tracking
+ // which requires the prototype to be in fast mode.
+ DirectHandle<Map> proto_map(Cast<JSObject>(prototype)->map(), isolate);
+ Map::SetShouldBeFastPrototypeMap(proto_map, true, isolate);
+ }
+
return result;
}
diff --git a/deps/v8/src/api/api.cc b/deps/v8/src/api/api.cc
index f498fee3431..adee19691fc 100644
--- a/deps/v8/src/api/api.cc
+++ b/deps/v8/src/api/api.cc
@@ -112,6 +112,7 @@
#include "src/objects/js-weak-refs-inl.h"
#include "src/objects/managed-inl.h"
#include "src/objects/module-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/ordered-hash-table-inl.h"
@@ -155,7 +156,6 @@
#include "src/utils/version.h"
#if V8_ENABLE_WEBASSEMBLY
-#include "src/base/fpu.h"
#include "src/debug/debug-wasm-objects.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/streaming-decoder.h"
@@ -955,8 +955,8 @@ Context::BackupIncumbentScope::~BackupIncumbentScope() {
}
static_assert(i::Internals::kEmbedderDataSlotSize == i::kEmbedderDataSlotSize);
-static_assert(i::Internals::kEmbedderDataSlotExternalPointerOffset ==
- i::EmbedderDataSlot::kExternalPointerOffset);
+static_assert(i::Internals::kEmbedderDataSlotCppHeapPointerOffset ==
+ i::EmbedderDataSlot::kCppHeapPointerOffset);
static i::DirectHandle<i::EmbedderDataArray> EmbedderDataFor(
Context* context, int index, bool can_grow, const char* location) {
@@ -1035,8 +1035,8 @@ void Context::SetEmbedderDataV2(int index, v8::Local<Data> value) {
*Utils::OpenDirectHandle(*GetEmbedderDataV2(index)));
}
-void* Context::SlowGetAlignedPointerFromEmbedderData(int index,
- EmbedderDataTypeTag tag) {
+void* Context::GetAlignedPointerFromEmbedderData(int index,
+ EmbedderDataTypeTag tag) {
const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
i::Isolate* i_isolate = i::Isolate::Current();
i::HandleScope handle_scope(i_isolate);
@@ -1051,19 +1051,44 @@ void* Context::SlowGetAlignedPointerFromEmbedderData(int index,
return result;
}
+void* Context::SlowGetAlignedPointerFromEmbedderData(int index,
+ CppHeapPointerTag tag) {
+ const char* location = "v8::Context::GetAlignedPointerFromEmbedderData()";
+ i::Isolate* i_isolate = i::Isolate::Current();
+ i::HandleScope handle_scope(i_isolate);
+ i::DirectHandle<i::EmbedderDataArray> data =
+ EmbedderDataFor(this, index, false, location);
+ if (data.is_null()) return nullptr;
+ void* result;
+ Utils::ApiCheck(i::EmbedderDataSlot(*data, index)
+ .ToAlignedPointer(i_isolate, &result, tag),
+ location, "Pointer is not aligned");
+ return result;
+}
+
void Context::SetAlignedPointerInEmbedderData(int index, void* value,
EmbedderDataTypeTag tag) {
const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
i::Isolate* i_isolate = i::Isolate::Current();
i::DirectHandle<i::EmbedderDataArray> data =
EmbedderDataFor(this, index, true, location);
- bool ok = i::EmbedderDataSlot(*data, index)
- .store_aligned_pointer(i_isolate, *data, value,
- ToExternalPointerTag(tag));
+ bool ok = i::EmbedderDataSlot::store_aligned_pointer(
+ i_isolate, data, index, value, ToExternalPointerTag(tag));
Utils::ApiCheck(ok, location, "Pointer is not aligned");
DCHECK_EQ(value, GetAlignedPointerFromEmbedderData(index, tag));
}
+void Context::SetAlignedPointerInEmbedderDataInternal(int index, void* value,
+ CppHeapPointerTag tag) {
+ const char* location = "v8::Context::SetAlignedPointerInEmbedderData()";
+ i::Isolate* i_isolate = i::Isolate::Current();
+ i::DirectHandle<i::EmbedderDataArray> data =
+ EmbedderDataFor(this, index, true, location);
+ bool ok = i::EmbedderDataSlot(*data, index)
+ .store_aligned_pointer(i_isolate, *data, value, tag);
+ Utils::ApiCheck(ok, location, "Pointer is not aligned");
+}
+
// --- T e m p l a t e ---
void Template::Set(v8::Local<Name> name, v8::Local<Data> value,
@@ -1563,17 +1588,6 @@ void Template::SetNativeDataProperty(v8::Local<Name> name,
getter_side_effect_type, setter_side_effect_type);
}
-void Template::SetNativeDataProperty(v8::Local<Name> name,
- AccessorNameGetterCallback getter,
- AccessorNameSetterCallback setter,
- v8::Local<Value> data,
- PropertyAttribute attribute,
- SideEffectType getter_side_effect_type,
- SideEffectType setter_side_effect_type) {
- TemplateSetAccessor(this, name, getter, setter, data, attribute, false,
- getter_side_effect_type, setter_side_effect_type);
-}
-
void Template::SetLazyDataProperty(v8::Local<Name> name,
AccessorNameGetterCallback getter,
v8::Local<Value> data,
@@ -1581,7 +1595,7 @@ void Template::SetLazyDataProperty(v8::Local<Name> name,
SideEffectType getter_side_effect_type,
SideEffectType setter_side_effect_type) {
TemplateSetAccessor(
- this, name, getter, static_cast<AccessorNameSetterCallback>(nullptr),
+ this, name, getter, static_cast<AccessorNameSetterCallbackV2>(nullptr),
data, attribute, true, getter_side_effect_type, setter_side_effect_type);
}
@@ -2438,7 +2452,7 @@ Maybe<bool> Module::InstantiateModule(Local<Context> context,
return Just(true);
}
-MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
+MaybeLocal<Promise> Module::Evaluate(Local<Context> context) {
auto i_isolate = i::Isolate::Current();
TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.Execute");
EnterV8Scope<InternalEscapableScope> api_scope{i_isolate, context,
@@ -2456,7 +2470,7 @@ MaybeLocal<Value> Module::Evaluate(Local<Context> context) {
return api_scope.EscapeMaybe(i::Module::Evaluate(i_isolate, self));
}
-MaybeLocal<Value> Module::EvaluateForImportDefer(Local<Context> context) {
+MaybeLocal<Promise> Module::EvaluateForImportDefer(Local<Context> context) {
auto i_isolate = i::Isolate::Current();
TRACE_EVENT_CALL_STATS_SCOPED(i_isolate, "v8", "V8.Execute");
EnterV8Scope<InternalEscapableScope> api_scope{i_isolate, context,
@@ -2486,7 +2500,7 @@ MaybeLocal<Value> Module::EvaluateForImportDefer(Local<Context> context) {
Local<Module> v8_dep_module = Utils::ToLocal(dep_module);
MaybeLocal<Value> maybe_eval_result = v8_dep_module->Evaluate(context);
if (maybe_eval_result.IsEmpty()) {
- return api_scope.EscapeMaybe(MaybeLocal<Value>());
+ return api_scope.EscapeMaybe(MaybeLocal<Promise>());
}
Local<Value> eval_result = maybe_eval_result.ToLocalChecked();
CHECK(eval_result->IsPromise());
@@ -2501,7 +2515,7 @@ MaybeLocal<Value> Module::EvaluateForImportDefer(Local<Context> context) {
i::MaybeHandle<i::JSPromise> maybe_promise_all_result =
i::JSPromise::PerformPromiseAll(i_isolate, promises);
if (maybe_promise_all_result.is_null()) {
- return api_scope.EscapeMaybe(MaybeLocal<Value>());
+ return api_scope.EscapeMaybe(MaybeLocal<Promise>());
}
return api_scope.Escape(
Utils::ToLocal(maybe_promise_all_result.ToHandleChecked()));
@@ -2537,6 +2551,34 @@ Local<Module> Module::CreateSyntheticModule(
i_host_defined_options)));
}
+START_ALLOW_USE_DEPRECATED()
+Local<Module> Module::CreateSyntheticModule(
+ Isolate* v8_isolate, Local<String> module_name,
+ const std::span<const Local<String>>& export_names,
+ v8::Module::LegacySyntheticModuleEvaluationSteps evaluation_steps,
+ Local<Data> host_defined_options) {
+ // TODO(https://crbug.com/545375591): Remove once
+ // LegacySyntheticModuleEvaluationSteps is gone.
+#if (__GNUC__ >= 8) || defined(__clang__)
+#pragma GCC diagnostic push
+#pragma GCC diagnostic ignored "-Wcast-function-type"
+#endif
+ // Cast from 'v8::MaybeLocal<v8::Value> (*)(v8::Local<v8::Context>,
+ // v8::Local<v8::Module>)' to 'v8::MaybeLocal<v8::Promise>
+ // (*)(v8::Local<v8::Context>, v8::Local<v8::Module>)'. Both return types are
+ // pointer-sized, trivially copyable handle wrappers, so they share the same
+ // representation. SyntheticModule::Evaluate() checks at runtime that the
+ // returned value really is a Promise.
+ auto promise_returning_steps =
+ reinterpret_cast<SyntheticModuleEvaluationSteps>(evaluation_steps);
+#if (__GNUC__ >= 8) || defined(__clang__)
+#pragma GCC diagnostic pop
+#endif
+ return CreateSyntheticModule(v8_isolate, module_name, export_names,
+ promise_returning_steps, host_defined_options);
+}
+END_ALLOW_USE_DEPRECATED()
+
Local<Data> Module::GetSyntheticModuleHostDefinedOptions() const {
auto self = Utils::OpenDirectHandle(this);
i::Isolate* i_isolate = i::Isolate::Current();
@@ -3006,6 +3048,7 @@ using TryCatchIsVerboseField = v8::base::BitField<bool, 0, 1, uint8_t>;
using TryCatchCanContinueField = TryCatchIsVerboseField::Next<bool, 1>;
using TryCatchCaptureMessageField = TryCatchCanContinueField::Next<bool, 1>;
using TryCatchRethrowField = TryCatchCaptureMessageField::Next<bool, 1>;
+using TryCatchIsInternalField = TryCatchRethrowField::Next<bool, 1>;
} // namespace
v8::TryCatch::TryCatch(v8::Isolate* v8_isolate)
@@ -3014,7 +3057,8 @@ v8::TryCatch::TryCatch(v8::Isolate* v8_isolate)
flags_(TryCatchIsVerboseField::encode(false) |
TryCatchCanContinueField::encode(true) |
TryCatchCaptureMessageField::encode(true) |
- TryCatchRethrowField::encode(false)) {
+ TryCatchRethrowField::encode(false) |
+ TryCatchIsInternalField::encode(false)) {
ResetInternal();
// Special handling for simulators which have a separate JS stack.
js_stack_comparable_address_ = static_cast<internal::Address>(
@@ -3160,6 +3204,14 @@ void v8::TryCatch::set_rethrow(bool value) {
flags_ = TryCatchRethrowField::update(flags_, value);
}
+bool v8::TryCatch::IsInternal() const {
+ return TryCatchIsInternalField::decode(flags_);
+}
+
+void v8::TryCatch::SetIsInternal(bool value) {
+ flags_ = TryCatchIsInternalField::update(flags_, value);
+}
+
// --- M e s s a g e ---
Local<String> Message::Get() const {
@@ -3477,8 +3529,7 @@ Local<String> StackFrame::GetFunctionName() const {
bool StackFrame::IsEval() const {
auto self = Utils::OpenDirectHandle(this);
- return self->script()->compilation_type() ==
- i::Script::CompilationType::kEval;
+ return self->script()->has_eval_origin();
}
bool StackFrame::IsConstructor() const {
@@ -3610,18 +3661,24 @@ void ValueSerializer::Delegate::FreeBufferMemory(void* buffer) {
}
struct ValueSerializer::PrivateData {
- explicit PrivateData(i::Isolate* i, ValueSerializer::Delegate* delegate)
- : isolate(i), serializer(i, delegate) {}
+ explicit PrivateData(
+ i::Isolate* i, ValueSerializer::Delegate* delegate,
+ SharedImmutableArrayBufferMode share_immutable_array_buffer)
+ : isolate(i), serializer(i, delegate, share_immutable_array_buffer) {}
i::Isolate* isolate;
i::ValueSerializer serializer;
};
-ValueSerializer::ValueSerializer(Isolate* v8_isolate)
- : ValueSerializer(v8_isolate, nullptr) {}
+ValueSerializer::ValueSerializer(
+ Isolate* v8_isolate,
+ SharedImmutableArrayBufferMode share_immutable_array_buffer)
+ : ValueSerializer(v8_isolate, nullptr, share_immutable_array_buffer) {}
-ValueSerializer::ValueSerializer(Isolate* v8_isolate, Delegate* delegate)
+ValueSerializer::ValueSerializer(
+ Isolate* v8_isolate, Delegate* delegate,
+ SharedImmutableArrayBufferMode share_immutable_array_buffer)
: private_(new PrivateData(reinterpret_cast<i::Isolate*>(v8_isolate),
- delegate)) {}
+ delegate, share_immutable_array_buffer)) {}
ValueSerializer::~ValueSerializer() { delete private_; }
@@ -3631,6 +3688,18 @@ void ValueSerializer::SetTreatArrayBufferViewsAsHostObjects(bool mode) {
private_->serializer.SetTreatArrayBufferViewsAsHostObjects(mode);
}
+std::vector<std::shared_ptr<v8::BackingStore>>
+ValueSerializer::ReleaseSharedImmutableBackingStores() {
+ auto i_stores = private_->serializer.ReleaseSharedImmutableBackingStores();
+ std::vector<std::shared_ptr<v8::BackingStore>> result;
+ result.reserve(i_stores.size());
+ for (auto& bs : i_stores) {
+ std::shared_ptr<i::BackingStoreBase> bs_base = bs;
+ result.push_back(std::static_pointer_cast<v8::BackingStore>(bs_base));
+ }
+ return result;
+}
+
Maybe<bool> ValueSerializer::WriteValue(Local<Context> context,
Local<Value> value) {
auto i_isolate = i::Isolate::Current();
@@ -3775,6 +3844,17 @@ void ValueDeserializer::TransferSharedArrayBuffer(
transfer_id, Utils::OpenDirectHandle(*shared_array_buffer));
}
+void ValueDeserializer::SetSharedImmutableBackingStores(
+ std::vector<std::shared_ptr<BackingStore>> backing_stores) {
+ std::vector<std::shared_ptr<i::BackingStore>> i_stores;
+ i_stores.reserve(backing_stores.size());
+ for (auto& bs : backing_stores) {
+ std::shared_ptr<i::BackingStoreBase> bs_base = bs;
+ i_stores.push_back(std::static_pointer_cast<i::BackingStore>(bs_base));
+ }
+ private_->deserializer.SetSharedImmutableBackingStores(std::move(i_stores));
+}
+
bool ValueDeserializer::ReadUint32(uint32_t* value) {
return private_->deserializer.ReadUint32(value);
}
@@ -3995,6 +4075,10 @@ bool Value::IsModuleNamespaceObject() const {
return IsJSModuleNamespace(*Utils::OpenDirectHandle(this));
}
+bool Value::IsDeferredModuleNamespaceObject() const {
+ return IsJSDeferredModuleNamespace(*Utils::OpenDirectHandle(this));
+}
+
MaybeLocal<String> Value::ToString(Local<Context> context) const {
auto obj = Utils::OpenDirectHandle(this);
if (i::IsString(*obj)) return ToApiHandle<String>(obj);
@@ -5234,24 +5318,13 @@ Maybe<bool> Object::SetNativeDataProperty(
setter_side_effect_type);
}
-Maybe<bool> Object::SetNativeDataProperty(
- v8::Local<v8::Context> context, v8::Local<Name> name,
- AccessorNameGetterCallback getter, AccessorNameSetterCallback setter,
- v8::Local<Value> data, PropertyAttribute attributes,
- SideEffectType getter_side_effect_type,
- SideEffectType setter_side_effect_type) {
- return ObjectSetAccessor(context, this, name, getter, setter, data,
- attributes, false, getter_side_effect_type,
- setter_side_effect_type);
-}
-
Maybe<bool> Object::SetLazyDataProperty(
v8::Local<v8::Context> context, v8::Local<Name> name,
AccessorNameGetterCallback getter, v8::Local<Value> data,
PropertyAttribute attributes, SideEffectType getter_side_effect_type,
SideEffectType setter_side_effect_type) {
return ObjectSetAccessor(context, this, name, getter,
- static_cast<AccessorNameSetterCallback>(nullptr),
+ static_cast<AccessorNameSetterCallbackV2>(nullptr),
data, attributes, true, getter_side_effect_type,
setter_side_effect_type);
}
@@ -5465,10 +5538,10 @@ Local<v8::Context> v8::Object::GetCreationContextChecked() {
}
namespace {
+template <typename TagType>
V8_INLINE void* GetAlignedPointerFromEmbedderDataInCreationContextImpl(
- i::DirectHandle<i::JSReceiver> object,
- i::IsolateForSandbox i_isolate_for_sandbox, int index,
- EmbedderDataTypeTag tag) {
+ i::DirectHandle<i::JSReceiver> object, i::Isolate* i_isolate, int index,
+ TagType tag) {
const char* location =
"v8::Object::GetAlignedPointerFromEmbedderDataInCreationContext()";
auto maybe_context = object->GetCreationContext();
@@ -5482,8 +5555,7 @@ V8_INLINE void* GetAlignedPointerFromEmbedderDataInCreationContextImpl(
// cleared on Detach to avoid leaks). Since we're doing a global proxy
// access though, the Isolate's current native context must be the native
// context we care about.
- i::Isolate* isolate = i::Isolate::Current();
- i::Tagged<i::Context> context = isolate->context();
+ i::Tagged<i::Context> context = i_isolate->context();
CHECK_EQ(context->global_proxy(), *object);
native_context = context->native_context();
}
@@ -5504,8 +5576,7 @@ V8_INLINE void* GetAlignedPointerFromEmbedderDataInCreationContextImpl(
static_cast<unsigned>(data->length()))) {
void* result;
Utils::ApiCheck(i::EmbedderDataSlot(data, index)
- .ToAlignedPointer(i_isolate_for_sandbox, &result,
- ToExternalPointerTag(tag)),
+ .ToAlignedPointer(i_isolate, &result, tag),
location, "Pointer is not aligned");
return result;
}
@@ -5521,15 +5592,22 @@ void* v8::Object::GetAlignedPointerFromEmbedderDataInCreationContext(
v8::Isolate* isolate, int index, EmbedderDataTypeTag tag) {
auto self = Utils::OpenDirectHandle(this);
auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- return GetAlignedPointerFromEmbedderDataInCreationContextImpl(self, i_isolate,
- index, tag);
+ return GetAlignedPointerFromEmbedderDataInCreationContextImpl(
+ self, i_isolate, index, ToExternalPointerTag(tag));
}
void* v8::Object::GetAlignedPointerFromEmbedderDataInCreationContext(
int index, EmbedderDataTypeTag tag) {
auto self = Utils::OpenDirectHandle(this);
- i::IsolateForSandbox isolate = i::GetCurrentIsolateForSandbox();
- return GetAlignedPointerFromEmbedderDataInCreationContextImpl(self, isolate,
+ return GetAlignedPointerFromEmbedderDataInCreationContextImpl(
+ self, i::Isolate::Current(), index, ToExternalPointerTag(tag));
+}
+
+void* v8::Object::GetAlignedPointerFromEmbedderDataInCreationContext(
+ v8::Isolate* isolate, int index, CppHeapPointerTag tag) {
+ auto self = Utils::OpenDirectHandle(this);
+ auto i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ return GetAlignedPointerFromEmbedderDataInCreationContextImpl(self, i_isolate,
index, tag);
}
@@ -6281,10 +6359,9 @@ void v8::Object::SetAlignedPointerInInternalField(int index, void* value,
const char* location = "v8::Object::SetAlignedPointerInInternalField()";
if (!InternalFieldOK(obj, index, location)) return;
- i::DisallowGarbageCollection no_gc;
- Utils::ApiCheck(i::EmbedderDataSlot(i::Cast<i::JSObject>(*obj), index)
- .store_aligned_pointer(i::Isolate::Current(), *obj, value,
- ToExternalPointerTag(tag)),
+ Utils::ApiCheck(i::EmbedderDataSlot::store_aligned_pointer(
+ i::Isolate::Current(), i::Cast<i::JSObject>(obj), index,
+ value, ToExternalPointerTag(tag)),
location, "Unaligned pointer");
DCHECK_EQ(value, GetAlignedPointerFromInternalField(index, tag));
}
@@ -6950,6 +7027,7 @@ bool IsJSReceiverSafeToFreeze(i::InstanceType obj_type) {
return true;
#if V8_ENABLE_WEBASSEMBLY
case i::WASM_ARRAY_TYPE:
+ case i::WASM_CUSTOM_MAP_TYPE:
case i::WASM_STRUCT_TYPE:
case i::WASM_TAG_OBJECT_TYPE:
#endif // V8_ENABLE_WEBASSEMBLY
@@ -8273,11 +8351,6 @@ FastIterateResult FastIterateArray(DirectHandle<JSArray> array,
void* callback_data) {
// Instead of relying on callers to check condition, this function returns
// {kSlowPath} for situations it can't handle.
- // Most code paths below don't allocate, and rely on {callback} not allocating
- // either, but this isn't enforced with {DisallowHeapAllocation} to allow
- // embedders to allocate error objects before terminating the iteration.
- // Since {callback} must not allocate anyway, we can get away with fake
- // handles, reducing per-element overhead.
if (!CanUseFastIteration(isolate, array)) return FastIterateResult::kSlowPath;
using Result = v8::Array::CallbackResult;
DisallowJavascriptExecution no_js(isolate);
@@ -8289,14 +8362,12 @@ FastIterateResult FastIterateArray(DirectHandle<JSArray> array,
case PACKED_FROZEN_ELEMENTS:
case PACKED_SEALED_ELEMENTS:
case PACKED_NONEXTENSIBLE_ELEMENTS: {
- Tagged<FixedArray> elements = Cast<FixedArray>(array->elements());
- for (uint32_t i = 0; i < length; i++) {
- Tagged<Object> element = elements->get(static_cast<int>(i));
- // TODO(13270): When we switch to CSS, we can pass {element} to
- // the callback directly, without {fake_handle}.
- IndirectHandle<Object> fake_handle(
- reinterpret_cast<Address*>(&element));
- Result result = callback(i, Utils::ToLocal(fake_handle), callback_data);
+ DirectHandle<FixedArray> elements(Cast<FixedArray>(array->elements()),
+ isolate);
+ FOR_WITH_HANDLE_SCOPE(isolate, uint32_t i = 0, i, i < length, i++) {
+ DirectHandle<Object> element(elements->get(static_cast<int>(i)),
+ isolate);
+ Result result = callback(i, Utils::ToLocal(element), callback_data);
if (result != Result::kContinue) {
return static_cast<FastIterateResult>(result);
}
@@ -8309,16 +8380,16 @@ FastIterateResult FastIterateArray(DirectHandle<JSArray> array,
case HOLEY_SEALED_ELEMENTS:
case HOLEY_NONEXTENSIBLE_ELEMENTS:
case HOLEY_ELEMENTS: {
- Tagged<FixedArray> elements = Cast<FixedArray>(array->elements());
- for (uint32_t i = 0; i < length; i++) {
- Tagged<Object> element = elements->get(static_cast<int>(i));
- // TODO(13270): When we switch to CSS, we can pass {element} to
- // the callback directly, without {fake_handle}.
- auto fake_handle =
- IsTheHole(element)
- ? isolate->factory()->undefined_value()
- : IndirectHandle<Object>(reinterpret_cast<Address*>(&element));
- Result result = callback(i, Utils::ToLocal(fake_handle), callback_data);
+ DirectHandle<FixedArray> elements(Cast<FixedArray>(array->elements()),
+ isolate);
+ FOR_WITH_HANDLE_SCOPE(isolate, uint32_t i = 0, i, i < length, i++) {
+ DirectHandle<Object> element(elements->get(static_cast<int>(i)),
+ isolate);
+ DirectHandle<Object> value =
+ IsTheHole(*element)
+ ? DirectHandle<Object>(isolate->factory()->undefined_value())
+ : element;
+ Result result = callback(i, Utils::ToLocal(value), callback_data);
if (result != Result::kContinue) {
return static_cast<FastIterateResult>(result);
}
@@ -8334,10 +8405,10 @@ FastIterateResult FastIterateArray(DirectHandle<JSArray> array,
FOR_WITH_HANDLE_SCOPE(isolate, uint32_t i = 0, i, i < length, i++) {
DirectHandle<Object> value;
if (elements->is_the_hole(i)) {
- value = Handle<Object>(isolate->factory()->undefined_value());
+ value = isolate->factory()->undefined_value();
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
} else if (elements->is_undefined(i)) {
- value = Handle<Object>(isolate->factory()->undefined_value());
+ value = isolate->factory()->undefined_value();
#endif // V8_ENABLE_UNDEFINED_DOUBLE
} else {
value = isolate->factory()->NewNumber(elements->get_scalar(i));
@@ -8351,32 +8422,32 @@ FastIterateResult FastIterateArray(DirectHandle<JSArray> array,
return FastIterateResult::kFinished;
}
case DICTIONARY_ELEMENTS: {
- DisallowGarbageCollection no_gc;
- Tagged<NumberDictionary> dict = array->element_dictionary();
struct Entry {
uint32_t index;
InternalIndex entry;
};
std::vector<Entry> sorted;
- sorted.reserve(dict->NumberOfElements());
- ReadOnlyRoots roots(isolate);
- for (InternalIndex i : dict->IterateEntries()) {
- Tagged<Object> key = dict->KeyAt(i);
- if (!dict->IsKey(roots, key)) continue;
- uint32_t index =
- static_cast<uint32_t>(Object::NumberValue(Cast<Number>(key)));
- sorted.push_back({index, i});
+ DirectHandle<NumberDictionary> dict(array->element_dictionary(), isolate);
+ {
+ DisallowGarbageCollection no_gc;
+ ReadOnlyRoots roots(isolate);
+ sorted.reserve(dict->NumberOfElements());
+ for (InternalIndex i : dict->IterateEntries()) {
+ Tagged<Object> key = dict->KeyAt(i);
+ if (!dict->IsKey(roots, key)) continue;
+ uint32_t index =
+ static_cast<uint32_t>(Object::NumberValue(Cast<Number>(key)));
+ sorted.push_back({index, i});
+ }
+ std::sort(
+ sorted.begin(), sorted.end(),
+ [](const Entry& a, const Entry& b) { return a.index < b.index; });
}
- std::sort(
- sorted.begin(), sorted.end(),
- [](const Entry& a, const Entry& b) { return a.index < b.index; });
- for (const Entry& entry : sorted) {
- Tagged<Object> value = dict->ValueAt(entry.entry);
- // TODO(13270): When we switch to CSS, we can pass {element} to
- // the callback directly, without {fake_handle}.
- IndirectHandle<Object> fake_handle(reinterpret_cast<Address*>(&value));
+ FOR_WITH_HANDLE_SCOPE(isolate, size_t i = 0, i, i < sorted.size(), i++) {
+ const Entry& entry = sorted[i];
+ DirectHandle<Object> value(dict->ValueAt(entry.entry), isolate);
Result result =
- callback(entry.index, Utils::ToLocal(fake_handle), callback_data);
+ callback(entry.index, Utils::ToLocal(value), callback_data);
if (result != Result::kContinue) {
return static_cast<FastIterateResult>(result);
}
@@ -8986,16 +9057,17 @@ MaybeLocal<WasmModuleObject> WasmModuleObject::FromCompiledModule(
#endif // V8_ENABLE_WEBASSEMBLY
}
-#if V8_ENABLE_WEBASSEMBLY
-namespace {
-MaybeLocal<WasmModuleObject> CompileWasmModuleImpl(
+MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
+ Isolate* v8_isolate, std::span<const uint8_t> wire_bytes) {
+ return Compile(v8_isolate, wire_bytes, CompileOptions{});
+}
+
+MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
Isolate* v8_isolate, std::span<const uint8_t> wire_bytes,
- i::wasm::CompileTimeImports compile_imports) {
- // Mirror the JS `WebAssembly.Module` constructor, which disables denormal
- // floats at compile time when the host FPU flushes them.
- if (base::FPU::GetFlushDenormals()) {
- compile_imports.Add(i::wasm::CompileTimeImport::kDisableDenormalFloats);
- }
+ const CompileOptions& options) {
+#if V8_ENABLE_WEBASSEMBLY
+ i::wasm::CompileTimeImports compile_imports =
+ i::wasm::CompileTimeImportsFromOptions(options);
base::OwnedVector<const uint8_t> bytes = base::OwnedCopyOf(wire_bytes);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(v8_isolate);
// We don't check for `IsWasmCodegenAllowed` here, because this function is
@@ -9008,42 +9080,13 @@ MaybeLocal<WasmModuleObject> CompileWasmModuleImpl(
i::wasm::WasmEnabledFeatures::FromIsolate(i_isolate);
maybe_compiled = i::wasm::GetWasmEngine()->SyncCompile(
i_isolate, enabled_features, std::move(compile_imports), &thrower,
- std::move(bytes));
+ std::move(bytes),
+ base::Vector<const char>(options.source_url.data(),
+ options.source_url.size()));
}
CHECK_EQ(maybe_compiled.is_null(), i_isolate->has_exception());
if (maybe_compiled.is_null()) return {};
return Utils::ToLocal(maybe_compiled.ToHandleChecked());
-}
-} // namespace
-#endif // V8_ENABLE_WEBASSEMBLY
-
-MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
- Isolate* v8_isolate, std::span<const uint8_t> wire_bytes) {
-#if V8_ENABLE_WEBASSEMBLY
- return CompileWasmModuleImpl(v8_isolate, wire_bytes,
- i::wasm::CompileTimeImports{});
-#else
- Utils::ApiCheck(false, "WasmModuleObject::Compile",
- "WebAssembly support is not enabled");
- UNREACHABLE();
-#endif // V8_ENABLE_WEBASSEMBLY
-}
-
-MaybeLocal<WasmModuleObject> WasmModuleObject::Compile(
- Isolate* v8_isolate, std::span<const uint8_t> wire_bytes,
- const CompileTimeImports& compile_imports) {
-#if V8_ENABLE_WEBASSEMBLY
- i::wasm::CompileTimeImports imports;
- using Builtins = CompileTimeImports::Builtins;
- if (compile_imports.builtins & Builtins::kJsString) {
- imports.Add(i::wasm::CompileTimeImport::kJsString);
- }
- if (compile_imports.imported_string_constants_module != nullptr) {
- imports.constants_module() =
- compile_imports.imported_string_constants_module;
- imports.Add(i::wasm::CompileTimeImport::kStringConstants);
- }
- return CompileWasmModuleImpl(v8_isolate, wire_bytes, std::move(imports));
#else
Utils::ApiCheck(false, "WasmModuleObject::Compile",
"WebAssembly support is not enabled");
@@ -10454,26 +10497,12 @@ i::ValueHelper::InternalRepresentationType Isolate::GetDataFromSnapshotOnce(
return GetSerializedDataFromFixedArray(i_isolate, list, index);
}
-Local<Value> Isolate::GetContinuationPreservedEmbedderData() {
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
-#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
- return ToApiHandle<Object>(i::direct_handle(
- i_isolate->isolate_data()->continuation_preserved_embedder_data(),
- i_isolate));
-#else // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
- return v8::Undefined(reinterpret_cast<v8::Isolate*>(i_isolate));
-#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
+Local<Data> Isolate::GetContinuationPreservedEmbedderData() {
+ return GetContinuationPreservedEmbedderDataV2();
}
-void Isolate::SetContinuationPreservedEmbedderData(Local<Value> data) {
-#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(this);
- if (data.IsEmpty()) {
- data = v8::Undefined(reinterpret_cast<v8::Isolate*>(this));
- }
- i_isolate->isolate_data()->set_continuation_preserved_embedder_data(
- *Utils::OpenDirectHandle(*data));
-#endif // V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
+void Isolate::SetContinuationPreservedEmbedderData(Local<Data> data) {
+ SetContinuationPreservedEmbedderDataV2(data);
}
Local<Data> Isolate::GetContinuationPreservedEmbedderDataV2() {
@@ -10856,8 +10885,8 @@ int Isolate::ContextDisposedNotification(bool dependant_context) {
}
void Isolate::ContextDisposedNotification(ContextDependants dependants) {
- // TODO(mlippautz): Replace implementation with the old version of
- // ContextDisposedNotification() that still has a return parameter.
+ // TODO(mlippautz): Move implementation here once the deprecated version of
+ // ContextDisposedNotification() with the return parameter is removed.
START_ALLOW_USE_DEPRECATED()
ContextDisposedNotification(dependants == ContextDependants::kSomeDependants);
END_ALLOW_USE_DEPRECATED()
@@ -11249,7 +11278,6 @@ bool v8::Object::IsCodeLike(v8::Isolate* v8_isolate) const {
}
// static
-#ifdef V8_CPPGC_MICROTASK_QUEUE
MicrotaskQueue* MicrotaskQueue::New(Isolate* v8_isolate,
MicrotasksPolicy policy) {
auto* microtask_queue =
@@ -11257,16 +11285,6 @@ MicrotaskQueue* MicrotaskQueue::New(Isolate* v8_isolate,
microtask_queue->set_microtasks_policy(policy);
return microtask_queue;
}
-#else
-std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* v8_isolate,
- MicrotasksPolicy policy) {
- auto microtask_queue =
- i::MicrotaskQueue::New(reinterpret_cast<i::Isolate*>(v8_isolate));
- microtask_queue->set_microtasks_policy(policy);
- std::unique_ptr<MicrotaskQueue> ret(std::move(microtask_queue));
- return ret;
-}
-#endif // V8_CPPGC_MICROTASK_QUEUE
MicrotasksScope::MicrotasksScope(Local<Context> v8_context,
MicrotasksScope::Type type)
diff --git a/deps/v8/src/ast/modules.cc b/deps/v8/src/ast/modules.cc
index ec77ed50c05..067f460c708 100644
--- a/deps/v8/src/ast/modules.cc
+++ b/deps/v8/src/ast/modules.cc
@@ -55,7 +55,7 @@ bool SourceTextModuleDescriptor::ModuleRequestComparer::operator()(
return false;
}
-void SourceTextModuleDescriptor::AddImport(
+bool SourceTextModuleDescriptor::AddImport(
const AstRawString* import_name, const AstRawString* local_name,
const AstRawString* specifier, const ModuleImportPhase import_phase,
const ImportAttributes* import_attributes, const Scanner::Location loc,
@@ -65,10 +65,10 @@ void SourceTextModuleDescriptor::AddImport(
entry->import_name = import_name;
entry->module_request = AddModuleRequest(
specifier, import_phase, import_attributes, specifier_loc, zone);
- AddRegularImport(entry);
+ return AddRegularImport(entry);
}
-void SourceTextModuleDescriptor::AddStarImport(
+bool SourceTextModuleDescriptor::AddStarImport(
const AstRawString* local_name, const AstRawString* specifier,
const ModuleImportPhase import_phase,
const ImportAttributes* import_attributes, const Scanner::Location loc,
@@ -77,7 +77,7 @@ void SourceTextModuleDescriptor::AddStarImport(
entry->local_name = local_name;
entry->module_request = AddModuleRequest(
specifier, import_phase, import_attributes, specifier_loc, zone);
- AddNamespaceImport(entry, zone);
+ return AddNamespaceImport(entry, zone);
}
void SourceTextModuleDescriptor::AddEmptyImport(
diff --git a/deps/v8/src/ast/modules.h b/deps/v8/src/ast/modules.h
index 6f2e56ceea3..8adecf4c5f8 100644
--- a/deps/v8/src/ast/modules.h
+++ b/deps/v8/src/ast/modules.h
@@ -35,20 +35,20 @@ class SourceTextModuleDescriptor : public ZoneObject {
// import x from "foo.js";
// import {x} from "foo.js";
// import {x as y} from "foo.js";
- void AddImport(const AstRawString* import_name,
- const AstRawString* local_name, const AstRawString* specifier,
- const ModuleImportPhase import_phase,
- const ImportAttributes* import_attributes,
- const Scanner::Location loc,
- const Scanner::Location specifier_loc, Zone* zone);
+ V8_NODISCARD bool AddImport(
+ const AstRawString* import_name, const AstRawString* local_name,
+ const AstRawString* specifier, const ModuleImportPhase import_phase,
+ const ImportAttributes* import_attributes, const Scanner::Location loc,
+ const Scanner::Location specifier_loc, Zone* zone);
// import * as x from "foo.js";
- void AddStarImport(const AstRawString* local_name,
- const AstRawString* specifier,
- const ModuleImportPhase import_phase,
- const ImportAttributes* import_attributes,
- const Scanner::Location loc,
- const Scanner::Location specifier_loc, Zone* zone);
+ V8_NODISCARD bool AddStarImport(const AstRawString* local_name,
+ const AstRawString* specifier,
+ const ModuleImportPhase import_phase,
+ const ImportAttributes* import_attributes,
+ const Scanner::Location loc,
+ const Scanner::Location specifier_loc,
+ Zone* zone);
// import "foo.js";
// import {} from "foo.js";
@@ -214,23 +214,20 @@ class SourceTextModuleDescriptor : public ZoneObject {
special_exports_.push_back(entry);
}
- void AddRegularImport(Entry* entry) {
+ V8_NODISCARD bool AddRegularImport(Entry* entry) {
DCHECK_NOT_NULL(entry->import_name);
DCHECK_NOT_NULL(entry->local_name);
DCHECK_NULL(entry->export_name);
DCHECK_LE(0, entry->module_request);
- regular_imports_.emplace(entry->local_name, entry);
- // We don't care if there's already an entry for this local name, as in that
- // case we will report an error when declaring the variable.
+ return regular_imports_.emplace(entry->local_name, entry).second;
}
- void AddNamespaceImport(const Entry* entry, Zone* zone) {
+ V8_NODISCARD bool AddNamespaceImport(const Entry* entry, Zone* zone) {
DCHECK_NULL(entry->import_name);
DCHECK_NULL(entry->export_name);
DCHECK_NOT_NULL(entry->local_name);
DCHECK_LE(0, entry->module_request);
- DCHECK_EQ(0, namespace_imports_.count(entry->local_name));
- namespace_imports_.emplace(entry->local_name, entry);
+ return namespace_imports_.emplace(entry->local_name, entry).second;
}
template <typename IsolateT>
diff --git a/deps/v8/src/ast/scopes.cc b/deps/v8/src/ast/scopes.cc
index 61b61e5c470..59d8ca6bbbf 100644
--- a/deps/v8/src/ast/scopes.cc
+++ b/deps/v8/src/ast/scopes.cc
@@ -3063,6 +3063,7 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* parse_info,
}
} else {
scope_info = Cast<ScopeInfo>(info);
+ if (scope_info->IsEmpty()) continue;
}
while (true) {
if (scope_info == outer) break;
@@ -3074,8 +3075,7 @@ void DeclarationScope::AllocateScopeInfos(ParseInfo* parse_info,
// TODO(crbug.com/401059828): remove once crashes are gone.
int last_checked_field_index = 0;
bool equal_scopes =
- it->second->Equals(scope_info, parse_info_sfi->live_edited(),
- &last_checked_field_index);
+ it->second->Equals(scope_info, &last_checked_field_index);
std::unique_ptr<char[]> script_name_or_url;
size_t script_name_or_url_length = 0;
diff --git a/deps/v8/src/ast/variables.h b/deps/v8/src/ast/variables.h
index b0bb0705451..7c83c335718 100644
--- a/deps/v8/src/ast/variables.h
+++ b/deps/v8/src/ast/variables.h
@@ -296,11 +296,13 @@ class Variable final : public ZoneObject {
int index() const { return index_; }
+ // LINT.IfChange(VariableIsReceiver)
bool IsReceiver() const {
DCHECK(IsParameter());
return index_ == -1;
}
+ // LINT.ThenChange(/src/debug/debug-scope-info.cc:VariableIsReceiver)
bool IsExport() const {
DCHECK_EQ(location(), VariableLocation::MODULE);
diff --git a/deps/v8/src/base/atomic-utils.h b/deps/v8/src/base/atomic-utils.h
index 36052304c46..4959538d1e8 100644
--- a/deps/v8/src/base/atomic-utils.h
+++ b/deps/v8/src/base/atomic-utils.h
@@ -112,8 +112,15 @@ class AsAtomicImpl {
template <typename T>
static T SeqCst_Swap(T* addr, std::remove_reference_t<T> new_value) {
static_assert(sizeof(T) <= sizeof(AtomicStorageType));
- return base::SeqCst_AtomicExchange(
- to_storage_addr(addr), cast_helper<T>::to_storage_type(new_value));
+ return cast_helper<T>::to_return_type(base::SeqCst_AtomicExchange(
+ to_storage_addr(addr), cast_helper<T>::to_storage_type(new_value)));
+ }
+
+ template <typename T>
+ static T Relaxed_Swap(T* addr, std::remove_reference_t<T> new_value) {
+ static_assert(sizeof(T) <= sizeof(AtomicStorageType));
+ return cast_helper<T>::to_return_type(base::Relaxed_AtomicExchange(
+ to_storage_addr(addr), cast_helper<T>::to_storage_type(new_value)));
}
template <typename T>
diff --git a/deps/v8/src/base/cpu/cpu-riscv.cc b/deps/v8/src/base/cpu/cpu-riscv.cc
index c78292eed1e..91fe06b3564 100644
--- a/deps/v8/src/base/cpu/cpu-riscv.cc
+++ b/deps/v8/src/base/cpu/cpu-riscv.cc
@@ -63,6 +63,12 @@ void CPU::DetectFeatures() {
if (pairs[0].value & RISCV_HWPROBE_EXT_ZFA) {
has_zfa_ = true;
}
+ if (pairs[0].value & RISCV_HWPROBE_EXT_ZFH) {
+ has_zfh_ = true;
+ }
+ if (pairs[0].value & RISCV_HWPROBE_EXT_ZVFH) {
+ has_zvfh_ = true;
+ }
if (pairs[0].value & RISCV_HWPROBE_IMA_C) {
has_rvc_ = true;
}
diff --git a/deps/v8/src/base/cpu/cpu-x86.cc b/deps/v8/src/base/cpu/cpu-x86.cc
index 74256e4b8dc..96ba25d15b2 100644
--- a/deps/v8/src/base/cpu/cpu-x86.cc
+++ b/deps/v8/src/base/cpu/cpu-x86.cc
@@ -137,6 +137,12 @@ void CPU::DetectFeatures() {
has_fma3_ = (cpu_info[2] & 0x00001000) != 0;
has_f16c_ = (cpu_info[2] & 0x20000000) != 0;
has_apx_f_ = (cpu_info71[3] & 0x00200000) != 0;
+ if ((cpu_info71[3] & 0x00080000) != 0 && num_ids >= 0x24) {
+ int cpu_info24[4] = {0};
+ __cpuid(cpu_info24, 0x24);
+ has_avx10_1_ = (cpu_info24[1] & 0xff) >= 1;
+ DCHECK_IMPLIES(has_avx10_1_, (cpu_info24[1] & 0x70000) == 0x70000);
+ }
// CET shadow stack feature flag. See
// https://en.wikipedia.org/wiki/CPUID#EAX=7,_ECX=0:_Extended_Features
has_cetss_ = (cpu_info70[2] & 0x00000080) != 0;
diff --git a/deps/v8/src/base/cpu/cpu.cc b/deps/v8/src/base/cpu/cpu.cc
index f5e72eeedc9..2a4551e4400 100644
--- a/deps/v8/src/base/cpu/cpu.cc
+++ b/deps/v8/src/base/cpu/cpu.cc
@@ -201,6 +201,7 @@ bool CPU::StarboardDetectCPU() {
has_popcnt_ = features.x86.has_popcnt;
has_f16c_ = features.x86.has_f16c;
// TODO(jiepan): Support APX_F on STARBOARD
+ // TODO(fanchen): Support AVX10.1 on STARBOARD
break;
default:
return false;
diff --git a/deps/v8/src/base/cpu/cpu.h b/deps/v8/src/base/cpu/cpu.h
index 1d434bf9ffe..363cc715748 100644
--- a/deps/v8/src/base/cpu/cpu.h
+++ b/deps/v8/src/base/cpu/cpu.h
@@ -97,6 +97,7 @@ class V8_BASE_EXPORT CPU final {
bool has_lzcnt() const { return has_lzcnt_; }
bool has_popcnt() const { return has_popcnt_; }
bool has_apx_f() const { return has_apx_f_; }
+ bool has_avx10_1() const { return has_avx10_1_; }
bool is_atom() const { return is_atom_; }
bool has_intel_jcc_erratum() const { return has_intel_jcc_erratum_; }
bool has_cetss() const { return has_cetss_; }
@@ -145,6 +146,8 @@ class V8_BASE_EXPORT CPU final {
bool has_zbs() const { return has_zbs_; }
bool has_zfa() const { return has_zfa_; }
bool has_rvc() const { return has_rvc_; }
+ bool has_zfh() const { return has_zfh_; }
+ bool has_zvfh() const { return has_zvfh_; }
enum class RV_MMU_MODE {
kRiscvSV39,
kRiscvSV48,
@@ -202,6 +205,7 @@ class V8_BASE_EXPORT CPU final {
bool has_lzcnt_ = false;
bool has_popcnt_ = false;
bool has_apx_f_ = false;
+ bool has_avx10_1_ = false;
bool has_idiva_ = false;
bool has_neon_ = false;
bool has_thumb2_ = false;
@@ -231,6 +235,8 @@ class V8_BASE_EXPORT CPU final {
bool has_zbb_ = false;
bool has_zbs_ = false;
bool has_zfa_ = false;
+ bool has_zfh_ = false;
+ bool has_zvfh_ = false;
bool has_rvc_ = false;
bool has_lsx_ = false;
bool has_lasx_ = false;
diff --git a/deps/v8/src/base/debug/stack_trace_win.cc b/deps/v8/src/base/debug/stack_trace_win.cc
index f981bec6101..7b3b430668b 100644
--- a/deps/v8/src/base/debug/stack_trace_win.cc
+++ b/deps/v8/src/base/debug/stack_trace_win.cc
@@ -52,6 +52,12 @@ long WINAPI StackDumpExceptionFilter(EXCEPTION_POINTERS* info) { // NOLINT
bool InitializeSymbols() {
if (g_initialized_symbols) return g_init_error == ERROR_SUCCESS;
g_initialized_symbols = true;
+
+ // Starting in SDK 10.0.28000, dbghelp loads msdia140.dll dynamically at
+ // runtime, so preload it before initializing DbgHelp.
+ if (!::GetModuleHandle(L"msdia140.dll")) {
+ ::LoadLibrary(L"msdia140.dll");
+ }
// Defer symbol load until they're needed, use undecorated names, and get line
// numbers.
SymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_UNDNAME | SYMOPT_LOAD_LINES);
diff --git a/deps/v8/src/base/macros.h b/deps/v8/src/base/macros.h
index c123f847626..c2c24e8229a 100644
--- a/deps/v8/src/base/macros.h
+++ b/deps/v8/src/base/macros.h
@@ -668,8 +668,8 @@ static_assert(V8_ENABLE_SIMD128);
#endif // defined(__clang__)
// Disable/enable -Wlifetime-safety warnings in code.
-#if defined(__clang__)
-#if defined(__has_warning) && __has_warning("-Wlifetime-safety")
+#if defined(__clang__) && defined(__has_warning) && \
+ __has_warning("-Wlifetime-safety")
#define START_IGNORE_LIFETIME_SAFETY_WARNINGS() \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wlifetime-safety\"")
@@ -677,15 +677,11 @@ static_assert(V8_ENABLE_SIMD128);
#else
#define START_IGNORE_LIFETIME_SAFETY_WARNINGS()
#define END_IGNORE_LIFETIME_SAFETY_WARNINGS()
-#endif // __has_warning("-Wlifetime-safety")
-#else
-#define START_IGNORE_LIFETIME_SAFETY_WARNINGS()
-#define END_IGNORE_LIFETIME_SAFETY_WARNINGS()
#endif // defined(__clang__)
// Disable/enable -Wreturn-stack-address warnings in code.
-#if defined(__clang__)
-#if defined(__has_warning) && __has_warning("-Wreturn-stack-address")
+#if defined(__clang__) && defined(__has_warning) && \
+ __has_warning("-Wreturn-stack-address")
#define START_IGNORE_RETURN_STACK_ADDRESS_WARNINGS() \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Wreturn-stack-address\"")
@@ -694,10 +690,6 @@ static_assert(V8_ENABLE_SIMD128);
#else
#define START_IGNORE_RETURN_STACK_ADDRESS_WARNINGS()
#define END_IGNORE_RETURN_STACK_ADDRESS_WARNINGS()
-#endif // __has_warning("-Wreturn-stack-address")
-#else
-#define START_IGNORE_RETURN_STACK_ADDRESS_WARNINGS()
-#define END_IGNORE_RETURN_STACK_ADDRESS_WARNINGS()
#endif // defined(__clang__)
#endif // V8_BASE_MACROS_H_
diff --git a/deps/v8/src/base/memcopy.h b/deps/v8/src/base/memcopy.h
index cb24d63a48f..4c2bea25979 100644
--- a/deps/v8/src/base/memcopy.h
+++ b/deps/v8/src/base/memcopy.h
@@ -9,6 +9,8 @@
#include <algorithm>
#include <atomic>
+#include <limits>
+#include <type_traits>
#include "include/v8config.h"
#include "src/base/base-export.h"
@@ -208,6 +210,15 @@ inline void MemCopyAndSwitchEndianness(void* dst, const void* src,
COPY_LOOP(uint32_t, bits::ByteReverse32);
case 8:
COPY_LOOP(uint64_t, bits::ByteReverse64);
+ case 16:
+ for (uint32_t i = 0; i < num_elements; i++) {
+ const uint8_t* s = reinterpret_cast<const uint8_t*>(src) + i * 16;
+ uint8_t* d = reinterpret_cast<uint8_t*>(dst) + i * 16;
+ for (size_t j = 0; j < 16; j++) {
+ d[j] = s[15 - j];
+ }
+ }
+ return;
default:
UNREACHABLE();
}
@@ -215,11 +226,59 @@ inline void MemCopyAndSwitchEndianness(void* dst, const void* src,
}
#endif
+// Helper to replicate an integral `value` across all bytes of a uintptr_t word.
+template <typename T>
+ requires std::is_integral_v<T>
+constexpr uintptr_t ReplicateValueWord(T value) {
+ if constexpr (sizeof(T) >= sizeof(uintptr_t)) {
+ return static_cast<uintptr_t>(value);
+ } else {
+ using UnsignedT = std::conditional_t<
+ sizeof(T) == 1, uint8_t,
+ std::conditional_t<
+ sizeof(T) == 2, uint16_t,
+ std::conditional_t<sizeof(T) == 4, uint32_t, uint64_t>>>;
+ constexpr uintptr_t kMultiplier =
+ static_cast<uintptr_t>(-1) / std::numeric_limits<UnsignedT>::max();
+ return static_cast<uintptr_t>(static_cast<UnsignedT>(value)) * kMultiplier;
+ }
+}
+
// Fills `destination` with `count` `value`s.
template <typename T>
-inline void Relaxed_Memset(T* destination, T value, size_t count)
+V8_INLINE void Relaxed_Memset(T* destination, T value, size_t count)
requires std::is_integral_v<T>
{
+#if defined(__ATOMIC_RELAXED) && (defined(__GNUC__) || defined(__clang__))
+ if constexpr (sizeof(T) < sizeof(uintptr_t)) {
+ constexpr size_t kElementsPerWord = sizeof(uintptr_t) / sizeof(T);
+ // Prologue: store elements until `destination` is word-aligned.
+ while (reinterpret_cast<uintptr_t>(destination) % sizeof(uintptr_t) != 0 &&
+ count > 0) {
+ std::atomic_ref<T>(*destination).store(value, std::memory_order_relaxed);
+ destination++;
+ count--;
+ }
+ // Main loop: store word-sized chunks using may_alias attribute and
+ // __atomic_store_n.
+ using AliasedWord = uintptr_t __attribute__((may_alias));
+ const uintptr_t word_val = ReplicateValueWord<T>(value);
+ AliasedWord* word_dest = reinterpret_cast<AliasedWord*>(destination);
+ size_t words = count / kElementsPerWord;
+ for (size_t w = 0; w < words; w++) {
+ __atomic_store_n(word_dest + w, word_val, __ATOMIC_RELAXED);
+ }
+ destination += words * kElementsPerWord;
+ count -= words * kElementsPerWord;
+ // Epilogue: store remaining trailing elements.
+ while (count > 0) {
+ std::atomic_ref<T>(*destination).store(value, std::memory_order_relaxed);
+ destination++;
+ count--;
+ }
+ return;
+ }
+#endif
for (size_t i = 0; i < count; i++) {
std::atomic_ref<T>(destination[i]).store(value, std::memory_order_relaxed);
}
diff --git a/deps/v8/src/base/memory.h b/deps/v8/src/base/memory.h
index 642d945bf12..de1c1b3c3f7 100644
--- a/deps/v8/src/base/memory.h
+++ b/deps/v8/src/base/memory.h
@@ -37,12 +37,10 @@ static inline V ReadUnalignedValue(const char p[sizeof(V)]) {
return ReadUnalignedValue<V>(reinterpret_cast<Address>(p));
}
-#if !defined(V8_OS_SOLARIS)
template <typename V>
static inline V ReadUnalignedValue(const int8_t p[sizeof(V)]) {
return ReadUnalignedValue<V>(reinterpret_cast<Address>(p));
}
-#endif
template <typename V>
static inline V ReadUnalignedValue(const uint8_t p[sizeof(V)]) {
diff --git a/deps/v8/src/base/platform/platform-aix.cc b/deps/v8/src/base/platform/platform-aix.cc
index 3593f36239a..c718cbf9b5b 100644
--- a/deps/v8/src/base/platform/platform-aix.cc
+++ b/deps/v8/src/base/platform/platform-aix.cc
@@ -191,26 +191,9 @@ bool OS::DecommitPages(void* address, size_t size) {
// with MAP_FIXED will fail and return -1 unless the application has requested
// SPEC1170 compliant behaviour:
// https://www.ibm.com/docs/en/aix/7.3?topic=m-mmap-mmap64-subroutine
- // As a workaround we use `mprotect` to make the page inaccessible and
- // `madvise` to hint the OS to release the memory.
- //
- // NOTE: On AIX, madvise() is a no-op and does not release physical
- // memory. The pages remain protected but the physical memory may only be
- // reclaimed by the OS under memory pressure. This trade-off is acceptable
- // because:
- // 1. It fixes critical race conditions (Refs:
- // https://github.com/nodejs/node/issues/62647)
- // 2. AIX's disclaim64() requires writable pages, incompatible with PROT_NONE
- // protection
- // 3. The alternative munmap/mmap approach causes "Check failed: ptr ==
- // address" errors
- // 4. Pages are inaccessible, preventing memory corruption
-
DCHECK_EQ(0, reinterpret_cast<uintptr_t>(address) % CommitPageSize());
DCHECK_EQ(0, size % CommitPageSize());
if (mprotect(address, size, PROT_NONE) != 0) return false;
- if (madvise(static_cast<caddr_t>(address), size, MADV_DONTNEED) != 0)
- return false;
return true;
}
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/platform/platform-solaris.cc b/deps/v8/src/base/platform/platform-solaris.cc
index 374728a2eaa..c991d2edac5 100644
--- a/deps/v8/src/base/platform/platform-solaris.cc
+++ b/deps/v8/src/base/platform/platform-solaris.cc
@@ -89,23 +89,5 @@ Stack::StackSlot Stack::ObtainCurrentThreadStackStart() {
return nullptr;
}
-// static
-Stack::StackSlot Stack::ObtainCurrentThreadStackReservedLimit() {
- pthread_attr_t attr;
- int error;
- pthread_attr_init(&attr);
- error = pthread_attr_get_np(pthread_self(), &attr);
- if (!error) {
- void* base;
- size_t size;
- error = pthread_attr_getstack(&attr, &base, &size);
- CHECK(!error);
- pthread_attr_destroy(&attr);
- return base;
- }
- pthread_attr_destroy(&attr);
- return nullptr;
-}
-
} // namespace base
} // namespace v8
diff --git a/deps/v8/src/baseline/arm64/baseline-assembler-arm64-inl.h b/deps/v8/src/baseline/arm64/baseline-assembler-arm64-inl.h
index b3ed4cfd284..27399c6235f 100644
--- a/deps/v8/src/baseline/arm64/baseline-assembler-arm64-inl.h
+++ b/deps/v8/src/baseline/arm64/baseline-assembler-arm64-inl.h
@@ -181,6 +181,40 @@ void BaselineAssembler::JumpIfSmi(Condition cc, Register lhs, Register rhs,
__ AssertSmi(rhs);
__ CompareTaggedAndBranch(lhs, rhs, cc, target);
}
+
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+void BaselineAssembler::JumpIfNotBothSmi(Register lhs, Register rhs,
+ Label* target, Label::Distance) {
+ ScratchRegisterScope scope(this);
+ Register tmp = scope.AcquireScratch();
+ __ Orr(tmp, lhs, rhs);
+ __ JumpIfNotSmi(tmp, target);
+}
+
+void BaselineAssembler::JumpIfTagged(Condition cc, Register lhs, Register rhs,
+ Label* target, Label::Distance) {
+ __ CompareTaggedAndBranch(lhs, rhs, cc, target);
+}
+
+void BaselineAssembler::SmiAddConstantAndJumpIfOverflow(Register value,
+ int constant,
+ Label* overflow,
+ Label::Distance) {
+ DCHECK(Smi::IsValid(constant));
+ ScratchRegisterScope scope(this);
+ Register tmp = scope.AcquireScratch();
+ if (SmiValuesAre31Bits()) {
+ __ Adds(tmp.W(), value.W(), Operand(Smi::FromInt(constant)));
+ __ B(overflow, vs);
+ __ Sxtw(value, tmp.W());
+ } else {
+ __ Adds(tmp, value, Operand(Smi::FromInt(constant)));
+ __ B(overflow, vs);
+ __ Mov(value, tmp);
+ }
+}
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
void BaselineAssembler::JumpIfTagged(Condition cc, Register value,
MemOperand operand, Label* target,
Label::Distance) {
diff --git a/deps/v8/src/baseline/baseline-assembler.h b/deps/v8/src/baseline/baseline-assembler.h
index 406da59cb5c..d5aebea695f 100644
--- a/deps/v8/src/baseline/baseline-assembler.h
+++ b/deps/v8/src/baseline/baseline-assembler.h
@@ -236,6 +236,24 @@ class BaselineAssembler {
inline void Word32And(Register output, Register lhs, int rhs);
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+ // Jumps to |target| unless both |lhs| and |rhs| are Smis, using a single
+ // merged tag test.
+ inline void JumpIfNotBothSmi(Register lhs, Register rhs, Label* target,
+ Label::Distance distance = Label::kFar);
+
+ // Compares two tagged values without asserting that they are Smis.
+ inline void JumpIfTagged(Condition cc, Register lhs, Register rhs,
+ Label* target,
+ Label::Distance distance = Label::kFar);
+
+ // value := value + Smi(constant). Jumps to |overflow| when the result is not
+ // a valid Smi.
+ inline void SmiAddConstantAndJumpIfOverflow(
+ Register value, int constant, Label* overflow,
+ Label::Distance distance = Label::kFar);
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
inline void Switch(Register reg, int case_value_base, Label** labels,
int num_labels);
diff --git a/deps/v8/src/baseline/baseline-compiler.cc b/deps/v8/src/baseline/baseline-compiler.cc
index 7f2475c0835..304dc849ac9 100644
--- a/deps/v8/src/baseline/baseline-compiler.cc
+++ b/deps/v8/src/baseline/baseline-compiler.cc
@@ -1471,26 +1471,108 @@ void BaselineCompiler::VisitShiftRightLogicalSmi() {
#endif // V8_ENABLE_SPARKPLUG_PLUS
#undef VISIT_TYPED_BINARY_OPERATION
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+template <Operation kOperation, Builtin kSmiBuiltin, Builtin kGenericBuiltin>
+bool BaselineCompiler::TryEmitInlineSmiUnary(
+ BinaryOperationFeedback::Type feedback_type, int feedback_index_offset) {
+ static_assert(kOperation == Operation::kIncrement ||
+ kOperation == Operation::kDecrement);
+ if (!v8_flags.sparkplug_inline_smi) {
+ return false;
+ }
+ if (feedback_type != BinaryOperationFeedback::Type::kSignedSmall) {
+ return false;
+ }
+
+ ASM_CODE_COMMENT_STRING(&masm_, "inlined Smi unary fast path");
+ constexpr int kDelta = kOperation == Operation::kIncrement ? 1 : -1;
+ Label slow, done;
+ __ JumpIfNotSmi(kInterpreterAccumulatorRegister, &slow, Label::kNear);
+ // Smi overflow bails out so that the stub records kNumber for the patcher.
+ __ SmiAddConstantAndJumpIfOverflow(kInterpreterAccumulatorRegister, kDelta,
+ &slow, Label::kNear);
+ __ Jump(&done);
+
+ __ Bind(&slow);
+ if (allow_sparkplug_plus_) {
+ CallBuiltin<kSmiBuiltin>(kInterpreterAccumulatorRegister,
+ feedback_index_offset);
+ } else {
+ CallBuiltin<kGenericBuiltin>(kInterpreterAccumulatorRegister,
+ feedback_index_offset);
+ }
+ __ Bind(&done);
+
+ return true;
+}
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
+// Inc/Dec/Negate/BitwiseNot are single-operand bytecodes; the embedded
+// feedback lives at kUnaryEmbeddedFeedbackOperandIndex (unlike binop/compare
+// bytecodes, which use kEmbeddedFeedbackOperandIndex).
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+#define TYPED_UNOP_CASE(type, name) \
+ case BinaryOperationFeedback::Type::k##type: \
+ CallBuiltin<Builtin::k##name##_##type##_Baseline>( \
+ kInterpreterAccumulatorRegister, feedback_index_offset); \
+ break;
+
+#define VISIT_TYPED_UNARY_OPERATION(TypedStubList, Name) \
+ using Feedback = BinaryOperationFeedback; \
+ auto feedback_index_offset = iterator().GetEmbeddedFeedbackOffset( \
+ kUnaryEmbeddedFeedbackOperandIndex); \
+ auto feedback_type = \
+ Feedback::DecodeTypeIndex(static_cast<Feedback::TypeIndex>( \
+ EmbeddedFeedback(kUnaryEmbeddedFeedbackOperandIndex))); \
+ if constexpr (Operation::k##Name == Operation::kIncrement || \
+ Operation::k##Name == Operation::kDecrement) { \
+ if (TryEmitInlineSmiUnary<Operation::k##Name, \
+ Builtin::k##Name##_SignedSmall_Baseline, \
+ Builtin::k##Name##_Generic_Baseline>( \
+ feedback_type, feedback_index_offset)) { \
+ return; \
+ } \
+ } \
+ if (allow_sparkplug_plus_) { \
+ switch (feedback_type) { \
+ TypedStubList(TYPED_UNOP_CASE, Name) default \
+ : CallBuiltin<Builtin::k##Name##_Generic_Baseline>( \
+ kInterpreterAccumulatorRegister, feedback_index_offset); \
+ break; \
+ } \
+ } else { \
+ CallBuiltin<Builtin::k##Name##_Generic_Baseline>( \
+ kInterpreterAccumulatorRegister, feedback_index_offset); \
+ }
+#else
+#define VISIT_TYPED_UNARY_OPERATION(TypedStubList, Name) \
+ auto feedback_index_offset = iterator().GetEmbeddedFeedbackOffset( \
+ kUnaryEmbeddedFeedbackOperandIndex); \
+ CallBuiltin<Builtin::k##Name##_Generic_Baseline>( \
+ kInterpreterAccumulatorRegister, feedback_index_offset);
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
void BaselineCompiler::VisitInc() {
- CallBuiltin<Builtin::kIncrement_Baseline>(kInterpreterAccumulatorRegister,
- FeedbackSlot(0));
+ VISIT_TYPED_UNARY_OPERATION(TYPED_UNARY_STUB_LIST, Increment);
}
void BaselineCompiler::VisitDec() {
- CallBuiltin<Builtin::kDecrement_Baseline>(kInterpreterAccumulatorRegister,
- FeedbackSlot(0));
+ VISIT_TYPED_UNARY_OPERATION(TYPED_UNARY_STUB_LIST, Decrement);
}
void BaselineCompiler::VisitNegate() {
- CallBuiltin<Builtin::kNegate_Baseline>(kInterpreterAccumulatorRegister,
- FeedbackSlot(0));
+ VISIT_TYPED_UNARY_OPERATION(TYPED_NEGATE_STUB_LIST, Negate);
}
void BaselineCompiler::VisitBitwiseNot() {
- CallBuiltin<Builtin::kBitwiseNot_Baseline>(kInterpreterAccumulatorRegister,
- FeedbackSlot(0));
+ VISIT_TYPED_UNARY_OPERATION(TYPED_UNARY_STUB_LIST, BitwiseNot);
}
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+#undef TYPED_UNOP_CASE
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+#undef VISIT_TYPED_UNARY_OPERATION
+
void BaselineCompiler::VisitToBooleanLogicalNot() {
SelectBooleanConstant(kInterpreterAccumulatorRegister,
[&](Label* if_true, Label::Distance distance) {
@@ -1892,6 +1974,81 @@ void BaselineCompiler::VisitConstructForwardAllArgs() {
FeedbackSlotAsTagged(1)); // kSlot
}
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+template <Operation kOperation, Builtin kSmiBuiltin, Builtin kGenericBuiltin>
+bool BaselineCompiler::TryEmitInlineSmiCompare(
+ CompareOperationFeedback::Type feedback_type, int feedback_index_offset) {
+ static_assert(IsComparisonOperation(kOperation));
+ if (!v8_flags.sparkplug_inline_smi) {
+ return false;
+ }
+ if (feedback_type != CompareOperationFeedback::Type::kSignedSmall) {
+ return false;
+ }
+
+ ASM_CODE_COMMENT_STRING(&masm_, "inlined Smi compare fast path");
+ Label slow, done;
+ {
+ BaselineAssembler::ScratchRegisterScope scratch_scope(&basm_);
+ Register lhs = scratch_scope.AcquireScratch();
+ __ Move(lhs, RegisterOperand(0));
+ if constexpr (kOperation == Operation::kEqual ||
+ kOperation == Operation::kStrictEqual) {
+ // Equal Smis have identical tagged values, so check lhs first and let a
+ // tagged-equal hit return true without checking rhs. Only the not-equal
+ // edge needs to verify rhs before returning false.
+ __ JumpIfNotSmi(lhs, &slow, Label::kNear);
+ } else {
+ __ JumpIfNotBothSmi(lhs, kInterpreterAccumulatorRegister, &slow,
+ Label::kNear);
+ }
+
+ SelectBooleanConstant(
+ kInterpreterAccumulatorRegister,
+ [&](Label* if_true, Label::Distance distance) {
+ if constexpr (kOperation == Operation::kEqual ||
+ kOperation == Operation::kStrictEqual) {
+ __ JumpIfTagged(kEqual, lhs, kInterpreterAccumulatorRegister,
+ if_true, distance);
+ // SelectBooleanConstant evaluates the condition before writing its
+ // output register, so the accumulator still holds the rhs on the
+ // path to `slow`.
+ __ JumpIfNotSmi(kInterpreterAccumulatorRegister, &slow,
+ Label::kNear);
+ } else if constexpr (kOperation == Operation::kLessThan) {
+ __ JumpIfTagged(kLessThan, lhs, kInterpreterAccumulatorRegister,
+ if_true, distance);
+ } else if constexpr (kOperation == Operation::kLessThanOrEqual) {
+ __ JumpIfTagged(kLessThanEqual, lhs,
+ kInterpreterAccumulatorRegister, if_true, distance);
+ } else if constexpr (kOperation == Operation::kGreaterThan) {
+ __ JumpIfTagged(kLessThan, kInterpreterAccumulatorRegister, lhs,
+ if_true, distance);
+ } else {
+ static_assert(kOperation == Operation::kGreaterThanOrEqual);
+ __ JumpIfTagged(kLessThanEqual, kInterpreterAccumulatorRegister,
+ lhs, if_true, distance);
+ }
+ });
+ }
+ __ Jump(&done);
+
+ __ Bind(&slow);
+ if (allow_sparkplug_plus_) {
+ CallBuiltin<kSmiBuiltin>(RegisterOperand(0),
+ kInterpreterAccumulatorRegister,
+ feedback_index_offset);
+ } else {
+ CallBuiltin<kGenericBuiltin>(RegisterOperand(0),
+ kInterpreterAccumulatorRegister,
+ feedback_index_offset);
+ }
+ __ Bind(&done);
+
+ return true;
+}
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
#ifdef V8_ENABLE_SPARKPLUG_PLUS
#define TYPED_COMPARE_CASE(type, name) \
case CompareOperationFeedback::Type::k##type: \
@@ -1904,9 +2061,17 @@ void BaselineCompiler::VisitConstructForwardAllArgs() {
using Feedback = CompareOperationFeedback; \
auto feedback_index_offset = \
iterator().GetEmbeddedFeedbackOffset(kEmbeddedFeedbackOperandIndex); \
+ auto feedback_type = \
+ Feedback::DecodeTypeIndex(static_cast<Feedback::TypeIndex>( \
+ EmbeddedFeedback(kEmbeddedFeedbackOperandIndex))); \
+ if (TryEmitInlineSmiCompare<Operation::k##Name, \
+ Builtin::k##Name##_SignedSmall_Baseline, \
+ Builtin::k##Name##_Generic_Baseline>( \
+ feedback_type, feedback_index_offset)) { \
+ return; \
+ } \
if (allow_sparkplug_plus_) { \
- switch (Feedback::DecodeTypeIndex(static_cast<Feedback::TypeIndex>( \
- EmbeddedFeedback(kEmbeddedFeedbackOperandIndex)))) { \
+ switch (feedback_type) { \
TypedStubList(TYPED_COMPARE_CASE, Name) default \
: CallBuiltin<Builtin::k##Name##_Generic_Baseline>( \
RegisterOperand(0), kInterpreterAccumulatorRegister, \
diff --git a/deps/v8/src/baseline/baseline-compiler.h b/deps/v8/src/baseline/baseline-compiler.h
index 60b862f63dc..724996805a5 100644
--- a/deps/v8/src/baseline/baseline-compiler.h
+++ b/deps/v8/src/baseline/baseline-compiler.h
@@ -11,6 +11,7 @@
#include "src/base/threaded-list.h"
#include "src/base/vlq.h"
#include "src/baseline/baseline-assembler.h"
+#include "src/common/operation.h"
#include "src/execution/local-isolate.h"
#include "src/handles/handles.h"
#include "src/interpreter/bytecode-array-iterator.h"
@@ -138,6 +139,24 @@ class BaselineCompiler {
void SelectBooleanConstant(
Register output, std::function<void(Label*, Label::Distance)> jump_func);
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+ // Emits an inlined Smi compare for |kOperation|, followed by a slow-path
+ // call to |kSmiStub|. Returns false without emitting anything when inlining
+ // is disabled or when the compile-time embedded feedback hint is not exactly
+ // kSignedSmall.
+ template <Operation kOperation, Builtin kSmiBuiltin, Builtin kGenericBuiltin>
+ bool TryEmitInlineSmiCompare(CompareOperationFeedback::Type feedback_type,
+ int feedback_index_offset);
+
+ // Emits an inlined Smi Inc/Dec for |kOperation|, followed by a slow-path
+ // call to |kSmiStub|. Returns false without emitting anything when inlining
+ // is disabled or when the compile-time embedded feedback hint is not exactly
+ // kSignedSmall.
+ template <Operation kOperation, Builtin kSmiBuiltin, Builtin kGenericBuiltin>
+ bool TryEmitInlineSmiUnary(BinaryOperationFeedback::Type feedback_type,
+ int feedback_index_offset);
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
// Jumps based on calling ToBoolean on kInterpreterAccumulatorRegister.
void JumpIfToBoolean(bool do_jump_if_true, Label* label,
Label::Distance distance = Label::kFar);
diff --git a/deps/v8/src/baseline/loong64/baseline-assembler-loong64-inl.h b/deps/v8/src/baseline/loong64/baseline-assembler-loong64-inl.h
index f2260abc26d..3398e47e6b4 100644
--- a/deps/v8/src/baseline/loong64/baseline-assembler-loong64-inl.h
+++ b/deps/v8/src/baseline/loong64/baseline-assembler-loong64-inl.h
@@ -179,6 +179,41 @@ void BaselineAssembler::JumpIfTagged(Condition cc, MemOperand operand,
__ CompareTaggedAndBranch(target, cc, scratch, Operand(value));
}
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+void BaselineAssembler::JumpIfNotBothSmi(Register lhs, Register rhs,
+ Label* target, Label::Distance) {
+ ScratchRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ __ Or(scratch, lhs, rhs);
+ __ JumpIfNotSmi(scratch, target);
+}
+
+void BaselineAssembler::JumpIfTagged(Condition cc, Register lhs, Register rhs,
+ Label* target, Label::Distance) {
+ __ CompareTaggedAndBranch(target, cc, lhs, Operand(rhs));
+}
+
+void BaselineAssembler::SmiAddConstantAndJumpIfOverflow(Register value,
+ int constant,
+ Label* overflow,
+ Label::Distance) {
+ DCHECK(Smi::IsValid(constant));
+ ScratchRegisterScope temps(this);
+ Register scratch1 = temps.AcquireScratch();
+ Register scratch2 = temps.AcquireScratch();
+ if (SmiValuesAre31Bits()) {
+ __ slli_w(scratch1, value, 0);
+ __ Add_w(scratch2, scratch1, Operand(Smi::FromInt(constant)));
+ __ Branch(overflow, constant > 0 ? lt : gt, scratch2, Operand(scratch1));
+ __ Move(value, scratch2);
+ } else {
+ __ Add_d(scratch1, value, Operand(Smi::FromInt(constant)));
+ __ Branch(overflow, constant > 0 ? lt : gt, scratch1, Operand(value));
+ __ Move(value, scratch1);
+ }
+}
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
#ifdef V8_STATIC_ROOTS
void BaselineAssembler::JumpIfStaticRootToBoolean(
Register value, Label* true_target, Label::Distance true_distance,
diff --git a/deps/v8/src/baseline/x64/baseline-assembler-x64-inl.h b/deps/v8/src/baseline/x64/baseline-assembler-x64-inl.h
index 7e0deb1d3fc..ac3f109e7f2 100644
--- a/deps/v8/src/baseline/x64/baseline-assembler-x64-inl.h
+++ b/deps/v8/src/baseline/x64/baseline-assembler-x64-inl.h
@@ -180,6 +180,43 @@ void BaselineAssembler::JumpIfSmi(Condition cc, Register lhs, Register rhs,
__ j(cc, target, distance);
}
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+void BaselineAssembler::JumpIfNotBothSmi(Register lhs, Register rhs,
+ Label* target,
+ Label::Distance distance) {
+ ScratchRegisterScope temps(this);
+ Register tmp = temps.AcquireScratch();
+ __ movq(tmp, lhs);
+ __ orq(tmp, rhs);
+ __ JumpIfNotSmi(tmp, target, distance);
+}
+
+void BaselineAssembler::JumpIfTagged(Condition cc, Register lhs, Register rhs,
+ Label* target, Label::Distance distance) {
+ __ cmp_tagged(lhs, rhs);
+ __ j(cc, target, distance);
+}
+
+void BaselineAssembler::SmiAddConstantAndJumpIfOverflow(
+ Register value, int constant, Label* overflow, Label::Distance distance) {
+ DCHECK(Smi::IsValid(constant));
+ ScratchRegisterScope scope(this);
+ Register tmp = scope.AcquireScratch();
+ if (SmiValuesAre31Bits()) {
+ __ movl(tmp, value);
+ __ addl(tmp, Immediate(Smi::FromInt(constant)));
+ __ j(kOverflow, overflow, distance);
+ __ movsxlq(value, tmp);
+ } else {
+ DCHECK(SmiValuesAre32Bits());
+ __ Move(tmp, Smi::FromInt(constant));
+ __ addq(tmp, value);
+ __ j(kOverflow, overflow, distance);
+ __ movq(value, tmp);
+ }
+}
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
void BaselineAssembler::JumpIfImmediate(Condition cc, Register left, int right,
Label* target,
Label::Distance distance) {
@@ -234,7 +271,7 @@ void BaselineAssembler::JumpIfStaticRootToBoolean(
void BaselineAssembler::JumpIfByte(Condition cc, Register value, int32_t byte,
Label* target, Label::Distance distance) {
- __ cmpb(value, Immediate(byte));
+ __ Cmpb(value, byte);
__ j(cc, target, distance);
}
@@ -479,7 +516,7 @@ void BaselineAssembler::LdaContextSlotNoCell(Register context, uint32_t index,
if (COMPRESS_POINTERS_BOOL &&
compression_mode == CompressionMode::kForceDecompression) {
- __ addq(tagged.reg(), kPtrComprCageBaseRegister);
+ __ orq(tagged.reg(), kPtrComprCageBaseRegister);
}
}
}
@@ -499,7 +536,7 @@ void BaselineAssembler::StaContextSlotNoCell(Register context, Register value,
}
if (COMPRESS_POINTERS_BOOL) {
// Decompress tagged pointer.
- __ addq(tagged.reg(), kPtrComprCageBaseRegister);
+ __ orq(tagged.reg(), kPtrComprCageBaseRegister);
}
}
StoreTaggedFieldWithWriteBarrier(context, Context::OffsetOfElementAt(index),
diff --git a/deps/v8/src/bigint/bigint-inl.h b/deps/v8/src/bigint/bigint-inl.h
index ccc66a14a66..9cf5721a5fd 100644
--- a/deps/v8/src/bigint/bigint-inl.h
+++ b/deps/v8/src/bigint/bigint-inl.h
@@ -1023,7 +1023,60 @@ inline std::pair<bool, digit_t> ModuloSmall(RWDigits& R, Digits& A, Digits& B) {
return {false, 0};
}
+ALWAYS_INLINE digit_t Processor::CachedModFold(RWDigits& R, Digits& A,
+ digit_t c) {
+ Digits& B = GetCachedDivisor();
+ uint32_t n = B.len();
+ DCHECK(n >= 2);
+ DCHECK(n <= A.len() && A.len() <= 2 * n);
+ DCHECK(R.len() == n);
+
+ // Each column sums A[i] + A[n+i]*c + carry, which for digit base D is at
+ // most (D-1) + (D-1)^2 + (D-1) == D^2 - 1. It therefore fits in two digits
+ // and {carry} stays single-digit for any {c}, including ~digit_t{0}.
+ digit_t carry = 0;
+ for (uint32_t i = 0; i < n; ++i) {
+ digit_t high = 0;
+ // A is always at least n digits: the only caller is {BigIntModulusImpl},
+ // which returns early when |x| < |y|.
+ digit_t low = A[i];
+ if (n + i < A.len()) {
+ digit_t product_low = digit_mul(A[n + i], c, &high);
+ digit_t add_carry;
+ low = digit_add2(low, product_low, &add_carry);
+ high += add_carry;
+ }
+ digit_t sum_carry;
+ R[i] = digit_add2(low, carry, &sum_carry);
+ DCHECK(high <= ~digit_t{0} - sum_carry);
+ carry = high + sum_carry;
+ }
+
+ if (carry) {
+ digit_t product_high;
+ digit_t product_low = digit_mul(carry, c, &product_high);
+ R[0] = digit_add2(R[0], product_low, &carry);
+ carry += product_high;
+ for (uint32_t i = 1; i < n && carry; ++i) {
+ R[i] = digit_add2(R[i], carry, &carry);
+ }
+ }
+
+ while (carry || GreaterThanOrEqual(R, B)) {
+ carry -= InplaceSubAndReturnBorrow(R, B);
+ }
+
+ return R[n - 1];
+}
+
ALWAYS_INLINE digit_t Processor::CachedMod(RWDigits& R, Digits& A) {
+ digit_t c = GetCachedModFoldFactor();
+ if (c != 0) {
+ // A fold-armed divisor leaves {cached_inverse_} allocated but stale; this
+ // path never reads it.
+ return CachedModFold(R, A, c);
+ }
+
Digits& B = GetCachedDivisor();
Digits& inv = GetCachedInverse();
uint32_t n = B.len();
diff --git a/deps/v8/src/bigint/bigint-internal.cc b/deps/v8/src/bigint/bigint-internal.cc
index 5ad6b0686a4..601d49579d0 100644
--- a/deps/v8/src/bigint/bigint-internal.cc
+++ b/deps/v8/src/bigint/bigint-internal.cc
@@ -135,10 +135,45 @@ void ProcessorImpl::CachedMod_MakeInverse(Digits& B) {
// from concurrent mutation.
Digits& cached_B = GetCachedDivisor();
CHECK(cached_B.msd() != 0); // {B} must have been canonicalized.
- // We can't use {GetSmallScratch()} here, because {DivideSchoolbook} already
- // does that (usually). It's fine because we don't expect to call this
- // function very often.
- ScratchDigits A(n * 2, platform());
+
+ set_cached_mod_fold_factor(0);
+
+ // {CachedMod} relies on the "small scratch" having been allocated, so make
+ // sure that has happened regardless of {DivideSchoolbook}'s internal
+ // decisions, and of which of the two paths below we take.
+ GetSmallScratch();
+
+ // We can't use {GetSmallScratch()} for the working space below, because
+ // {DivideSchoolbook} already does that (usually). It's fine because we don't
+ // expect to call this function very often. One allocation serves both the
+ // fold check below and the inverse computation afterwards, which needs
+ // {n * 2} digits.
+ ScratchDigits scratch(n + 1 + 2 + n, platform());
+
+ {
+ // T := 1 << (n * kDigitBits), i.e. the smallest power of the digit base
+ // above the divisor. If T == q * B + C has a small q and a single-digit C,
+ // then C is the factor {CachedModFold} folds the dividend's high half by.
+ RWDigits T(scratch, 0, n + 1);
+ T.Clear();
+ T[n] = 1;
+
+ RWDigits Q(scratch, n + 1, 2);
+ RWDigits R(scratch, n + 3, n);
+ DivideSchoolbook(Q, R, T, cached_B);
+
+ Q.Normalize();
+ R.Normalize();
+ // Cap the quotient so the corrective while loop in {CachedModFold} doesn't
+ // have to subtract the divisor too many times.
+ constexpr digit_t kMaxFoldQuotient = 4;
+ if (Q.len() == 1 && Q[0] <= kMaxFoldQuotient && R.len() == 1) {
+ set_cached_mod_fold_factor(R[0]);
+ return;
+ }
+ }
+
+ RWDigits A(scratch, 0, n * 2);
// The idea is to set A = 1 << 2*n, and then compute Inv = A / B. However,
// having that lone "1" bit in A's top digit is inefficient and far-reaching:
// it requires us to make Inv bigger too. So we use a trick: first we
@@ -159,11 +194,6 @@ void ProcessorImpl::CachedMod_MakeInverse(Digits& B) {
// corrective loop in {CachedDiv}. But don't do it when there's a risk
// of overflowing {inv}.
if (Inv[0] != ~digit_t{0} || Inv.msd() != ~digit_t{0}) Add(Inv, 1);
-
- // {CachedMod} relies on the "small scratch" having been allocated, so
- // make sure that has happened regardless of {DivideSchoolbook}'s internal
- // decisions.
- GetSmallScratch();
}
void Processor::CachedMod_MakeInverse(Digits& B) {
diff --git a/deps/v8/src/bigint/bigint.h b/deps/v8/src/bigint/bigint.h
index 87e8c5a1a3d..80d6a5cfec1 100644
--- a/deps/v8/src/bigint/bigint.h
+++ b/deps/v8/src/bigint/bigint.h
@@ -403,6 +403,15 @@ class Processor {
RWDigits& AllocateCachedInverseFor(Digits& divisor);
+ // Crandall reduction, used by {CachedMod} when the cached divisor is close
+ // enough to a power of the digit base for {c} to be armed.
+ digit_t CachedModFold(RWDigits& R, Digits& A, digit_t c);
+
+ digit_t GetCachedModFoldFactor() { return cached_mod_fold_factor_; }
+ void set_cached_mod_fold_factor(digit_t factor) {
+ cached_mod_fold_factor_ = factor;
+ }
+
// TODO(jkummerow): Consider merging ProcessorImpl and Processor.
std::unique_ptr<Platform> platform_;
Status status_{Status::kOk};
@@ -415,6 +424,7 @@ class Processor {
RWDigits cached_inverse_{nullptr, 0};
uint32_t cached_inverse_allocated_length_{0};
int divisor_count_{0};
+ digit_t cached_mod_fold_factor_{0};
};
inline uint32_t AddResultLength(uint32_t x_length, uint32_t y_length) {
diff --git a/deps/v8/src/builtins/accessors.cc b/deps/v8/src/builtins/accessors.cc
index ec95489e5a2..313ac22137c 100644
--- a/deps/v8/src/builtins/accessors.cc
+++ b/deps/v8/src/builtins/accessors.cc
@@ -22,6 +22,7 @@
#include "src/objects/js-function.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/module-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-details.h"
#include "src/objects/prototype.h"
@@ -635,6 +636,15 @@ class FrameFunctionIterator {
if (frame_iterator_.done()) return;
JavaScriptFrame* frame = frame_iterator_.frame();
summaries_ = frame->Summarize();
+#if V8_ENABLE_WEBASSEMBLY
+ if (summaries_.size() == 0) {
+ // We skip method wrappers from summaries and stack traces, because
+ // they are not interesting.
+ DCHECK_EQ(frame->function()->shared()->builtin_id(),
+ Builtin::kWasmMethodWrapper);
+ return;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
inlined_frame_index_ = static_cast<int>(summaries_.size());
DCHECK_LT(0, inlined_frame_index_);
}
diff --git a/deps/v8/src/builtins/arm/builtins-arm.cc b/deps/v8/src/builtins/arm/builtins-arm.cc
index 93648514cbd..7fdedb6e004 100644
--- a/deps/v8/src/builtins/arm/builtins-arm.cc
+++ b/deps/v8/src/builtins/arm/builtins-arm.cc
@@ -3025,6 +3025,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register return_reg,
Register return_value, Register context, Register tmp1,
Register tmp2, Register tmp3) {
+ DCHECK(!AreAliased(tmp1, tmp2, tmp3));
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3037,7 +3038,10 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {return_reg, return_value, context, parent});
+ __ ldr(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false, tmp3);
+ __ str(tmp1,
+ MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void RestoreParentSuspender(MacroAssembler* masm, Register tmp1) {
@@ -3280,6 +3284,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ cmp(kJavaScriptCallArgCountRegister, Operand(JSParameterCount(1)));
+ __ Check(eq, AbortReason::kJSSignatureMismatch);
+
auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
__ EnterFrame(StackFrame::WASM_JSPI);
@@ -3739,6 +3746,10 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, RegisterAllocator& regs,
FREE_REG(promise);
FREE_REG(return_value);
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ ldr(tmp,
+ MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
+ __ bx(tmp);
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -3962,6 +3973,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, regs, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
@@ -5076,7 +5088,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERNAL);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ ldr(r2, FieldMemOperand(r1, offsetof(JSFunction, shared_function_info_)));
__ ldrh(r2, FieldMemOperand(
r2, offsetof(SharedFunctionInfo, formal_parameter_count_)));
diff --git a/deps/v8/src/builtins/arm64/builtins-arm64.cc b/deps/v8/src/builtins/arm64/builtins-arm64.cc
index 26f396576fd..083e3f09db8 100644
--- a/deps/v8/src/builtins/arm64/builtins-arm64.cc
+++ b/deps/v8/src/builtins/arm64/builtins-arm64.cc
@@ -3607,6 +3607,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register return_reg,
Register return_value, Register context, Register tmp1,
Register tmp2, Register tmp3) {
+ DCHECK(!AreAliased(tmp1, tmp2, tmp3));
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3619,7 +3620,10 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {return_reg, return_value, context, parent});
+ __ Ldr(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false, tmp3);
+ __ Str(tmp1,
+ MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void RestoreParentSuspender(MacroAssembler* masm, Register tmp1) {
@@ -3858,6 +3862,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ Cmp(kJavaScriptCallArgCountRegister, JSParameterCount(1));
+ __ Check(eq, AbortReason::kJSSignatureMismatch);
+
auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
__ EnterFrame(StackFrame::WASM_JSPI);
@@ -4301,6 +4308,10 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, RegisterAllocator& regs,
FREE_REG(promise);
FREE_REG(return_value);
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ Ldr(tmp,
+ MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
+ __ Br(tmp);
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -4548,6 +4559,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, regs, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ Bind(&suspend, BranchTargetIdentifier::kBtiJump);
@@ -5768,7 +5780,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ InvokeFunction(x1, x0, InvokeType::kJump, ArgumentAdaptionMode::kAdapt);
}
diff --git a/deps/v8/src/builtins/array-from.tq b/deps/v8/src/builtins/array-from.tq
index 9e1cbe9229b..b8ceeaf41a7 100644
--- a/deps/v8/src/builtins/array-from.tq
+++ b/deps/v8/src/builtins/array-from.tq
@@ -66,7 +66,7 @@ transitioning javascript builtin ArrayFrom(
const fastIteratorResultMap = GetIteratorResultMap();
// d. Let k be 0.
- let k: Smi = 0;
+ let k: Number = 0;
// e. Repeat,
while (true) {
// i. If k ≥ 2^53-1, then
@@ -164,7 +164,7 @@ transitioning javascript builtin ArrayFrom(
}
// 11. Let k be 0.
- let k: Smi = 0;
+ let k: Number = 0;
// 12. Repeat, while k < len
while (k < len) {
// a. Let Pk be ! ToString(k).
diff --git a/deps/v8/src/builtins/array-join.tq b/deps/v8/src/builtins/array-join.tq
index c9ec15e06ea..324013960e3 100644
--- a/deps/v8/src/builtins/array-join.tq
+++ b/deps/v8/src/builtins/array-join.tq
@@ -351,19 +351,20 @@ 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, lengthNumber: Number): 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>(kMaxFastArrayLength));
- static_assert(Convert<uintptr>(kMaxFastArrayLength) < kSmiMaxValue);
+ 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>(kMaxFastArrayLength) - 1) <=
+ (Convert<uintptr>(kFixedArrayMaxLength) - 1) <=
Convert<uintptr>(kStringMaxLength));
const separatorLength: intptr = sep.length_intptr;
@@ -428,7 +429,6 @@ transitioning macro FastArrayJoin(
}
} else {
- dcheck(IsSmiElementsKind(kind));
const fixedArray: FixedArray = UnsafeCast<FixedArray>(elements);
const element: Object = fixedArray.objects[k++];
if constexpr (IsHoleyElementsKind(kind)) {
@@ -436,8 +436,37 @@ transitioning macro FastArrayJoin(
continue;
}
}
- const smiValue = UnsafeCast<Smi>(element);
- next = SmiToString(smiValue);
+ if constexpr (IsSmiElementsKind(kind)) {
+ const smiValue = UnsafeCast<Smi>(element);
+ next = SmiToString(smiValue);
+ } else {
+ typeswitch (element) {
+ case (str: String): {
+ if (str == kEmptyString) {
+ continue;
+ }
+ next = str;
+ }
+ case (smi: Smi): {
+ next = SmiToString(smi);
+ }
+ case (heapNum: HeapNumber): {
+ next = NumberToString(heapNum);
+ }
+ case (Undefined): {
+ continue;
+ }
+ case (Null): {
+ continue;
+ }
+ case (b: Boolean): {
+ next = b.to_string;
+ }
+ case (Object): {
+ goto Bailout;
+ }
+ }
+ }
}
// d. Set R to the string-concatenation of R and next.
@@ -852,30 +881,44 @@ transitioning builtin ArrayPrototypeJoinImpl(
dcheck(len <= kMaxArrayLength);
try {
- const castResult = CastFastJSArrayForRead(o) otherwise NotFastJSArray;
+ const castResult = CastFastJSArrayForRead(o) otherwise Fallback;
const fastO = castResult.object;
const elementsKind = castResult.elementsKind;
if (IsFastSmiElementsKind(elementsKind)) {
if (IsHoleyFastElementsKind(elementsKind)) {
return FastArrayJoin(
- ElementsKind::HOLEY_SMI_ELEMENTS, fastO, separator, len);
+ ElementsKind::HOLEY_SMI_ELEMENTS, fastO, separator, len)
+ otherwise Fallback;
} else {
return FastArrayJoin(
- ElementsKind::PACKED_SMI_ELEMENTS, fastO, separator, len);
+ ElementsKind::PACKED_SMI_ELEMENTS, fastO, separator, len)
+ otherwise Fallback;
}
} else if (IsDoubleElementsKind(elementsKind)) {
if (IsHoleyFastElementsKind(elementsKind)) {
return FastArrayJoin(
- ElementsKind::HOLEY_DOUBLE_ELEMENTS, fastO, separator, len);
+ ElementsKind::HOLEY_DOUBLE_ELEMENTS, fastO, separator, len)
+ otherwise Fallback;
+ } else {
+ return FastArrayJoin(
+ ElementsKind::PACKED_DOUBLE_ELEMENTS, fastO, separator, len)
+ otherwise Fallback;
+ }
+ } else if (IsFastElementsKind(elementsKind)) {
+ if (IsHoleyFastElementsKind(elementsKind)) {
+ return FastArrayJoin(
+ ElementsKind::HOLEY_ELEMENTS, fastO, separator, len)
+ otherwise Fallback;
} else {
return FastArrayJoin(
- ElementsKind::PACKED_DOUBLE_ELEMENTS, fastO, separator, len);
+ ElementsKind::PACKED_ELEMENTS, fastO, separator, len)
+ otherwise Fallback;
}
}
// Fall through.
- } label NotFastJSArray {
+ } label Fallback {
// Fall through.
}
diff --git a/deps/v8/src/builtins/array-lastindexof.tq b/deps/v8/src/builtins/array-lastindexof.tq
index bd718039423..ac8bd9e8374 100644
--- a/deps/v8/src/builtins/array-lastindexof.tq
+++ b/deps/v8/src/builtins/array-lastindexof.tq
@@ -3,66 +3,133 @@
// found in the LICENSE file.
namespace array {
-macro LoadWithHoleCheck<Elements : type extends FixedArrayBase>(
- elements: FixedArrayBase, index: Smi): JSAny
- labels IfHole;
-
-LoadWithHoleCheck<FixedArray>(
- implicit context: Context)(elements: FixedArrayBase, index: Smi): JSAny
- labels IfHole {
- const elements: FixedArray = UnsafeCast<FixedArray>(elements);
- const element: Object = elements.objects[index];
- if (element == TheHole) goto IfHole;
- return UnsafeCast<JSAny>(element);
+macro ClampLastIndexOfFrom(from: Smi, elementsLen: Smi): Smi {
+ // Bug(898785): Due to side-effects in the evaluation of `fromIndex`
+ // the {from} can be out-of-bounds here, so we need to clamp {k} to
+ // the {elements} length. We might be reading holes / hole NaNs still
+ // due to that, but those will be ignored below.
+ if (from >= elementsLen) {
+ return elementsLen - 1;
+ }
+ return from;
}
-LoadWithHoleCheck<FixedDoubleArray>(
- implicit context: Context)(elements: FixedArrayBase, index: Smi): JSAny
- labels IfHole {
- const elements: FixedDoubleArray = UnsafeCast<FixedDoubleArray>(elements);
- try {
- const element: float64 =
- elements.values[index].Value() otherwise IfUndefined,
- IfHole;
- return AllocateHeapNumberWithValue(element);
- } label IfUndefined {
- return Undefined;
+macro LastIndexOfNumberInFixedArray(
+ elements: FixedArray, from: Smi, search: Number): Smi {
+ const searchNum: float64 = Convert<float64>(search);
+ if (Float64IsNaN(searchNum)) return -1;
+
+ let k: Smi = from;
+ while (k >= 0) {
+ const element = UnsafeCast<(JSAny | TheHole)>(elements.objects[k]);
+ if (TaggedEqual(element, search)) return k;
+ typeswitch (element) {
+ case (n: Number): {
+ if (searchNum == Convert<float64>(n)) return k;
+ }
+ case (JSAny | TheHole): {
+ // Fallthrough.
+ }
+ }
+ --k;
}
+ return -1;
}
-macro FastArrayLastIndexOf<Elements : type extends FixedArrayBase>(
- context: Context, array: JSArray, from: Smi, searchElement: JSAny): Smi {
- const elements: FixedArrayBase = array.elements;
- const elementsLen: Smi = Convert<Smi>(elements.length_intptr);
+macro LastIndexOfAnyInFixedArray(
+ implicit context: Context)(elements: FixedArray, from: Smi,
+ searchElement: JSAny): Smi {
let k: Smi = from;
+ while (k >= 0) {
+ const element = UnsafeCast<(JSAny | TheHole)>(elements.objects[k]);
+ if (TaggedEqual(searchElement, element)) return k;
+ typeswitch (element) {
+ case (e: JSAny): {
+ if (StrictEqual(searchElement, e) == True) return k;
+ }
+ case (TheHole): {
+ // Fallthrough.
+ }
+ }
+ --k;
+ }
+ return -1;
+}
- // Bug(898785): Due to side-effects in the evaluation of `fromIndex`
- // the {from} can be out-of-bounds here, so we need to clamp {k} to
- // the {elements} length. We might be reading holes / hole NaNs still
- // due to that, but those will be ignored below.
- if (k >= elementsLen) {
- k = elementsLen - 1;
+macro FastArrayLastIndexOfFixedArray(
+ context: Context, array: FastJSArrayForRead, from: Smi,
+ searchElement: JSAny): Smi {
+ const elements: FixedArray = UnsafeCast<FixedArray>(array.elements);
+ const elementsLen: Smi = Convert<Smi>(elements.length_intptr);
+ const k: Smi = ClampLastIndexOfFrom(from, elementsLen);
+
+ typeswitch (searchElement) {
+ case (search: Number): {
+ return LastIndexOfNumberInFixedArray(elements, k, search);
+ }
+ case (JSAny): {
+ return LastIndexOfAnyInFixedArray(elements, k, searchElement);
+ }
}
+}
+macro LastIndexOfDoubleValue(
+ elements: FixedDoubleArray, from: Smi, searchNum: float64): Smi {
+ let k: Smi = from;
while (k >= 0) {
try {
- const element: JSAny = LoadWithHoleCheck<Elements>(elements, k)
- otherwise Hole;
-
- const same: Boolean = StrictEqual(searchElement, element);
- if (same == True) {
- dcheck(Is<FastJSArray>(array));
- return k;
- }
- } label Hole {} // Do nothing for holes.
-
+ const element: float64 = elements.values[k].Value() otherwise IfUndefined,
+ IfHole;
+ if (element == searchNum) return k;
+ } label IfUndefined {
+ // Fallthrough.
+ } label IfHole {
+ // Fallthrough.
+ }
--k;
}
+ return -1;
+}
- dcheck(Is<FastJSArray>(array));
+macro LastIndexOfUndefinedInDoubles(elements: FixedDoubleArray, from: Smi):
+ Smi {
+ let k: Smi = from;
+ while (k >= 0) {
+ try {
+ elements.values[k].Value() otherwise IfUndefined, IfHole;
+ } label IfUndefined {
+ return k;
+ } label IfHole {
+ // Fallthrough.
+ }
+ --k;
+ }
return -1;
}
+macro FastArrayLastIndexOfDoubles(
+ context: Context, array: FastJSArrayForRead, from: Smi,
+ searchElement: JSAny): Smi {
+ const elements: FixedDoubleArray =
+ UnsafeCast<FixedDoubleArray>(array.elements);
+ const elementsLen: Smi = Convert<Smi>(elements.length_intptr);
+ const k: Smi = ClampLastIndexOfFrom(from, elementsLen);
+
+ typeswitch (searchElement) {
+ case (search: Number): {
+ const searchNum: float64 = Convert<float64>(search);
+ if (Float64IsNaN(searchNum)) return -1;
+ return LastIndexOfDoubleValue(elements, k, searchNum);
+ }
+ case (Undefined): {
+ return LastIndexOfUndefinedInDoubles(elements, k);
+ }
+ case (JSAny): {
+ return -1;
+ }
+ }
+}
+
transitioning macro GetFromIndex(
context: Context, length: Number, arguments: Arguments): Number {
// 4. If fromIndex is present, let n be ? ToInteger(fromIndex);
@@ -87,19 +154,19 @@ macro TryFastArrayLastIndexOf(
context: Context, receiver: JSReceiver, searchElement: JSAny,
from: Number): JSAny
labels Slow {
- const array: FastJSArray = Cast<FastJSArray>(receiver) otherwise Slow;
+ const array: FastJSArrayForRead = Cast<FastJSArrayForRead>(receiver)
+ otherwise Slow;
const length: Smi = array.length;
if (length == 0) return SmiConstant(-1);
const fromSmi: Smi = Cast<Smi>(from) otherwise Slow;
const kind: ElementsKind = array.map.elements_kind;
- if (IsFastSmiOrTaggedElementsKind(kind)) {
- return FastArrayLastIndexOf<FixedArray>(
- context, array, fromSmi, searchElement);
+ if (IsDoubleElementsKind(kind)) {
+ return FastArrayLastIndexOfDoubles(context, array, fromSmi, searchElement);
}
- dcheck(IsDoubleElementsKind(kind));
- return FastArrayLastIndexOf<FixedDoubleArray>(
- context, array, fromSmi, searchElement);
+ dcheck(IsElementsKindLessThanOrEqual(
+ kind, ElementsKind::LAST_ANY_NONEXTENSIBLE_ELEMENTS_KIND));
+ return FastArrayLastIndexOfFixedArray(context, array, fromSmi, searchElement);
}
transitioning macro GenericArrayLastIndexOf(
diff --git a/deps/v8/src/builtins/base.tq b/deps/v8/src/builtins/base.tq
index bdcd122eff7..e3a860d0022 100644
--- a/deps/v8/src/builtins/base.tq
+++ b/deps/v8/src/builtins/base.tq
@@ -263,14 +263,20 @@ extern class JSSetIteratorPrototype extends JSInternalPrototypeBase
extern class JSStringIteratorPrototype extends JSInternalPrototypeBase
generates 'JSObject';
+// OrderedHashMap/Set and OrderedNameDictionary are OrderedHashTable
+// instances. OrderedHashTable extends FixedArray directly (a separate
+// family from HashTable, with a different layout) and is a class template
+// with no instance type of its own, so FixedArray is their nearest
+// instance-typed base.
+extern class OrderedHashMap extends FixedArray;
+extern class OrderedHashSet extends FixedArray;
+extern class OrderedNameDictionary extends FixedArray;
+
// The HashTable inheritance hierarchy doesn't actually look like this in C++
// because it uses some class templates that we can't yet (and may never)
// express in Torque, but this is the expected organization of instance types.
@doNotGenerateCast
extern class HashTable extends FixedArray generates 'FixedArray';
-extern class OrderedHashMap extends HashTable;
-extern class OrderedHashSet extends HashTable;
-extern class OrderedNameDictionary extends HashTable;
extern class NameToIndexHashTable extends HashTable;
extern class RegisteredSymbolTable extends HashTable;
extern class NameDictionary extends HashTable;
@@ -1506,6 +1512,7 @@ extern macro IsTypedArraySpeciesProtectorCellInvalid(): bool;
extern macro IsPromiseSpeciesProtectorCellInvalid(): bool;
extern macro IsMockArrayBufferAllocatorFlag(): bool;
extern macro HasBuiltinSubclassingFlag(): bool;
+extern macro HasJsPr3883Flag(): bool;
extern macro IsPrototypeTypedArrayPrototype(
implicit context: Context)(Map): bool;
extern macro IsSetIteratorProtectorCellInvalid(): bool;
@@ -1519,6 +1526,7 @@ extern operator '.elements_kind' macro LoadElementsKind(JSTypedArray):
ElementsKind;
extern operator '.length' macro LoadFastJSArrayLength(FastJSArray): Smi;
+extern operator '.length' macro LoadFastJSArrayLength(FastJSArrayForRead): Smi;
operator '.length=' macro StoreFastJSArrayLength(
array: FastJSArray, length: Smi): void {
const array: JSArray = array;
diff --git a/deps/v8/src/builtins/builtins-array.cc b/deps/v8/src/builtins/builtins-array.cc
index dc11d10c1c3..ac39dac4cf4 100644
--- a/deps/v8/src/builtins/builtins-array.cc
+++ b/deps/v8/src/builtins/builtins-array.cc
@@ -26,6 +26,7 @@
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-shared-array.h"
#include "src/objects/lookup.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/prototype.h"
#include "src/objects/smi.h"
diff --git a/deps/v8/src/builtins/builtins-arraybuffer.cc b/deps/v8/src/builtins/builtins-arraybuffer.cc
index 9aefc23b1c3..f3a6e701fa1 100644
--- a/deps/v8/src/builtins/builtins-arraybuffer.cc
+++ b/deps/v8/src/builtins/builtins-arraybuffer.cc
@@ -10,6 +10,7 @@
#include "src/logging/counters.h"
#include "src/numbers/conversions.h"
#include "src/objects/js-array-buffer-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
diff --git a/deps/v8/src/builtins/builtins-atomics-synchronization.cc b/deps/v8/src/builtins/builtins-atomics-synchronization.cc
index 2056c5f22b8..d60667d9507 100644
--- a/deps/v8/src/builtins/builtins-atomics-synchronization.cc
+++ b/deps/v8/src/builtins/builtins-atomics-synchronization.cc
@@ -4,6 +4,7 @@
#include "src/builtins/builtins-utils-inl.h"
#include "src/objects/js-atomics-synchronization-inl.h"
+#include "src/objects/object-conversions-inl.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/builtins/builtins-bigint.cc b/deps/v8/src/builtins/builtins-bigint.cc
index 36cc472d357..8a8c037fe09 100644
--- a/deps/v8/src/builtins/builtins-bigint.cc
+++ b/deps/v8/src/builtins/builtins-bigint.cc
@@ -6,6 +6,7 @@
#include "src/builtins/builtins.h"
#include "src/logging/counters.h"
#include "src/numbers/conversions.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/intl-objects.h"
diff --git a/deps/v8/src/builtins/builtins-callsite.cc b/deps/v8/src/builtins/builtins-callsite.cc
index 9ee452a00b1..dfb280ca0b5 100644
--- a/deps/v8/src/builtins/builtins-callsite.cc
+++ b/deps/v8/src/builtins/builtins-callsite.cc
@@ -4,6 +4,7 @@
#include "src/builtins/builtins-utils-inl.h"
#include "src/builtins/builtins.h"
+#include "src/execution/isolate-inl.h"
#include "src/logging/counters.h"
#include "src/objects/call-site-info-inl.h"
#include "src/objects/contexts-inl.h"
@@ -44,6 +45,29 @@ namespace internal {
namespace {
+bool IsSecurityTokenCompatible(Isolate* isolate,
+ DirectHandle<CallSiteInfo> frame) {
+ Tagged<NativeContext> current_native_context = isolate->raw_native_context();
+
+ auto is_compatible = [&](Tagged<Object> obj) {
+ if (!IsJSReceiver(obj)) return true;
+ std::optional<Tagged<NativeContext>> maybe_creation_context =
+ Cast<JSReceiver>(obj)->GetCreationContext();
+ if (maybe_creation_context.has_value()) {
+ Tagged<NativeContext> cc = maybe_creation_context.value();
+ if (!cc->HasSameSecurityTokenAs(current_native_context)) {
+ return false;
+ }
+ } else {
+ return false;
+ }
+ return true;
+ };
+
+ return is_compatible(frame->function()) &&
+ is_compatible(frame->receiver_or_instance());
+}
+
Tagged<Object> PositiveNumberOrNull(int value, Isolate* isolate) {
if (value > 0) return *isolate->factory()->NewNumberFromInt(value);
return ReadOnlyRoots(isolate).null_value();
@@ -54,12 +78,18 @@ Tagged<Object> PositiveNumberOrNull(int value, Isolate* isolate) {
BUILTIN(CallSitePrototypeGetColumnNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getColumnNumber");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return PositiveNumberOrNull(CallSiteInfo::GetColumnNumber(frame), isolate);
}
BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getEnclosingColumnNumber");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return PositiveNumberOrNull(CallSiteInfo::GetEnclosingColumnNumber(frame),
isolate);
}
@@ -67,6 +97,9 @@ BUILTIN(CallSitePrototypeGetEnclosingColumnNumber) {
BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getEnclosingLineNumber");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return PositiveNumberOrNull(CallSiteInfo::GetEnclosingLineNumber(frame),
isolate);
}
@@ -74,12 +107,18 @@ BUILTIN(CallSitePrototypeGetEnclosingLineNumber) {
BUILTIN(CallSitePrototypeGetEvalOrigin) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getEvalOrigin");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return *CallSiteInfo::GetEvalOrigin(frame);
}
BUILTIN(CallSitePrototypeGetFileName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getFileName");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return frame->GetScriptName();
}
@@ -87,6 +126,9 @@ BUILTIN(CallSitePrototypeGetFunction) {
static const char method_name[] = "getFunction";
HandleScope scope(isolate);
CHECK_CALLSITE(frame, method_name);
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).undefined_value();
+ }
Tagged<Object> func_obj = frame->function();
if (frame->IsStrict() ||
@@ -121,30 +163,57 @@ BUILTIN(CallSitePrototypeGetFunction) {
BUILTIN(CallSitePrototypeGetFunctionName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getFunctionName");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
+
+ Tagged<Object> func_obj = frame->function();
+ if (IsJSReceiver(func_obj)) {
+ // Get function's creation context. Return null if not available.
+ Tagged<JSReceiver> function_obj = Cast<JSReceiver>(func_obj);
+ std::optional<Tagged<NativeContext>> maybe_creation_context =
+ function_obj->GetCreationContext();
+ if (!maybe_creation_context.has_value()) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
+ }
+
return *CallSiteInfo::GetFunctionName(frame);
}
BUILTIN(CallSitePrototypeGetLineNumber) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getLineNumber");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return PositiveNumberOrNull(CallSiteInfo::GetLineNumber(frame), isolate);
}
BUILTIN(CallSitePrototypeGetMethodName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getMethodName");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return *CallSiteInfo::GetMethodName(frame);
}
BUILTIN(CallSitePrototypeGetPosition) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getPosition");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return Smi::FromInt(CallSiteInfo::GetSourcePosition(frame));
}
BUILTIN(CallSitePrototypeGetPromiseIndex) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getPromiseIndex");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
if (!frame->IsPromiseAll() && !frame->IsPromiseAny() &&
!frame->IsPromiseAllSettled()) {
return ReadOnlyRoots(isolate).null_value();
@@ -155,12 +224,18 @@ BUILTIN(CallSitePrototypeGetPromiseIndex) {
BUILTIN(CallSitePrototypeGetScriptHash) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getScriptHash");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return *CallSiteInfo::GetScriptHash(frame);
}
BUILTIN(CallSitePrototypeGetScriptNameOrSourceURL) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getScriptNameOrSourceUrl");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return frame->GetScriptNameOrSourceURL();
}
@@ -168,6 +243,9 @@ BUILTIN(CallSitePrototypeGetThis) {
static const char method_name[] = "getThis";
HandleScope scope(isolate);
CHECK_CALLSITE(frame, method_name);
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).undefined_value();
+ }
if (frame->IsStrict()) return ReadOnlyRoots(isolate).undefined_value();
isolate->CountUsage(v8::Isolate::kCallSiteAPIGetThisSloppyCall);
@@ -197,48 +275,72 @@ BUILTIN(CallSitePrototypeGetThis) {
BUILTIN(CallSitePrototypeGetTypeName) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "getTypeName");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return *CallSiteInfo::GetTypeName(frame);
}
BUILTIN(CallSitePrototypeIsAsync) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isAsync");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return ReadOnlyRoots(isolate).boolean_value(frame->IsAsync());
}
BUILTIN(CallSitePrototypeIsConstructor) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isConstructor");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return ReadOnlyRoots(isolate).boolean_value(frame->IsConstructor());
}
BUILTIN(CallSitePrototypeIsEval) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isEval");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return ReadOnlyRoots(isolate).boolean_value(frame->IsEval());
}
BUILTIN(CallSitePrototypeIsNative) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isNative");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return ReadOnlyRoots(isolate).boolean_value(frame->IsNative());
}
BUILTIN(CallSitePrototypeIsPromiseAll) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isPromiseAll");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return ReadOnlyRoots(isolate).boolean_value(frame->IsPromiseAll());
}
BUILTIN(CallSitePrototypeIsToplevel) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "isToplevel");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return ReadOnlyRoots(isolate).null_value();
+ }
return ReadOnlyRoots(isolate).boolean_value(frame->IsToplevel());
}
BUILTIN(CallSitePrototypeToString) {
HandleScope scope(isolate);
CHECK_CALLSITE(frame, "toString");
+ if (!IsSecurityTokenCompatible(isolate, frame)) {
+ return *isolate->factory()->empty_string();
+ }
RETURN_RESULT_OR_FAILURE(isolate, SerializeCallSiteInfo(isolate, frame));
}
diff --git a/deps/v8/src/builtins/builtins-dataview.cc b/deps/v8/src/builtins/builtins-dataview.cc
index 0eea7f3d78c..e7781790d10 100644
--- a/deps/v8/src/builtins/builtins-dataview.cc
+++ b/deps/v8/src/builtins/builtins-dataview.cc
@@ -9,6 +9,7 @@
#include "src/logging/counters.h"
#include "src/numbers/conversions.h"
#include "src/objects/js-array-buffer-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
diff --git a/deps/v8/src/builtins/builtins-date.cc b/deps/v8/src/builtins/builtins-date.cc
index 191d34a9265..ad5c62f6383 100644
--- a/deps/v8/src/builtins/builtins-date.cc
+++ b/deps/v8/src/builtins/builtins-date.cc
@@ -17,6 +17,7 @@
#ifdef V8_TEMPORAL_SUPPORT
#include "src/objects/js-temporal-objects-inl.h"
#endif // V8_TEMPORAL_SUPPORT
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/strings/string-stream.h"
diff --git a/deps/v8/src/builtins/builtins-definitions.h b/deps/v8/src/builtins/builtins-definitions.h
index 4918024d311..cdf10357995 100644
--- a/deps/v8/src/builtins/builtins-definitions.h
+++ b/deps/v8/src/builtins/builtins-definitions.h
@@ -5,13 +5,23 @@
#ifndef V8_BUILTINS_BUILTINS_DEFINITIONS_H_
#define V8_BUILTINS_BUILTINS_DEFINITIONS_H_
+#ifdef V8_METAGEN_GENERATION_PASS
+// During the metagen libclang harvest the generated headers may not
+// exist yet: the harvest runs before (and independently of) the
+// generators, so it must parse without them. Both lists only feed
+// BUILTIN_LIST's expansion downstream; defining them to empty keeps
+// the Builtin enum well-formed, minus entries the harvest never
+// references by name.
+#define BUILTIN_LIST_BYTECODE_HANDLERS(V_TSA, V)
+#define BUILTIN_LIST_FROM_TORQUE(CPP, TFJ_TSA, TFJ, TFC_TSA, TFC, TFS, TFH, ASM)
+#define TORQUE_FUNCTION_POINTER_TYPE_TO_BUILTIN_MAP(V)
+#else
#include "builtins-generated/bytecodes-builtins-list.h"
+#include "torque-generated/builtin-definitions.h"
+#endif
#include "src/base/strong-alias.h"
#include "src/common/globals.h"
-// include generated header
-#include "torque-generated/builtin-definitions.h"
-
namespace v8 {
namespace internal {
@@ -169,6 +179,18 @@ constexpr int kGearboxGenericBuiltinIdOffset = -2;
#define GENERATE_BUILTIN_TYPED_BITWISE_HANDLER(V, OP) \
TYPED_BINOP_HANDLER_HELPER(V, OP, None) \
TYPED_BINOP_HANDLER_HELPER(V, OP, SignedSmall)
+
+#define TYPED_UNOP_HANDLER_HELPER(V, OPERATION, TYPE) \
+ V(OPERATION##_##TYPE##_Baseline, UnaryOp_WithEmbeddedFeedbackOffset)
+
+#define GENERATE_BUILTIN_TYPED_UNOP_HANDLER(V, OP) \
+ TYPED_UNOP_HANDLER_HELPER(V, OP, None) \
+ TYPED_UNOP_HANDLER_HELPER(V, OP, SignedSmall)
+
+#define GENERATE_BUILTIN_TYPED_NEGATE_HANDLER(V) \
+ TYPED_UNOP_HANDLER_HELPER(V, Negate, None) \
+ TYPED_UNOP_HANDLER_HELPER(V, Negate, SignedSmall) \
+ TYPED_UNOP_HANDLER_HELPER(V, Negate, Number)
#endif
/* Tiering related builtins
@@ -199,7 +221,8 @@ constexpr int kGearboxGenericBuiltinIdOffset = -2;
BUILTIN_LIST_BASE_TIERING_TURBOFAN(TFC) \
TFC(FunctionLogNextExecution, JSTrampoline) \
TFC(MarkReoptimizeLazyDeoptimized, JSTrampoline) \
- TFC(MarkLazyDeoptimized, JSTrampoline)
+ TFC(MarkLazyDeoptimized, JSTrampoline) \
+ TFC(MarkFlushed, JSTrampoline)
#define BUILTIN_LIST_BASE_TIER1(CPP, TFJ_TSA, TFJ, TFC_TSA, TFC, TFS, TFH, \
ASM) \
@@ -1058,14 +1081,22 @@ constexpr int kGearboxGenericBuiltinIdOffset = -2;
TFC(GreaterThanOrEqual_WithEmbeddedFeedback, Compare_WithEmbeddedFeedback) \
\
/* Unary ops with feedback collection */ \
- TFC(BitwiseNot_Baseline, UnaryOp_Baseline) \
- TFC(Decrement_Baseline, UnaryOp_Baseline) \
- TFC(Increment_Baseline, UnaryOp_Baseline) \
- TFC(Negate_Baseline, UnaryOp_Baseline) \
- IF_TSA(TFC_TSA, TFC, BitwiseNot_WithFeedback, UnaryOp_WithFeedback) \
- TFC(Decrement_WithFeedback, UnaryOp_WithFeedback) \
- TFC(Increment_WithFeedback, UnaryOp_WithFeedback) \
- TFC(Negate_WithFeedback, UnaryOp_WithFeedback) \
+ TFC(BitwiseNot_Generic_Baseline, UnaryOp_WithEmbeddedFeedbackOffset) \
+ IF_SPARKPLUG_PLUS(GENERATE_BUILTIN_TYPED_UNOP_HANDLER, TFC, BitwiseNot) \
+ IF_SPARKPLUG_PLUS(TFC, BitwiseNotAndTryPatchCode, UnaryOpAndTryPatchCode) \
+ TFC(Decrement_Generic_Baseline, UnaryOp_WithEmbeddedFeedbackOffset) \
+ IF_SPARKPLUG_PLUS(GENERATE_BUILTIN_TYPED_UNOP_HANDLER, TFC, Decrement) \
+ IF_SPARKPLUG_PLUS(TFC, DecrementAndTryPatchCode, UnaryOpAndTryPatchCode) \
+ TFC(Increment_Generic_Baseline, UnaryOp_WithEmbeddedFeedbackOffset) \
+ IF_SPARKPLUG_PLUS(GENERATE_BUILTIN_TYPED_UNOP_HANDLER, TFC, Increment) \
+ IF_SPARKPLUG_PLUS(TFC, IncrementAndTryPatchCode, UnaryOpAndTryPatchCode) \
+ TFC(Negate_Generic_Baseline, UnaryOp_WithEmbeddedFeedbackOffset) \
+ IF_SPARKPLUG_PLUS(GENERATE_BUILTIN_TYPED_NEGATE_HANDLER, TFC) \
+ IF_SPARKPLUG_PLUS(TFC, NegateAndTryPatchCode, UnaryOpAndTryPatchCode) \
+ IF_TSA(TFC_TSA, TFC, BitwiseNot_WithFeedback, UnaryOp_WithEmbeddedFeedback) \
+ TFC(Decrement_WithFeedback, UnaryOp_WithEmbeddedFeedback) \
+ TFC(Increment_WithFeedback, UnaryOp_WithEmbeddedFeedback) \
+ TFC(Negate_WithFeedback, UnaryOp_WithEmbeddedFeedback) \
\
/* Object */ \
TFJ(ObjectAssign, kDontAdaptArgumentsSentinel) \
diff --git a/deps/v8/src/builtins/builtins-inl.h b/deps/v8/src/builtins/builtins-inl.h
index a2fcf92c60f..220ec111dd2 100644
--- a/deps/v8/src/builtins/builtins-inl.h
+++ b/deps/v8/src/builtins/builtins-inl.h
@@ -323,6 +323,7 @@ bool Builtins::IsJSTrampoline(Builtin builtin) {
switch (builtin) {
case Builtin::kIllegal:
case Builtin::kCompileLazy:
+ case Builtin::kMarkFlushed:
case Builtin::kInterpreterEntryTrampoline:
case Builtin::kDebugBreakTrampoline:
#ifdef V8_ENABLE_WEBASSEMBLY
diff --git a/deps/v8/src/builtins/builtins-intl-gen.cc b/deps/v8/src/builtins/builtins-intl-gen.cc
index 24acfd55921..e095a5528af 100644
--- a/deps/v8/src/builtins/builtins-intl-gen.cc
+++ b/deps/v8/src/builtins/builtins-intl-gen.cc
@@ -184,6 +184,12 @@ void IntlBuiltinsAssembler::ToLowerCaseImpl(
&call_c);
{
+ // The allocation above may have internalized a shared source, forwarding
+ // it to a ThinString or freeing an external resource. The loop below would
+ // read that through a stale raw pointer, so bail out instead. {call_c}
+ // re-resolves the source and needs no such check.
+ to_direct.BailIfTransitioned(&runtime);
+
const TNode<IntPtrT> dst_ptr = PointerToSeqStringData(dst);
TVARIABLE(IntPtrT, var_cursor, IntPtrConstant(0));
diff --git a/deps/v8/src/builtins/builtins-intl.cc b/deps/v8/src/builtins/builtins-intl.cc
index bbfdb2c5505..4b97358d910 100644
--- a/deps/v8/src/builtins/builtins-intl.cc
+++ b/deps/v8/src/builtins/builtins-intl.cc
@@ -30,6 +30,7 @@
#include "src/objects/js-segment-iterator-inl.h"
#include "src/objects/js-segmenter-inl.h"
#include "src/objects/js-segments-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "src/objects/property-descriptor.h"
@@ -1240,7 +1241,8 @@ BUILTIN(CollatorInternalCompare) {
Object::ToString(isolate, y));
// 7. Return CompareStrings(collator, X, Y).
- Managed<icu::Collator>::Ptr icu_collator = collator->icu_collator()->ptr();
+ CppGCManaged<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
@@ -1325,7 +1327,7 @@ BUILTIN(SegmentsPrototypeIterator) {
HandleScope scope(isolate);
CHECK_RECEIVER(JSSegments, segments, method_name);
- Managed<IcuBreakIteratorWithText>::Ptr iterator_with_text =
+ CppGCManaged<IcuBreakIteratorWithText>::Ptr iterator_with_text =
segments->icu_iterator_with_text()->ptr();
RETURN_RESULT_OR_FAILURE(
diff --git a/deps/v8/src/builtins/builtins-iterator-inl.h b/deps/v8/src/builtins/builtins-iterator-inl.h
index 45858a78f63..ca0897c0855 100644
--- a/deps/v8/src/builtins/builtins-iterator-inl.h
+++ b/deps/v8/src/builtins/builtins-iterator-inl.h
@@ -17,6 +17,7 @@
#include "src/objects/js-collection-inl.h"
#include "src/objects/js-objects-inl.h"
#include "src/objects/js-regexp-string-iterator-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
diff --git a/deps/v8/src/builtins/builtins-math.cc b/deps/v8/src/builtins/builtins-math.cc
index 18b9477684a..a9370f7b14a 100644
--- a/deps/v8/src/builtins/builtins-math.cc
+++ b/deps/v8/src/builtins/builtins-math.cc
@@ -10,6 +10,7 @@
#include "src/execution/execution.h"
#include "src/execution/protectors-inl.h"
#include "src/numbers/conversions.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
diff --git a/deps/v8/src/builtins/builtins-microtask-queue-gen.cc b/deps/v8/src/builtins/builtins-microtask-queue-gen.cc
index 36f37918529..0193b0bd0cd 100644
--- a/deps/v8/src/builtins/builtins-microtask-queue-gen.cc
+++ b/deps/v8/src/builtins/builtins-microtask-queue-gen.cc
@@ -69,15 +69,9 @@ class MicrotaskQueueBuiltinsAssembler : public CodeStubAssembler {
TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskQueue(
TNode<Context> native_context) {
CSA_DCHECK(this, IsNativeContext(native_context));
-#ifdef V8_CPPGC_MICROTASK_QUEUE
return LoadCppHeapPointerFromObject(native_context,
NativeContext::kMicrotaskQueueOffset,
CppHeapPointerTag::kMicrotaskQueueTag);
-#else
- return LoadExternalPointerFromObject(native_context,
- NativeContext::kMicrotaskQueueOffset,
- kNativeContextMicrotaskQueueTag);
-#endif
}
TNode<RawPtrT> MicrotaskQueueBuiltinsAssembler::GetMicrotaskRingBuffer(
diff --git a/deps/v8/src/builtins/builtins-number-gen.cc b/deps/v8/src/builtins/builtins-number-gen.cc
index a96f788d0ec..8613da3f613 100644
--- a/deps/v8/src/builtins/builtins-number-gen.cc
+++ b/deps/v8/src/builtins/builtins-number-gen.cc
@@ -137,20 +137,21 @@ DEF_BINOP(ShiftRightSmi, ShiftRight, true)
DEF_BINOP(ShiftRightLogicalSmi, ShiftRightLogical, true)
#undef DEF_BINOP
-#define DEF_UNOP(Name, Generator) \
- TF_BUILTIN(Name, CodeStubAssembler) { \
- auto value = Parameter<Object>(Descriptor::kValue); \
- auto context = Parameter<Context>(Descriptor::kContext); \
- auto feedback_vector = \
- Parameter<FeedbackVector>(Descriptor::kFeedbackVector); \
- auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot); \
- \
- UnaryOpAssembler a(state()); \
- TNode<Object> result = \
- a.Generator(context, value, slot, feedback_vector, \
- UpdateFeedbackMode::kGuaranteedFeedback); \
- \
- Return(result); \
+#define DEF_UNOP(Name, Generator) \
+ TF_BUILTIN(Name, CodeStubAssembler) { \
+ auto value = Parameter<Object>(Descriptor::kValue); \
+ auto context = Parameter<Context>(Descriptor::kContext); \
+ auto bytecode_array = \
+ Parameter<BytecodeArray>(Descriptor::kBytecodeArray); \
+ auto feedback_offset = \
+ UncheckedParameter<IntPtrT>(Descriptor::kFeedbackOffset); \
+ \
+ UnaryOpAssembler a(state()); \
+ TNode<Object> result = a.Generator( \
+ context, value, \
+ a.MakeEmbeddedFeedbackUpdater(bytecode_array, feedback_offset)); \
+ \
+ Return(result); \
}
#ifndef V8_ENABLE_EXPERIMENTAL_TSA_BUILTINS
DEF_UNOP(BitwiseNot_WithFeedback, Generate_BitwiseNotWithFeedback)
@@ -160,25 +161,23 @@ DEF_UNOP(Increment_WithFeedback, Generate_IncrementWithFeedback)
DEF_UNOP(Negate_WithFeedback, Generate_NegateWithFeedback)
#undef DEF_UNOP
-#define DEF_UNOP(Name, Generator) \
- TF_BUILTIN(Name, CodeStubAssembler) { \
- auto value = Parameter<Object>(Descriptor::kValue); \
- auto context = LoadContextFromBaseline(); \
- auto feedback_vector = LoadFeedbackVectorFromBaseline(); \
- auto slot = UncheckedParameter<UintPtrT>(Descriptor::kSlot); \
- \
- UnaryOpAssembler a(state()); \
- TNode<Object> result = \
- a.Generator(context, value, slot, feedback_vector, \
- UpdateFeedbackMode::kGuaranteedFeedback); \
- \
- Return(result); \
+#define DEF_UNOP_GENERIC(Name, Generator) \
+ TF_BUILTIN(Name##_Generic_Baseline, CodeStubAssembler) { \
+ auto value = Parameter<Object>(Descriptor::kValue); \
+ auto feedback_offset = \
+ UncheckedParameter<IntPtrT>(Descriptor::kFeedbackOffset); \
+ UnaryOpAssembler a(state()); \
+ TNode<Object> result = \
+ a.Generator(LoadContextFromBaseline(), value, \
+ a.MakeEmbeddedFeedbackUpdater( \
+ LoadBytecodeArrayFromBaseline(), feedback_offset)); \
+ Return(result); \
}
-DEF_UNOP(BitwiseNot_Baseline, Generate_BitwiseNotWithFeedback)
-DEF_UNOP(Decrement_Baseline, Generate_DecrementWithFeedback)
-DEF_UNOP(Increment_Baseline, Generate_IncrementWithFeedback)
-DEF_UNOP(Negate_Baseline, Generate_NegateWithFeedback)
-#undef DEF_UNOP
+DEF_UNOP_GENERIC(BitwiseNot, Generate_BitwiseNotWithFeedback)
+DEF_UNOP_GENERIC(Decrement, Generate_DecrementWithFeedback)
+DEF_UNOP_GENERIC(Increment, Generate_IncrementWithFeedback)
+DEF_UNOP_GENERIC(Negate, Generate_NegateWithFeedback)
+#undef DEF_UNOP_GENERIC
#define DEF_RELATIONAL_COMPARE(Name) \
TF_BUILTIN(Name##_WithEmbeddedFeedback, CodeStubAssembler) { \
@@ -404,6 +403,47 @@ TF_BUILTIN(StrictEqual_Generic_Baseline, CodeStubAssembler) {
}
#ifdef V8_ENABLE_SPARKPLUG_PLUS
+#define DEF_TYPED_UNOP_COMMON(OpName) \
+ TF_BUILTIN(OpName##AndTryPatchCode, CodeStubAssembler) { \
+ auto value = Parameter<Object>(Descriptor::kValue); \
+ auto current_feedback = \
+ UncheckedParameter<Int32T>(Descriptor::kCurrentFeedback); \
+ auto feedback_offset = \
+ UncheckedParameter<UintPtrT>(Descriptor::kFeedbackOffset); \
+ GenerateUnaryOpAndTryPatchCode(Operation::k##OpName, value, \
+ current_feedback, feedback_offset); \
+ } \
+ TF_BUILTIN(OpName##_None_Baseline, CodeStubAssembler) { \
+ auto value = Parameter<Object>(Descriptor::kValue); \
+ auto feedback_offset = \
+ UncheckedParameter<UintPtrT>(Descriptor::kFeedbackOffset); \
+ TailCallBuiltin( \
+ Builtin::k##OpName##AndTryPatchCode, LoadContextFromBaseline(), value, \
+ Int32Constant( \
+ static_cast<int32_t>(BinaryOperationFeedback::TypeIndex::kNone)), \
+ feedback_offset); \
+ } \
+ TF_BUILTIN(OpName##_SignedSmall_Baseline, CodeStubAssembler) { \
+ auto value = Parameter<Object>(Descriptor::kValue); \
+ auto feedback_offset = \
+ UncheckedParameter<UintPtrT>(Descriptor::kFeedbackOffset); \
+ GenerateSmiUnaryOp(Operation::k##OpName, value, feedback_offset, \
+ Builtin::k##OpName##AndTryPatchCode); \
+ }
+DEF_TYPED_UNOP_COMMON(Increment)
+DEF_TYPED_UNOP_COMMON(Decrement)
+DEF_TYPED_UNOP_COMMON(Negate)
+DEF_TYPED_UNOP_COMMON(BitwiseNot)
+#undef DEF_TYPED_UNOP_COMMON
+
+// Negate-only Number stub.
+TF_BUILTIN(Negate_Number_Baseline, CodeStubAssembler) {
+ auto value = Parameter<Object>(Descriptor::kValue);
+ auto feedback_offset =
+ UncheckedParameter<UintPtrT>(Descriptor::kFeedbackOffset);
+ GenerateNumberNegate(value, feedback_offset);
+}
+
#define DEFINE_TYPED_EQUALITY_COMMON(Name) \
TF_BUILTIN(Name##_None_Baseline, CodeStubAssembler) { \
auto lhs = Parameter<Object>(Descriptor::kLeft); \
@@ -626,7 +666,7 @@ TF_BUILTIN(Add_String_Baseline, CodeStubAssembler) {
auto rhs = Parameter<Object>(Descriptor::kRight);
auto feedback_offset =
UncheckedParameter<UintPtrT>(Descriptor::kFeedbackOffset);
- GenerateStringAdd(lhs, rhs, feedback_offset, Builtin::kAddAndTryPatchCode);
+ GenerateStringAdd(lhs, rhs, feedback_offset);
}
TF_BUILTIN(ExponentiateAndTryPatchCode, CodeStubAssembler) {
diff --git a/deps/v8/src/builtins/builtins-number-tsa.cc b/deps/v8/src/builtins/builtins-number-tsa.cc
index 746e19bff7c..85ddfe02ded 100644
--- a/deps/v8/src/builtins/builtins-number-tsa.cc
+++ b/deps/v8/src/builtins/builtins-number-tsa.cc
@@ -418,12 +418,11 @@ TS_BUILTIN(BitwiseNot_WithFeedback, NumberBuiltinsAssemblerTS) {
// Descriptor directly.
V<Object> value = Parameter<Object>(Descriptor::kValue);
V<Context> context = Parameter<Context>(Descriptor::kContext);
- V<FeedbackVector> feedback_vector =
- Parameter<FeedbackVector>(Descriptor::kFeedbackVector);
- V<WordPtr> slot = Parameter<WordPtr>(Descriptor::kSlot);
+ V<BytecodeArray> bytecode_array =
+ Parameter<BytecodeArray>(Descriptor::kBytecodeArray);
+ V<WordPtr> feedback_offset = Parameter<WordPtr>(Descriptor::kFeedbackOffset);
- SetFeedbackSlot(slot);
- SetFeedbackVector(feedback_vector);
+ SetEmbeddedFeedback(bytecode_array, feedback_offset);
V<Object> result = BitwiseNot(context, value);
Return(result);
diff --git a/deps/v8/src/builtins/builtins-number.cc b/deps/v8/src/builtins/builtins-number.cc
index e25af221b61..e031dcfa83d 100644
--- a/deps/v8/src/builtins/builtins-number.cc
+++ b/deps/v8/src/builtins/builtins-number.cc
@@ -7,6 +7,7 @@
#include "src/codegen/code-factory.h"
#include "src/logging/counters.h"
#include "src/numbers/conversions.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/intl-objects.h"
diff --git a/deps/v8/src/builtins/builtins-regexp-gen.cc b/deps/v8/src/builtins/builtins-regexp-gen.cc
index be445c39534..951b56c662f 100644
--- a/deps/v8/src/builtins/builtins-regexp-gen.cc
+++ b/deps/v8/src/builtins/builtins-regexp-gen.cc
@@ -181,6 +181,128 @@ TNode<RegExpData> RegExpBuiltinsAssembler::LoadRegExpDataFromObject(
offset);
}
+// On a hit, sets {var_result} to a fresh array over the cached parts and jumps
+// to {if_found}. On a miss, falls through. Mirrors ResultsCache::Lookup.
+void RegExpBuiltinsAssembler::TryRegExpSplitCacheLookup(
+ TNode<Context> context, TNode<JSRegExp> regexp, TNode<RegExpData> data,
+ TNode<String> string, TVariable<JSArray>* var_result, Label* if_found) {
+ Label miss(this);
+
+ TNode<FixedArray> cache =
+ CAST(CodeAssembler::LoadRoot(RootIndex::kRegExpSplitCache));
+ // The cache is allocated on the first Enter; until then there is nothing to
+ // probe.
+ GotoIf(TaggedEqual(cache, EmptyFixedArrayConstant()), &miss);
+
+ TNode<Object> key_pattern =
+ LoadObjectField(data, offsetof(RegExpData, wrapper_));
+
+ CSA_DCHECK(this, IsInternalizedString(string));
+ TNode<IntPtrT> hash =
+ Signed(ChangeUint32ToWord(LoadNameHashAssumeComputed(string)));
+ constexpr int kSizeMask =
+ regexp::ResultsCache::kRegExpSplitResultsCacheSize - 1;
+ constexpr int kSlotsPerEntry =
+ regexp::ResultsCache::kArrayEntriesPerCacheEntry;
+ TNode<IntPtrT> first_index = WordAnd(WordAnd(hash, IntPtrConstant(kSizeMask)),
+ IntPtrConstant(~(kSlotsPerEntry - 1)));
+
+ // Read as part of the probe, so a later eviction cannot be observed.
+ TVARIABLE(FixedArray, var_elements);
+ TVARIABLE(FixedArray, var_last_match_cache);
+
+ Label found(this, {&var_elements, &var_last_match_cache});
+ auto probe = [&](TNode<IntPtrT> index, Label* if_no_match) {
+ TNode<Object> key_string = UnsafeLoadFixedArrayElement(
+ cache, index, regexp::ResultsCache::kStringOffset * kTaggedSize);
+ GotoIfNot(TaggedEqual(key_string, string), if_no_match);
+ TNode<Object> pattern = UnsafeLoadFixedArrayElement(
+ cache, index, regexp::ResultsCache::kPatternOffset * kTaggedSize);
+ GotoIfNot(TaggedEqual(pattern, key_pattern), if_no_match);
+ var_elements = CAST(UnsafeLoadFixedArrayElement(
+ cache, index, regexp::ResultsCache::kArrayOffset * kTaggedSize));
+ var_last_match_cache = CAST(UnsafeLoadFixedArrayElement(
+ cache, index, regexp::ResultsCache::kLastMatchOffset * kTaggedSize));
+ Goto(&found);
+ };
+
+ Label try_second(this);
+ probe(first_index, &try_second);
+
+ BIND(&try_second);
+ probe(WordAnd(IntPtrAdd(first_index, IntPtrConstant(kSlotsPerEntry)),
+ IntPtrConstant(kSizeMask)),
+ &miss);
+
+ BIND(&found);
+ {
+ ReplayLastMatchInfo(context, string, var_last_match_cache.value());
+
+ // Enter made the elements copy-on-write, so the result can share them: a
+ // write copies the backing store instead of clobbering the entry.
+ TNode<FixedArray> elements = var_elements.value();
+ CSA_DCHECK(this, IsFixedCOWArrayMap(LoadMap(elements)));
+ TNode<Map> array_map =
+ LoadJSArrayElementsMap(PACKED_ELEMENTS, LoadNativeContext(context));
+ *var_result = AllocateJSArray(array_map, elements,
+ SmiTag(LoadFixedArrayBaseLength(elements)));
+ Goto(if_found);
+ }
+
+ BIND(&miss);
+}
+
+// Restores LastMatchInfo from a SnapshotLastMatchInfo result. An empty
+// snapshot means the split loop never matched, so LastMatchInfo is left alone.
+void RegExpBuiltinsAssembler::ReplayLastMatchInfo(
+ TNode<Context> context, TNode<String> subject,
+ TNode<FixedArray> last_match_cache) {
+ Label done(this);
+ TNode<IntPtrT> register_count = LoadFixedArrayBaseLength(last_match_cache);
+ GotoIf(IntPtrEqual(register_count, IntPtrConstant(0)), &done);
+
+ CSA_DCHECK(this, TaggedEqual(context, LoadNativeContext(context)));
+ TNode<RegExpMatchInfo> match_info = CAST(
+ LoadContextElementNoCell(context, Context::REGEXP_LAST_MATCH_INFO_INDEX));
+ 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);
+ Goto(&done);
+
+ BIND(&done);
+}
+
+// Records the match LastMatchInfo currently holds, for a later hit to replay.
+// Returns the empty array if the split loop never matched.
+TNode<FixedArray> RegExpBuiltinsAssembler::SnapshotLastMatchInfo(
+ TNode<Context> context, TNode<BoolT> did_match) {
+ TVARIABLE(FixedArray, var_result, EmptyFixedArrayConstant());
+ Label done(this, &var_result);
+ GotoIfNot(did_match, &done);
+
+ CSA_DCHECK(this, TaggedEqual(context, LoadNativeContext(context)));
+ TNode<RegExpMatchInfo> match_info = CAST(
+ LoadContextElementNoCell(context, Context::REGEXP_LAST_MATCH_INFO_INDEX));
+ TNode<IntPtrT> register_count = PositiveSmiUntag(LoadObjectField<Smi>(
+ match_info, offsetof(RegExpMatchInfo, number_of_capture_registers_)));
+
+ 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);
+ var_result = snapshot;
+ Goto(&done);
+
+ BIND(&done);
+ return var_result.value();
+}
+
TNode<Smi> RegExpBuiltinsAssembler::LoadCaptureCount(TNode<RegExpData> data) {
return Select<Smi>(
SmiEqual(LoadObjectField<Smi>(data, offsetof(RegExpData, type_tag_)),
@@ -497,11 +619,9 @@ static_assert(kInt32Size == 1 << kInt32SizeLog2);
} // namespace
-TNode<RegExpMatchInfo>
-RegExpBuiltinsAssembler::InitializeMatchInfoFromRegisters(
+TNode<RegExpMatchInfo> RegExpBuiltinsAssembler::PrepareMatchInfo(
TNode<Context> context, TNode<RegExpMatchInfo> match_info,
- TNode<Smi> register_count, TNode<String> subject,
- TNode<RawPtrT> result_offsets_vector) {
+ TNode<Smi> register_count, TNode<String> subject) {
TVARIABLE(RegExpMatchInfo, var_match_info, match_info);
// Check that the last match info has space for the capture registers.
@@ -521,7 +641,6 @@ RegExpBuiltinsAssembler::InitializeMatchInfoFromRegisters(
BIND(&next);
}
- // Fill match_info.
StoreObjectField(var_match_info.value(),
offsetof(RegExpMatchInfo, number_of_capture_registers_),
register_count);
@@ -529,6 +648,16 @@ RegExpBuiltinsAssembler::InitializeMatchInfoFromRegisters(
offsetof(RegExpMatchInfo, last_subject_), subject);
StoreObjectField(var_match_info.value(),
offsetof(RegExpMatchInfo, last_input_), subject);
+ return var_match_info.value();
+}
+
+TNode<RegExpMatchInfo>
+RegExpBuiltinsAssembler::InitializeMatchInfoFromRegisters(
+ TNode<Context> context, TNode<RegExpMatchInfo> match_info,
+ TNode<Smi> register_count, TNode<String> subject,
+ TNode<RawPtrT> result_offsets_vector) {
+ TNode<RegExpMatchInfo> prepared_match_info =
+ PrepareMatchInfo(context, match_info, register_count, subject);
// Fill match and capture offsets in match_info. They are located in the
// region:
@@ -554,14 +683,14 @@ RegExpBuiltinsAssembler::InitializeMatchInfoFromRegisters(
Load(MachineType::Int32(), current_register_address));
TNode<Smi> smi_value = SmiFromInt32(value);
StoreNoWriteBarrier(MachineRepresentation::kTagged,
- var_match_info.value(), var_to_offset.value(),
+ prepared_match_info, var_to_offset.value(),
smi_value);
Increment(&var_to_offset, kTaggedSize);
},
kInt32Size, kLoopUnrolling, IndexAdvanceMode::kPost);
}
- return var_match_info.value();
+ return prepared_match_info;
}
TNode<RegExpMatchInfo> RegExpBuiltinsAssembler::RegExpExecInternal_Single(
@@ -705,31 +834,83 @@ TNode<UintPtrT> RegExpBuiltinsAssembler::RegExpExecInternal(
BIND(&next);
}
- // Fast-reject via (chars & mask) == value, using up to a 4-character
- // mask precomputed during RegExp compilation.
+ // Throw out attempts that cannot match without entering the engine, using
+ // two filters built during compilation: (chars & mask) == value over the
+ // next four characters, and a bitset of what a match can start with. A
+ // regexp may have either, both, or neither, and running both rejects more
+ // than either does alone. This is RegExpData::QuickCheckRejects in CSA.
{
- Label proceed(this);
+ Label try_bitset(this), proceed(this);
+
+ // Most regexps have neither filter; see RegExpData::kHasQuickCheck.
+ TNode<Uint32T> internal_flags =
+ LoadObjectField<Uint32T>(data, offsetof(RegExpData, internal_flags_));
+ GotoIf(Word32Equal(Word32And(internal_flags,
+ Uint32Constant(RegExpData::kHasQuickCheck)),
+ Int32Constant(0)),
+ &proceed);
GotoIfNot(to_direct.IsOneByte(), &proceed);
- TNode<Uint32T> mask =
- LoadObjectField<Uint32T>(data, offsetof(RegExpData, quick_check_mask_));
- GotoIf(Word32Equal(mask, Int32Constant(0)), &proceed);
-
+ TNode<IntPtrT> actual_index = IntPtrAdd(int_last_index, to_direct.offset());
TNode<IntPtrT> remaining = IntPtrSub(int_string_length, int_last_index);
- GotoIf(IntPtrLessThan(remaining, IntPtrConstant(kUInt32Size / kCharSize)),
- &proceed);
+ TNode<RawPtrT> string_data = to_direct.PointerToData(&proceed);
- TNode<Uint32T> expected = LoadObjectField<Uint32T>(
- data, offsetof(RegExpData, quick_check_value_));
+ // Mask first.
+ {
+ TNode<Uint32T> mask = LoadObjectField<Uint32T>(
+ data, offsetof(RegExpData, quick_check_mask_));
+ GotoIf(Word32Equal(mask, Int32Constant(0)), &try_bitset);
- TNode<IntPtrT> actual_index = IntPtrAdd(int_last_index, to_direct.offset());
- TNode<RawPtrT> string_data = to_direct.PointerToData(&proceed);
+ // Four characters have to be left to read four. The bitset reads only
+ // one, so a shorter tail skips ahead to it rather than giving up.
+ GotoIf(IntPtrLessThan(remaining, IntPtrConstant(kUInt32Size / kCharSize)),
+ &try_bitset);
+
+ TNode<Uint32T> expected = LoadObjectField<Uint32T>(
+ data, offsetof(RegExpData, quick_check_value_));
- TNode<Uint32T> loaded_word = Load<Uint32T>(string_data, actual_index);
+ TNode<Uint32T> loaded_word = Load<Uint32T>(string_data, actual_index);
+
+ TNode<Word32T> masked_chars = Word32And(loaded_word, mask);
+ Branch(Word32Equal(masked_chars, expected), &try_bitset, &out);
+ }
- TNode<Word32T> masked_chars = Word32And(loaded_word, mask);
- Branch(Word32Equal(masked_chars, expected), &proceed, &out);
+ // A set bit means "no match can start with this character", so a regexp
+ // without a bitset has all zeroes and falls through on its own. Reads a
+ // single character, so unlike the mask it works on a short tail too.
+ BIND(&try_bitset);
+ {
+ GotoIf(IntPtrEqual(remaining, IntPtrConstant(0)), &proceed);
+
+ TNode<Uint32T> c = Load<Uint8T>(string_data, actual_index);
+
+ // RegExpData::QuickCheckBitsetBit open-coded, since CSA cannot call it:
+ // 'a' (97) is word 3, bit 1, so load at byte offset 12 and test 1 << 1.
+ // This offset is computed rather than constant, and |data| is a trusted
+ // object, so the bitset has to cover every value the load above can
+ // produce. It does: |c| is a byte, and the bitset has a bit per byte.
+ static_assert(RegExpData::kQuickCheckBitsetChars ==
+ 1 << (kUInt8Size * kBitsPerByte));
+ static_assert(RegExpData::kQuickCheckBitsetBitsPerWord ==
+ kInt32Size * kBitsPerByte);
+ constexpr int kBitsPerWordLog2 = kInt32SizeLog2 + kBitsPerByteLog2;
+ TNode<IntPtrT> word_index = Signed(
+ WordShr(ChangeUint32ToWord(c), IntPtrConstant(kBitsPerWordLog2)));
+ TNode<IntPtrT> word_offset =
+ WordShl(word_index, IntPtrConstant(kInt32SizeLog2));
+ TNode<Uint32T> word = LoadObjectField<Uint32T>(
+ data, IntPtrAdd(IntPtrConstant(
+ offsetof(RegExpData, quick_check_reject_bitset_)),
+ word_offset));
+
+ TNode<Uint32T> bit = Word32Shl(
+ Uint32Constant(1),
+ Word32And(
+ c, Uint32Constant(RegExpData::kQuickCheckBitsetBitsPerWord - 1)));
+ Branch(Word32Equal(Word32And(word, bit), Int32Constant(0)), &proceed,
+ &out);
+ }
BIND(&proceed);
}
@@ -1603,7 +1784,7 @@ TNode<Number> RegExpBuiltinsAssembler::AdvanceStringIndex(
// Must be in Smi range on the fast path. We control the value of {index}
// on all call-sites and can never exceed the length of the string.
static_assert(String::kMaxLength + 2 < Smi::kMaxValue);
- // TODO(532595489): Hard CHECK for now as a quick fix.
+ // CSA_CHECK kept as defense-in-depth against unexpected fast-path overflow.
CSA_CHECK(this, TaggedIsPositiveSmi(index_plus_one));
}
@@ -1701,9 +1882,11 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
const ElementsKind elements_kind = PACKED_ELEMENTS;
+ TVARIABLE(JSArray, var_result);
+
Label done(this);
+ Label done_no_result_vector(this, &var_result);
Label return_empty_array(this, Label::kDeferred);
- TVARIABLE(JSArray, var_result);
// Exception handling is necessary to free any allocated memory.
TVARIABLE(Object, var_exception);
@@ -1714,6 +1897,23 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
// the specialized AdvanceStringIndex logic below.
TNode<RegExpData> data =
LoadRegExpDataFromObject(regexp, offsetof(JSRegExp, data_));
+
+ // Only an unlimited split is cacheable, since the cached array holds every
+ // part. v8_flags.regexp_results_cache is a mksnapshot-time constant here, so
+ // it is checked in ResultsCache::{Lookup,Enter} instead.
+ TNode<BoolT> is_cacheable =
+ Word32And(SmiEqual(limit, SmiConstant(Smi::kMaxValue)),
+ IsInternalizedString(string));
+ {
+ Label next(this);
+ GotoIfNot(is_cacheable, &next);
+ TryRegExpSplitCacheLookup(context, regexp, data, string, &var_result,
+ &done_no_result_vector);
+ Goto(&next);
+
+ BIND(&next);
+ }
+
TNode<Smi> capture_count = LoadCaptureCount(data);
TNode<Smi> register_count_per_match = RegistersForCaptureCount(capture_count);
TNode<RawPtrT> result_offsets_vector;
@@ -1791,11 +1991,13 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
TVARIABLE(Smi, var_last_matched_until, SmiZero());
TVARIABLE(Smi, var_next_search_from, SmiZero());
+ // Whether the loop wrote LastMatchInfo. Only then may a hit replay it.
+ TVARIABLE(BoolT, var_did_match, Int32FalseConstant());
- Label loop(this,
- {array.var_array(), array.var_length(), array.var_capacity(),
- &var_last_matched_until, &var_next_search_from}),
- push_suffix_and_out(this), out(this);
+ Label loop(
+ this, {array.var_array(), array.var_length(), array.var_capacity(),
+ &var_last_matched_until, &var_next_search_from, &var_did_match}),
+ push_suffix_and_out(this), out(this), out_cacheable(this);
Goto(&loop);
BIND(&loop);
@@ -1833,6 +2035,7 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
match_info = InitializeMatchInfoFromRegisters(
context, match_info, register_count_per_match, string,
result_offsets_vector);
+ var_did_match = Int32TrueConstant();
TNode<Smi> match_to = LoadArrayElement(match_info, IntPtrConstant(1));
@@ -1925,7 +2128,32 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
TNode<Smi> from = var_last_matched_until.value();
TNode<Smi> to = string_length;
array.Push(CallBuiltin(Builtin::kSubString, context, string, from, to));
- Goto(&out);
+ Branch(is_cacheable, &out_cacheable, &out);
+ }
+
+ // Only reached when the split ran to the end of the subject. A split cut
+ // short by {limit} exits through {out} and must not be cached.
+ BIND(&out_cacheable);
+ {
+ var_result = array.ToJSArray(context);
+
+ // Snapshot rather than reconstruct which match was the last one: the
+ // final match may contribute no element, e.g. one at the end of the
+ // subject.
+ TNode<FixedArray> last_match_cache =
+ SnapshotLastMatchInfo(context, var_did_match.value());
+ TNode<ExternalReference> function =
+ ExternalConstant(ExternalReference::re_split_cache_enter());
+ TNode<ExternalReference> isolate_ptr =
+ ExternalConstant(ExternalReference::isolate_address());
+ CallCFunction(
+ function, MachineType::AnyTagged(),
+ std::make_pair(MachineType::Pointer(), isolate_ptr),
+ std::make_pair(MachineType::AnyTagged(), string),
+ std::make_pair(MachineType::AnyTagged(), regexp),
+ std::make_pair(MachineType::AnyTagged(), var_result.value()),
+ std::make_pair(MachineType::AnyTagged(), last_match_cache));
+ Goto(&done);
}
BIND(&out);
@@ -1957,6 +2185,9 @@ TNode<JSArray> RegExpBuiltinsAssembler::RegExpPrototypeSplitBody(
BIND(&done);
FreeRegExpResultVector(result_offsets_vector,
result_offsets_vector_is_dynamic);
+ Goto(&done_no_result_vector);
+
+ BIND(&done_no_result_vector);
return var_result.value();
}
diff --git a/deps/v8/src/builtins/builtins-regexp-gen.h b/deps/v8/src/builtins/builtins-regexp-gen.h
index 480150132b6..2470de6e572 100644
--- a/deps/v8/src/builtins/builtins-regexp-gen.h
+++ b/deps/v8/src/builtins/builtins-regexp-gen.h
@@ -65,11 +65,27 @@ class RegExpBuiltinsAssembler : public CodeStubAssembler {
void FreeRegExpResultVector(TNode<RawPtrT> result_vector,
TNode<BoolT> is_dynamic);
+ // Grows {match_info} if it cannot hold {register_count} registers and
+ // initializes its header. The caller fills in the capture offsets.
+ TNode<RegExpMatchInfo> PrepareMatchInfo(TNode<Context> context,
+ TNode<RegExpMatchInfo> match_info,
+ TNode<Smi> register_count,
+ TNode<String> subject);
+
TNode<RegExpMatchInfo> InitializeMatchInfoFromRegisters(
TNode<Context> context, TNode<RegExpMatchInfo> match_info,
TNode<Smi> register_count, TNode<String> subject,
TNode<RawPtrT> result_offsets_vector);
+ void TryRegExpSplitCacheLookup(TNode<Context> context, TNode<JSRegExp> regexp,
+ TNode<RegExpData> data, TNode<String> string,
+ TVariable<JSArray>* var_result,
+ Label* if_found);
+ TNode<FixedArray> SnapshotLastMatchInfo(TNode<Context> context,
+ TNode<BoolT> did_match);
+ void ReplayLastMatchInfo(TNode<Context> context, TNode<String> subject,
+ TNode<FixedArray> last_match_cache);
+
// Low level logic around the actual call into pattern matching code.
//
// TODO(jgruber): Callers that either 1. don't need the RegExpMatchInfo, or
diff --git a/deps/v8/src/builtins/builtins-sharedarraybuffer.cc b/deps/v8/src/builtins/builtins-sharedarraybuffer.cc
index 2c34fefd8e8..430a251b77b 100644
--- a/deps/v8/src/builtins/builtins-sharedarraybuffer.cc
+++ b/deps/v8/src/builtins/builtins-sharedarraybuffer.cc
@@ -11,6 +11,7 @@
#include "src/logging/counters.h"
#include "src/numbers/conversions-inl.h"
#include "src/objects/js-array-buffer-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
@@ -87,6 +88,8 @@ V8_WARN_UNUSED_RESULT MaybeDirectHandle<JSTypedArray> ValidateIntegerTypedArray(
V8_WARN_UNUSED_RESULT Maybe<size_t> ValidateAtomicAccess(
Isolate* isolate, DirectHandle<JSTypedArray> typed_array,
Handle<Object> request_index) {
+ size_t typed_array_length = typed_array->GetLength();
+
DirectHandle<Object> access_index_obj;
ASSIGN_RETURN_ON_EXCEPTION(
isolate, access_index_obj,
@@ -94,7 +97,6 @@ V8_WARN_UNUSED_RESULT Maybe<size_t> ValidateAtomicAccess(
MessageTemplate::kInvalidAtomicAccessIndex));
size_t access_index;
- size_t typed_array_length = typed_array->GetLength();
if (!TryNumberToSize(*access_index_obj, &access_index) ||
access_index >= typed_array_length) {
isolate->Throw(*isolate->factory()->NewRangeError(
diff --git a/deps/v8/src/builtins/builtins-string-gen.cc b/deps/v8/src/builtins/builtins-string-gen.cc
index cefce65959e..06c2de1f2a7 100644
--- a/deps/v8/src/builtins/builtins-string-gen.cc
+++ b/deps/v8/src/builtins/builtins-string-gen.cc
@@ -1575,6 +1575,11 @@ TNode<JSArray> StringBuiltinsAssembler::StringToArray(
TNode<FixedArray> elements =
CAST(AllocateFixedArray(PACKED_ELEMENTS, length));
+ // The allocation above may have internalized a shared subject, forwarding
+ // it to a ThinString or freeing an external resource, which would leave
+ // the pointer below pointing at unrelated heap data.
+ to_direct.BailIfTransitioned(&fill_thehole_and_call_runtime);
+
// Don't allocate anything while {string_data} is live!
TNode<RawPtrT> string_data =
to_direct.PointerToData(&fill_thehole_and_call_runtime);
@@ -1854,13 +1859,16 @@ void StringBuiltinsAssembler::ReplaceUnpairedSurrogates(TNode<String> source,
if_indirect);
TNode<RawPtrT> source_data = DirectStringData(source, source_instance_type);
- // The destination string is a freshly allocated SeqString, and so is always
- // direct.
- TNode<Uint16T> dest_instance_type = LoadInstanceType(dest);
- CSA_DCHECK(this, Word32Equal(Word32And(dest_instance_type,
- Int32Constant(kStringEncodingMask)),
- Int32Constant(kTwoByteStringTag)));
- TNode<RawPtrT> dest_data = DirectStringData(dest, dest_instance_type);
+ // The destination string is a freshly allocated TwoByteSeqString, and so is
+ // always direct.
+ CSA_DCHECK(this,
+ Word32Equal(
+ Word32And(LoadInstanceType(dest),
+ Int32Constant(kIsNotStringMask |
+ kStringRepresentationAndEncodingMask)),
+ Int32Constant(kSeqTwoByteStringTag)));
+ TNode<RawPtrT> dest_data =
+ DirectStringData(dest, Int32Constant(SEQ_TWO_BYTE_STRING_TYPE));
TNode<IntPtrT> length = LoadStringLengthAsWord(source);
CSA_DCHECK(this, IntPtrEqual(length, LoadStringLengthAsWord(dest)));
diff --git a/deps/v8/src/builtins/builtins-string.cc b/deps/v8/src/builtins/builtins-string.cc
index ccb5ca65560..235d2f09c1e 100644
--- a/deps/v8/src/builtins/builtins-string.cc
+++ b/deps/v8/src/builtins/builtins-string.cc
@@ -8,6 +8,7 @@
#include "src/builtins/builtins.h"
#include "src/logging/counters.h"
#include "src/numbers/conversions.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#ifdef V8_INTL_SUPPORT
#include "src/objects/intl-objects.h"
diff --git a/deps/v8/src/builtins/builtins-struct.cc b/deps/v8/src/builtins/builtins-struct.cc
index e3288f16061..0ab121a5012 100644
--- a/deps/v8/src/builtins/builtins-struct.cc
+++ b/deps/v8/src/builtins/builtins-struct.cc
@@ -6,6 +6,7 @@
#include "src/builtins/builtins-utils-inl.h"
#include "src/objects/js-struct.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-details.h"
namespace v8 {
diff --git a/deps/v8/src/builtins/builtins-temporal.cc b/deps/v8/src/builtins/builtins-temporal.cc
index 17e209bb0f8..b323771263b 100644
--- a/deps/v8/src/builtins/builtins-temporal.cc
+++ b/deps/v8/src/builtins/builtins-temporal.cc
@@ -6,6 +6,7 @@
#include "src/builtins/builtins.h"
#include "src/objects/bigint.h"
#include "src/objects/js-temporal-objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/builtins/builtins-trace.cc b/deps/v8/src/builtins/builtins-trace.cc
index 6b209893add..5acfb72e446 100644
--- a/deps/v8/src/builtins/builtins-trace.cc
+++ b/deps/v8/src/builtins/builtins-trace.cc
@@ -7,6 +7,7 @@
#include "src/builtins/builtins.h"
#include "src/json/json-stringifier.h"
#include "src/logging/counters.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/roots/roots-inl.h"
#include "src/tracing/perfetto-sdk.h"
diff --git a/deps/v8/src/builtins/builtins.cc b/deps/v8/src/builtins/builtins.cc
index cae92c151a1..31474ac5f24 100644
--- a/deps/v8/src/builtins/builtins.cc
+++ b/deps/v8/src/builtins/builtins.cc
@@ -654,6 +654,7 @@ Builtins::JSBuiltinStateFlags Builtins::GetJSBuiltinState(Builtin builtin) {
case Builtin::kFunctionLogNextExecution:
case Builtin::kMarkReoptimizeLazyDeoptimized:
case Builtin::kMarkLazyDeoptimized:
+ case Builtin::kMarkFlushed:
// All *DeoptContinuation builtins.
case Builtin::kArrayEveryLoopEagerDeoptContinuation:
case Builtin::kArrayEveryLoopLazyDeoptContinuation:
@@ -842,52 +843,6 @@ Builtins::JSBuiltinStateFlags Builtins::GetJSBuiltinState(Builtin builtin) {
case Builtin::kSharedStructConstructor:
RETURN_FLAG_DEPENDENT_LAZY_BUILTIN_STATE(v8_flags.harmony_struct);
- // --js-promise-try
- case Builtin::kPromiseTry:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_promise_try);
-
- // --js-atomics-pause
- case Builtin::kAtomicsPause:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_atomics_pause);
-
- // --js-error-iserror
- case Builtin::kErrorIsError:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_error_iserror);
-
- // --js-regexp-escape
- case Builtin::kRegExpEscape:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_regexp_escape);
-
- // --js-explicit-resource-management
- case Builtin::kSuppressedErrorConstructor:
- case Builtin::kDisposableStackConstructor:
- case Builtin::kDisposableStackPrototypeUse:
- case Builtin::kDisposableStackPrototypeDispose:
- case Builtin::kDisposableStackPrototypeAdopt:
- case Builtin::kDisposableStackPrototypeDefer:
- case Builtin::kDisposableStackPrototypeMove:
- case Builtin::kDisposableStackPrototypeGetDisposed:
- case Builtin::kAsyncDisposableStackConstructor:
- case Builtin::kAsyncDisposableStackPrototypeUse:
- case Builtin::kAsyncDisposableStackPrototypeDisposeAsync:
- case Builtin::kAsyncDisposableStackPrototypeAdopt:
- case Builtin::kAsyncDisposableStackPrototypeDefer:
- case Builtin::kAsyncDisposableStackPrototypeMove:
- case Builtin::kAsyncDisposableStackPrototypeGetDisposed:
- case Builtin::kIteratorPrototypeDispose:
- case Builtin::kAsyncIteratorPrototypeAsyncDispose:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(
- v8_flags.js_explicit_resource_management);
-
- // --js-base-64
- case Builtin::kUint8ArrayFromBase64:
- case Builtin::kUint8ArrayFromHex:
- case Builtin::kUint8ArrayPrototypeToBase64:
- case Builtin::kUint8ArrayPrototypeSetFromBase64:
- case Builtin::kUint8ArrayPrototypeToHex:
- case Builtin::kUint8ArrayPrototypeSetFromHex:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_base_64);
-
// --js-iterator-sequencing:
case Builtin::kIteratorConcat:
RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_iterator_sequencing);
@@ -897,23 +852,12 @@ Builtins::JSBuiltinStateFlags Builtins::GetJSBuiltinState(Builtin builtin) {
case Builtin::kIteratorZipKeyed:
RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_joint_iteration);
- // --js-upsert
- case Builtin::kMapPrototypeGetOrInsert:
- case Builtin::kMapPrototypeGetOrInsertComputed:
- case Builtin::kWeakMapPrototypeGetOrInsert:
- case Builtin::kWeakMapPrototypeGetOrInsertComputed:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_upsert);
-
// --js-immutable-arraybuffer
case Builtin::kArrayBufferPrototypeGetImmutable:
case Builtin::kArrayBufferPrototypeTransferToImmutable:
case Builtin::kArrayBufferPrototypeSliceToImmutable:
RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_immutable_arraybuffer);
- // --js-sum-precise
- case Builtin::kMathSumPrecise:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_sum_precise);
-
// --enable-queue-microtask
case Builtin::kGlobalQueueMicrotask:
RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.enable_queue_microtask);
@@ -926,12 +870,6 @@ Builtins::JSBuiltinStateFlags Builtins::GetJSBuiltinState(Builtin builtin) {
case Builtin::kIteratorPrototypeIncludes:
RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_iterator_includes);
-#ifdef V8_INTL_SUPPORT
- // --js-intl-locale-variants
- case Builtin::kLocalePrototypeVariants:
- RETURN_FLAG_DEPENDENT_BUILTIN_STATE(v8_flags.js_intl_locale_variants);
-#endif // V8_INTL_SUPPORT
-
default: {
// Treat all other JS builtins as mandatory core JS language builtins.
// This will allow us to detect optional builtins (because mandatory JS
@@ -962,7 +900,7 @@ void Builtins::VerifyGetJSBuiltinState(bool allow_non_initial_state) {
// JSFunctions.
for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
- if (IsAnyHole(obj)) continue;
+ if (IsInaccessible(obj)) continue;
Tagged<JSFunction> func;
if (!TryCast(obj, &func)) continue;
diff --git a/deps/v8/src/builtins/builtins.h b/deps/v8/src/builtins/builtins.h
index e318f9d1de6..938885ffdf7 100644
--- a/deps/v8/src/builtins/builtins.h
+++ b/deps/v8/src/builtins/builtins.h
@@ -156,6 +156,12 @@ class Builtins {
static constexpr Builtin kLastTier0 =
static_cast<Builtin>(kBuiltinTier0Count - 1);
+#ifdef V8_METAGEN_GENERATION_PASS
+ static constexpr int kFirstWideBytecodeHandler = 0;
+ static constexpr int kFirstExtraWideBytecodeHandler = 0;
+ static constexpr int kLastBytecodeHandlerPlusOne = 0;
+ static constexpr bool kBytecodeHandlersAreSortedLast = true;
+#else
static constexpr int kFirstWideBytecodeHandler =
static_cast<int>(Builtin::kFirstBytecodeHandler) +
kNumberOfBytecodeHandlers;
@@ -165,6 +171,7 @@ class Builtins {
kFirstExtraWideBytecodeHandler + kNumberOfWideBytecodeHandlers;
static constexpr bool kBytecodeHandlersAreSortedLast =
kLastBytecodeHandlerPlusOne == kBuiltinCount;
+#endif // V8_METAGEN_GENERATION_PASS
static_assert(kBytecodeHandlersAreSortedLast);
#if V8_ENABLE_GEARBOX
@@ -728,6 +735,11 @@ DEFINE_TYPED_OP_CHECKER(BitwiseAnd, None, SignedSmall)
DEFINE_TYPED_OP_CHECKER(ShiftLeft, None, SignedSmall)
DEFINE_TYPED_OP_CHECKER(ShiftRight, None, SignedSmall)
DEFINE_TYPED_OP_CHECKER(ShiftRightLogical, None, SignedSmall)
+// Unary op typed-stub families.
+DEFINE_TYPED_OP_CHECKER(Increment, None, SignedSmall)
+DEFINE_TYPED_OP_CHECKER(Decrement, None, SignedSmall)
+DEFINE_TYPED_OP_CHECKER(Negate, None, Number)
+DEFINE_TYPED_OP_CHECKER(BitwiseNot, None, SignedSmall)
#undef DEFINE_TYPED_OP_CHECKER
#endif // V8_ENABLE_SPARKPLUG_PLUS
diff --git a/deps/v8/src/builtins/convert.tq b/deps/v8/src/builtins/convert.tq
index cb2043c65a3..ce4823056cb 100644
--- a/deps/v8/src/builtins/convert.tq
+++ b/deps/v8/src/builtins/convert.tq
@@ -298,6 +298,9 @@ Convert<uint32, uintptr>(ui: uintptr): uint32 {
Convert<intptr, Smi>(s: Smi): intptr {
return SmiUntag(s);
}
+Convert<uintptr, Smi>(s: Smi): uintptr {
+ return Unsigned(SmiUntag(s));
+}
Convert<uintptr, PositiveSmi>(ps: PositiveSmi): uintptr {
return Unsigned(SmiUntag(ps));
}
diff --git a/deps/v8/src/builtins/generator.tq b/deps/v8/src/builtins/generator.tq
index d6f2b748e07..8f8fd2d5c97 100644
--- a/deps/v8/src/builtins/generator.tq
+++ b/deps/v8/src/builtins/generator.tq
@@ -43,7 +43,8 @@ transitioning javascript builtin GeneratorPrototypeNextLazyDeoptContinuation(
// Allocating the iterator result object was skipped; allocate it here.
if (result == TheHole) {
- return AllocateJSIteratorResult(yieldedValue, False);
+ const val = (yieldedValue == TheHole) ? Undefined : yieldedValue;
+ return AllocateJSIteratorResult(val, False);
}
return result;
diff --git a/deps/v8/src/builtins/ia32/builtins-ia32.cc b/deps/v8/src/builtins/ia32/builtins-ia32.cc
index 603ea966edb..4af3c368c7c 100644
--- a/deps/v8/src/builtins/ia32/builtins-ia32.cc
+++ b/deps/v8/src/builtins/ia32/builtins-ia32.cc
@@ -3373,6 +3373,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register promise,
Register return_value, Register context, Register tmp,
Register tmp2) {
+ DCHECK_NE(tmp, tmp2);
Register active_stack = tmp;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3384,7 +3385,10 @@ void ReloadParentStack(MacroAssembler* masm, Register promise,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {promise, return_value, context, parent});
+ __ mov(tmp, Operand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false);
+ __ mov(MemOperand(ebp, WasmJspiFrameConstants::kParentReturnAddressOffset),
+ tmp);
}
// Loads the context field of the WasmTrustedInstanceData or WasmImportData
@@ -3524,6 +3528,8 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, Register tmp,
}
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ jmp(MemOperand(ebp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -3746,6 +3752,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
if (stack_switch) {
SwitchBackAndReturnPromise(masm, edx, edi, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
@@ -3852,6 +3859,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ cmp(kJavaScriptCallArgCountRegister, Immediate(JSParameterCount(1)));
+ __ Check(equal, AbortReason::kJSSignatureMismatch);
+
__ EnterFrame(StackFrame::WASM_JSPI);
Register closure = kJSFunctionRegister; // edi
@@ -5287,7 +5297,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ mov(ecx, FieldOperand(edi, offsetof(JSFunction, shared_function_info_)));
__ movzx_w(ecx, FieldOperand(ecx, offsetof(SharedFunctionInfo,
formal_parameter_count_)));
diff --git a/deps/v8/src/builtins/iterator-helpers.tq b/deps/v8/src/builtins/iterator-helpers.tq
index 38ec255f000..50bf3b492b5 100644
--- a/deps/v8/src/builtins/iterator-helpers.tq
+++ b/deps/v8/src/builtins/iterator-helpers.tq
@@ -1750,6 +1750,7 @@ transitioning macro IteratorZipHelperNextCommon(
// ii. Return ? IteratorCloseAll(openIters, result).
iterators.objects[kIteratorRecordFieldCount * i] = TheHole;
IteratorZipCloseAll(iterators, false);
+ MarkIteratorHelperAsExhausted(helper);
goto DoneWithException(exception, message);
} label IterDone {
// d. If result is done, then
@@ -1809,6 +1810,7 @@ transitioning macro IteratorZipHelperNextCommon(
// ii. Return ? IteratorCloseAll(openIters, open).
iterators.objects[kIteratorRecordFieldCount * k] = TheHole;
IteratorZipCloseAll(iterators, false);
+ MarkIteratorHelperAsExhausted(helper);
goto DoneWithException(e, message);
} label InnerDone {
// v. If open is done, then
@@ -2119,17 +2121,21 @@ transitioning javascript builtin IteratorPrototypeIncludes(
}
// 6. If toSkip < -0𝔽, then
- if (toSkip < 0) {
- // a. Let error be ThrowCompletion(a newly created RangeError object).
- // b. Return ? IteratorClose(iterated, error).
+ // a. Let error be ThrowCompletion(a newly created RangeError object).
+ // b. Return ? IteratorClose(iterated, error).
+ // 7. If toSkip is finite and toSkip > 𝔽(2^53 - 1), then
+ // a. Let error be ThrowCompletion(a newly created RangeError object).
+ // b. Return ? IteratorClose(iterated, error).
+ if (toSkip < 0 ||
+ (!NumberIsSomeInfinity(toSkip) && toSkip > kMaxSafeInteger)) {
IteratorCloseOnException(o);
ThrowRangeError(MessageTemplate::kMustBePositive, skippedElements);
}
- // 7. Let skipped be +0𝔽.
+ // 8. Let skipped be +0𝔽.
let skipped: Number = 0;
- // 8. Set iterated to ? GetIteratorDirect(O).
+ // 9. Set iterated to ? GetIteratorDirect(O).
const iterated = GetIteratorDirect(o);
const fastIteratorResultMap = GetIteratorResultMap();
diff --git a/deps/v8/src/builtins/iterator.tq b/deps/v8/src/builtins/iterator.tq
index a3880479e06..3dc42371b1c 100644
--- a/deps/v8/src/builtins/iterator.tq
+++ b/deps/v8/src/builtins/iterator.tq
@@ -385,9 +385,9 @@ transitioning javascript builtin AsyncIteratorPrototypeAsyncDispose(
const returnMethod =
GetMethod(receiver, kReturnString) otherwise IfUndefined;
// 6. Else,
- // a. Let result be Call(return, O, « undefined »).
+ // a. Let result be Call(return, O, « »).
// b. IfAbruptRejectPromise(result, promiseCapability).
- const result = Call(context, returnMethod, receiver, Undefined);
+ const result = Call(context, returnMethod, receiver);
// c. Let resultWrapper be Completion(PromiseResolve(%Promise%, result)).
// d. IfAbruptRejectPromise(resultWrapper, promiseCapability).
diff --git a/deps/v8/src/builtins/js-trampoline-assembler.cc b/deps/v8/src/builtins/js-trampoline-assembler.cc
index 0eec800258c..1f5c17a22c5 100644
--- a/deps/v8/src/builtins/js-trampoline-assembler.cc
+++ b/deps/v8/src/builtins/js-trampoline-assembler.cc
@@ -158,18 +158,24 @@ TF_BUILTIN(OptimizeTurbofanEager, JSTrampolineAssembler) {
TF_BUILTIN(MarkLazyDeoptimized, JSTrampolineAssembler) {
TieringBuiltinImpl([&](TNode<Context> context, TNode<JSFunction> function) {
- CallRuntime(Runtime::kMarkLazyDeoptimized, context, function,
+ CallRuntime(Runtime::kMarkLazyDeoptimizedOrFlushed, context, function,
/* reoptimize */ SmiConstant(false));
});
}
TF_BUILTIN(MarkReoptimizeLazyDeoptimized, JSTrampolineAssembler) {
TieringBuiltinImpl([&](TNode<Context> context, TNode<JSFunction> function) {
- CallRuntime(Runtime::kMarkLazyDeoptimized, context, function,
+ CallRuntime(Runtime::kMarkLazyDeoptimizedOrFlushed, context, function,
/* reoptimize */ SmiConstant(true));
});
}
+TF_BUILTIN(MarkFlushed, JSTrampolineAssembler) {
+ TieringBuiltinImpl([&](TNode<Context> context, TNode<JSFunction> function) {
+ CallRuntime(Runtime::kMarkLazyDeoptimizedOrFlushed, context, function,
+ /* reoptimize */ SmiConstant(false));
+ });
+}
#include "src/codegen/undef-code-stub-assembler-macros.inc"
diff --git a/deps/v8/src/builtins/loong64/builtins-loong64.cc b/deps/v8/src/builtins/loong64/builtins-loong64.cc
index 042043bef99..1257a6ee3b0 100644
--- a/deps/v8/src/builtins/loong64/builtins-loong64.cc
+++ b/deps/v8/src/builtins/loong64/builtins-loong64.cc
@@ -391,7 +391,7 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
Register dispatch_handle = kJavaScriptCallDispatchHandleRegister;
Register code = kJavaScriptCallCodeStartRegister;
Register scratch = t5;
- __ Ld_w(dispatch_handle,
+ __ Ld_wu(dispatch_handle,
FieldMemOperand(a5, offsetof(JSFunction, dispatch_handle_)));
__ LoadEntrypointAndParameterCountFromJSDispatchTable(
code, argc, dispatch_handle, scratch);
@@ -3237,6 +3237,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register return_reg,
Register return_value, Register context, Register tmp1,
Register tmp2, Register tmp3) {
+ DCHECK(!AreAliased(tmp1, tmp2, tmp3));
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3250,7 +3251,10 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {return_reg, return_value, context, parent});
+ __ Ld_d(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false, tmp3);
+ __ St_d(tmp1,
+ MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void RestoreParentSuspender(MacroAssembler* masm, Register tmp1) {
@@ -3519,6 +3523,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ Check(eq, AbortReason::kJSSignatureMismatch,
+ kJavaScriptCallArgCountRegister, Operand(JSParameterCount(1)));
+
auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
__ EnterFrame(StackFrame::WASM_JSPI);
@@ -3957,6 +3964,10 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, RegisterAllocator& regs,
FREE_REG(return_value);
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ Ld_d(tmp,
+ MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
+ __ Jump(tmp);
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -4198,6 +4209,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, regs, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
@@ -5353,7 +5365,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ InvokeFunction(a1, a0, InvokeType::kJump, ArgumentAdaptionMode::kAdapt);
}
diff --git a/deps/v8/src/builtins/mips64/builtins-mips64.cc b/deps/v8/src/builtins/mips64/builtins-mips64.cc
index 3d7b34af866..e811c841236 100644
--- a/deps/v8/src/builtins/mips64/builtins-mips64.cc
+++ b/deps/v8/src/builtins/mips64/builtins-mips64.cc
@@ -391,8 +391,8 @@ void Builtins::Generate_ResumeGeneratorTrampoline(MacroAssembler* masm) {
Register argc = kJavaScriptCallArgCountRegister;
Register dispatch_handle = kJavaScriptCallDispatchHandleRegister;
Register code = kJavaScriptCallCodeStartRegister;
- __ Lw(dispatch_handle,
- FieldMemOperand(a5, offsetof(JSFunction, dispatch_handle_)));
+ __ Lwu(dispatch_handle,
+ FieldMemOperand(a5, offsetof(JSFunction, dispatch_handle_)));
__ LoadEntrypointAndParameterCountFromJSDispatchTable(code, argc,
dispatch_handle, t3);
// In case the formal parameter count is kDontAdaptArgumentsSentinel the
@@ -4223,7 +4223,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ InvokeFunction(a1, a0, InvokeType::kJump, ArgumentAdaptionMode::kAdapt);
}
diff --git a/deps/v8/src/builtins/ppc/builtins-ppc.cc b/deps/v8/src/builtins/ppc/builtins-ppc.cc
index b19567abf28..60be0d9367c 100644
--- a/deps/v8/src/builtins/ppc/builtins-ppc.cc
+++ b/deps/v8/src/builtins/ppc/builtins-ppc.cc
@@ -426,7 +426,9 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
Label next;
__ Move(r4, ExternalReference::address_of_log_or_trace_osr());
__ LoadU8(r4, MemOperand(r4));
- __ andi(r0, r4, Operand(0xFF)); // Mask to the LSB.
+ UseScratchRegisterScope temps(masm);
+ Register scratch = temps.Acquire();
+ __ andi(scratch, r4, Operand(0xFF)); // Mask to the LSB.
__ beq(&next, cr0);
{
@@ -471,10 +473,12 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
LeaveRC);
// Compute the target address = code start + osr_offset
- __ add(r0, r3, r4);
+ UseScratchRegisterScope temps(masm);
+ Register scratch = temps.Acquire();
+ __ add(scratch, r3, r4);
// And "return" to the OSR entry point of the function.
- __ mtlr(r0);
+ __ mtlr(scratch);
__ blr();
}
}
@@ -1826,7 +1830,7 @@ void Builtins::Generate_InterpreterPushArgsThenFastConstructFunction(
Label non_constructor;
__ LoadMap(r5, r4);
__ lbz(r5, FieldMemOperand(r5, offsetof(Map, bit_field_)));
- __ TestBit(r5, Map::Bits1::IsConstructorBit::kShift, r0);
+ __ TestBit(r5, Map::Bits1::IsConstructorBit::kShift);
__ beq(&non_constructor, cr0);
// Add a stack check before pushing arguments.
@@ -1993,7 +1997,7 @@ static void Generate_InterpreterEnterBytecode(MacroAssembler* masm) {
if (v8_flags.debug_code) {
// Check function data field is actually a BytecodeArray object.
- __ TestIfSmi(kInterpreterBytecodeArrayRegister, r0);
+ __ TestIfSmi(kInterpreterBytecodeArrayRegister);
__ Assert(ne,
AbortReason::kFunctionDataShouldBeBytecodeArrayOnInterpreterEntry,
cr0);
@@ -2208,7 +2212,7 @@ static void GenerateCall(MacroAssembler* masm, Register argc, Register target,
DCHECK(!AreAliased(argc, target, flags));
__ lbz(flags, FieldMemOperand(map, offsetof(Map, bit_field_)));
map = no_reg;
- __ TestBit(flags, Map::Bits1::IsCallableBit::kShift, r0);
+ __ TestBit(flags, Map::Bits1::IsCallableBit::kShift);
__ beq(&non_callable, cr0);
}
@@ -2588,7 +2592,7 @@ void Builtins::Generate_CallOrConstructForwardVarargs(MacroAssembler* masm,
__ LoadTaggedField(scratch,
FieldMemOperand(r6, offsetof(HeapObject, map_)));
__ lbz(scratch, FieldMemOperand(scratch, offsetof(Map, bit_field_)));
- __ TestBit(scratch, Map::Bits1::IsConstructorBit::kShift, r0);
+ __ TestBit(scratch, Map::Bits1::IsConstructorBit::kShift);
__ bne(&new_target_constructor, cr0);
__ bind(&new_target_not_constructor);
{
@@ -2937,7 +2941,7 @@ void Builtins::Generate_Construct(MacroAssembler* masm) {
Register flags = r5;
DCHECK(!AreAliased(r3, target, map, instance_type, flags));
__ lbz(flags, FieldMemOperand(map, offsetof(Map, bit_field_)));
- __ TestBit(flags, Map::Bits1::IsConstructorBit::kShift, r0);
+ __ TestBit(flags, Map::Bits1::IsConstructorBit::kShift);
__ beq(&non_constructor, cr0);
}
@@ -3271,6 +3275,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register return_reg,
Register return_value, Register context, Register tmp1,
Register tmp2, Register tmp3) {
+ DCHECK(!AreAliased(tmp1, tmp2, tmp3));
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3283,7 +3288,10 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {return_reg, return_value, context, parent});
+ __ LoadU64(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false, tmp3);
+ __ StoreU64(
+ tmp1, MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void RestoreParentSuspender(MacroAssembler* masm, Register tmp1) {
@@ -3527,6 +3535,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ CmpS64(kJavaScriptCallArgCountRegister, Operand(JSParameterCount(1)));
+ __ Check(eq, AbortReason::kJSSignatureMismatch);
+
auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
__ EnterFrame(StackFrame::WASM_JSPI);
@@ -3985,6 +3996,10 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, RegisterAllocator& regs,
FREE_REG(promise);
FREE_REG(return_value);
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ LoadU64(
+ tmp, MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
+ __ Jump(tmp);
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -4219,6 +4234,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, regs, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
@@ -4476,9 +4492,7 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// r14: still holds argc (C caller-saved).
__ LeaveExitFrame();
if (argv_mode == ArgvMode::kStack) {
- DCHECK(!AreAliased(scratch, argc_sav));
- __ ShiftLeftU64(scratch, argc_sav, Operand(kSystemPointerSizeLog2));
- __ AddS64(sp, sp, scratch);
+ __ Drop(argc_sav);
}
__ blr();
@@ -4609,7 +4623,7 @@ void Builtins::Generate_DoubleToI(MacroAssembler* masm) {
result_reg, d0);
// Test for overflow
- __ TestIfInt32(result_reg, r0);
+ __ TestIfInt32(result_reg);
__ beq(&fastpath_done);
__ Push(scratch_high, scratch_low);
@@ -5251,7 +5265,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ LoadTaggedField(
r5, FieldMemOperand(r4, offsetof(JSFunction, shared_function_info_)));
__ LoadU16(r5, FieldMemOperand(r5, offsetof(SharedFunctionInfo,
diff --git a/deps/v8/src/builtins/promise-try.tq b/deps/v8/src/builtins/promise-try.tq
index f08df498552..48a4506911f 100644
--- a/deps/v8/src/builtins/promise-try.tq
+++ b/deps/v8/src/builtins/promise-try.tq
@@ -8,15 +8,47 @@ namespace promise {
@incrementUseCounter('v8::Isolate::kPromiseTry')
transitioning javascript builtin PromiseTry(
js-implicit context: Context, receiver: JSAny)(...arguments): JSAny {
- // 1. Let C be the this value.
- // 2. If C is not an Object, throw a TypeError exception.
+ // 1. Let ctor be the this value.
+ // 2. If ctor is not an Object, throw a TypeError exception.
const receiver = Cast<JSReceiver>(receiver)
otherwise ThrowTypeError(MessageTemplate::kCalledOnNonObject, 'Promise.try');
- // 3. Let promiseCapability be ? NewPromiseCapability(C).
- const capability = NewPromiseCapability(receiver, False);
+ if (!HasJsPr3883Flag()) {
+ // Legacy behavior before PR 3883:
+ // 3. Let promiseCapability be ? NewPromiseCapability(C).
+ const capability = NewPromiseCapability(receiver, False);
- // 4. Let status be Completion(Call(callbackfn, undefined, args)).
+ // 4. Let status be Completion(Call(callbackfn, undefined, args)).
+ const callbackfn = arguments[0];
+ let result: JSAny;
+ try {
+ if (arguments.length <= 1) {
+ result = Call(context, callbackfn, Undefined);
+ } else {
+ const rest = NewRestArgumentsFromArguments(arguments, 1);
+ result = Call(
+ context, GetReflectApply(), Undefined, callbackfn, Undefined, rest);
+ }
+ } catch (e, _message) {
+ // 5. If status is an abrupt completion, then
+ // a. Perform ? Call(promiseCapability.[[Reject]], undefined, «
+ // status.[[Value]] »).
+ Call(context, UnsafeCast<Callable>(capability.reject), Undefined, e);
+
+ // 7. Return promiseCapability.[[Promise]].
+ return capability.promise;
+ }
+
+ // 6. Else,
+ // a. Perform ? Call(promiseCapability.[[Resolve]], undefined, «
+ // status.[[Value]] »).
+ Call(context, UnsafeCast<Callable>(capability.resolve), Undefined, result);
+
+ // 7. Return promiseCapability.[[Promise]].
+ return capability.promise;
+ }
+
+ // 3. Let status be Completion(Call(callback, undefined, args)).
const callbackfn = arguments[0];
let result: JSAny;
try {
@@ -28,22 +60,19 @@ transitioning javascript builtin PromiseTry(
context, GetReflectApply(), Undefined, callbackfn, Undefined, rest);
}
} catch (e, _message) {
- // 5. If status is an abrupt completion, then
- // a. Perform ? Call(promiseCapability.[[Reject]], undefined, «
+ // 4. If status is an abrupt completion, then
+ // a. Let promiseCapability be ? NewPromiseCapability(ctor).
+ // b. Perform ? Call(promiseCapability.[[Reject]], undefined, «
// status.[[Value]] »).
+ // c. Return promiseCapability.[[Promise]].
+ const capability = NewPromiseCapability(receiver, False);
Call(context, UnsafeCast<Callable>(capability.reject), Undefined, e);
-
- // 7. Return promiseCapability.[[Promise]].
return capability.promise;
}
- // 6. Else,
- // a. Perform ? Call(promiseCapability.[[Resolve]], undefined, «
- // status.[[Value]] »).
- Call(context, UnsafeCast<Callable>(capability.resolve), Undefined, result);
-
- // 7. Return promiseCapability.[[Promise]].
- return capability.promise;
+ // 5. Else,
+ // a. Return ? PromiseResolve(ctor, ! status).
+ return PromiseResolve(receiver, result);
}
} // namespace promise
diff --git a/deps/v8/src/builtins/regexp-match-all.tq b/deps/v8/src/builtins/regexp-match-all.tq
index fa777e4cf7c..9871d2604bf 100644
--- a/deps/v8/src/builtins/regexp-match-all.tq
+++ b/deps/v8/src/builtins/regexp-match-all.tq
@@ -9,6 +9,11 @@ namespace regexp {
extern transitioning macro RegExpMatchAllAssembler::CreateRegExpStringIterator(
NativeContext, JSAny, String, bool, bool): JSAny;
+const kRegExpMatcherFlagsMismatch: constexpr UseCounterFeature
+ generates 'v8::Isolate::kRegExpMatcherFlagsMismatch';
+const kRegExpCustomSpecies: constexpr UseCounterFeature
+ generates 'v8::Isolate::kRegExpCustomSpecies';
+
@export
transitioning macro RegExpPrototypeMatchAllImpl(
implicit context: Context)(nativeContext: NativeContext, receiver: JSAny,
@@ -62,6 +67,9 @@ transitioning macro RegExpPrototypeMatchAllImpl(
const regexpFun = LoadRegExpFunction(nativeContext);
const speciesConstructor =
UnsafeCast<Constructor>(SpeciesConstructor(receiver, regexpFun));
+ if (speciesConstructor != regexpFun) {
+ IncrementUseCounter(context, SmiConstant(kRegExpCustomSpecies));
+ }
// 5. Let flags be ? ToString(? Get(R, "flags")).
const flags = GetProperty(receiver, 'flags');
@@ -91,6 +99,25 @@ transitioning macro RegExpPrototypeMatchAllImpl(
const unicodeSetsIndex: Smi =
StringIndexOf(flagsString, unicodeSetsCharString, 0);
unicode = unicodeIndex != -1 || unicodeSetsIndex != -1;
+
+ let hasFlagMismatch: bool = false;
+ typeswitch (matcher) {
+ case (matcherRegExp: JSRegExp): {
+ const isGlobal: bool = FastFlagGetter(matcherRegExp, Flag::kGlobal);
+ const isUnicode: bool =
+ FastFlagGetter(matcherRegExp, Flag::kUnicode) ||
+ FastFlagGetter(matcherRegExp, Flag::kUnicodeSets);
+ if (isGlobal != global || isUnicode != unicode) {
+ hasFlagMismatch = true;
+ }
+ }
+ case (Object): {
+ hasFlagMismatch = true;
+ }
+ }
+ if (hasFlagMismatch) {
+ IncrementUseCounter(context, SmiConstant(kRegExpMatcherFlagsMismatch));
+ }
}
}
@@ -140,14 +167,27 @@ transitioning javascript builtin RegExpStringIteratorPrototypeNext(
try {
if (IsFastRegExpPermissive(iteratingRegExp)) {
const regexp = UnsafeCast<JSRegExp>(iteratingRegExp);
- const lastIndex = LoadLastIndexAsLength(regexp, true);
- const matchIndices: RegExpMatchInfo =
- RegExpPrototypeExecBodyWithoutResultFast(
- regexp, iteratingString, lastIndex)
- otherwise IfNoMatch;
- match = ConstructNewResultFromMatchInfo(
- regexp, matchIndices, iteratingString, lastIndex);
- isFastRegExp = true;
+ // Only use the fast path if there aren't flag mismatches.
+ // Note that this condition uses bitwise operations to prevent
+ // short-circuit evaluation.
+ const isGlobal = FastFlagGetter(regexp, Flag::kGlobal);
+ const isUnicode = FastFlagGetter(regexp, Flag::kUnicode) |
+ FastFlagGetter(regexp, Flag::kUnicodeSets);
+ if ((isGlobal == flags.global) & (isUnicode == flags.unicode)) {
+ const lastIndex = LoadLastIndexAsLength(regexp, true);
+ const matchIndices: RegExpMatchInfo =
+ RegExpPrototypeExecBodyWithoutResultFast(
+ regexp, iteratingString, lastIndex)
+ otherwise IfNoMatch;
+ match = ConstructNewResultFromMatchInfo(
+ regexp, matchIndices, iteratingString, lastIndex);
+ isFastRegExp = true;
+ } else {
+ match = RegExpExec(iteratingRegExp, iteratingString);
+ if (match == Null) {
+ goto IfNoMatch;
+ }
+ }
} else {
match = RegExpExec(iteratingRegExp, iteratingString);
if (match == Null) {
diff --git a/deps/v8/src/builtins/riscv/builtins-riscv.cc b/deps/v8/src/builtins/riscv/builtins-riscv.cc
index 34272b84539..e35e8861d0d 100644
--- a/deps/v8/src/builtins/riscv/builtins-riscv.cc
+++ b/deps/v8/src/builtins/riscv/builtins-riscv.cc
@@ -2178,8 +2178,7 @@ void OnStackReplacement(MacroAssembler* masm, OsrSourceTier source,
// Check we are actually jumping to an OSR code object. This among other
// things ensures that the object contains deoptimization data below.
- __ Load32U(scratch,
- FieldMemOperand(maybe_target_code, Code::kOsrOffsetOffset));
+ __ Lw(scratch, FieldMemOperand(maybe_target_code, Code::kOsrOffsetOffset));
__ SbxCheck(ne, AbortReason::kExpectedOsrCode, scratch,
Operand(BytecodeOffset::None().ToInt()));
@@ -3572,8 +3571,6 @@ void Builtins::Generate_CEntry(MacroAssembler* masm, int result_size,
// Stack unwinding and popchk shadow stack before function return.
// The num_frames_above_handler been modified in
// Runtime::kUnwindAndFindExceptionHandler.
- ER num_frames_above_pending_handler_address = ER::Create(
- IsolateAddressId::kNumFramesAbovePendingHandlerAddress, masm->isolate());
__ LoadWord(t1,
__ AsMemOperand(IsolateFieldId::kNumFramesAbovePendingHandler));
Label popchk_start;
@@ -3907,6 +3904,7 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
Register return_value, Register context, Register tmp1,
Register tmp2, Register tmp3) {
ASM_CODE_COMMENT(masm);
+ DCHECK(!AreAliased(tmp1, tmp2, tmp3));
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3921,7 +3919,10 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, tmp3,
{return_reg, return_value, context, parent});
+ __ LoadWord(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false, tmp3);
+ __ StoreWord(
+ tmp1, MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void RestoreParentSuspender(MacroAssembler* masm, Register tmp1) {
@@ -4004,6 +4005,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ Check(eq, AbortReason::kJSSignatureMismatch,
+ kJavaScriptCallArgCountRegister, Operand(JSParameterCount(1)));
+
auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
UseScratchRegisterScope temps(masm);
__ EnterFrame(StackFrame::WASM_JSPI);
@@ -4476,6 +4480,10 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, RegisterAllocator& regs,
FREE_REG(promise);
FREE_REG(return_value);
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ LoadWord(
+ tmp, MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
+ __ Jump(tmp);
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -4719,6 +4727,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, regs, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
@@ -5540,7 +5549,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
#if defined(V8_TARGET_ARCH_RISCV64)
__ InvokeFunction(a1, a0, InvokeType::kJump, ArgumentAdaptionMode::kAdapt);
#else
diff --git a/deps/v8/src/builtins/s390/builtins-s390.cc b/deps/v8/src/builtins/s390/builtins-s390.cc
index 14661596fa9..78f88bc4726 100644
--- a/deps/v8/src/builtins/s390/builtins-s390.cc
+++ b/deps/v8/src/builtins/s390/builtins-s390.cc
@@ -3264,6 +3264,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register return_reg,
Register return_value, Register context, Register tmp1,
Register tmp2, Register tmp3) {
+ DCHECK(!AreAliased(tmp1, tmp2, tmp3));
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3276,7 +3277,10 @@ void ReloadParentStack(MacroAssembler* masm, Register return_reg,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {return_reg, return_value, context, parent});
+ __ LoadU64(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false, tmp3);
+ __ StoreU64(
+ tmp1, MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void RestoreParentSuspender(MacroAssembler* masm, Register tmp1) {
@@ -3520,6 +3524,9 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ CmpS64(kJavaScriptCallArgCountRegister, Operand(JSParameterCount(1)));
+ __ Check(eq, AbortReason::kJSSignatureMismatch);
+
auto regs = RegisterAllocator::WithAllocatableGeneralRegisters();
__ EnterFrame(StackFrame::WASM_JSPI);
@@ -3980,6 +3987,10 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, RegisterAllocator& regs,
FREE_REG(promise);
FREE_REG(return_value);
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ LoadU64(
+ tmp, MemOperand(fp, WasmJspiFrameConstants::kParentReturnAddressOffset));
+ __ Jump(tmp);
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -4213,6 +4224,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, regs, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
@@ -5272,7 +5284,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ LoadTaggedField(
r4, FieldMemOperand(r3, offsetof(JSFunction, shared_function_info_)));
__ LoadU16(r4, FieldMemOperand(r4, offsetof(SharedFunctionInfo,
diff --git a/deps/v8/src/builtins/typed-array-set.tq b/deps/v8/src/builtins/typed-array-set.tq
index 51562299edc..c77e07a0f42 100644
--- a/deps/v8/src/builtins/typed-array-set.tq
+++ b/deps/v8/src/builtins/typed-array-set.tq
@@ -55,14 +55,23 @@ transitioning javascript builtin TypedArrayPrototypeSet(
arguments.length > 1 ? arguments[1] : SmiConstant(0);
typeswitch (offsetArg) {
case (offsetSmi: Smi): {
- // 5. Let targetOffset be ? ToInteger(offset).
+ // 5. Let targetOffset be ? ToIntegerOrInfinity(offset).
// 6. If targetOffset < 0, throw a RangeError exception.
- if (offsetSmi < 0) goto OffsetOutOfBounds;
+ if (offsetSmi < 0) {
+ // For negative Smi offsets, integer conversion has no side effects,
+ // but we still need to perform step 4 before throwing a RangeError.
+ // 4. If IsImmutableBuffer(target.[[ViewedArrayBuffer]]) is true,
+ // throw a TypeError exception.
+ if (IsImmutableArrayBuffer(target.buffer)) deferred {
+ goto Fail;
+ }
+ goto OffsetOutOfBounds;
+ }
targetOffset = Unsigned(SmiUntag(offsetSmi));
- // For Smi offsets, integer conversion has no side effects, so step 4
- // (IsImmutableBuffer check) can be deferred and combined with steps 7-9
- // in EnsureValidAndReadLength without observable differences.
+ // For non-negative Smi offsets, integer conversion has no side effects,
+ // so step 4 (IsImmutableBuffer check) can be deferred and combined with
+ // steps 7-9 in EnsureValidAndReadLength without observable differences.
// 4. If IsImmutableBuffer(target.[[ViewedArrayBuffer]]) is true, throw
// a TypeError exception.
// 7. Let targetBuffer be target.[[ViewedArrayBuffer]].
@@ -79,7 +88,7 @@ transitioning javascript builtin TypedArrayPrototypeSet(
goto Fail;
}
- // 5. Let targetOffset be ? ToInteger(offset).
+ // 5. Let targetOffset be ? ToIntegerOrInfinity(offset).
// 6. If targetOffset < 0, throw a RangeError exception.
try {
targetOffset = ToUintPtr(offsetOther)
diff --git a/deps/v8/src/builtins/wasm-strings.tq b/deps/v8/src/builtins/wasm-strings.tq
index 9f8a4ab5ba6..7080bc11197 100644
--- a/deps/v8/src/builtins/wasm-strings.tq
+++ b/deps/v8/src/builtins/wasm-strings.tq
@@ -27,6 +27,11 @@ transitioning javascript builtin WebAssemblyStringTest(
extern runtime WasmCastToSpecialPrimitiveArray(
Context, Object, Smi, Smi): WasmArray;
+const kWtf16Unshared: constexpr int31
+ generates 'UnicodeConfig::kWtf16Unshared().raw_as_int()';
+const kWtf16Shared: constexpr int31
+ generates 'UnicodeConfig::kWtf16Shared().raw_as_int()';
+
transitioning javascript builtin WebAssemblyStringFromWtf16Array(
js-implicit context: Context)(arrayArg: JSAny, startArg: JSAny,
endArg: JSAny): JSAny {
@@ -34,7 +39,8 @@ transitioning javascript builtin WebAssemblyStringFromWtf16Array(
context, arrayArg, SmiConstant(16), SmiConstant(0));
const start = NumberToUint32(ToNumber_Inline(startArg));
const end = NumberToUint32(ToNumber_Inline(endArg));
- return wasm::WasmStringNewWtf16Array(array, start, end);
+ return wasm::WasmStringNewWtf16Array(
+ array, start, end, SmiConstant(kWtf16Unshared));
}
transitioning javascript builtin WebAssemblyStringFromWtf16ArrayShared(
@@ -44,11 +50,16 @@ transitioning javascript builtin WebAssemblyStringFromWtf16ArrayShared(
context, arrayArg, SmiConstant(16), SmiConstant(1));
const start = NumberToUint32(ToNumber_Inline(startArg));
const end = NumberToUint32(ToNumber_Inline(endArg));
- return wasm::WasmStringNewWtf16ArrayShared(array, start, end);
+ return wasm::WasmStringNewWtf16Array(
+ array, start, end, SmiConstant(kWtf16Shared));
}
-const kLossyUtf8:
- constexpr int31 generates 'unibrow::Utf8Variant::kLossyUtf8';
+const kLossyUtf8: constexpr int31
+ generates 'unibrow::Utf8Variant::kLossyUtf8';
+const kLossyUtf8Unshared: constexpr int31
+ generates 'UnicodeConfig::kLossyUtf8Unshared().raw_as_int()';
+const kLossyUtf8Shared: constexpr int31
+ generates 'UnicodeConfig::kLossyUtf8Shared().raw_as_int()';
transitioning javascript builtin WebAssemblyStringFromUtf8Array(
js-implicit context: Context)(arrayArg: JSAny, startArg: JSAny,
@@ -58,7 +69,7 @@ transitioning javascript builtin WebAssemblyStringFromUtf8Array(
const start = NumberToUint32(ToNumber_Inline(startArg));
const end = NumberToUint32(ToNumber_Inline(endArg));
const result = wasm::WasmStringNewWtf8Array(
- start, end, array, SmiConstant(kLossyUtf8), SmiConstant(0) /* shared */);
+ start, end, array, SmiConstant(kLossyUtf8Unshared));
dcheck(Is<String>(result));
return %RawDownCast<String>(result);
}
@@ -71,7 +82,7 @@ transitioning javascript builtin WebAssemblyStringFromUtf8ArrayShared(
const start = NumberToUint32(ToNumber_Inline(startArg));
const end = NumberToUint32(ToNumber_Inline(endArg));
const result = wasm::WasmStringNewWtf8Array(
- start, end, array, SmiConstant(kLossyUtf8), SmiConstant(1) /* shared */);
+ start, end, array, SmiConstant(kLossyUtf8Shared));
dcheck(Is<String>(result));
return %RawDownCast<String>(result);
}
diff --git a/deps/v8/src/builtins/wasm.tq b/deps/v8/src/builtins/wasm.tq
index 937c259d000..9f06bebc51a 100644
--- a/deps/v8/src/builtins/wasm.tq
+++ b/deps/v8/src/builtins/wasm.tq
@@ -60,10 +60,10 @@ extern runtime WasmArrayInitSegment(
extern runtime WasmStringNewWtf8(
Context, WasmTrustedInstanceData, Smi, Smi, Number, Number): String
|WasmNull;
-extern runtime WasmStringNewWtf8Array(Context, Smi, WasmArray, Smi, Smi, Smi):
- String|WasmNull;
+extern runtime WasmStringNewWtf8Array(Context, Smi, WasmArray, Smi, Smi): String
+ |WasmNull;
extern runtime WasmStringNewWtf16(
- Context, WasmTrustedInstanceData, Smi, Number, Number): String;
+ Context, WasmTrustedInstanceData, Smi, Number, Number, Smi): String;
extern runtime WasmStringNewWtf16Array(Context, WasmArray, Smi, Smi, Smi):
String;
extern runtime WasmStringConst(Context, WasmTrustedInstanceData, Smi): String;
@@ -107,6 +107,8 @@ extern macro Allocate(intptr): HeapObject;
extern macro Allocate(intptr, constexpr AllocationFlag): HeapObject;
}
+extern macro Retain(Object): void;
+
macro NumberToInt32(input: Number): int32 {
return Convert<int32>(input);
}
@@ -167,19 +169,15 @@ builtin WasmInt32ToSharedHeapNumber(val: int32): HeapNumber {
builtin WasmFuncRefToJS(
implicit context: Context)(val: WasmFuncRef|WasmNull): JSFunction|Null {
- typeswitch (val) {
- case (WasmNull): {
- return Null;
- }
- case (func: WasmFuncRef): {
- const internal: WasmInternalFunction = func.internal;
- const maybeExternal: Object = internal.external;
- if (maybeExternal != Undefined) {
- return %RawDownCast<JSFunction>(maybeExternal);
- }
- tail runtime::WasmInternalFunctionCreateExternal(context, internal);
- }
+ if (val == kWasmNull) return Null;
+
+ const func = Cast<WasmFuncRef>(val) otherwise unreachable;
+ const internal: WasmInternalFunction = func.internal;
+ const maybeExternal: Object = internal.external;
+ if (maybeExternal != Undefined) {
+ return %RawDownCast<JSFunction>(maybeExternal);
}
+ tail runtime::WasmInternalFunctionCreateExternal(context, internal);
}
builtin WasmTaggedNonSmiToInt32(implicit context: Context)(val: HeapObject):
@@ -353,11 +351,10 @@ builtin WasmTableGetFuncRef(tableIndex: intptr, index: intptr): Object {
const entry: HeapObject =
UnsafeCast<HeapObject>(LoadFixedArrayElement(entries, index));
- dcheck(Is<WasmFuncRef>(entry) || Is<WasmNull>(entry) || Is<Tuple2>(entry));
- if (IsTuple2Map(entry.map)) goto CallRuntime;
- if (Is<WasmNull>(entry)) return entry;
- dcheck(Is<WasmFuncRef>(entry));
- return entry;
+ if (entry == kWasmNull) return entry;
+ if (Is<WasmFuncRef>(entry)) return entry;
+ dcheck(IsTuple2Map(entry.map));
+ goto CallRuntime;
} label CallRuntime deferred {
tail runtime::WasmFunctionTableGet(
LoadContextFromInstanceData(trustedData), trustedData,
@@ -381,7 +378,7 @@ builtin WasmFunctionTableGet(tableIndex: intptr, index: intptr): Object {
builtin WasmTableSetFuncRef(
tableIndex: intptr, index: intptr, value: WasmFuncRef): Object {
const trustedData: WasmTrustedInstanceData = LoadInstanceDataFromFrame();
- dcheck(Is<WasmFuncRef>(value) || Is<WasmNull>(value));
+ dcheck(value == kWasmNull || Is<WasmFuncRef>(value));
try {
dcheck(IsValidPositiveSmi(tableIndex));
@@ -948,37 +945,36 @@ macro GetRefAt<T: type, From: type>(base: From, offset: intptr): &T {
extern macro LoadPointerFromRootRegister(intptr): RawPtr;
builtin WasmStringNewWtf8(
- offset: uintptr, size: uint32, memory: uint32, utf8Variant: Smi): String
+ offset: uintptr, size: uint32, memory: uint32, utf8Config: Smi): String
|WasmNull {
const trustedData = LoadInstanceDataFromFrame();
tail runtime::WasmStringNewWtf8(
LoadContextFromInstanceData(trustedData), trustedData,
- SmiFromUint32(memory), utf8Variant, UintPtrToNumberRounding(offset),
+ SmiFromUint32(memory), utf8Config, UintPtrToNumberRounding(offset),
WasmUint32ToNumber(size));
}
builtin WasmStringNewWtf8Array(
- start: uint32, end: uint32, array: WasmArray, utf8Variant: Smi,
- shared: Smi): String|WasmNull {
+ start: uint32, end: uint32, array: WasmArray, utf8Config: Smi): String
+ |WasmNull {
// This can be called from Wasm and from "JS String Builtins".
const context = LoadContextFromWasmOrJsFrame();
try {
if (array.length < end) goto OffsetOutOfRange;
if (end < start) goto OffsetOutOfRange;
tail runtime::WasmStringNewWtf8Array(
- context, utf8Variant, array, SmiFromUint32(start), SmiFromUint32(end),
- shared);
+ context, utf8Config, array, SmiFromUint32(start), SmiFromUint32(end));
} label OffsetOutOfRange deferred {
const error = MessageTemplate::kWasmTrapArrayOutOfBounds;
runtime::ThrowWasmError(context, SmiConstant(error));
}
}
-builtin WasmStringNewWtf16(memory: uint32, offset: uintptr, size: uint32):
- String {
+builtin WasmStringNewWtf16(
+ memory: uint32, offset: uintptr, size: uint32, config: Smi): String {
const trustedData = LoadInstanceDataFromFrame();
tail runtime::WasmStringNewWtf16(
LoadContextFromInstanceData(trustedData), trustedData,
SmiFromUint32(memory), UintPtrToNumberRounding(offset),
- WasmUint32ToNumber(size));
+ WasmUint32ToNumber(size), config);
}
struct TwoByteToOneByteIterator {
@@ -1060,13 +1056,16 @@ macro StringFromTwoByteSlice(length: uint32, slice: ConstSlice<char16>):
});
}
-builtin WasmStringNewWtf16Array(array: WasmArray, start: uint32, end: uint32):
- String {
+builtin WasmStringNewWtf16Array(
+ array: WasmArray, start: uint32, end: uint32, config: Smi): String {
try {
if (array.length < end) goto OffsetOutOfRange;
if (end < start) goto OffsetOutOfRange;
const length: uint32 = end - start;
if (length == 0) return kEmptyString;
+ // TODO(448741522): Support inline creation of short shared Strings.
+ // "config == 0" means both array and string are unshared.
+ if (config != SmiConstant(0)) goto Runtime;
if (length == 1) {
const offset = kWasmArrayHeaderSize +
torque_internal::TimesSizeOf<char16>(Convert<intptr>(start));
@@ -1095,31 +1094,7 @@ builtin WasmStringNewWtf16Array(array: WasmArray, start: uint32, end: uint32):
} label Runtime deferred {
const context = LoadContextFromWasmOrJsFrame();
tail runtime::WasmStringNewWtf16Array(
- context, array, SmiFromUint32(start), SmiFromUint32(end),
- SmiConstant(0) /* shared */);
- }
-}
-
-builtin WasmStringNewWtf16ArrayShared(
- array: WasmArray, start: uint32, end: uint32): String {
- try {
- if (array.length < end) goto OffsetOutOfRange;
- if (end < start) goto OffsetOutOfRange;
- const length: uint32 = end - start;
- if (length == 0) return kEmptyString;
- // TODO(448741522): Inline creation of Strings of size 1 and small size
- // (<32);
- goto Runtime;
- } label OffsetOutOfRange deferred {
- // This can be called from Wasm and from "JS String Builtins".
- const context = LoadContextFromWasmOrJsFrame();
- const error = MessageTemplate::kWasmTrapArrayOutOfBounds;
- runtime::ThrowWasmError(context, SmiConstant(error));
- } label Runtime deferred {
- const context = LoadContextFromWasmOrJsFrame();
- tail runtime::WasmStringNewWtf16Array(
- context, array, SmiFromUint32(start), SmiFromUint32(end),
- SmiConstant(1) /* shared */);
+ context, array, SmiFromUint32(start), SmiFromUint32(end), config);
}
}
@@ -1434,13 +1409,17 @@ transitioning builtin WasmStringViewWtf16Slice(
let subslice = Subslice(
slice, Convert<intptr>(start), Convert<intptr>(clampedLength))
otherwise unreachable;
- return AllocateNonEmptySeqOneByteString(
- clampedLength, subslice.Iterator());
+ const result =
+ AllocateNonEmptySeqOneByteString(clampedLength, subslice.Iterator());
+ Retain(string);
+ return result;
} label TwoByte(slice: ConstSlice<char16>) {
let subslice = Subslice(
slice, Convert<intptr>(start), Convert<intptr>(clampedLength))
otherwise unreachable;
- return StringFromTwoByteSlice(clampedLength, subslice);
+ const result = StringFromTwoByteSlice(clampedLength, subslice);
+ Retain(string);
+ return result;
} label Runtime deferred {
const context = LoadContextFromWasmOrJsFrame();
tail runtime::WasmSubstring(
@@ -1681,38 +1660,39 @@ builtin WasmStringIndexOf(s: String, searchString: String, start: Smi): Smi {
// TODO(mliedtke): It would be nice to type the result as bool, however that is
// not supported.
builtin WasmLiftoffIsEqRefUnshared(obj: Object, nullSucceeds: bool): int32 {
+ if (Is<Smi>(obj)) return 1;
+ if (obj == kWasmNull) return Convert<int32>(nullSucceeds);
try {
- if (Is<Smi>(obj)) {
- return 1;
- }
const heapObject: HeapObject = Cast<HeapObject>(obj) otherwise ReturnFalse;
return Convert<int32>(
!InSharedSpace(heapObject) &&
- (Is<WasmArray>(heapObject) || Is<WasmStruct>(heapObject) ||
- (nullSucceeds && Is<WasmNull>(heapObject))));
- } label ReturnFalse {}
- return 0;
+ (Is<WasmArray>(heapObject) || Is<WasmStruct>(heapObject)));
+ } label ReturnFalse {
+ return 0;
+ }
}
builtin WasmLiftoffIsArrayRefUnshared(obj: Object, nullSucceeds: bool): int32 {
+ if (obj == kWasmNull) return Convert<int32>(nullSucceeds);
try {
const heapObject: HeapObject = Cast<HeapObject>(obj) otherwise ReturnFalse;
return Convert<int32>(
- !InSharedSpace(heapObject) && Is<WasmArray>(heapObject) ||
- (nullSucceeds && Is<WasmNull>(heapObject)));
- } label ReturnFalse {}
- return 0;
+ !InSharedSpace(heapObject) && Is<WasmArray>(heapObject));
+ } label ReturnFalse {
+ return 0;
+ }
}
builtin WasmLiftoffIsStructRefUnshared(obj: Object, nullSucceeds: bool):
int32 {
+ if (obj == kWasmNull) return Convert<int32>(nullSucceeds);
try {
const heapObject: HeapObject = Cast<HeapObject>(obj) otherwise ReturnFalse;
return Convert<int32>(
- !InSharedSpace(heapObject) && Is<WasmStruct>(heapObject) ||
- (nullSucceeds && Is<WasmNull>(heapObject)));
- } label ReturnFalse {}
- return 0;
+ !InSharedSpace(heapObject) && Is<WasmStruct>(heapObject));
+ } label ReturnFalse {
+ return 0;
+ }
}
// Return type JSAny to be able to tail-call ThrowWasmTrapIllegalCast(). It must
@@ -1722,22 +1702,31 @@ builtin WasmLiftoffCastEqRefUnshared(obj: Object, nullSucceeds: bool): JSAny {
if (Is<Smi>(obj)) {
return SmiConstant(0);
}
- const heapObject: HeapObject = UnsafeCast<HeapObject>(obj);
- if (InSharedSpace(heapObject) ||
- (!Is<WasmArray>(heapObject) && !Is<WasmStruct>(heapObject) &&
- (!nullSucceeds || !Is<WasmNull>(heapObject)))) {
+ try {
+ if (obj == kWasmNull) {
+ if (nullSucceeds) return SmiConstant(0);
+ goto IllegalCast;
+ }
+ const heapObject: HeapObject = UnsafeCast<HeapObject>(obj);
+ if (InSharedSpace(heapObject) ||
+ (!Is<WasmArray>(heapObject) && !Is<WasmStruct>(heapObject))) {
+ goto IllegalCast;
+ }
+ return SmiConstant(0);
+ } label IllegalCast {
tail ThrowWasmTrapIllegalCast();
}
- return SmiConstant(0);
}
builtin WasmLiftoffCastArrayRefUnshared(obj: Object, nullSucceeds: bool):
JSAny {
try {
+ if (obj == kWasmNull) {
+ if (nullSucceeds) return SmiConstant(0);
+ goto IllegalCast;
+ }
const heapObject: HeapObject = Cast<HeapObject>(obj) otherwise IllegalCast;
- if (InSharedSpace(heapObject) ||
- (!Is<WasmArray>(heapObject) &&
- (!nullSucceeds || !Is<WasmNull>(heapObject)))) {
+ if (InSharedSpace(heapObject) || (!Is<WasmArray>(heapObject))) {
goto IllegalCast;
}
return SmiConstant(0);
@@ -1749,10 +1738,12 @@ builtin WasmLiftoffCastArrayRefUnshared(obj: Object, nullSucceeds: bool):
builtin WasmLiftoffCastStructRefUnshared(obj: Object, nullSucceeds: bool):
JSAny {
try {
+ if (obj == kWasmNull) {
+ if (nullSucceeds) return SmiConstant(0);
+ goto IllegalCast;
+ }
const heapObject: HeapObject = Cast<HeapObject>(obj) otherwise IllegalCast;
- if (InSharedSpace(heapObject) ||
- (!Is<WasmStruct>(heapObject) &&
- (!nullSucceeds || !Is<WasmNull>(heapObject)))) {
+ if (InSharedSpace(heapObject) || (!Is<WasmStruct>(heapObject))) {
goto IllegalCast;
}
return SmiConstant(0);
diff --git a/deps/v8/src/builtins/x64/builtins-x64.cc b/deps/v8/src/builtins/x64/builtins-x64.cc
index 0d752755c0b..c5cb7ddda09 100644
--- a/deps/v8/src/builtins/x64/builtins-x64.cc
+++ b/deps/v8/src/builtins/x64/builtins-x64.cc
@@ -3190,7 +3190,7 @@ void Builtins::Generate_AdaptShadowStackForDeopt(MacroAssembler* masm) {
__ popq(count_reg);
// Now `kReturnRegister0` is the address we want to jump to.
- __ cmpl(count_reg, Immediate(0));
+ __ Cmp(count_reg, 0);
Label finished;
__ j(equal, &finished, Label::kNear);
// This will jump to CallToAdaptShadowStackForDeopt which call back into this
@@ -3489,6 +3489,7 @@ void SwitchStacks(MacroAssembler* masm, ExternalReference fn,
void ReloadParentStack(MacroAssembler* masm, Register promise,
Register return_value, Register context, Register tmp1,
Register tmp2) {
+ DCHECK_NE(tmp1, tmp2);
Register active_stack = tmp1;
__ LoadRootRelative(active_stack, IsolateData::active_stack_offset());
@@ -3497,7 +3498,10 @@ void ReloadParentStack(MacroAssembler* masm, Register promise,
// Switch stack!
SwitchStacks(masm, ExternalReference::wasm_return_jspi_stack(), parent,
nullptr, no_reg, {promise, return_value, context, parent});
+ __ movq(tmp1, MemOperand(parent, wasm::kStackPcOffset));
LoadJumpBuffer(masm, parent, false);
+ __ movq(MemOperand(rbp, WasmJspiFrameConstants::kParentReturnAddressOffset),
+ tmp1);
}
// Loads the context field of the WasmTrustedInstanceData or WasmImportData
@@ -3621,6 +3625,8 @@ void SwitchBackAndReturnPromise(MacroAssembler* masm, Register tmp1,
}
__ bind(return_promise);
+ // The initial wrapper and a resume callback have different argument cleanup.
+ __ jmp(MemOperand(rbp, WasmJspiFrameConstants::kParentReturnAddressOffset));
}
void GenerateExceptionHandlingLandingPad(MacroAssembler* masm,
@@ -3820,6 +3826,7 @@ void JSToWasmWrapperHelper(MacroAssembler* masm, wasm::Promise mode) {
Label return_promise;
if (stack_switch) {
SwitchBackAndReturnPromise(masm, r8, rdi, mode, &return_promise);
+ __ Trap(); // Unreachable.
}
__ bind(&suspend);
__ endbr64();
@@ -3938,10 +3945,11 @@ namespace {
// forwards the value, the onRejected variant throws the value.
void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
+ __ cmpq(kJavaScriptCallArgCountRegister, Immediate(JSParameterCount(1)));
+ __ Check(equal, AbortReason::kJSSignatureMismatch);
+
__ EnterFrame(StackFrame::WASM_JSPI);
- Register param_count = rax;
- __ decq(param_count); // Exclude receiver.
Register closure = kJSFunctionRegister; // rdi
__ AllocateStackSpace(WasmJspiFrameConstants::kNumSpillSlots *
@@ -3949,8 +3957,6 @@ void Generate_WasmResumeHelper(MacroAssembler* masm, wasm::OnResume on_resume) {
// Set a sentinel value for the spill slots visited by the GC.
ResetWasmJspiFrameStackSlots(masm);
- param_count = no_reg;
-
// -------------------------------------------
// Load suspender from closure.
// -------------------------------------------
@@ -4362,7 +4368,7 @@ void SwitchFromTheCentralStackIfNeeded(MacroAssembler* masm,
using ER = ExternalReference;
Label no_stack_change;
- __ cmpq(kOldSPRegister, Immediate(0));
+ __ Cmpq(kOldSPRegister, 0);
__ j(equal, &no_stack_change);
__ movq(rsp, kOldSPRegister);
@@ -5670,7 +5676,7 @@ void Builtins::Generate_RestartFrameTrampoline(MacroAssembler* masm) {
__ LeaveFrame(StackFrame::INTERPRETED);
// The arguments are already in the stack, but we might need to adapt them
- // if the function signature changed (e.g. via LiveEdit).
+ // if the function signature changed.
__ InvokeFunction(rdi, no_reg, rax, InvokeType::kJump,
ArgumentAdaptionMode::kAdapt);
}
diff --git a/deps/v8/src/codegen/arm64/interface-descriptors-arm64-inl.h b/deps/v8/src/codegen/arm64/interface-descriptors-arm64-inl.h
index b3a40b3b02f..d008fba1b2e 100644
--- a/deps/v8/src/codegen/arm64/interface-descriptors-arm64-inl.h
+++ b/deps/v8/src/codegen/arm64/interface-descriptors-arm64-inl.h
@@ -326,6 +326,14 @@ constexpr auto BinaryOpAndTryPatchCodeDescriptor::registers() {
// x3: feedback offset
return RegisterArray(x1, x0, x2, x3);
}
+
+// static
+constexpr auto UnaryOpAndTryPatchCodeDescriptor::registers() {
+ // x0: value
+ // x2: current feedback value
+ // x3: feedback offset
+ return RegisterArray(x0, x2, x3);
+}
#endif // V8_ENABLE_SPARKPLUG_PLUS
// static
diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc
index f6af185086b..a797c09ef53 100644
--- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc
+++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.cc
@@ -3611,13 +3611,27 @@ void MacroAssembler::DecompressTagged(const Register& destination,
void MacroAssembler::DecompressTagged(const Register& destination,
const Register& source) {
ASM_CODE_COMMENT(this);
- Orr(destination, kPtrComprCageBaseRegister, Operand(source, UXTW));
+ // Runtime values decompress with the cage base or'd in so that accidental
+ // double-decompression is idempotent, but Orr has no extended-register
+ // form, so or-ing a W source takes a scratch register and two instructions
+ // (ubfx + orr). The extended-register Add is a single instruction and
+ // computes the same function: Uxtw strips the high word -- an
+ // already-present cage base included, which is what keeps the idempotence
+ // -- and the 4GB-aligned cage base has no low bits to carry into, so
+ // adding equals or-ing for every source value.
+ Add(destination, kPtrComprCageBaseRegister, Operand(source, UXTW));
}
void MacroAssembler::DecompressTagged(const Register& destination,
Tagged_t immediate) {
ASM_CODE_COMMENT(this);
if (IsImmAddSub(immediate)) {
+ // Runtime values decompress with Orr so that accidental
+ // double-decompression is idempotent, but a constant has no input that
+ // could already be decompressed, and the 4GB-aligned cage base makes Add
+ // equal to Orr for any 32-bit offset. Only Add can encode the offset
+ // directly, though -- Orr would need a (rarely matching) logical
+ // immediate and otherwise materializes through a scratch register.
Add(destination, kPtrComprCageBaseRegister,
Immediate(immediate, RelocInfo::Mode::NO_INFO));
} else {
@@ -3626,7 +3640,7 @@ void MacroAssembler::DecompressTagged(const Register& destination,
DCHECK_NE(destination, sp);
Operand imm_operand =
MoveImmediateForShiftedOp(destination, immediate, kAnyShift);
- Add(destination, kPtrComprCageBaseRegister, imm_operand);
+ Orr(destination, kPtrComprCageBaseRegister, imm_operand);
}
}
@@ -3667,7 +3681,7 @@ int MacroAssembler::AtomicDecompressTagged(const Register& destination,
Add(temp, base, index);
int pc_offset_of_load = pc_offset();
Ldar(destination.W(), temp);
- Add(destination, kPtrComprCageBaseRegister, destination);
+ Orr(destination, kPtrComprCageBaseRegister, destination);
return pc_offset_of_load;
}
@@ -3819,22 +3833,13 @@ void MacroAssembler::RecordWriteField(
Bind(&done);
}
-void MacroAssembler::DecodeSandboxedPointer(Register value) {
- ASM_CODE_COMMENT(this);
-#ifdef V8_ENABLE_SANDBOX
- Add(value, kPtrComprCageBaseRegister,
- Operand(value, LSR, kSandboxedPointerShift));
-#else
- UNREACHABLE();
-#endif
-}
-
void MacroAssembler::LoadSandboxedPointerField(Register destination,
MemOperand field_operand) {
#ifdef V8_ENABLE_SANDBOX
ASM_CODE_COMMENT(this);
Ldr(destination, field_operand);
- DecodeSandboxedPointer(destination);
+ Add(destination, kPtrComprCageBaseRegister,
+ Operand(destination, LSR, kSandboxedPointerShift));
#else
UNREACHABLE();
#endif
@@ -4454,264 +4459,6 @@ void MacroAssembler::TryLoadOptimizedOsrCode(Register scratch_and_result,
Mov(scratch_and_result, 0);
}
-// This is the main Printf implementation. All other Printf variants call
-// PrintfNoPreserve after setting up one or more PreserveRegisterScopes.
-void MacroAssembler::PrintfNoPreserve(const char* format,
- const CPURegister& arg0,
- const CPURegister& arg1,
- const CPURegister& arg2,
- const CPURegister& arg3) {
- ASM_CODE_COMMENT(this);
- // We cannot handle a caller-saved stack pointer. It doesn't make much sense
- // in most cases anyway, so this restriction shouldn't be too serious.
- DCHECK(!kCallerSaved.IncludesAliasOf(sp));
-
- // The provided arguments, and their proper procedure-call standard registers.
- CPURegister args[kPrintfMaxArgCount] = {arg0, arg1, arg2, arg3};
- CPURegister pcs[kPrintfMaxArgCount] = {NoReg, NoReg, NoReg, NoReg};
-
- int arg_count = kPrintfMaxArgCount;
-
- // The PCS varargs registers for printf. Note that x0 is used for the printf
- // format string.
- static const CPURegList kPCSVarargs =
- CPURegList(CPURegister::kRegister, kXRegSizeInBits, 1, arg_count);
- static const CPURegList kPCSVarargsFP =
- CPURegList(CPURegister::kVRegister, kDRegSizeInBits, 0, arg_count - 1);
-
- // We can use caller-saved registers as scratch values, except for the
- // arguments and the PCS registers where they might need to go.
- CPURegList tmp_list = kCallerSaved;
- tmp_list.Remove(x0); // Used to pass the format string.
- tmp_list.Remove(kPCSVarargs);
- tmp_list.Remove(arg0, arg1, arg2, arg3);
-
- CPURegList fp_tmp_list = kCallerSavedV;
- fp_tmp_list.Remove(kPCSVarargsFP);
- fp_tmp_list.Remove(arg0, arg1, arg2, arg3);
-
- // Override the MacroAssembler's scratch register list. The lists will be
- // reset automatically at the end of the UseScratchRegisterScope.
- UseScratchRegisterScope temps(this);
- TmpList()->set_bits(tmp_list.bits());
- FPTmpList()->set_bits(fp_tmp_list.bits());
-
- // Copies of the printf vararg registers that we can pop from.
- CPURegList pcs_varargs = kPCSVarargs;
-#ifndef V8_OS_WIN
- CPURegList pcs_varargs_fp = kPCSVarargsFP;
-#endif
-
- // Place the arguments. There are lots of clever tricks and optimizations we
- // could use here, but Printf is a debug tool so instead we just try to keep
- // it simple: Move each input that isn't already in the right place to a
- // scratch register, then move everything back.
- for (unsigned i = 0; i < kPrintfMaxArgCount; i++) {
- // Work out the proper PCS register for this argument.
- if (args[i].IsRegister()) {
- pcs[i] = pcs_varargs.PopLowestIndex().X();
- // We might only need a W register here. We need to know the size of the
- // argument so we can properly encode it for the simulator call.
- if (args[i].Is32Bits()) pcs[i] = pcs[i].W();
- } else if (args[i].IsVRegister()) {
- // In C, floats are always cast to doubles for varargs calls.
-#ifdef V8_OS_WIN
- // In case of variadic functions SIMD and Floating-point registers
- // aren't used. The general x0-x7 should be used instead.
- // https://docs.microsoft.com/en-us/cpp/build/arm64-windows-abi-conventions
- pcs[i] = pcs_varargs.PopLowestIndex().X();
-#else
- pcs[i] = pcs_varargs_fp.PopLowestIndex().D();
-#endif
- } else {
- DCHECK(args[i].IsNone());
- arg_count = i;
- break;
- }
-
- // If the argument is already in the right place, leave it where it is.
- if (args[i].Aliases(pcs[i])) continue;
-
- // Otherwise, if the argument is in a PCS argument register, allocate an
- // appropriate scratch register and then move it out of the way.
- if (kPCSVarargs.IncludesAliasOf(args[i]) ||
- kPCSVarargsFP.IncludesAliasOf(args[i])) {
- if (args[i].IsRegister()) {
- Register old_arg = args[i].Reg();
- Register new_arg = temps.AcquireSameSizeAs(old_arg);
- Mov(new_arg, old_arg);
- args[i] = new_arg;
- } else {
- VRegister old_arg = args[i].VReg();
- VRegister new_arg = temps.AcquireSameSizeAs(old_arg);
- Fmov(new_arg, old_arg);
- args[i] = new_arg;
- }
- }
- }
-
- // Do a second pass to move values into their final positions and perform any
- // conversions that may be required.
- for (int i = 0; i < arg_count; i++) {
-#ifdef V8_OS_WIN
- if (args[i].IsVRegister()) {
- if (pcs[i].SizeInBytes() != args[i].SizeInBytes()) {
- // If the argument is half- or single-precision
- // converts to double-precision before that is
- // moved into the one of X scratch register.
- VRegister temp0 = temps.AcquireD();
- Fcvt(temp0.VReg(), args[i].VReg());
- Fmov(pcs[i].Reg(), temp0);
- } else {
- Fmov(pcs[i].Reg(), args[i].VReg());
- }
- } else {
- Mov(pcs[i].Reg(), args[i].Reg(), kDiscardForSameWReg);
- }
-#else
- DCHECK(pcs[i].type() == args[i].type());
- if (pcs[i].IsRegister()) {
- Mov(pcs[i].Reg(), args[i].Reg(), kDiscardForSameWReg);
- } else {
- DCHECK(pcs[i].IsVRegister());
- if (pcs[i].SizeInBytes() == args[i].SizeInBytes()) {
- Fmov(pcs[i].VReg(), args[i].VReg());
- } else {
- Fcvt(pcs[i].VReg(), args[i].VReg());
- }
- }
-#endif
- }
-
- // Load the format string into x0, as per the procedure-call standard.
- //
- // To make the code as portable as possible, the format string is encoded
- // directly in the instruction stream. It might be cleaner to encode it in a
- // literal pool, but since Printf is usually used for debugging, it is
- // beneficial for it to be minimally dependent on other features.
- Label format_address;
- Adr(x0, &format_address);
-
- // Emit the format string directly in the instruction stream.
- {
- BlockPoolsScope scope(this);
- Label after_data;
- B(&after_data);
- Bind(&format_address);
- EmitStringData(format);
- Unreachable();
- Bind(&after_data);
- }
-
- CallPrintf(arg_count, pcs);
-}
-
-void MacroAssembler::CallPrintf(int arg_count, const CPURegister* args) {
- ASM_CODE_COMMENT(this);
- // A call to printf needs special handling for the simulator, since the system
- // printf function will use a different instruction set and the procedure-call
- // standard will not be compatible.
- if (options().enable_simulator_code) {
- InstructionAccurateScope scope(this, kPrintfLength / kInstrSize);
- hlt(kImmExceptionIsPrintf);
- dc32(arg_count); // kPrintfArgCountOffset
-
- // Determine the argument pattern.
- uint32_t arg_pattern_list = 0;
- for (int i = 0; i < arg_count; i++) {
- uint32_t arg_pattern;
- if (args[i].IsRegister()) {
- arg_pattern = args[i].Is32Bits() ? kPrintfArgW : kPrintfArgX;
- } else {
- DCHECK(args[i].Is64Bits());
- arg_pattern = kPrintfArgD;
- }
- DCHECK(arg_pattern < (1 << kPrintfArgPatternBits));
- arg_pattern_list |= (arg_pattern << (kPrintfArgPatternBits * i));
- }
- dc32(arg_pattern_list); // kPrintfArgPatternListOffset
- return;
- }
-
- Call(ExternalReference::printf_function());
-}
-
-void MacroAssembler::Printf(const char* format, CPURegister arg0,
- CPURegister arg1, CPURegister arg2,
- CPURegister arg3) {
- ASM_CODE_COMMENT(this);
- // Printf is expected to preserve all registers, so make sure that none are
- // available as scratch registers until we've preserved them.
- uint64_t old_tmp_list = TmpList()->bits();
- uint64_t old_fp_tmp_list = FPTmpList()->bits();
- TmpList()->set_bits(0);
- FPTmpList()->set_bits(0);
-
- CPURegList saved_registers = kCallerSaved;
- saved_registers.Align();
-
- // Preserve all caller-saved registers as well as NZCV.
- // PushCPURegList asserts that the size of each list is a multiple of 16
- // bytes.
- PushCPURegList(saved_registers);
- PushCPURegList(kCallerSavedV);
-
- // We can use caller-saved registers as scratch values (except for argN).
- CPURegList tmp_list = saved_registers;
- CPURegList fp_tmp_list = kCallerSavedV;
- tmp_list.Remove(arg0, arg1, arg2, arg3);
- fp_tmp_list.Remove(arg0, arg1, arg2, arg3);
- TmpList()->set_bits(tmp_list.bits());
- FPTmpList()->set_bits(fp_tmp_list.bits());
-
- {
- UseScratchRegisterScope temps(this);
- // If any of the arguments are the current stack pointer, allocate a new
- // register for them, and adjust the value to compensate for pushing the
- // caller-saved registers.
- bool arg0_sp = arg0.is_valid() && sp.Aliases(arg0);
- bool arg1_sp = arg1.is_valid() && sp.Aliases(arg1);
- bool arg2_sp = arg2.is_valid() && sp.Aliases(arg2);
- bool arg3_sp = arg3.is_valid() && sp.Aliases(arg3);
- if (arg0_sp || arg1_sp || arg2_sp || arg3_sp) {
- // Allocate a register to hold the original stack pointer value, to pass
- // to PrintfNoPreserve as an argument.
- Register arg_sp = temps.AcquireX();
- Add(arg_sp, sp,
- saved_registers.TotalSizeInBytes() +
- kCallerSavedV.TotalSizeInBytes());
- if (arg0_sp) arg0 = Register::Create(arg_sp.code(), arg0.SizeInBits());
- if (arg1_sp) arg1 = Register::Create(arg_sp.code(), arg1.SizeInBits());
- if (arg2_sp) arg2 = Register::Create(arg_sp.code(), arg2.SizeInBits());
- if (arg3_sp) arg3 = Register::Create(arg_sp.code(), arg3.SizeInBits());
- }
-
- // Preserve NZCV.
- {
- UseScratchRegisterScope temps(this);
- Register tmp = temps.AcquireX();
- Mrs(tmp, NZCV);
- Push(tmp, xzr);
- }
-
- PrintfNoPreserve(format, arg0, arg1, arg2, arg3);
-
- // Restore NZCV.
- {
- UseScratchRegisterScope temps(this);
- Register tmp = temps.AcquireX();
- Pop(xzr, tmp);
- Msr(NZCV, tmp);
- }
- }
-
- PopCPURegList(kCallerSavedV);
- PopCPURegList(saved_registers);
-
- TmpList()->set_bits(old_tmp_list);
- FPTmpList()->set_bits(old_fp_tmp_list);
-}
-
void MacroAssembler::ComputeCodeStartAddress(const Register& rd) {
// We can use adr to load a pc relative location.
adr(rd, -pc_offset());
diff --git a/deps/v8/src/codegen/arm64/macro-assembler-arm64.h b/deps/v8/src/codegen/arm64/macro-assembler-arm64.h
index 31b9c5be8e8..9467b9b2cf2 100644
--- a/deps/v8/src/codegen/arm64/macro-assembler-arm64.h
+++ b/deps/v8/src/codegen/arm64/macro-assembler-arm64.h
@@ -698,33 +698,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Print a message to stderr and abort execution.
void Abort(AbortReason reason);
- // Like printf, but print at run-time from generated code.
- //
- // The caller must ensure that arguments for floating-point placeholders
- // (such as %e, %f or %g) are VRegisters, and that arguments for integer
- // placeholders are Registers.
- //
- // Format placeholders that refer to more than one argument, or to a specific
- // argument, are not supported. This includes formats like "%1$d" or "%.*d".
- //
- // This function automatically preserves caller-saved registers so that
- // calling code can use Printf at any point without having to worry about
- // corruption. The preservation mechanism generates a lot of code. If this is
- // a problem, preserve the important registers manually and then call
- // PrintfNoPreserve. Callee-saved registers are not used by Printf, and are
- // implicitly preserved.
- void Printf(const char* format, CPURegister arg0 = NoCPUReg,
- CPURegister arg1 = NoCPUReg, CPURegister arg2 = NoCPUReg,
- CPURegister arg3 = NoCPUReg);
-
- // Like Printf, but don't preserve any caller-saved registers, not even 'lr'.
- //
- // The return code from the system printf call will be returned in x0.
- void PrintfNoPreserve(const char* format, const CPURegister& arg0 = NoCPUReg,
- const CPURegister& arg1 = NoCPUReg,
- const CPURegister& arg2 = NoCPUReg,
- const CPURegister& arg3 = NoCPUReg);
-
// Remaining instructions are simple pass-through calls to the assembler.
inline void Asr(const Register& rd, const Register& rn, unsigned shift);
inline void Asr(const Register& rd, const Register& rn, const Register& rm);
@@ -1687,7 +1660,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Transform a SandboxedPointer from/to its encoded form, which is used when
// the pointer is stored on the heap and ensures that the pointer will always
// point into the sandbox.
- void DecodeSandboxedPointer(Register value);
void LoadSandboxedPointerField(Register destination,
MemOperand field_operand);
void StoreSandboxedPointerField(Register value, MemOperand dst_field_operand);
@@ -2077,9 +2049,20 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
template <typename Field>
void DecodeField(Register dst, Register src) {
- static const int shift = Field::kShift;
- static const int setbits = CountSetBits(Field::kMask, 32);
- Ubfx(dst, src, shift, setbits);
+ static constexpr int shift = Field::kShift;
+ static constexpr uint64_t mask =
+ static_cast<uint64_t>(Field::kMask) >> shift;
+ if constexpr ((mask & (mask + 1)) == 0) {
+ static const int setbits = CountSetBits(Field::kMask, 32);
+ Ubfx(dst, src, shift, setbits);
+ } else {
+ if constexpr (shift != 0) {
+ Lsr(dst, src, shift);
+ And(dst, dst, mask);
+ } else {
+ And(dst, src, mask);
+ }
+ }
}
template <typename Field>
@@ -2411,16 +2394,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
const Operand& operand, FlagsUpdate S,
AddSubWithCarryOp op);
- // Call Printf. On a native build, a simple call will be generated, but if the
- // simulator is being used then a suitable pseudo-instruction is used. The
- // arguments and stack must be prepared by the caller as for a normal AAPCS64
- // call to 'printf'.
- //
- // The 'args' argument should point to an array of variable arguments in their
- // proper PCS registers (and in calling order). The argument registers can
- // have mixed types. The format string (x0) should not be included.
- void CallPrintf(int arg_count = 0, const CPURegister* args = nullptr);
-
private:
#if DEBUG
// Tell whether any of the macro instruction can be used. When false the
diff --git a/deps/v8/src/codegen/code-stub-assembler.cc b/deps/v8/src/codegen/code-stub-assembler.cc
index 08f6e6703f9..f5738d915f1 100644
--- a/deps/v8/src/codegen/code-stub-assembler.cc
+++ b/deps/v8/src/codegen/code-stub-assembler.cc
@@ -24,6 +24,7 @@
#include "src/heap/heap-inl.h" // For MutablePage. TODO(jkummerow): Drop.
#include "src/heap/mutable-page.h"
#include "src/ic/binary-op-assembler.h"
+#include "src/ic/unary-op-assembler.h"
#include "src/logging/counters.h"
#include "src/numbers/integer-literal-inl.h"
#include "src/numbers/math-random.h"
@@ -2216,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)),
@@ -4276,6 +4268,18 @@ void CodeStubAssembler::StoreMapNoWriteBarrier(TNode<HeapObject> object,
DcheckHasValidMap(object);
}
+void CodeStubAssembler::StoreMapReleaseNoWriteBarrier(
+ TNode<HeapObject> object, RootIndex map_root_index) {
+ StoreMapReleaseNoWriteBarrier(object, CAST(LoadRoot(map_root_index)));
+}
+
+void CodeStubAssembler::StoreMapReleaseNoWriteBarrier(TNode<HeapObject> object,
+ TNode<Map> map) {
+ MemoryBarrier(AtomicMemoryOrder::kAcqRel);
+ OptimizedStoreMap(object, map);
+ DcheckHasValidMap(object);
+}
+
void CodeStubAssembler::StoreObjectFieldRoot(TNode<HeapObject> object,
int offset, RootIndex root_index) {
TNode<Object> root = LoadRoot(root_index);
@@ -6693,7 +6697,12 @@ void CodeStubAssembler::CopyRange(TNode<HeapObject> dst_object, int dst_offset,
TNode<Object> value = LoadObjectField(src_object, current_src_offset);
TNode<IntPtrT> current_dst_offset =
IntPtrAdd(TimesTaggedSize(index), IntPtrConstant(dst_offset));
- if (mode == SKIP_WRITE_BARRIER) {
+ if (mode == UNSAFE_SKIP_WRITE_BARRIER) {
+ UnsafeStoreNoWriteBarrier(
+ MachineRepresentation::kTagged, dst_object,
+ IntPtrSub(current_dst_offset, IntPtrConstant(kHeapObjectTag)),
+ value);
+ } else if (mode == SKIP_WRITE_BARRIER) {
StoreObjectFieldNoWriteBarrier(dst_object, current_dst_offset, value);
} else {
StoreObjectField(dst_object, current_dst_offset, value);
@@ -9789,6 +9798,17 @@ TNode<String> ToDirectStringAssembler::ToDirect() {
return var_string_.value();
}
+void ToDirectStringAssembler::BailIfTransitioned(Label* if_bailout) {
+#if V8_STATIC_ROOTS_BOOL
+ GotoIfNot(TaggedEqual(LoadMap(var_string_.value()), var_map_.value()),
+ if_bailout);
+#else
+ GotoIfNot(Word32Equal(LoadInstanceType(var_string_.value()),
+ var_instance_type_.value()),
+ if_bailout);
+#endif
+}
+
TNode<BoolT> ToDirectStringAssembler::IsOneByte() {
#if V8_STATIC_ROOTS_BOOL
return IsOneByteStringMap(var_map_.value());
@@ -12783,7 +12803,7 @@ TNode<Object> CodeStubAssembler::CallGetterIfAccessorAndBailoutOnLazyClosures(
// signature and receiver is not a JSReceiver the signature check
// in CallFunctionTemplate builtin will fail anyway, so we can
// short cut it here and throw kIllegalInvocation immediately.
- js_receiver = ToObject_Inline(context, receiver);
+ js_receiver = ConvertReceiver(context, receiver);
break;
}
TNode<JSReceiver> holder_receiver = *holder;
@@ -13586,10 +13606,16 @@ TNode<Boolean> CodeStubAssembler::OrdinaryHasInstance(
CSA_DCHECK(this, IsJSReceiver(object));
// Throw TypeError in case of non-instance prototype.
- TNode<JSReceiver> callable_prototype = CAST(LoadJSFunctionPrototype(
+ TNode<JSPrototype> maybe_callable_prototype = CAST(LoadJSFunctionPrototype(
CAST(callable), &return_runtime, &if_non_instance_prototype,
&var_non_instance_prototype));
+ // Usually, we don't expect JSFunctions with prototypes to have initial
+ // maps with null prototype, however this is currently the case for shared
+ // struct constructors.
+ var_non_instance_prototype = maybe_callable_prototype;
+ GotoIf(IsNull(maybe_callable_prototype), &if_non_instance_prototype);
+ TNode<JSReceiver> callable_prototype = CAST(maybe_callable_prototype);
// Loop through the prototype chain looking for the {callable} prototype.
var_result = HasInPrototypeChain(context, object, callable_prototype);
Goto(&return_result);
@@ -15203,6 +15229,7 @@ TNode<IntPtrT> CodeStubAssembler::MemoryChunkFromAddress(
IntPtrConstant(~MemoryChunk::GetAlignmentMaskForAssembler()));
}
+// LINT.IfChange(BasePageFromMemoryChunk)
TNode<IntPtrT> CodeStubAssembler::BasePageFromMemoryChunk(
TNode<IntPtrT> address) {
#ifdef V8_ENABLE_SANDBOX
@@ -15219,17 +15246,34 @@ TNode<IntPtrT> CodeStubAssembler::BasePageFromMemoryChunk(
MemoryChunkConstants::kMetadataPointerTableSizeMask));
TNode<IntPtrT> offset = ChangeInt32ToIntPtr(
Word32Shl(index, UniqueUint32Constant(kBasePageTableEntrySizeLog2)));
+ static_assert(offsetof(IsolateGroup::BasePageTableEntry, metadata_) == 0);
TNode<IntPtrT> metadata = Load<IntPtrT>(table, offset);
// Check that the Metadata belongs to this Chunk, since an attacker with write
// inside the sandbox could've swapped the index.
TNode<IntPtrT> metadata_chunk = MemoryChunkFromAddress(
Load<IntPtrT>(metadata, IntPtrConstant(BasePage::AreaStartOffset())));
CSA_CHECK(this, WordEqual(metadata_chunk, address));
+
+ // Check that the page is accessible from the current isolate.
+ TNode<RawPtrT> isolate = Load<RawPtrT>(
+ table,
+ IntPtrAdd(offset, IntPtrConstant(offsetof(
+ IsolateGroup::BasePageTableEntry, isolate_))));
+ TNode<RawPtrT> current_isolate = UncheckedCast<RawPtrT>(
+ ExternalConstant(ExternalReference::isolate_address()));
+ CSA_CHECK(
+ this,
+ Word32Or(WordEqual(isolate, current_isolate),
+ WordEqual(
+ isolate,
+ IntPtrConstant(IsolateGroup::BasePageTableEntry::
+ kReadOnlyOrSharedEntryIsolateSentinel))));
return metadata;
#else
return Load<IntPtrT>(address, IntPtrConstant(MemoryChunk::MetadataOffset()));
#endif
}
+// LINT.ThenChange(/src/heap/memory-chunk-inl.h:BasePageFromMemoryChunk)
TNode<IntPtrT> CodeStubAssembler::BasePageFromAddress(TNode<IntPtrT> address) {
return BasePageFromMemoryChunk(MemoryChunkFromAddress(address));
@@ -16953,8 +16997,7 @@ void CodeStubAssembler::GenerateNumberBinaryOp(Operation op, TNode<Object> lhs,
}
void CodeStubAssembler::GenerateStringAdd(TNode<Object> lhs, TNode<Object> rhs,
- TNode<UintPtrT> feedback_offset,
- Builtin fallback_builtin) {
+ TNode<UintPtrT> feedback_offset) {
Label fallback(this, Label::kDeferred);
GotoIf(TaggedIsSmi(lhs), &fallback);
@@ -16971,10 +17014,11 @@ void CodeStubAssembler::GenerateStringAdd(TNode<Object> lhs, TNode<Object> rhs,
BIND(&fallback);
{
- TailCallBuiltin(fallback_builtin, LoadContextFromBaseline(), lhs, rhs,
- Int32Constant(static_cast<int32_t>(
- BinaryOperationFeedback::TypeIndex::kString)),
- feedback_offset);
+ TailCallBuiltin(
+ Builtin::kAddAndTryPatchCode, LoadContextFromBaseline(), lhs, rhs,
+ Int32Constant(
+ static_cast<int32_t>(BinaryOperationFeedback::TypeIndex::kString)),
+ feedback_offset);
}
}
@@ -17071,6 +17115,149 @@ void CodeStubAssembler::GenerateBinaryOpAndTryPatchCode(
ChangeUintPtrToTagged(feedback_offset));
}
}
+
+void CodeStubAssembler::GenerateSmiUnaryOp(Operation op, TNode<Object> value,
+ TNode<UintPtrT> feedback_offset,
+ Builtin fallback_builtin) {
+ Label fallback(this, Label::kDeferred);
+ GotoIfNot(TaggedIsSmi(value), &fallback);
+ TNode<Smi> smi = CAST(value);
+
+ switch (op) {
+ case Operation::kIncrement:
+ Return(TrySmiAdd(smi, SmiConstant(1), &fallback));
+ break;
+ case Operation::kDecrement:
+ Return(TrySmiAdd(smi, SmiConstant(-1), &fallback));
+ break;
+ case Operation::kNegate:
+ // 0 negates to -0; kMinValue overflows. Both bail so feedback widens
+ // correctly.
+ GotoIf(SmiEqual(smi, SmiConstant(0)), &fallback);
+ GotoIf(SmiEqual(smi, SmiConstant(Smi::kMinValue)), &fallback);
+ Return(SmiSub(SmiConstant(0), smi));
+ break;
+ case Operation::kBitwiseNot: {
+ TNode<Object> result =
+ ChangeInt32ToTagged(Word32BitwiseNot(SmiToInt32(smi)));
+ // On 32-bit Smi builds the result may not fit a Smi; bail if so.
+ GotoIfNot(TaggedIsSmi(result), &fallback);
+ Return(result);
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+
+ BIND(&fallback);
+ {
+ TailCallBuiltin(fallback_builtin, LoadContextFromBaseline(), value,
+ Int32Constant(static_cast<int32_t>(
+ BinaryOperationFeedback::TypeIndex::kSignedSmall)),
+ feedback_offset);
+ }
+}
+
+void CodeStubAssembler::GenerateNumberNegate(TNode<Object> value,
+ TNode<UintPtrT> feedback_offset) {
+ Label fallback(this, Label::kDeferred), do_float(this);
+ TVARIABLE(Float64T, var_float);
+
+ Label if_smi(this);
+ GotoIf(TaggedIsSmi(value), &if_smi);
+ GotoIfNot(IsHeapNumber(CAST(value)), &fallback);
+ var_float = LoadHeapNumberValue(CAST(value));
+ Goto(&do_float);
+
+ BIND(&if_smi);
+ {
+ TNode<Smi> smi = CAST(value);
+ Label if_zero(this), if_min(this);
+ GotoIf(SmiEqual(smi, SmiConstant(0)), &if_zero);
+ GotoIf(SmiEqual(smi, SmiConstant(Smi::kMinValue)), &if_min);
+ Return(SmiSub(SmiConstant(0), smi));
+
+ BIND(&if_zero);
+ Return(MinusZeroConstant());
+
+ BIND(&if_min);
+ var_float = SmiToFloat64(smi);
+ Goto(&do_float);
+ }
+
+ BIND(&do_float);
+ Return(AllocateHeapNumberWithValue(Float64Neg(var_float.value())));
+
+ BIND(&fallback);
+ {
+ TailCallBuiltin(
+ Builtin::kNegateAndTryPatchCode, LoadContextFromBaseline(), value,
+ Int32Constant(
+ static_cast<int32_t>(BinaryOperationFeedback::TypeIndex::kNumber)),
+ feedback_offset);
+ }
+}
+
+void CodeStubAssembler::GenerateUnaryOpAndTryPatchCode(
+ Operation op, TNode<Object> value, TNode<Int32T> current_type_feedback,
+ TNode<UintPtrT> feedback_offset) {
+ TVARIABLE(Smi, var_type_feedback,
+ SmiConstant(BinaryOperationFeedback::kNone));
+ TVARIABLE(Object, var_exception);
+ TVARIABLE(Object, var_result);
+ TVARIABLE(Uint8T, new_feedback);
+ TVARIABLE(Int32T, feedback_index);
+
+ auto bytecode_array = LoadBytecodeArrayFromBaseline();
+ Label if_exception(this, Label::kDeferred);
+ {
+ ScopedExceptionHandler handler(this, &if_exception, &var_exception);
+ UnaryOpAssembler unary_asm(state());
+ auto context = LoadContextFromBaseline();
+ auto record_feedback = [&](TNode<Smi> feedback) {
+ var_type_feedback = feedback;
+ };
+ switch (op) {
+ case Operation::kIncrement:
+ var_result = unary_asm.Generate_IncrementWithFeedback(context, value,
+ record_feedback);
+ break;
+ case Operation::kDecrement:
+ var_result = unary_asm.Generate_DecrementWithFeedback(context, value,
+ record_feedback);
+ break;
+ case Operation::kNegate:
+ var_result = unary_asm.Generate_NegateWithFeedback(context, value,
+ record_feedback);
+ break;
+ case Operation::kBitwiseNot:
+ var_result = unary_asm.Generate_BitwiseNotWithFeedback(context, value,
+ record_feedback);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+ feedback_index = EncodeEmbeddedFeedback<BinaryOperationFeedback>(
+ var_type_feedback.value());
+ new_feedback = CombineEmbeddedFeedback<BinaryOperationFeedback>(
+ current_type_feedback, feedback_index.value());
+ TailCallRuntime(Runtime::kPatchUnaryOpBaselineCode, NoContextConstant(),
+ SmiFromInt32(new_feedback.value()), var_result.value(),
+ bytecode_array, ChangeUintPtrToTagged(feedback_offset));
+
+ BIND(&if_exception);
+ {
+ feedback_index = EncodeEmbeddedFeedback<BinaryOperationFeedback>(
+ var_type_feedback.value());
+ new_feedback = CombineEmbeddedFeedback<BinaryOperationFeedback>(
+ current_type_feedback, feedback_index.value());
+ TailCallRuntime(Runtime::kPatchUnaryOpBaselineCodeAndThrow,
+ NoContextConstant(), SmiFromInt32(new_feedback.value()),
+ var_exception.value(), bytecode_array,
+ ChangeUintPtrToTagged(feedback_offset));
+ }
+}
#endif // V8_ENABLE_SPARKPLUG_PLUS
void CodeStubAssembler::GenerateEqual_Same(TNode<Object> value, Label* if_equal,
diff --git a/deps/v8/src/codegen/code-stub-assembler.h b/deps/v8/src/codegen/code-stub-assembler.h
index 8abea7ebc86..968b1710583 100644
--- a/deps/v8/src/codegen/code-stub-assembler.h
+++ b/deps/v8/src/codegen/code-stub-assembler.h
@@ -1871,6 +1871,9 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
void StoreMapNoWriteBarrier(TNode<HeapObject> object,
RootIndex map_root_index);
void StoreMapNoWriteBarrier(TNode<HeapObject> object, TNode<Map> map);
+ void StoreMapReleaseNoWriteBarrier(TNode<HeapObject> object,
+ RootIndex map_root_index);
+ void StoreMapReleaseNoWriteBarrier(TNode<HeapObject> object, TNode<Map> map);
void StoreObjectFieldRoot(TNode<HeapObject> object, int offset,
RootIndex root);
@@ -3082,6 +3085,10 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
ExternalReference::address_of_builtin_subclassing_flag());
}
+ TNode<BoolT> HasJsPr3883Flag() {
+ return LoadRuntimeFlag(ExternalReference::address_of_js_pr_3883_flag());
+ }
+
TNode<BoolT> HasSharedStringTableFlag() {
return LoadRuntimeFlag(
ExternalReference::address_of_shared_string_table_flag());
@@ -4287,13 +4294,23 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
Builtin fallback_builtin);
void GenerateStringAdd(TNode<Object> lhs, TNode<Object> rhs,
- TNode<UintPtrT> feedback_offset,
- Builtin fallback_builtin);
+ TNode<UintPtrT> feedback_offset);
void GenerateBinaryOpAndTryPatchCode(Operation op, TNode<Object> lhs,
TNode<Object> rhs,
TNode<Int32T> current_type_feedback,
TNode<UintPtrT> feedback_offset);
+
+ void GenerateSmiUnaryOp(Operation op, TNode<Object> value,
+ TNode<UintPtrT> feedback_offset,
+ Builtin fallback_builtin);
+
+ void GenerateNumberNegate(TNode<Object> value,
+ TNode<UintPtrT> feedback_offset);
+
+ void GenerateUnaryOpAndTryPatchCode(Operation op, TNode<Object> value,
+ TNode<Int32T> current_type_feedback,
+ TNode<UintPtrT> feedback_offset);
#endif // V8_ENABLE_SPARKPLUG_PLUS
TNode<Boolean> Equal(TNode<Object> lhs, TNode<Object> rhs,
@@ -5285,6 +5302,12 @@ class ToDirectStringAssembler : public CodeStubAssembler {
return TryToSequential(PTR_TO_STRING, if_bailout);
}
+ // Jumps to {if_bailout} if the direct string's map changed since the last
+ // TryToDirect, i.e. if a GC thinned it or swapped in an external resource.
+ // Callers must re-check across an allocation before using string(),
+ // PointerToData() or PointerToString().
+ void BailIfTransitioned(Label* if_bailout);
+
TNode<BoolT> IsOneByte();
TNode<String> string() { return var_string_.value(); }
diff --git a/deps/v8/src/codegen/compiler.cc b/deps/v8/src/codegen/compiler.cc
index adfbf3f4a15..7918e1548f8 100644
--- a/deps/v8/src/codegen/compiler.cc
+++ b/deps/v8/src/codegen/compiler.cc
@@ -28,7 +28,6 @@
#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/compiler/turbofan.h"
#include "src/debug/debug.h"
-#include "src/debug/liveedit.h"
#include "src/diagnostics/code-tracer.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
@@ -1177,6 +1176,35 @@ void RecordMaglevFunctionCompilation(Isolate* isolate,
isolate, LogEventListener::CodeTag::kFunction, script, shared,
feedback_vector, code, code->kind(), time_taken_ms);
}
+
+// A bailout on a property of the function itself repeats on every attempt.
+// Recording it stops the tiering manager from picking Maglev again, so the
+// function tiers up to Turbofan instead of recompiling Maglev forever.
+void MaybeMarkMaglevCompilationFailed(DirectHandle<JSFunction> function,
+ BytecodeOffset osr_offset,
+ BailoutReason reason) {
+ // The bit lives on the SharedFunctionInfo, so an OSR-only bailout must not
+ // disable Maglev for the regular entry point too.
+ if (IsOSR(osr_offset)) return;
+ switch (reason) {
+ case BailoutReason::kMaglevGraphBuildingFailed:
+ function->shared()->set_maglev_compilation_failed(true);
+ break;
+ default:
+ break;
+ }
+}
+
+void AbortMaglevCompilationJob(Isolate* isolate,
+ DirectHandle<JSFunction> function,
+ BytecodeOffset osr_offset,
+ BailoutReason reason) {
+ CompilerTracer::TraceAbortedMaglevCompile(isolate, function, reason);
+ MaybeMarkMaglevCompilationFailed(function, osr_offset, reason);
+ function->SetTieringInProgress(isolate, false, osr_offset);
+ function->shared()->set_cached_tiering_decision(
+ CachedTieringDecision::kDelayMaglev);
+}
#endif // V8_ENABLE_MAGLEV
MaybeHandle<Code> CompileMaglev(Isolate* isolate, Handle<JSFunction> function,
@@ -1228,6 +1256,12 @@ MaybeHandle<Code> CompileMaglev(Isolate* isolate, Handle<JSFunction> function,
job->ExecuteJob(isolate->counters()->runtime_call_stats(),
isolate->main_thread_local_isolate());
if (status == CompilationJob::FAILED) {
+ // Synchronous compilation never sets tiering_in_progress, so unlike
+ // FinalizeMaglevCompilationJob this must not reset it.
+ CompilerTracer::TraceAbortedMaglevCompile(isolate, function,
+ job->bailout_reason_);
+ MaybeMarkMaglevCompilationFailed(function, osr_offset,
+ job->bailout_reason_);
return {};
}
CHECK_EQ(status, CompilationJob::SUCCEEDED);
@@ -2680,6 +2714,9 @@ MaybeHandle<SharedFunctionInfo> BackgroundCompileTask::FinalizeScript(
*/
Tagged<WeakFixedArray> infos = script->infos();
uint32_t length = infos->ulength().value();
+ bool may_have_parallel_tasks =
+ flags_.post_parallel_compile_tasks_for_eager_toplevel() ||
+ flags_.post_parallel_compile_tasks_for_lazy();
for (uint32_t i = 0; i < length; ++i) {
Tagged<MaybeObject> maybe_obj = infos->get(i);
Tagged<HeapObject> obj;
@@ -2687,10 +2724,16 @@ MaybeHandle<SharedFunctionInfo> BackgroundCompileTask::FinalizeScript(
if (Tagged<SharedFunctionInfo> shared; TryCast(obj, &shared)) {
// Once all compilation jobs are over, and before merging, we expect that
// a function is either compiled (HasBytecodeArray) or is ready for lazy
- // compilation (HasUncompiledData). Function here are all user defined
- // functions and should not have a builtin_id.
- DCHECK(!shared->HasBuiltinId());
- DCHECK(shared->HasBytecodeArray() || shared->HasUncompiledData(isolate));
+ // compilation (HasUncompiledData). Functions here are all user defined
+ // functions and should not have a builtin_id (unless parallel compilation
+ // is enabled and the function is still in the dispatcher queue).
+ DCHECK_IMPLIES(!may_have_parallel_tasks, !shared->HasBuiltinId());
+ DCHECK_IMPLIES(may_have_parallel_tasks,
+ !shared->HasBuiltinId() ||
+ shared->builtin_id() == Builtin::kCompileLazy);
+ DCHECK(shared->HasBytecodeArray() || shared->HasUncompiledData(isolate) ||
+ (may_have_parallel_tasks &&
+ shared->builtin_id() == Builtin::kCompileLazy));
}
}
#endif
@@ -3256,8 +3299,7 @@ void Compiler::CompileOptimized(Isolate* isolate,
DCHECK(function->is_compiled(isolate));
DCHECK(function->shared()->HasBytecodeArray());
- DCHECK_IMPLIES(function->IsTieringRequestedOrInProgress(isolate) &&
- !function->IsLoggingRequested(isolate),
+ DCHECK_IMPLIES(function->IsOptimizationRequested(isolate),
function->tiering_in_progress());
DCHECK_IMPLIES(!tiering_was_in_progress && function->tiering_in_progress(),
function->ChecksTieringState(isolate));
@@ -3266,15 +3308,6 @@ void Compiler::CompileOptimized(Isolate* isolate,
#endif // DEBUG
}
-// static
-MaybeDirectHandle<SharedFunctionInfo> Compiler::CompileForLiveEdit(
- ParseInfo* parse_info, Handle<Script> script,
- MaybeDirectHandle<ScopeInfo> outer_scope_info, Isolate* isolate) {
- IsCompiledScope is_compiled_scope;
- return v8::internal::CompileToplevel(parse_info, script, outer_scope_info,
- isolate, &is_compiled_scope);
-}
-
// static
MaybeDirectHandle<JSFunction> Compiler::GetFunctionFromEval(
Isolate* isolate, DirectHandle<String> source,
@@ -3352,6 +3385,15 @@ MaybeDirectHandle<JSFunction> Compiler::GetFunctionFromEval(
script = parse_info.CreateScript(
isolate, source, kNullMaybeHandle,
OriginOptionsForEval(outer_info->script(), parsing_while_debugging));
+ script->set_outer_language_mode(language_mode);
+ if (eval_position == kNoSourcePosition) {
+ script->set_compilation_kind(
+ restriction == ONLY_SINGLE_FUNCTION_LITERAL
+ ? Script::CompilationKind::kFunctionConstructor
+ : Script::CompilationKind::kIndirectEval);
+ } else {
+ script->set_compilation_kind(Script::CompilationKind::kDirectEval);
+ }
script->set_eval_from_shared(*outer_info);
if (eval_position == kNoSourcePosition) {
// If the position is missing, attempt to get the code offset by
@@ -4515,9 +4557,6 @@ void Compiler::FinalizeTurbofanCompilationJob(TurbofanCompilationJob* job,
if (V8_LIKELY(use_result)) {
function->SetTieringInProgress(isolate, false,
job->compilation_info()->osr_offset());
- if (!IsOSR(osr_offset)) {
- function->UpdateCode(isolate, shared->GetCode(isolate));
- }
}
}
@@ -4540,25 +4579,27 @@ void Compiler::FinalizeMaglevCompilationJob(maglev::MaglevCompilationJob* job,
DirectHandle<JSFunction> function = job->function();
BytecodeOffset osr_offset = job->osr_offset();
+ if (job->state() == CompilationJob::State::kFailed) {
+ AbortMaglevCompilationJob(isolate, function, osr_offset,
+ job->bailout_reason_);
+ return;
+ }
+ DCHECK_EQ(job->state(), CompilationJob::State::kReadyToFinalize);
+
if (function->ActiveTierIsTurbofan(isolate) && !job->is_osr()) {
- function->SetTieringInProgress(isolate, false, osr_offset);
- CompilerTracer::TraceAbortedMaglevCompile(isolate, function,
- BailoutReason::kCancelled);
+ AbortMaglevCompilationJob(isolate, function, osr_offset,
+ BailoutReason::kCancelled);
return;
}
// Discard code compiled for a discarded native context without finalization.
if (function->native_context()->IsDetached()) {
- CompilerTracer::TraceAbortedMaglevCompile(
- isolate, function, BailoutReason::kDetachedNativeContext);
+ AbortMaglevCompilationJob(isolate, function, osr_offset,
+ BailoutReason::kDetachedNativeContext);
return;
}
const CompilationJob::Status status = job->FinalizeJob(isolate);
- // TODO(v8:7700): Use the result and check if job succeed
- // when all the bytecodes are implemented.
- USE(status);
-
if (status == CompilationJob::SUCCEEDED) {
DirectHandle<SharedFunctionInfo> shared(function->shared(), isolate);
if (shared->HasBreakInfo(isolate)) {
@@ -4593,11 +4634,11 @@ void Compiler::FinalizeMaglevCompilationJob(maglev::MaglevCompilationJob* job,
CompilerTracer::TraceFinishMaglevCompile(
isolate, function, job->is_osr(), job->prepare_in_ms(),
job->execute_in_ms(), job->finalize_in_ms());
+ function->SetTieringInProgress(isolate, false, osr_offset);
} else {
- CompilerTracer::TraceAbortedMaglevCompile(isolate, function,
- job->bailout_reason_);
+ AbortMaglevCompilationJob(isolate, function, osr_offset,
+ job->bailout_reason_);
}
- function->SetTieringInProgress(isolate, false, osr_offset);
#endif
}
diff --git a/deps/v8/src/codegen/compiler.h b/deps/v8/src/codegen/compiler.h
index 4547b230df3..7f8c3152e8a 100644
--- a/deps/v8/src/codegen/compiler.h
+++ b/deps/v8/src/codegen/compiler.h
@@ -115,11 +115,6 @@ class V8_EXPORT_PRIVATE Compiler : public AllStatic {
Isolate* isolate, DirectHandle<JSFunction> function,
BytecodeOffset osr_offset, ConcurrencyMode mode, CodeKind code_kind);
- V8_WARN_UNUSED_RESULT static MaybeDirectHandle<SharedFunctionInfo>
- CompileForLiveEdit(ParseInfo* parse_info, Handle<Script> script,
- MaybeDirectHandle<ScopeInfo> outer_scope_info,
- Isolate* isolate);
-
// Collect source positions for a function that has already been compiled to
// bytecode, but for which source positions were not collected (e.g. because
// they were not immediately needed).
diff --git a/deps/v8/src/codegen/cpu-features.h b/deps/v8/src/codegen/cpu-features.h
index a475c97bd1e..fdaa3e15aa3 100644
--- a/deps/v8/src/codegen/cpu-features.h
+++ b/deps/v8/src/codegen/cpu-features.h
@@ -33,6 +33,7 @@ enum CpuFeature {
CETSS,
F16C,
APX_F,
+ AVX10_1,
#elif V8_TARGET_ARCH_ARM
// - Standard configurations. The baseline is ARMv6+VFPv2.
@@ -111,6 +112,7 @@ enum CpuFeature {
ZICOND,
ZICFISS,
RVC,
+ ZCB,
#endif
NUMBER_OF_CPU_FEATURES
diff --git a/deps/v8/src/codegen/external-reference.cc b/deps/v8/src/codegen/external-reference.cc
index 807947ac558..55aa8422578 100644
--- a/deps/v8/src/codegen/external-reference.cc
+++ b/deps/v8/src/codegen/external-reference.cc
@@ -846,6 +846,10 @@ ExternalReference ExternalReference::address_of_builtin_subclassing_flag() {
return ExternalReference(&v8_flags.builtin_subclassing);
}
+ExternalReference ExternalReference::address_of_js_pr_3883_flag() {
+ return ExternalReference(&v8_flags.js_pr_3883);
+}
+
ExternalReference ExternalReference::address_of_runtime_stats_flag() {
return ExternalReference(&TracingFlags::runtime_stats);
}
@@ -1112,6 +1116,8 @@ FUNCTION_REFERENCE(re_experimental_match_for_call_from_js,
FUNCTION_REFERENCE(re_atom_exec_raw, RegExp::AtomExecRaw)
+FUNCTION_REFERENCE(re_split_cache_enter, regexp::ResultsCache::EnterRaw)
+
FUNCTION_REFERENCE(allocate_regexp_result_vector,
regexp::ResultVector::Allocate)
FUNCTION_REFERENCE(free_regexp_result_vector, regexp::ResultVector::Free)
diff --git a/deps/v8/src/codegen/external-reference.h b/deps/v8/src/codegen/external-reference.h
index 194e60e0a2f..87881c862b3 100644
--- a/deps/v8/src/codegen/external-reference.h
+++ b/deps/v8/src/codegen/external-reference.h
@@ -111,6 +111,7 @@ enum class IsolateFieldId : uint8_t;
V(address_of_float_neg_constant, "float_negate_constant") \
V(address_of_log10_offset_table, "log10_offset_table") \
V(address_of_min_int, "LDoubleConstant::min_int") \
+ V(address_of_js_pr_3883_flag, "v8_flags.js_pr_3883") \
V(address_of_mock_arraybuffer_allocator_flag, \
"v8_flags.mock_arraybuffer_allocator") \
V(address_of_one_half, "LDoubleConstant::one_half") \
@@ -501,6 +502,7 @@ enum class IsolateFieldId : uint8_t;
V(re_experimental_match_for_call_from_js, \
"ExperimentalRegExp::MatchForCallFromJs") \
V(re_atom_exec_raw, "RegExp::AtomExecRaw") \
+ V(re_split_cache_enter, "regexp::ResultsCache::EnterRaw") \
V(allocate_regexp_result_vector, "regexp::ResultVector::Allocate") \
V(free_regexp_result_vector, "regexp::ResultVector::Free") \
EXTERNAL_REFERENCE_LIST_REGEXP_DIAGNOSTICS(V) \
diff --git a/deps/v8/src/codegen/handler-table.cc b/deps/v8/src/codegen/handler-table.cc
index 80b3bc8067d..44030906761 100644
--- a/deps/v8/src/codegen/handler-table.cc
+++ b/deps/v8/src/codegen/handler-table.cc
@@ -141,7 +141,9 @@ void HandlerTable::SetRangeEnd(uint32_t index, int value) {
void HandlerTable::SetRangeHandler(uint32_t index, int handler_offset,
CatchPrediction prediction) {
- CHECK(HandlerOffsetField::is_valid(handler_offset));
+ // Use CHECK_NO_SECURITY_IMPACT to prevent fuzzers from reporting bitfield
+ // overflow on large functions as a security bug.
+ CHECK_NO_SECURITY_IMPACT(HandlerOffsetField::is_valid(handler_offset));
int value = HandlerOffsetField::encode(handler_offset) |
HandlerWasUsedField::encode(false) |
HandlerPredictionField::encode(prediction);
diff --git a/deps/v8/src/codegen/ia32/macro-assembler-ia32.h b/deps/v8/src/codegen/ia32/macro-assembler-ia32.h
index cd2c42e1572..e864b884f6a 100644
--- a/deps/v8/src/codegen/ia32/macro-assembler-ia32.h
+++ b/deps/v8/src/codegen/ia32/macro-assembler-ia32.h
@@ -363,6 +363,37 @@ class V8_EXPORT_PRIVATE MacroAssembler
void PinsrdPreSse41(XMMRegister dst, Operand src, uint8_t imm8,
uint32_t* load_pc_offset);
+ // SIMD128
+ void I64x2Abs(XMMRegister dst, XMMRegister src, XMMRegister scratch) {
+ I64x2AbsPreAvx10(dst, src, scratch);
+ }
+ void I64x2ShrS(XMMRegister dst, XMMRegister src, uint8_t shift,
+ XMMRegister xmm_tmp) {
+ I64x2ShrSPreAvx10(dst, src, shift, xmm_tmp);
+ }
+ void I64x2ShrS(XMMRegister dst, XMMRegister src, Register shift,
+ XMMRegister xmm_tmp, XMMRegister xmm_shift,
+ Register tmp_shift) {
+ I64x2ShrSPreAvx10(dst, src, shift, xmm_tmp, xmm_shift, tmp_shift);
+ }
+ void I64x2Mul(XMMRegister dst, XMMRegister lhs, XMMRegister rhs,
+ XMMRegister tmp1, XMMRegister tmp2) {
+ I64x2MulPreAvx10(dst, lhs, rhs, tmp1, tmp2);
+ }
+ void I8x16Popcnt(XMMRegister dst, XMMRegister src, Register scratch,
+ XMMRegister tmp1, XMMRegister tmp2) {
+ I8x16PopcntPreAvx10(dst, src, tmp1, tmp2, scratch);
+ }
+ void S128Not(XMMRegister dst, XMMRegister src, XMMRegister scratch) {
+ ASM_CODE_COMMENT(this);
+ S128NotPreAvx10(dst, src, scratch);
+ }
+ void S128Select(XMMRegister dst, XMMRegister mask, XMMRegister src1,
+ XMMRegister src2, XMMRegister scratch) {
+ ASM_CODE_COMMENT(this);
+ S128SelectPreAvx10(dst, mask, src1, src2, scratch);
+ }
+
// Expression support
// cvtsi2sd instruction only writes to the low 64-bit of dst register, which
// hinders register renaming and makes dependence chains longer. So we use
diff --git a/deps/v8/src/codegen/interface-descriptors.h b/deps/v8/src/codegen/interface-descriptors.h
index 37c282545bc..9da51025d9f 100644
--- a/deps/v8/src/codegen/interface-descriptors.h
+++ b/deps/v8/src/codegen/interface-descriptors.h
@@ -68,6 +68,7 @@ namespace internal {
V(Compare_Baseline) \
IF_SPARKPLUG_PLUS(V, CompareAndTryPatchCode) \
IF_SPARKPLUG_PLUS(V, BinaryOpAndTryPatchCode) \
+ IF_SPARKPLUG_PLUS(V, UnaryOpAndTryPatchCode) \
V(Compare_WithFeedback) \
V(Compare_WithEmbeddedFeedback) \
V(Compare_WithEmbeddedFeedbackOffset) \
@@ -157,7 +158,8 @@ namespace internal {
V(TypeConversionNoContext) \
V(Typeof) \
V(UnaryOp_Baseline) \
- V(UnaryOp_WithFeedback) \
+ V(UnaryOp_WithEmbeddedFeedback) \
+ V(UnaryOp_WithEmbeddedFeedbackOffset) \
V(Void) \
IF_WASM(V, WasmAllocateShared) \
IF_WASM(V, WasmFXResume) \
@@ -3128,6 +3130,20 @@ class BinaryOpAndTryPatchCodeDescriptor
static constexpr inline auto registers();
};
+
+class UnaryOpAndTryPatchCodeDescriptor
+ : public StaticCallInterfaceDescriptor<UnaryOpAndTryPatchCodeDescriptor> {
+ public:
+ INTERNAL_DESCRIPTOR()
+ SANDBOXING_MODE(kSandboxed)
+ DEFINE_PARAMETERS_NO_CONTEXT(kValue, kCurrentFeedback, kFeedbackOffset)
+ DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
+ MachineType::Int32(), // kCurrentFeedback
+ MachineType::UintPtr()) // kFeedbackOffset
+ DECLARE_DESCRIPTOR(UnaryOpAndTryPatchCodeDescriptor)
+
+ static constexpr inline auto registers();
+};
#endif // V8_ENABLE_SPARKPLUG_PLUS
class Compare_WithEmbeddedFeedbackOffsetDescriptor
@@ -3167,16 +3183,17 @@ class Construct_WithFeedbackDescriptor
DECLARE_JS_COMPATIBLE_DESCRIPTOR(Construct_WithFeedbackDescriptor)
};
-class UnaryOp_WithFeedbackDescriptor
- : public StaticCallInterfaceDescriptor<UnaryOp_WithFeedbackDescriptor> {
+class UnaryOp_WithEmbeddedFeedbackDescriptor
+ : public StaticCallInterfaceDescriptor<
+ UnaryOp_WithEmbeddedFeedbackDescriptor> {
public:
INTERNAL_DESCRIPTOR()
SANDBOXING_MODE(kSandboxed)
- DEFINE_PARAMETERS(kValue, kSlot, kFeedbackVector)
+ DEFINE_PARAMETERS(kValue, kFeedbackOffset, kBytecodeArray)
DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
- MachineType::UintPtr(), // kSlot
- MachineType::AnyTagged()) // kFeedbackVector
- DECLARE_DESCRIPTOR(UnaryOp_WithFeedbackDescriptor)
+ MachineType::UintPtr(), // kFeedbackOffset
+ MachineType::AnyTagged()) // kBytecodeArray
+ DECLARE_DESCRIPTOR(UnaryOp_WithEmbeddedFeedbackDescriptor)
};
class UnaryOp_BaselineDescriptor
@@ -3190,6 +3207,18 @@ class UnaryOp_BaselineDescriptor
DECLARE_DESCRIPTOR(UnaryOp_BaselineDescriptor)
};
+class UnaryOp_WithEmbeddedFeedbackOffsetDescriptor
+ : public StaticCallInterfaceDescriptor<
+ UnaryOp_WithEmbeddedFeedbackOffsetDescriptor> {
+ public:
+ INTERNAL_DESCRIPTOR()
+ SANDBOXING_MODE(kSandboxed)
+ DEFINE_PARAMETERS_NO_CONTEXT(kValue, kFeedbackOffset)
+ DEFINE_PARAMETER_TYPES(MachineType::AnyTagged(), // kValue
+ MachineType::UintPtr()) // kFeedbackOffset
+ DECLARE_DESCRIPTOR(UnaryOp_WithEmbeddedFeedbackOffsetDescriptor)
+};
+
class CheckTurboshaftFloat32TypeDescriptor
: public StaticCallInterfaceDescriptor<
CheckTurboshaftFloat32TypeDescriptor> {
diff --git a/deps/v8/src/codegen/loong64/assembler-loong64.h b/deps/v8/src/codegen/loong64/assembler-loong64.h
index 8c7d8f86e7d..5a4188020e2 100644
--- a/deps/v8/src/codegen/loong64/assembler-loong64.h
+++ b/deps/v8/src/codegen/loong64/assembler-loong64.h
@@ -133,6 +133,10 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
virtual ~Assembler() {}
+ // Distance between the address of the near call instruction and the return
+ // address pushed on the stack.
+ static const int kCallTargetAddressOffset = 4;
+
// GetCode emits any pending (non-emitted) code and fills the descriptor desc.
static constexpr int kNoHandlerTable = 0;
static constexpr SafepointTableBuilderBase* kNoSafepointTable = nullptr;
diff --git a/deps/v8/src/codegen/loong64/interface-descriptors-loong64-inl.h b/deps/v8/src/codegen/loong64/interface-descriptors-loong64-inl.h
index 79449cc897a..f6fd111087c 100644
--- a/deps/v8/src/codegen/loong64/interface-descriptors-loong64-inl.h
+++ b/deps/v8/src/codegen/loong64/interface-descriptors-loong64-inl.h
@@ -307,6 +307,34 @@ constexpr auto Compare_BaselineDescriptor::registers() {
return RegisterArray(a1, a0, a2);
}
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+// static
+constexpr auto CompareAndTryPatchCodeDescriptor::registers() {
+ // a1: left operand
+ // a0: right operand
+ // a2: current feedback value
+ // a3: feedback offset
+ return RegisterArray(a1, a0, a2, a3);
+}
+
+// static
+constexpr auto BinaryOpAndTryPatchCodeDescriptor::registers() {
+ // a1: left operand
+ // a0: right operand
+ // a2: current feedback value
+ // a3: feedback offset
+ return RegisterArray(a1, a0, a2, a3);
+}
+
+// static
+constexpr auto UnaryOpAndTryPatchCodeDescriptor::registers() {
+ // a0: value
+ // a2: current feedback value
+ // a3: feedback offset
+ return RegisterArray(a0, a2, a3);
+}
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
// static
constexpr auto Compare_WithEmbeddedFeedbackOffsetDescriptor::registers() {
// a1: left operand
diff --git a/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc b/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
index 28b87e6af75..0ff1ab0cbb4 100644
--- a/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
+++ b/deps/v8/src/codegen/loong64/macro-assembler-loong64.cc
@@ -358,23 +358,14 @@ void MacroAssembler::RecordWriteField(Register object, int offset,
bind(&done);
}
-void MacroAssembler::DecodeSandboxedPointer(Register value) {
- ASM_CODE_COMMENT(this);
-#ifdef V8_ENABLE_SANDBOX
- srli_d(value, value, kSandboxedPointerShift);
- Add_d(value, value, kPtrComprCageBaseRegister);
-#else
- UNREACHABLE();
-#endif
-}
-
void MacroAssembler::LoadSandboxedPointerField(Register destination,
MemOperand field_operand,
int* trap_pc) {
#ifdef V8_ENABLE_SANDBOX
ASM_CODE_COMMENT(this);
Ld_d(destination, field_operand, trap_pc);
- DecodeSandboxedPointer(destination);
+ srli_d(destination, destination, kSandboxedPointerShift);
+ Add_d(destination, kPtrComprCageBaseRegister, destination);
#else
UNREACHABLE();
#endif
@@ -591,7 +582,11 @@ void MacroAssembler::LoadEntrypointFromJSDispatchTable(Register destination,
Register index = destination;
Ld_d(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- srli_d(index, dispatch_handle, kJSDispatchHandleShift);
+ // JSDispatchHandle is an unsigned 32-bit value. bstrpick.d extracts bits
+ // [31:kJSDispatchHandleShift], zero-extending and shifting right in a single
+ // instruction, so handles with bit 31 set don't produce a negative table
+ // offset.
+ bstrpick_d(index, dispatch_handle, 31, kJSDispatchHandleShift);
slli_d(destination, index, kJSDispatchTableEntrySizeLog2);
Add_d(scratch, scratch, destination);
Ld_d(destination, MemOperand(scratch, JSDispatchEntry::kEntrypointOffset));
@@ -604,7 +599,11 @@ void MacroAssembler::LoadParameterCountFromJSDispatchTable(
Register index = destination;
Ld_d(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- srli_d(index, dispatch_handle, kJSDispatchHandleShift);
+ // JSDispatchHandle is an unsigned 32-bit value. bstrpick.d extracts bits
+ // [31:kJSDispatchHandleShift], zero-extending and shifting right in a single
+ // instruction, so handles with bit 31 set don't produce a negative table
+ // offset.
+ bstrpick_d(index, dispatch_handle, 31, kJSDispatchHandleShift);
slli_d(destination, index, kJSDispatchTableEntrySizeLog2);
Add_d(scratch, scratch, destination);
static_assert(JSDispatchEntry::kParameterCountMask == 0xffff);
@@ -619,7 +618,11 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
Register index = parameter_count;
Ld_d(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- srli_d(index, dispatch_handle, kJSDispatchHandleShift);
+ // JSDispatchHandle is an unsigned 32-bit value. bstrpick.d extracts bits
+ // [31:kJSDispatchHandleShift], zero-extending and shifting right in a single
+ // instruction, so handles with bit 31 set don't produce a negative table
+ // offset.
+ bstrpick_d(index, dispatch_handle, 31, kJSDispatchHandleShift);
slli_d(parameter_count, index, kJSDispatchTableEntrySizeLog2);
Add_d(scratch, scratch, parameter_count);
Ld_d(entrypoint, MemOperand(scratch, JSDispatchEntry::kEntrypointOffset));
@@ -914,7 +917,6 @@ void MacroAssembler::Sub_w(Register rd, Register rj, const Operand& rk) {
if (rk.is_reg()) {
sub_w(rd, rj, rk.rm());
} else {
- DCHECK(is_int32(rk.immediate()));
if (is_int12(-rk.immediate()) && !MustUseReg(rk.rmode())) {
// No subi_w instr, use addi_w(x, y, -imm).
addi_w(rd, rj, static_cast<int32_t>(-rk.immediate()));
@@ -926,7 +928,12 @@ void MacroAssembler::Sub_w(Register rd, Register rj, const Operand& rk) {
// Use load -imm and addu when loading -imm generates one instruction.
li(scratch, -rk.immediate());
add_w(rd, rj, scratch);
+ } else if (RelocInfo::IsFullEmbeddedObject(rk.rmode())) {
+ li(scratch,
+ Operand(rk.immediate(), RelocInfo::COMPRESSED_EMBEDDED_OBJECT));
+ sub_w(rd, rj, scratch);
} else {
+ DCHECK(is_int32(rk.immediate()));
// li handles the relocation.
li(scratch, rk);
sub_w(rd, rj, scratch);
@@ -1147,16 +1154,26 @@ void MacroAssembler::And(Register rd, Register rj, const Operand& rk) {
if (rk.is_reg()) {
and_(rd, rj, rk.rm());
} else {
- if (is_uint12(rk.immediate()) && !MustUseReg(rk.rmode())) {
- andi(rd, rj, static_cast<int32_t>(rk.immediate()));
- } else {
- // li handles the relocation.
- UseScratchRegisterScope temps(this);
- Register scratch = temps.Acquire();
- DCHECK(rj != scratch);
- li(scratch, rk);
- and_(rd, rj, scratch);
+ if (!MustUseReg(rk.rmode())) {
+ uint64_t mask = rk.immediate();
+ if (is_uint12(mask)) {
+ andi(rd, rj, static_cast<int32_t>(rk.immediate()));
+ return;
+ }
+ uint64_t mask_width = base::bits::CountPopulation(mask);
+ uint64_t mask_clz = base::bits::CountLeadingZeros64(mask);
+ if ((mask_width != 0) && ((mask_width + mask_clz) == 64)) {
+ bstrpick_d(rd, rj, mask_width - 1, 0);
+ return;
+ }
}
+
+ // li handles the relocation.
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ DCHECK(rj != scratch);
+ li(scratch, rk);
+ and_(rd, rj, scratch);
}
}
@@ -1238,6 +1255,32 @@ void MacroAssembler::Neg(Register rj, const Operand& rk) {
sub_d(rj, zero_reg, rk.rm());
}
+// Performs a bitwise test on rj with mask rk.
+// NOTE: When rk is an immediate exceeding uint12 range and forms a contiguous
+// bitmask with trailing zeros (mask_ctz > 0), Tst() optimizes using bstrpick_d.
+// In this case, the value saved to 'rd' differs from 'And':
+// E.g., for rj = 0x30000 and mask rk = 0x30000 (mask_ctz = 16, > uint12):
+// - And(): rd = 0x30000 (bitwise AND value)
+// - Tst(): rd = 0x3 (extracted field value via bstrpick_d)
+// Registers or uint12 immediates fall back to And(). In all cases, rd == 0 if
+// and only if (rj & rk) == 0, making it safe for conditional branch testing
+// (eq/ne).
+void MacroAssembler::Tst(Register rd, Register rj, const Operand& rk) {
+ if (rk.is_reg() || is_uint12(rk.immediate())) {
+ And(rd, rj, rk);
+ } else {
+ uint64_t mask = rk.immediate();
+ uint64_t mask_width = base::bits::CountPopulation(mask);
+ uint64_t mask_clz = base::bits::CountLeadingZeros64(mask);
+ uint64_t mask_ctz = base::bits::CountTrailingZeros64(mask);
+ if ((mask_width != 0) && ((mask_width + mask_clz + mask_ctz) == 64)) {
+ bstrpick_d(rd, rj, mask_width + mask_ctz - 1, mask_ctz);
+ } else {
+ And(rd, rj, rk);
+ }
+ }
+}
+
void MacroAssembler::Slt(Register rd, Register rj, const Operand& rk) {
if (rk.is_reg()) {
slt(rd, rj, rk.rm());
@@ -1747,7 +1790,11 @@ void MacroAssembler::li(Register dst, Handle<HeapObject> value,
IndirectLoadConstant(dst, value);
return;
}
- li(dst, Operand(value), mode);
+ if (rmode == RelocInfo::COMPRESSED_EMBEDDED_OBJECT) {
+ li(dst, Operand(value, rmode), mode);
+ } else {
+ li(dst, Operand(value), mode);
+ }
}
void MacroAssembler::li(Register dst, ExternalReference reference,
@@ -3640,31 +3687,12 @@ 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();
- 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);
- }
+ Sub_w(scratch0, r1, r2);
+ Branch(label, cond, scratch0, Operand(zero_reg), need_link);
} else {
Branch(label, cond, r1, r2, need_link);
}
@@ -3847,6 +3875,7 @@ void MacroAssembler::Call(Register target, Condition cond, Register rj,
void MacroAssembler::CompareTaggedRootAndBranch(const Register& obj,
RootIndex index, Condition cc,
Label* target) {
+ DCHECK(cc == eq || cc == ne);
ASM_CODE_COMMENT(this);
AssertSmiOrHeapObjectInMainCompressionCage(obj);
UseScratchRegisterScope temps(this);
@@ -3875,6 +3904,7 @@ void MacroAssembler::CompareTaggedRootAndBranch(const Register& obj,
void MacroAssembler::CompareRootAndBranch(const Register& obj, RootIndex index,
Condition cc, Label* target,
ComparisonMode mode) {
+ DCHECK(cc == eq || cc == ne);
ASM_CODE_COMMENT(this);
if (mode == ComparisonMode::kFullPointer ||
!base::IsInRange(index, RootIndex::kFirstStrongOrReadOnlyRoot,
@@ -4486,8 +4516,8 @@ void MacroAssembler::InvokeFunctionCode(
DCHECK_IMPLIES(new_target.is_valid(), new_target == a3);
Register dispatch_handle = kJavaScriptCallDispatchHandleRegister;
- Ld_w(dispatch_handle,
- FieldMemOperand(function, offsetof(JSFunction, dispatch_handle_)));
+ Ld_wu(dispatch_handle,
+ FieldMemOperand(function, offsetof(JSFunction, dispatch_handle_)));
// On function call, call into the debugger if necessary.
Label debug_hook, continue_after_hook;
@@ -4594,30 +4624,46 @@ void MacroAssembler::AddOverflow_d(Register dst, Register left,
BlockTrampolinePoolScope block_trampoline_pool(this);
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
- Register scratch2 = temps.Acquire();
- Register right_reg = no_reg;
if (!right.is_reg()) {
- li(scratch, Operand(right));
- right_reg = scratch;
- } else {
- right_reg = right.rm();
+ int64_t imm = right.immediate();
+ DCHECK(!AreAliased(overflow, dst));
+ if (dst == left) {
+ mov(scratch, left);
+ left = scratch;
+ }
+ Add_d(dst, left, right);
+ if (imm > 0) {
+ Slt(overflow, dst, left);
+ } else {
+ Sgt(overflow, dst, left);
+ }
+ return;
}
+ Register right_reg = right.rm();
+ Register scratch2 = temps.Acquire();
+ DCHECK(left != scratch && right_reg != scratch && dst != scratch &&
+ overflow != scratch);
DCHECK(left != scratch2 && right_reg != scratch2 && dst != scratch2 &&
overflow != scratch2);
- DCHECK(overflow != left && overflow != right_reg);
- if (dst == left || dst == right_reg) {
- add_d(scratch2, left, right_reg);
+ if (dst != left) {
+ slti(scratch, right_reg, 0);
+ add_d(dst, left, right_reg);
+ slt(scratch2, dst, left);
+ xor_(overflow, scratch, scratch2);
+ } else if (left != right_reg) {
+ // dst == left
+ slti(scratch, left, 0);
+ add_d(dst, right_reg, left);
+ slt(scratch2, dst, right_reg);
+ xor_(overflow, scratch, scratch2);
+ } else {
+ // dst == left == right_reg
+ add_d(scratch2, left, left);
xor_(overflow, scratch2, left);
- xor_(scratch, scratch2, right_reg);
- and_(overflow, overflow, scratch);
+ slti(overflow, overflow, 0);
mov(dst, scratch2);
- } else {
- add_d(dst, left, right_reg);
- xor_(overflow, dst, left);
- xor_(scratch, dst, right_reg);
- and_(overflow, overflow, scratch);
}
}
@@ -4627,31 +4673,30 @@ void MacroAssembler::SubOverflow_d(Register dst, Register left,
BlockTrampolinePoolScope block_trampoline_pool(this);
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
- Register scratch2 = temps.Acquire();
- Register right_reg = no_reg;
if (!right.is_reg()) {
- li(scratch, Operand(right));
- right_reg = scratch;
- } else {
- right_reg = right.rm();
+ int64_t imm = right.immediate();
+ if (dst == left) {
+ mov(scratch, left);
+ left = scratch;
+ }
+ Sub_d(dst, left, right);
+ if (imm < 0) {
+ Slt(overflow, dst, left);
+ } else {
+ Sgt(overflow, dst, left);
+ }
+ return;
}
+ Register right_reg = right.rm();
+ Register scratch2 = temps.Acquire();
DCHECK(left != scratch2 && right_reg != scratch2 && dst != scratch2 &&
overflow != scratch2);
- DCHECK(overflow != left && overflow != right_reg);
- if (dst == left || dst == right_reg) {
- Sub_d(scratch2, left, right_reg);
- xor_(overflow, left, scratch2);
- xor_(scratch, left, right_reg);
- and_(overflow, overflow, scratch);
- mov(dst, scratch2);
- } else {
- sub_d(dst, left, right_reg);
- xor_(overflow, left, dst);
- xor_(scratch, left, right_reg);
- and_(overflow, overflow, scratch);
- }
+ slt(scratch2, left, right_reg);
+ sub_d(dst, left, right_reg);
+ slti(overflow, dst, 0);
+ xor_(overflow, overflow, scratch2);
}
void MacroAssembler::MulOverflow_w(Register dst, Register left,
@@ -4669,21 +4714,12 @@ void MacroAssembler::MulOverflow_w(Register dst, Register left,
right_reg = right.rm();
}
- DCHECK(left != scratch2 && right_reg != scratch2 && dst != scratch2 &&
- overflow != scratch2);
- DCHECK(overflow != left && overflow != right_reg);
-
- if (dst == left || dst == right_reg) {
- Mul_w(scratch2, left, right_reg);
- Mulh_w(overflow, left, right_reg);
- mov(dst, scratch2);
- } else {
- Mul_w(dst, left, right_reg);
- Mulh_w(overflow, left, right_reg);
- }
+ DCHECK(dst != scratch2);
- srai_d(scratch2, dst, 32);
- xor_(overflow, overflow, scratch2);
+ mulw_d_w(scratch2, left, right_reg);
+ slli_w(dst, scratch2, 0);
+ xor_(scratch2, scratch2, dst);
+ sltu(overflow, zero_reg, scratch2);
}
void MacroAssembler::MulOverflow_d(Register dst, Register left,
@@ -4703,19 +4739,13 @@ void MacroAssembler::MulOverflow_d(Register dst, Register left,
DCHECK(left != scratch2 && right_reg != scratch2 && dst != scratch2 &&
overflow != scratch2);
- DCHECK(overflow != left && overflow != right_reg);
- if (dst == left || dst == right_reg) {
- Mul_d(scratch2, left, right_reg);
- Mulh_d(overflow, left, right_reg);
- mov(dst, scratch2);
- } else {
- Mul_d(dst, left, right_reg);
- Mulh_d(overflow, left, right_reg);
- }
+ Mulh_d(scratch2, left, right_reg);
+ Mul_d(dst, left, right_reg);
- srai_d(scratch2, dst, 63);
+ srai_d(overflow, dst, 63);
xor_(overflow, overflow, scratch2);
+ sltu(overflow, zero_reg, overflow);
}
void MacroAssembler::CallRuntime(const Runtime::Function* f,
@@ -5839,7 +5869,7 @@ void MacroAssembler::CallJSFunction(Register function_object,
Register parameter_count = s1;
Register scratch = s2;
- Ld_w(
+ Ld_wu(
dispatch_handle,
FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
LoadEntrypointAndParameterCountFromJSDispatchTable(code, parameter_count,
@@ -6090,18 +6120,18 @@ void MacroAssembler::DecompressTagged(Register dst, const MemOperand& src,
int* trap_pc) {
ASM_CODE_COMMENT(this);
Ld_wu(dst, src, trap_pc);
- Add_d(dst, kPtrComprCageBaseRegister, dst);
+ or_(dst, kPtrComprCageBaseRegister, dst);
}
void MacroAssembler::DecompressTagged(Register dst, Register src) {
ASM_CODE_COMMENT(this);
Bstrpick_d(dst, src, 31, 0);
- Add_d(dst, kPtrComprCageBaseRegister, Operand(dst));
+ or_(dst, kPtrComprCageBaseRegister, dst);
}
void MacroAssembler::DecompressTagged(Register dst, Tagged_t immediate) {
ASM_CODE_COMMENT(this);
- Add_d(dst, kPtrComprCageBaseRegister, static_cast<int32_t>(immediate));
+ Or(dst, kPtrComprCageBaseRegister, Operand(immediate));
}
void MacroAssembler::DecompressProtected(const Register& destination,
@@ -6139,7 +6169,7 @@ void MacroAssembler::AtomicDecompressTagged(Register dst, const MemOperand& src,
ASM_CODE_COMMENT(this);
Ld_wu(dst, src, trap_pc);
dbar(0);
- Add_d(dst, kPtrComprCageBaseRegister, dst);
+ or_(dst, kPtrComprCageBaseRegister, dst);
}
// Calls an API function. Allocates HandleScope, extracts returned value
diff --git a/deps/v8/src/codegen/loong64/macro-assembler-loong64.h b/deps/v8/src/codegen/loong64/macro-assembler-loong64.h
index cf3b0c9667b..7436c20ac4c 100644
--- a/deps/v8/src/codegen/loong64/macro-assembler-loong64.h
+++ b/deps/v8/src/codegen/loong64/macro-assembler-loong64.h
@@ -575,6 +575,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
DEFINE_INSTRUCTION2(Neg)
DEFINE_INSTRUCTION(Andn)
DEFINE_INSTRUCTION(Orn)
+ DEFINE_INSTRUCTION(Tst)
DEFINE_INSTRUCTION(Slt)
DEFINE_INSTRUCTION(Sltu)
@@ -1070,7 +1071,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Transform a SandboxedPointer from/to its encoded form, which is used when
// the pointer is stored on the heap and ensures that the pointer will always
// point into the sandbox.
- void DecodeSandboxedPointer(Register value);
void LoadSandboxedPointerField(Register destination, MemOperand field_operand,
int* trap_pc = NULL);
void StoreSandboxedPointerField(Register value, MemOperand dst_field_operand,
@@ -1446,7 +1446,19 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
template <typename Field>
void DecodeField(Register dst, Register src) {
- Bstrpick_d(dst, src, Field::kShift + Field::kSize - 1, Field::kShift);
+ static constexpr int shift = Field::kShift;
+ static constexpr uint64_t mask =
+ static_cast<uint64_t>(Field::kMask) >> shift;
+ if constexpr ((mask & (mask + 1)) == 0) {
+ Bstrpick_d(dst, src, shift + Field::kSize - 1, shift);
+ } else {
+ if constexpr (shift != 0) {
+ srli_d(dst, src, shift);
+ And(dst, dst, mask);
+ } else {
+ And(dst, src, mask);
+ }
+ }
}
template <typename Field>
diff --git a/deps/v8/src/codegen/machine-type.h b/deps/v8/src/codegen/machine-type.h
index 8f738d3d863..18ca74eb416 100644
--- a/deps/v8/src/codegen/machine-type.h
+++ b/deps/v8/src/codegen/machine-type.h
@@ -396,6 +396,10 @@ constexpr inline bool IsSimd128(MachineRepresentation rep) {
return rep == MachineRepresentation::kSimd128;
}
+constexpr inline bool IsSimd256(MachineRepresentation rep) {
+ return rep == MachineRepresentation::kSimd256;
+}
+
constexpr inline bool CanBeTaggedPointer(MachineRepresentation rep) {
return rep == MachineRepresentation::kTagged ||
rep == MachineRepresentation::kTaggedPointer ||
diff --git a/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc b/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc
index 291c6f844e8..f556b79aefe 100644
--- a/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc
+++ b/deps/v8/src/codegen/mips64/macro-assembler-mips64.cc
@@ -5075,7 +5075,11 @@ void MacroAssembler::LoadEntrypointFromJSDispatchTable(Register destination,
Register index = destination;
CHECK(root_array_available());
Ld(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- dsrl(index, dispatch_handle, kJSDispatchHandleShift);
+ // JSDispatchHandle is an unsigned 32-bit value; dext extracts bits
+ // [31:kJSDispatchHandleShift] into the low bits in a single instruction, so
+ // handles with bit 31 set don't produce a negative table offset.
+ Dext(index, dispatch_handle, kJSDispatchHandleShift,
+ 32 - kJSDispatchHandleShift);
dsll(destination, index, kJSDispatchTableEntrySizeLog2);
Daddu(scratch, scratch, destination);
Ld(destination, MemOperand(scratch, JSDispatchEntry::kEntrypointOffset));
@@ -5089,7 +5093,11 @@ void MacroAssembler::LoadParameterCountFromJSDispatchTable(
// MSARegister index = MSARegister::from_code(destination.code());
Register index = destination;
Ld(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- dsrl(index, dispatch_handle, kJSDispatchHandleShift);
+ // JSDispatchHandle is an unsigned 32-bit value; dext extracts bits
+ // [31:kJSDispatchHandleShift] into the low bits in a single instruction, so
+ // handles with bit 31 set don't produce a negative table offset.
+ Dext(index, dispatch_handle, kJSDispatchHandleShift,
+ 32 - kJSDispatchHandleShift);
dsll(destination, index, kJSDispatchTableEntrySizeLog2);
Daddu(scratch, scratch, destination);
static_assert(JSDispatchEntry::kParameterCountMask == 0xffff);
@@ -5105,7 +5113,11 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
// MSARegister index = MSARegister::from_code(parameter_count.code());
Register index = parameter_count;
Ld(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- dsrl(index, dispatch_handle, kJSDispatchHandleShift);
+ // JSDispatchHandle is an unsigned 32-bit value; dext extracts bits
+ // [31:kJSDispatchHandleShift] into the low bits in a single instruction, so
+ // handles with bit 31 set don't produce a negative table offset.
+ Dext(index, dispatch_handle, kJSDispatchHandleShift,
+ 32 - kJSDispatchHandleShift);
dsll(parameter_count, index, kJSDispatchTableEntrySizeLog2);
Daddu(scratch, scratch, parameter_count);
Ld(entrypoint, MemOperand(scratch, JSDispatchEntry::kEntrypointOffset));
@@ -5274,8 +5286,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_)));
+ Lwu(dispatch_handle,
+ FieldMemOperand(function, offsetof(JSFunction, dispatch_handle_)));
// On function call, call into the debugger if necessary.
Label debug_hook, continue_after_hook;
@@ -6497,8 +6509,8 @@ void MacroAssembler::CallJSFunction(Register function_object,
Register parameter_count = s1;
Register scratch = s2;
- Lw(dispatch_handle,
- FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
+ Lwu(dispatch_handle,
+ FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
LoadEntrypointAndParameterCountFromJSDispatchTable(code, parameter_count,
dispatch_handle, scratch);
diff --git a/deps/v8/src/codegen/mips64/macro-assembler-mips64.h b/deps/v8/src/codegen/mips64/macro-assembler-mips64.h
index 4d1555ed66e..297628a41cd 100644
--- a/deps/v8/src/codegen/mips64/macro-assembler-mips64.h
+++ b/deps/v8/src/codegen/mips64/macro-assembler-mips64.h
@@ -1263,7 +1263,22 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void GenerateTailCallToReturnedCode(Runtime::FunctionId function_id);
template <typename Field>
void DecodeField(Register dst, Register src) {
- Ext(dst, src, Field::kShift, Field::kSize);
+ static constexpr int shift = Field::kShift;
+ static constexpr uint64_t mask =
+ static_cast<uint64_t>(Field::kMask) >> shift;
+ if constexpr ((mask & (mask + 1)) == 0) {
+ Ext(dst, src, shift, Field::kSize);
+ } else {
+ if constexpr (shift == 0) {
+ And(dst, src, mask);
+ } else if constexpr (shift < 32) {
+ dsrl(dst, src, shift);
+ And(dst, dst, mask);
+ } else {
+ dsrl32(dst, src, shift - 32);
+ And(dst, dst, mask);
+ }
+ }
}
template <typename Field>
diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
index a246a778c31..73cb3d6573d 100644
--- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
+++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.cc
@@ -405,7 +405,9 @@ void MacroAssembler::Drop(int count) {
}
}
-void MacroAssembler::Drop(Register count, Register scratch) {
+void MacroAssembler::Drop(Register count) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
ShiftLeftU64(scratch, count, Operand(kSystemPointerSizeLog2));
add(sp, sp, scratch);
}
@@ -950,8 +952,10 @@ void MacroAssembler::RecordWrite(Register object, Register slot_address,
SaveFPRegsMode fp_mode, SmiCheck smi_check) {
DCHECK(!AreAliased(object, value, slot_address));
if (v8_flags.slow_debug_code) {
- LoadTaggedField(r0, MemOperand(slot_address));
- CmpS64(r0, value);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadTaggedField(scratch, MemOperand(slot_address));
+ CmpS64(scratch, value);
Check(eq, AbortReason::kWrongAddressOrValuePassedToRecordWrite);
}
@@ -1015,21 +1019,23 @@ void MacroAssembler::PopLR(Register scratch) {
void MacroAssembler::PushCommonFrame(Register marker_reg) {
int fp_delta = 0;
- mflr(r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mflr(scratch);
if (V8_EMBEDDED_CONSTANT_POOL_BOOL) {
if (marker_reg.is_valid()) {
- Push(r0, fp, kConstantPoolRegister, marker_reg);
+ Push(scratch, fp, kConstantPoolRegister, marker_reg);
fp_delta = 2;
} else {
- Push(r0, fp, kConstantPoolRegister);
+ Push(scratch, fp, kConstantPoolRegister);
fp_delta = 1;
}
} else {
if (marker_reg.is_valid()) {
- Push(r0, fp, marker_reg);
+ Push(scratch, fp, marker_reg);
fp_delta = 1;
} else {
- Push(r0, fp);
+ Push(scratch, fp);
fp_delta = 0;
}
}
@@ -1038,21 +1044,23 @@ void MacroAssembler::PushCommonFrame(Register marker_reg) {
void MacroAssembler::PushStandardFrame(Register function_reg) {
int fp_delta = 0;
- mflr(r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ mflr(scratch);
if (V8_EMBEDDED_CONSTANT_POOL_BOOL) {
if (function_reg.is_valid()) {
- Push(r0, fp, kConstantPoolRegister, cp, function_reg);
+ Push(scratch, fp, kConstantPoolRegister, cp, function_reg);
fp_delta = 3;
} else {
- Push(r0, fp, kConstantPoolRegister, cp);
+ Push(scratch, fp, kConstantPoolRegister, cp);
fp_delta = 2;
}
} else {
if (function_reg.is_valid()) {
- Push(r0, fp, cp, function_reg);
+ Push(scratch, fp, cp, function_reg);
fp_delta = 2;
} else {
- Push(r0, fp, cp);
+ Push(scratch, fp, cp);
fp_delta = 1;
}
}
@@ -1066,9 +1074,11 @@ void MacroAssembler::RestoreFrameStateForTailCall() {
MemOperand(fp, StandardFrameConstants::kConstantPoolOffset));
set_constant_pool_available(false);
}
- LoadU64(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadU64(scratch, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
LoadU64(fp, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
- mtlr(r0);
+ mtlr(scratch);
}
void MacroAssembler::CanonicalizeNaN(const DoubleRegister dst,
@@ -1216,12 +1226,7 @@ void MacroAssembler::Prologue() {
}
}
-void MacroAssembler::DropArguments(Register count) {
- UseScratchRegisterScope temps(this);
- Register scratch = temps.Acquire();
- ShiftLeftU64(scratch, count, Operand(kSystemPointerSizeLog2));
- add(sp, sp, scratch);
-}
+void MacroAssembler::DropArguments(Register count) { Drop(count); }
void MacroAssembler::DropArgumentsAndPushNewReceiver(Register argc,
Register receiver) {
@@ -1259,7 +1264,8 @@ void MacroAssembler::EnterFrame(StackFrame::Type type,
int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) {
ConstantPoolUnavailableScope constant_pool_unavailable(this);
UseScratchRegisterScope temps(this);
- Register scratch = temps.Acquire();
+ Register scratch1 = temps.Acquire();
+ Register scratch2 = temps.Acquire();
// r3: preserved
// r4: preserved
// r5: preserved
@@ -1267,17 +1273,17 @@ int MacroAssembler::LeaveFrame(StackFrame::Type type, int stack_adjustment) {
// Drop the execution stack down to the frame pointer and restore
// the caller's state.
int frame_ends;
- LoadU64(r0, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
- LoadU64(scratch, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
+ LoadU64(scratch2, MemOperand(fp, StandardFrameConstants::kCallerPCOffset));
+ LoadU64(scratch1, MemOperand(fp, StandardFrameConstants::kCallerFPOffset));
if (V8_EMBEDDED_CONSTANT_POOL_BOOL) {
LoadU64(kConstantPoolRegister,
MemOperand(fp, StandardFrameConstants::kConstantPoolOffset));
}
- mtlr(r0);
+ mtlr(scratch2);
frame_ends = pc_offset();
AddS64(sp, fp,
Operand(StandardFrameConstants::kCallerSPOffset + stack_adjustment));
- mr(fp, scratch);
+ mr(fp, scratch1);
return frame_ends;
}
@@ -1342,9 +1348,9 @@ void MacroAssembler::EnterExitFrame(int stack_space,
ClearRightImm(sp, sp,
Operand(base::bits::WhichPowerOfTwo(frame_alignment)));
}
- li(r0, Operand::Zero());
- StoreU64WithUpdate(
- r0, MemOperand(sp, -kNumRequiredStackFrameSlots * kSystemPointerSize));
+ li(scratch, Operand::Zero());
+ StoreU64WithUpdate(scratch, MemOperand(sp, -kNumRequiredStackFrameSlots *
+ kSystemPointerSize));
// Set the exit frame sp value to point just before the return address
// location.
@@ -1452,18 +1458,19 @@ void MacroAssembler::InvokePrologue(Register expected_parameter_count,
Label copy, skip;
Register src = r9, dest = r8;
addi(src, sp, Operand(-kSystemPointerSize));
- ShiftLeftU64(r0, expected_parameter_count, Operand(kSystemPointerSizeLog2));
- sub(sp, sp, r0);
+ ShiftLeftU64(scratch, expected_parameter_count,
+ Operand(kSystemPointerSizeLog2));
+ sub(sp, sp, scratch);
// Update stack pointer.
addi(dest, sp, Operand(-kSystemPointerSize));
- mr(r0, actual_parameter_count);
- cmpi(r0, Operand::Zero());
+ mr(scratch, actual_parameter_count);
+ cmpi(scratch, Operand::Zero());
ble(&skip);
- mtctr(r0);
+ mtctr(scratch);
bind(©);
- LoadU64WithUpdate(r0, MemOperand(src, kSystemPointerSize));
- StoreU64WithUpdate(r0, MemOperand(dest, kSystemPointerSize));
+ LoadU64WithUpdate(scratch, MemOperand(src, kSystemPointerSize));
+ StoreU64WithUpdate(scratch, MemOperand(dest, kSystemPointerSize));
bdnz(©);
bind(&skip);
}
@@ -1618,8 +1625,10 @@ void MacroAssembler::PushStackHandler() {
// Link the current handler as the next handler.
// Preserve r4-r8.
- LoadU64(r0, AsMemOperand(IsolateFieldId::kHandler));
- push(r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadU64(scratch, AsMemOperand(IsolateFieldId::kHandler));
+ push(scratch);
// Set this new handler as the current one.
StoreU64(sp, AsMemOperand(IsolateFieldId::kHandler));
@@ -1680,8 +1689,10 @@ void MacroAssembler::CompareTaggedRoot(const Register& obj, RootIndex index) {
// Some smi roots contain system pointer size values like stack limits.
DCHECK(base::IsInRange(index, RootIndex::kFirstStrongOrReadOnlyRoot,
RootIndex::kLastStrongOrReadOnlyRoot));
- LoadRoot(r0, index);
- CompareTagged(obj, r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadRoot(scratch, index);
+ CompareTagged(obj, scratch);
}
void MacroAssembler::CompareRoot(Register obj, RootIndex index) {
@@ -1689,8 +1700,10 @@ void MacroAssembler::CompareRoot(Register obj, RootIndex index) {
if (!base::IsInRange(index, RootIndex::kFirstStrongOrReadOnlyRoot,
RootIndex::kLastStrongOrReadOnlyRoot)) {
// Some smi roots contain system pointer size values like stack limits.
- LoadRoot(r0, index);
- CmpU64(obj, r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadRoot(scratch, index);
+ CmpU64(obj, scratch);
return;
}
CompareTaggedRoot(obj, index);
@@ -1771,7 +1784,7 @@ void MacroAssembler::TryInlineTruncateDoubleToI(Register result,
result, double_scratch);
// Test for overflow
- TestIfInt32(result, r0);
+ TestIfInt32(result);
beq(done);
}
@@ -2036,7 +2049,7 @@ void MacroAssembler::AssertZeroExtended(Register int32_register) {
void MacroAssembler::AssertMap(Register object) {
if (!v8_flags.debug_code) return;
ASM_CODE_COMMENT(this);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsNotAMap);
UseScratchRegisterScope temps(this);
Register temp = temps.Acquire();
@@ -2047,7 +2060,7 @@ void MacroAssembler::AssertMap(Register object) {
void MacroAssembler::AssertNotSmi(Register object) {
if (v8_flags.debug_code) {
static_assert(kSmiTag == 0);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsASmi, cr0);
}
}
@@ -2055,7 +2068,7 @@ void MacroAssembler::AssertNotSmi(Register object) {
void MacroAssembler::AssertSmi(Register object) {
if (v8_flags.debug_code) {
static_assert(kSmiTag == 0);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(eq, AbortReason::kOperandIsNotASmi, cr0);
}
}
@@ -2063,7 +2076,7 @@ void MacroAssembler::AssertSmi(Register object) {
void MacroAssembler::AssertConstructor(Register object) {
if (v8_flags.debug_code) {
static_assert(kSmiTag == 0);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsASmiAndNotAConstructor, cr0);
push(object);
LoadMap(object, object);
@@ -2077,7 +2090,7 @@ void MacroAssembler::AssertConstructor(Register object) {
void MacroAssembler::AssertFunction(Register object) {
if (v8_flags.debug_code) {
static_assert(kSmiTag == 0);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsASmiAndNotAFunction, cr0);
UseScratchRegisterScope temps(this);
Register temp = temps.Acquire();
@@ -2092,7 +2105,7 @@ void MacroAssembler::AssertCallableFunction(Register object) {
if (!v8_flags.debug_code) return;
ASM_CODE_COMMENT(this);
static_assert(kSmiTag == 0);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsASmiAndNotAFunction, cr0);
UseScratchRegisterScope temps(this);
Register temp = temps.Acquire();
@@ -2105,7 +2118,7 @@ void MacroAssembler::AssertCallableFunction(Register object) {
void MacroAssembler::AssertBoundFunction(Register object) {
if (v8_flags.debug_code) {
static_assert(kSmiTag == 0);
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsASmiAndNotABoundFunction, cr0);
UseScratchRegisterScope temps(this);
Register temp = temps.Acquire();
@@ -2116,7 +2129,7 @@ void MacroAssembler::AssertBoundFunction(Register object) {
void MacroAssembler::AssertGeneratorObject(Register object) {
if (!v8_flags.debug_code) return;
- TestIfSmi(object, r0);
+ TestIfSmi(object);
Check(ne, AbortReason::kOperandIsASmiAndNotAGeneratorObject, cr0);
// Check if JSGeneratorObject
@@ -5189,8 +5202,7 @@ void CallApiFunctionAndReturn(MacroAssembler* masm, bool with_profiling,
} else {
// {argc_operand} was loaded into {argc_reg} above.
__ AddS64(sp, sp, Operand(slots_to_drop_on_return * kSystemPointerSize));
- __ ShiftLeftU64(r0, argc_reg, Operand(kSystemPointerSizeLog2));
- __ AddS64(sp, sp, r0);
+ __ Drop(argc_reg);
}
__ blr();
diff --git a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
index fc3c34dd6d2..709554b7761 100644
--- a/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
+++ b/deps/v8/src/codegen/ppc/macro-assembler-ppc.h
@@ -750,7 +750,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Emit code to discard a non-negative number of pointer-sized elements
// from the stack, clobbering only the sp register.
void Drop(int count);
- void Drop(Register count, Register scratch = r0);
+ void Drop(Register count);
void Ret() { blr(); }
void Ret(Condition cond, CRegister cr = cr0) { bclr(cond, cr); }
@@ -896,33 +896,37 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
}
// Test single bit in value.
- inline void TestBit(Register value, int bitNumber, Register scratch = r0) {
+ inline void TestBit(Register value, int bitNumber) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
ExtractBitRange(scratch, value, bitNumber, bitNumber, SetRC, true);
}
// Test consecutive bit range in value. Range is defined by mask.
- inline void TestBitMask(Register value, uintptr_t mask,
- Register scratch = r0) {
+ inline void TestBitMask(Register value, uintptr_t mask) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
ExtractBitMask(scratch, value, mask, SetRC, true);
}
// Test consecutive bit range in value. Range is defined by
// rangeStart - rangeEnd.
- inline void TestBitRange(Register value, int rangeStart, int rangeEnd,
- Register scratch = r0) {
+ inline void TestBitRange(Register value, int rangeStart, int rangeEnd) {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
ExtractBitRange(scratch, value, rangeStart, rangeEnd, SetRC, true);
}
- inline void TestIfSmi(Register value, Register scratch) {
- TestBitRange(value, kSmiTagSize - 1, 0, scratch);
+ inline void TestIfSmi(Register value) {
+ TestBitRange(value, kSmiTagSize - 1, 0);
}
// Jump the register contains a smi.
inline void JumpIfSmi(Register value, Label* smi_label) {
- TestIfSmi(value, r0);
+ TestIfSmi(value);
beq(smi_label, cr0); // branch if SMI
}
Condition CheckSmi(Register src) {
- TestIfSmi(src, r0);
+ TestIfSmi(src);
return eq;
}
@@ -955,9 +959,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void LoadInterpreterDataInterpreterTrampoline(Register destination,
Register interpreter_data);
- inline void TestIfInt32(Register value, Register scratch,
- CRegister cr = cr0) {
+ inline void TestIfInt32(Register value, CRegister cr = cr0) {
// High bits must be identical to fit into an 32-bit integer
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
extsw(scratch, value);
CmpS64(scratch, value, cr);
}
@@ -1627,8 +1632,10 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void CompareTaggedRoot(const Register& with, RootIndex index);
void PushRoot(RootIndex index) {
- LoadRoot(r0, index);
- Push(r0);
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ LoadRoot(scratch, index);
+ Push(scratch);
}
// Compare the object in a register to a value and jump if they are equal.
@@ -1720,7 +1727,7 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Jump if either of the registers contain a non-smi.
inline void JumpIfNotSmi(Register value, Label* not_smi_label) {
- TestIfSmi(value, r0);
+ TestIfSmi(value);
bne(not_smi_label, cr0);
}
diff --git a/deps/v8/src/codegen/reloc-info.h b/deps/v8/src/codegen/reloc-info.h
index aea2844f9d8..af8b3b20ea8 100644
--- a/deps/v8/src/codegen/reloc-info.h
+++ b/deps/v8/src/codegen/reloc-info.h
@@ -408,7 +408,8 @@ class RelocInfo {
ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT) |
ModeMask(RelocInfo::NEAR_BUILTIN_ENTRY) |
ModeMask(RelocInfo::WASM_STUB_CALL) |
- ModeMask(RelocInfo::RELATIVE_CODE_TARGET) | kApplyMask;
+ ModeMask(RelocInfo::RELATIVE_CODE_TARGET) |
+ JSDispatchHandleModeMask() | kApplyMask;
}
protected:
diff --git a/deps/v8/src/codegen/riscv/assembler-riscv.cc b/deps/v8/src/codegen/riscv/assembler-riscv.cc
index f6e7865bafd..f9c12ab9a75 100644
--- a/deps/v8/src/codegen/riscv/assembler-riscv.cc
+++ b/deps/v8/src/codegen/riscv/assembler-riscv.cc
@@ -49,7 +49,7 @@ namespace internal {
#ifdef CAN_USE_RVA23U64_INSTRUCTIONS
static const CpuFeatureSet kRVA23U64 =
- CpuFeatureSet{} | ZFA | ZBB | ZBS | ZBA | ZICOND;
+ CpuFeatureSet{} | RVC | ZFA | ZBB | ZBS | ZBA | ZICOND | ZCB;
#endif
// Get the CPU features enabled by the build. For cross compilation the
// preprocessor symbols __riscv_f and __riscv_d
@@ -105,6 +105,8 @@ static CpuFeatureSet SimulatorFeatures() {
features.Add(ZFH);
features.Add(ZVFH);
features.Add(ZFA);
+ features.Add(RVC);
+ features.Add(ZCB);
return features;
}
#endif
diff --git a/deps/v8/src/codegen/riscv/base-assembler-riscv.cc b/deps/v8/src/codegen/riscv/base-assembler-riscv.cc
index 1876069352f..cf6263c5bdc 100644
--- a/deps/v8/src/codegen/riscv/base-assembler-riscv.cc
+++ b/deps/v8/src/codegen/riscv/base-assembler-riscv.cc
@@ -217,8 +217,8 @@ void AssemblerRiscvBase::GenInstrS(uint8_t funct3, BaseOpcode opcode,
void AssemblerRiscvBase::GenInstrB(uint8_t funct3, BaseOpcode opcode,
Register rs1, Register rs2, int16_t imm13) {
- DCHECK(is_uint3(funct3) && rs1.is_valid() && rs2.is_valid() &&
- is_int13(imm13) && ((imm13 & 1) == 0));
+ CHECK(is_uint3(funct3) && rs1.is_valid() && rs2.is_valid() &&
+ is_int13(imm13) && ((imm13 & 1) == 0));
Instr instr = opcode | ((imm13 & 0x800) >> 4) | // bit 11
((imm13 & 0x1e) << 7) | // bits 4-1
(funct3 << kFunct3Shift) | (rs1.code() << kRs1Shift) |
@@ -237,7 +237,8 @@ void AssemblerRiscvBase::GenInstrU(BaseOpcode opcode, Register rd,
void AssemblerRiscvBase::GenInstrJ(BaseOpcode opcode, Register rd,
int32_t imm21) {
- DCHECK(rd.is_valid() && is_int21(imm21) && ((imm21 & 1) == 0));
+ CHECK(is_int21(imm21));
+ DCHECK(rd.is_valid() && ((imm21 & 1) == 0));
Instr instr = opcode | (rd.code() << kRdShift) |
(imm21 & 0xff000) | // bits 19-12
((imm21 & 0x800) << 9) | // bit 11
@@ -386,6 +387,20 @@ void AssemblerRiscvBase::GenInstrCBA(uint8_t funct3, uint8_t funct2,
(funct3 << kRvcFunct3Shift) | (funct2 << 10);
emit(instr);
}
+
+// CU (Compressed Unary) format, used by the Zcb extension:
+// | funct3 | nzuimm[5:3] | rd'/rs1' | funct2 | nzuimm[2:0] | opcode |
+// 15:13 12:10 9:7 6:5 4:2 1:0
+void AssemblerRiscvBase::GenInstrCU(uint8_t funct3, uint8_t funct2,
+ BaseOpcode opcode, Register rd,
+ uint8_t nzuimm) {
+ DCHECK(is_uint3(funct3) && is_uint2(funct2) && is_uint6(nzuimm));
+ ShortInstr instr = opcode | ((nzuimm & 0x7) << kRvcRs2sShift) |
+ ((rd.code() & 0x7) << kRvcRs1sShift) |
+ ((nzuimm & 0x38) << 7) | (funct2 << kRvcFunct2Shift) |
+ (funct3 << kRvcFunct3Shift);
+ emit(instr);
+}
// ----- Instruction class templates match those in the compiler
void AssemblerRiscvBase::GenInstrBranchCC_rri(uint8_t funct3, Register rs1,
diff --git a/deps/v8/src/codegen/riscv/base-assembler-riscv.h b/deps/v8/src/codegen/riscv/base-assembler-riscv.h
index 52b8dccc408..12366e42958 100644
--- a/deps/v8/src/codegen/riscv/base-assembler-riscv.h
+++ b/deps/v8/src/codegen/riscv/base-assembler-riscv.h
@@ -181,6 +181,8 @@ class AssemblerRiscvBase {
uint8_t uimm8);
void GenInstrCBA(uint8_t funct3, uint8_t funct2, BaseOpcode opcode,
Register rs1, int8_t imm6);
+ void GenInstrCU(uint8_t funct3, uint8_t funct2, BaseOpcode opcode,
+ Register rd, uint8_t nzuimm);
// ----- Instruction class templates match those in LLVM's RISCVInstrInfo.td
void GenInstrBranchCC_rri(uint8_t funct3, Register rs1, Register rs2,
diff --git a/deps/v8/src/codegen/riscv/base-constants-riscv.cc b/deps/v8/src/codegen/riscv/base-constants-riscv.cc
index 53a852d11f3..a110d722904 100644
--- a/deps/v8/src/codegen/riscv/base-constants-riscv.cc
+++ b/deps/v8/src/codegen/riscv/base-constants-riscv.cc
@@ -366,6 +366,12 @@ InstructionBase::Type InstructionBase::InstructionType() const {
case RO_C_LD:
#endif
return kCLType;
+ case RO_C_LBU: // Zcb loads/stores, all sharing funct3=100.
+ // The five Zcb load/store instructions are distinguished by the
+ // fixed bits [12:10]: 000/001 are CL-format loads, 010/011 are
+ // CS-format stores.
+ return (Bits(12, 10) == 0b000 || Bits(12, 10) == 0b001) ? kCLType
+ : kCSType;
case RO_C_FSD:
case RO_C_SW:
#ifdef V8_TARGET_ARCH_RISCV64
@@ -380,10 +386,12 @@ InstructionBase::Type InstructionBase::InstructionType() const {
case RO_C_LUI_ADD:
return kCIType;
case RO_C_MISC_ALU:
- if (Bits(11, 10) != 0b11)
- return kCBType;
- else
- return kCAType;
+ if (Bits(11, 10) != 0b11) return kCBType;
+ // CU-format Zcb unary instructions (c.zext.b, c.not, ...) share the
+ // funct3=100 and bits [12:10]=111 encodings with the RV64 CA
+ // instructions but use funct2=11 at bits [6:5].
+ if (Bits(12, 10) == 0b111 && Bits(6, 5) == 0b11) return kCBType;
+ return kCAType;
case RO_C_J:
return kCJType;
case RO_C_BEQZ:
diff --git a/deps/v8/src/codegen/riscv/constant-riscv-c.h b/deps/v8/src/codegen/riscv/constant-riscv-c.h
index 8191131ea95..319c8e680be 100644
--- a/deps/v8/src/codegen/riscv/constant-riscv-c.h
+++ b/deps/v8/src/codegen/riscv/constant-riscv-c.h
@@ -59,6 +59,48 @@ constexpr Opcode RO_C_FSWSP = C2 | (0b111 << kRvcFunct3Shift);
constexpr Opcode RO_C_FLW = C0 | (0b011 << kRvcFunct3Shift);
constexpr Opcode RO_C_FSW = C0 | (0b111 << kRvcFunct3Shift);
#endif
+// Zcb extension.
+//
+// C0 quadrant: all five load/store instructions share funct3=100 and are
+// distinguished by the fixed bits [12:10] and bit 6 (see
+// https://github.com/riscv/riscv-isa-manual/blob/main/src/unpriv/zcb.adoc):
+// c.lbu rd', uimm(rs1'): 100 000 rs1' uimm[1:0] rd' 00
+// (uimm[1] = enc[5], uimm[0] = enc[6])
+// c.lhu rd', uimm(rs1'): 100 001 rs1' 0 uimm[1] rd' 00
+// c.lh rd', uimm(rs1'): 100 001 rs1' 1 uimm[1] rd' 00
+// c.sb rs2', uimm(rs1'): 100 010 rs1' uimm[1:0] rs2' 00
+// c.sh rs2', uimm(rs1'): 100 011 rs1' 0 uimm[1] rs2' 00
+constexpr Opcode RO_C_LBU = C0 | (0b100 << kRvcFunct3Shift) | (0b000 << 10);
+constexpr Opcode RO_C_LHU = C0 | (0b100 << kRvcFunct3Shift) | (0b001 << 10);
+constexpr Opcode RO_C_LH =
+ C0 | (0b100 << kRvcFunct3Shift) | (0b001 << 10) | (0b1 << 6);
+constexpr Opcode RO_C_SB = C0 | (0b100 << kRvcFunct3Shift) | (0b010 << 10);
+constexpr Opcode RO_C_SH = C0 | (0b100 << kRvcFunct3Shift) | (0b011 << 10);
+// C1 quadrant (CA format): c.mul reuses the reserved funct6=100111 slot.
+constexpr Opcode RO_C_MUL =
+ C1 | (0b100111 << kRvcFunct6Shift) | (FUNCT2_2 << kRvcFunct2Shift);
+// C1 quadrant (CU format, funct2=11): unary instructions whose opcode is
+// determined by nzuimm[5:0] = 111xxx (56..61).
+constexpr Opcode RO_C_ZEXT_B = C1 | (0b100111 << kRvcFunct6Shift) |
+ (FUNCT2_3 << kRvcFunct2Shift) |
+ (0b000 << kRvcRs2sShift);
+constexpr Opcode RO_C_SEXT_B = C1 | (0b100111 << kRvcFunct6Shift) |
+ (FUNCT2_3 << kRvcFunct2Shift) |
+ (0b001 << kRvcRs2sShift);
+constexpr Opcode RO_C_ZEXT_H = C1 | (0b100111 << kRvcFunct6Shift) |
+ (FUNCT2_3 << kRvcFunct2Shift) |
+ (0b010 << kRvcRs2sShift);
+constexpr Opcode RO_C_SEXT_H = C1 | (0b100111 << kRvcFunct6Shift) |
+ (FUNCT2_3 << kRvcFunct2Shift) |
+ (0b011 << kRvcRs2sShift);
+constexpr Opcode RO_C_NOT = C1 | (0b100111 << kRvcFunct6Shift) |
+ (FUNCT2_3 << kRvcFunct2Shift) |
+ (0b101 << kRvcRs2sShift);
+#ifdef V8_TARGET_ARCH_RISCV64
+constexpr Opcode RO_C_ZEXT_W = C1 | (0b100111 << kRvcFunct6Shift) |
+ (FUNCT2_3 << kRvcFunct2Shift) |
+ (0b100 << kRvcRs2sShift);
+#endif
// clang-format on
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/codegen/riscv/extension-riscv-c.cc b/deps/v8/src/codegen/riscv/extension-riscv-c.cc
index 5616136d6b0..6a2cb08ae38 100644
--- a/deps/v8/src/codegen/riscv/extension-riscv-c.cc
+++ b/deps/v8/src/codegen/riscv/extension-riscv-c.cc
@@ -253,6 +253,89 @@ void AssemblerRISCVC::c_andi(Register rs1, int8_t imm6) {
GenInstrCBA(0b100, 0b10, C1, rs1, imm6);
}
+// Zcb Instructions
+
+void AssemblerRISCVC::c_lbu(Register rd, Register rs1, uint16_t uimm) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000) &&
+ ((rs1.code() & 0b11000) == 0b01000) && is_uint2(uimm));
+ // uimm[1] = enc[5], uimm[0] = enc[6]; bits [12:10] are fixed to 000.
+ uint8_t uimm5 = ((uimm & 0x1) << 1) | ((uimm >> 1) & 0x1);
+ GenInstrCL(0b100, C0, rd, rs1, uimm5);
+}
+
+void AssemblerRISCVC::c_lhu(Register rd, Register rs1, uint16_t uimm) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000) &&
+ ((rs1.code() & 0b11000) == 0b01000) && is_uint2(uimm) &&
+ ((uimm & 0x1) == 0));
+ // uimm[1] = enc[5], enc[6] = 0; bits [12:10] are fixed to 001.
+ uint8_t uimm5 = 0b00100 | ((uimm >> 1) & 0x1);
+ GenInstrCL(0b100, C0, rd, rs1, uimm5);
+}
+
+void AssemblerRISCVC::c_lh(Register rd, Register rs1, uint16_t uimm) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000) &&
+ ((rs1.code() & 0b11000) == 0b01000) && is_uint2(uimm) &&
+ ((uimm & 0x1) == 0));
+ // uimm[1] = enc[5], enc[6] = 1; bits [12:10] are fixed to 001.
+ uint8_t uimm5 = 0b00110 | ((uimm >> 1) & 0x1);
+ GenInstrCL(0b100, C0, rd, rs1, uimm5);
+}
+
+void AssemblerRISCVC::c_sb(Register rs2, Register rs1, uint16_t uimm) {
+ DCHECK(((rs2.code() & 0b11000) == 0b01000) &&
+ ((rs1.code() & 0b11000) == 0b01000) && is_uint2(uimm));
+ // uimm[1] = enc[5], uimm[0] = enc[6]; bits [12:10] are fixed to 010.
+ uint8_t uimm5 = 0b01000 | ((uimm & 0x1) << 1) | ((uimm >> 1) & 0x1);
+ GenInstrCS(0b100, C0, rs2, rs1, uimm5);
+}
+
+void AssemblerRISCVC::c_sh(Register rs2, Register rs1, uint16_t uimm) {
+ DCHECK(((rs2.code() & 0b11000) == 0b01000) &&
+ ((rs1.code() & 0b11000) == 0b01000) && is_uint2(uimm) &&
+ ((uimm & 0x1) == 0));
+ // uimm[1] = enc[5], enc[6] = 0; bits [12:10] are fixed to 011.
+ uint8_t uimm5 = 0b01100 | ((uimm >> 1) & 0x1);
+ GenInstrCS(0b100, C0, rs2, rs1, uimm5);
+}
+
+void AssemblerRISCVC::c_mul(Register rd, Register rs2) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000) &&
+ ((rs2.code() & 0b11000) == 0b01000));
+ GenInstrCA(0b100111, C1, rd, 0b10, rs2);
+}
+
+void AssemblerRISCVC::c_zext_b(Register rd) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000));
+ GenInstrCU(0b100, 0b11, C1, rd, 0b111000);
+}
+
+void AssemblerRISCVC::c_sext_b(Register rd) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000));
+ GenInstrCU(0b100, 0b11, C1, rd, 0b111001);
+}
+
+void AssemblerRISCVC::c_zext_h(Register rd) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000));
+ GenInstrCU(0b100, 0b11, C1, rd, 0b111010);
+}
+
+void AssemblerRISCVC::c_sext_h(Register rd) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000));
+ GenInstrCU(0b100, 0b11, C1, rd, 0b111011);
+}
+
+#ifdef V8_TARGET_ARCH_RISCV64
+void AssemblerRISCVC::c_zext_w(Register rd) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000));
+ GenInstrCU(0b100, 0b11, C1, rd, 0b111100);
+}
+#endif
+
+void AssemblerRISCVC::c_not(Register rd) {
+ DCHECK(((rd.code() & 0b11000) == 0b01000));
+ GenInstrCU(0b100, 0b11, C1, rd, 0b111101);
+}
+
bool AssemblerRISCVC::IsCJal(Instr instr) {
return (instr & kRvcOpcodeMask) == RO_C_J;
}
diff --git a/deps/v8/src/codegen/riscv/extension-riscv-c.h b/deps/v8/src/codegen/riscv/extension-riscv-c.h
index 27e2ae65282..82e700bafb5 100644
--- a/deps/v8/src/codegen/riscv/extension-riscv-c.h
+++ b/deps/v8/src/codegen/riscv/extension-riscv-c.h
@@ -57,6 +57,23 @@ class AssemblerRISCVC : public AssemblerRiscvBase {
void c_sdsp(Register rs2, uint16_t uimm9);
#endif
+ // Zcb extension.
+ void c_lbu(Register rd, Register rs1, uint16_t uimm);
+ void c_lhu(Register rd, Register rs1, uint16_t uimm);
+ void c_lh(Register rd, Register rs1, uint16_t uimm);
+ void c_sb(Register rs2, Register rs1, uint16_t uimm);
+ void c_sh(Register rs2, Register rs1, uint16_t uimm);
+ void c_mul(Register rd, Register rs2);
+ void c_zext_b(Register rd);
+ void c_sext_b(Register rd);
+ void c_zext_h(Register rd);
+ void c_sext_h(Register rd);
+ void c_not(Register rd);
+#ifdef V8_TARGET_ARCH_RISCV64
+ void c_zext_w(Register rd);
+ void c_sext_w(Register rd) { c_addiw(rd, 0); }
+#endif
+
int CJumpOffset(Instr instr);
static bool IsCBranch(Instr instr);
diff --git a/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc b/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc
index 46a9740f454..a1e8a4adcf6 100644
--- a/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc
+++ b/deps/v8/src/codegen/riscv/macro-assembler-riscv.cc
@@ -56,6 +56,9 @@ int MacroAssembler::RequiredStackSizeForCallerSaved(SaveFPRegsMode fp_mode,
if (fp_mode == SaveFPRegsMode::kSave) {
bytes += kCallerSavedFPU.Count() * kDoubleSize;
+#if V8_ENABLE_SIMD128
+ bytes += kCallerSavedVR.Count() * kSimd128Size;
+#endif
}
return bytes;
@@ -73,6 +76,14 @@ int MacroAssembler::PushCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
if (fp_mode == SaveFPRegsMode::kSave) {
MultiPushFPU(kCallerSavedFPU);
bytes += kCallerSavedFPU.Count() * kDoubleSize;
+#if V8_ENABLE_SIMD128
+ // The vector registers are a separate register file from the FPU
+ // registers, so they must be saved independently. SaveVectorRegisters
+ // takes care of only accessing vector registers if the hardware supports
+ // SIMD, reserving the same amount of stack space in either case.
+ SaveVectorRegisters(kCallerSavedVR);
+ bytes += kCallerSavedVR.Count() * kSimd128Size;
+#endif
}
return bytes;
@@ -82,6 +93,10 @@ int MacroAssembler::PopCallerSaved(SaveFPRegsMode fp_mode, Register exclusion1,
Register exclusion2, Register exclusion3) {
int bytes = 0;
if (fp_mode == SaveFPRegsMode::kSave) {
+#if V8_ENABLE_SIMD128
+ RestoreVectorRegisters(kCallerSavedVR);
+ bytes += kCallerSavedVR.Count() * kSimd128Size;
+#endif
MultiPopFPU(kCallerSavedFPU);
bytes += kCallerSavedFPU.Count() * kDoubleSize;
}
@@ -150,7 +165,6 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
Push(kJavaScriptCallTargetRegister);
CallRuntime(function_id, 1);
- LoadCodeInstructionStart(a2, a0, kJSEntrypointTag);
// Restore target function, new target, actual argument count and dispatch
// handle.
@@ -163,6 +177,13 @@ void MacroAssembler::GenerateTailCallToReturnedCode(
}
static_assert(kJavaScriptCallCodeStartRegister == a2, "ABI mismatch");
+#ifndef V8_JS_LINKAGE_INCLUDES_DISPATCH_HANDLE
+ Lwu(kJavaScriptCallDispatchHandleRegister,
+ FieldMemOperand(kJavaScriptCallTargetRegister,
+ offsetof(JSFunction, dispatch_handle_)));
+#endif
+ LoadEntrypointFromJSDispatchTable(a2, kJavaScriptCallDispatchHandleRegister,
+ a5);
Jump(a2);
}
@@ -786,23 +807,14 @@ void MacroAssembler::RecordWrite(Register object, Operand offset,
// ---------------------------------------------------------------------------
// Instruction macros.
#if V8_TARGET_ARCH_RISCV64
-void MacroAssembler::DecodeSandboxedPointer(Register value) {
- ASM_CODE_COMMENT(this);
-#ifdef V8_ENABLE_SANDBOX
- SrlWord(value, value, kSandboxedPointerShift);
- AddWord(value, value, kPtrComprCageBaseRegister);
-#else
- UNREACHABLE();
-#endif
-}
-
void MacroAssembler::LoadSandboxedPointerField(Register destination,
const MemOperand& field_operand,
Trapper&& trapper) {
#ifdef V8_ENABLE_SANDBOX
ASM_CODE_COMMENT(this);
LoadWord(destination, field_operand, std::forward<Trapper>(trapper));
- DecodeSandboxedPointer(destination);
+ SrlWord(destination, destination, kSandboxedPointerShift);
+ AddWord(destination, kPtrComprCageBaseRegister, destination);
#else
UNREACHABLE();
#endif
@@ -825,8 +837,7 @@ void MacroAssembler::StoreSandboxedPointerField(
void MacroAssembler::Add32(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_addw(rd, rt.rm());
} else {
addw(rd, rs, rt.rm());
@@ -855,8 +866,7 @@ void MacroAssembler::Add32(Register rd, Register rs, const Operand& rt) {
void MacroAssembler::Sub32(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_subw(rd, rt.rm());
} else {
subw(rd, rs, rt.rm());
@@ -905,8 +915,7 @@ void MacroAssembler::SubWord(Register rd, Register rs, const Operand& rt) {
void MacroAssembler::Sub64(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_sub(rd, rt.rm());
} else {
sub(rd, rs, rt.rm());
@@ -969,8 +978,7 @@ void MacroAssembler::Add64(Register rd, Register rs, const Operand& rt) {
(rd.code() == rs.code()) && (rd == sp) &&
!MustUseReg(rt.rmode())) {
c_addi16sp(static_cast<int16_t>(rt.immediate()));
- } else if (CpuFeatures::IsSupported(RVC) &&
- ((rd.code() & 0b11000) == 0b01000) && (rs == sp) &&
+ } else if (CpuFeatures::IsSupported(RVC) && IsRvcReg(rd) && (rs == sp) &&
is_uint10(rt.immediate()) && (rt.immediate() != 0) &&
!MustUseReg(rt.rmode())) {
c_addi4spn(rd, static_cast<uint16_t>(rt.immediate()));
@@ -1182,8 +1190,7 @@ void MacroAssembler::Add32(Register rd, Register rs, const Operand& rt) {
(rd.code() == rs.code()) && (rd == sp) &&
!MustUseReg(rt.rmode())) {
c_addi16sp(static_cast<int16_t>(rt.immediate()));
- } else if (CpuFeatures::IsSupported(RVC) &&
- ((rd.code() & 0b11000) == 0b01000) && (rs == sp) &&
+ } else if (CpuFeatures::IsSupported(RVC) && IsRvcReg(rd) && (rs == sp) &&
is_uint10(rt.immediate()) && (rt.immediate() != 0) &&
!MustUseReg(rt.rmode())) {
c_addi4spn(rd, static_cast<uint16_t>(rt.immediate()));
@@ -1211,8 +1218,7 @@ void MacroAssembler::SubWord(Register rd, Register rs, const Operand& rt) {
void MacroAssembler::Sub32(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_sub(rd, rt.rm());
} else {
sub(rd, rs, rt.rm());
@@ -1352,16 +1358,14 @@ void MacroAssembler::Divu(Register res, Register rs, const Operand& rt) {
void MacroAssembler::And(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_and(rd, rt.rm());
} else {
and_(rd, rs, rt.rm());
}
} else {
if (CpuFeatures::IsSupported(RVC) && is_int6(rt.immediate()) &&
- !MustUseReg(rt.rmode()) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000)) {
+ !MustUseReg(rt.rmode()) && (rd.code() == rs.code()) && IsRvcReg(rd)) {
c_andi(rd, static_cast<int8_t>(rt.immediate()));
} else if (is_int12(rt.immediate()) && !MustUseReg(rt.rmode())) {
andi(rd, rs, static_cast<int32_t>(rt.immediate()));
@@ -1378,8 +1382,7 @@ void MacroAssembler::And(Register rd, Register rs, const Operand& rt) {
void MacroAssembler::Or(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_or(rd, rt.rm());
} else {
or_(rd, rs, rt.rm());
@@ -1400,8 +1403,7 @@ void MacroAssembler::Or(Register rd, Register rs, const Operand& rt) {
void MacroAssembler::Xor(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) &&
- ((rt.rm().code() & 0b11000) == 0b01000)) {
+ IsRvcReg(rd) && IsRvcReg(rt.rm())) {
c_xor(rd, rt.rm());
} else {
xor_(rd, rs, rt.rm());
@@ -1606,7 +1608,7 @@ void MacroAssembler::Sra64(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
sra(rd, rs, rt.rm());
} else if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) && is_int6(rt.immediate())) {
+ IsRvcReg(rd) && is_int6(rt.immediate())) {
uint8_t shamt = static_cast<uint8_t>(rt.immediate());
c_srai(rd, shamt);
} else {
@@ -1623,7 +1625,7 @@ void MacroAssembler::Srl64(Register rd, Register rs, const Operand& rt) {
if (rt.is_reg()) {
srl(rd, rs, rt.rm());
} else if (CpuFeatures::IsSupported(RVC) && (rd.code() == rs.code()) &&
- ((rd.code() & 0b11000) == 0b01000) && is_int6(rt.immediate())) {
+ IsRvcReg(rd) && is_int6(rt.immediate())) {
uint8_t shamt = static_cast<uint8_t>(rt.immediate());
c_srli(rd, shamt);
} else {
@@ -2250,7 +2252,12 @@ void MacroAssembler::Lb(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Lbu(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register target, const MemOperand& source) {
trapper(pc_offset());
- lbu(target, source.rm(), source.offset());
+ if (CpuFeatures::IsSupported(ZCB) && IsRvcReg(source.rm()) &&
+ IsRvcReg(rd) && is_uint2(source.offset())) {
+ c_lbu(rd, source.rm(), source.offset());
+ } else {
+ lbu(target, source.rm(), source.offset());
+ }
};
AlignedLoadHelper(rd, rs, fn);
}
@@ -2266,7 +2273,13 @@ void MacroAssembler::Sb(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Lh(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register target, const MemOperand& source) {
trapper(pc_offset());
- lh(target, source.rm(), source.offset());
+ if (CpuFeatures::IsSupported(ZCB) && IsRvcReg(source.rm()) &&
+ IsRvcReg(rd) && is_uint2(source.offset()) &&
+ ((source.offset() & 1) == 0)) {
+ c_lh(rd, source.rm(), source.offset());
+ } else {
+ lh(target, source.rm(), source.offset());
+ }
};
AlignedLoadHelper(rd, rs, fn);
}
@@ -2274,7 +2287,13 @@ void MacroAssembler::Lh(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Lhu(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register target, const MemOperand& source) {
trapper(pc_offset());
- lhu(target, source.rm(), source.offset());
+ if (CpuFeatures::IsSupported(ZCB) && IsRvcReg(source.rm()) &&
+ IsRvcReg(rd) && is_uint2(source.offset()) &&
+ ((source.offset() & 1) == 0)) {
+ c_lhu(rd, source.rm(), source.offset());
+ } else {
+ lhu(target, source.rm(), source.offset());
+ }
};
AlignedLoadHelper(rd, rs, fn);
}
@@ -2290,10 +2309,9 @@ void MacroAssembler::Sh(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Lw(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register target, const MemOperand& source) {
trapper(pc_offset());
- if (CpuFeatures::IsSupported(RVC) &&
- ((target.code() & 0b11000) == 0b01000) &&
- ((source.rm().code() & 0b11000) == 0b01000) &&
- is_uint7(source.offset()) && ((source.offset() & 0x3) == 0)) {
+ if (CpuFeatures::IsSupported(RVC) && IsRvcReg(target) &&
+ IsRvcReg(source.rm()) && is_uint7(source.offset()) &&
+ ((source.offset() & 0x3) == 0)) {
c_lw(target, source.rm(), source.offset());
} else if (CpuFeatures::IsSupported(RVC) && (target != zero_reg) &&
is_uint8(source.offset()) && (source.rm() == sp) &&
@@ -2319,10 +2337,9 @@ void MacroAssembler::Lwu(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Sw(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register value, const MemOperand& source) {
trapper(pc_offset());
- if (CpuFeatures::IsSupported(RVC) &&
- ((value.code() & 0b11000) == 0b01000) &&
- ((source.rm().code() & 0b11000) == 0b01000) &&
- is_uint7(source.offset()) && ((source.offset() & 0x3) == 0)) {
+ if (CpuFeatures::IsSupported(RVC) && IsRvcReg(value) &&
+ IsRvcReg(source.rm()) && is_uint7(source.offset()) &&
+ ((source.offset() & 0x3) == 0)) {
c_sw(value, source.rm(), source.offset());
} else if (CpuFeatures::IsSupported(RVC) && (source.rm() == sp) &&
is_uint8(source.offset()) && (((source.offset() & 0x3) == 0))) {
@@ -2338,10 +2355,9 @@ void MacroAssembler::Sw(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Ld(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register target, const MemOperand& source) {
trapper(pc_offset());
- if (CpuFeatures::IsSupported(RVC) &&
- ((target.code() & 0b11000) == 0b01000) &&
- ((source.rm().code() & 0b11000) == 0b01000) &&
- is_uint8(source.offset()) && ((source.offset() & 0x7) == 0)) {
+ if (CpuFeatures::IsSupported(RVC) && IsRvcReg(target) &&
+ IsRvcReg(source.rm()) && is_uint8(source.offset()) &&
+ ((source.offset() & 0x7) == 0)) {
c_ld(target, source.rm(), source.offset());
} else if (CpuFeatures::IsSupported(RVC) && (target != zero_reg) &&
is_uint9(source.offset()) && (source.rm() == sp) &&
@@ -2357,10 +2373,9 @@ void MacroAssembler::Ld(Register rd, const MemOperand& rs, Trapper&& trapper) {
void MacroAssembler::Sd(Register rd, const MemOperand& rs, Trapper&& trapper) {
auto fn = [&](Register value, const MemOperand& source) {
trapper(pc_offset());
- if (CpuFeatures::IsSupported(RVC) &&
- ((value.code() & 0b11000) == 0b01000) &&
- ((source.rm().code() & 0b11000) == 0b01000) &&
- is_uint8(source.offset()) && ((source.offset() & 0x7) == 0)) {
+ if (CpuFeatures::IsSupported(RVC) && IsRvcReg(value) &&
+ IsRvcReg(source.rm()) && is_uint8(source.offset()) &&
+ ((source.offset() & 0x7) == 0)) {
c_sd(value, source.rm(), source.offset());
} else if (CpuFeatures::IsSupported(RVC) && (source.rm() == sp) &&
is_uint9(source.offset()) && ((source.offset() & 0x7) == 0)) {
@@ -2413,10 +2428,9 @@ void MacroAssembler::LoadDouble(FPURegister fd, const MemOperand& src,
Trapper&& trapper) {
auto fn = [&](FPURegister target, const MemOperand& source) {
trapper(pc_offset());
- if (CpuFeatures::IsSupported(RVC) &&
- ((target.code() & 0b11000) == 0b01000) &&
- ((source.rm().code() & 0b11000) == 0b01000) &&
- is_uint8(source.offset()) && ((source.offset() & 0x7) == 0)) {
+ if (CpuFeatures::IsSupported(RVC) && IsRvcReg(target) &&
+ IsRvcReg(source.rm()) && is_uint8(source.offset()) &&
+ ((source.offset() & 0x7) == 0)) {
c_fld(target, source.rm(), source.offset());
} else if (CpuFeatures::IsSupported(RVC) && (source.rm() == sp) &&
is_uint9(source.offset()) && ((source.offset() & 0x7) == 0)) {
@@ -2432,10 +2446,9 @@ void MacroAssembler::StoreDouble(FPURegister fs, const MemOperand& src,
Trapper&& trapper) {
auto fn = [&](FPURegister value, const MemOperand& source) {
trapper(pc_offset());
- if (CpuFeatures::IsSupported(RVC) &&
- ((value.code() & 0b11000) == 0b01000) &&
- ((source.rm().code() & 0b11000) == 0b01000) &&
- is_uint8(source.offset()) && ((source.offset() & 0x7) == 0)) {
+ if (CpuFeatures::IsSupported(RVC) && IsRvcReg(value) &&
+ IsRvcReg(source.rm()) && is_uint8(source.offset()) &&
+ ((source.offset() & 0x7) == 0)) {
c_fsd(value, source.rm(), source.offset());
} else if (CpuFeatures::IsSupported(RVC) && (source.rm() == sp) &&
is_uint9(source.offset()) && ((source.offset() & 0x7) == 0)) {
@@ -2810,7 +2823,7 @@ void MacroAssembler::SaveVectorRegisters(const Simd128RegList& reg_list) {
}
} else {
SubWord(sp, sp,
- Operand(-static_cast<int32_t>(reg_list.Count()) * kSimd128Size));
+ Operand(static_cast<int32_t>(reg_list.Count()) * kSimd128Size));
}
}
}
@@ -7611,8 +7624,8 @@ void MacroAssembler::CallJSFunction(Register function_object,
Register parameter_count = s1;
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
- Lw(dispatch_handle,
- FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
+ Lwu(dispatch_handle,
+ FieldMemOperand(function_object, offsetof(JSFunction, dispatch_handle_)));
LoadEntrypointAndParameterCountFromJSDispatchTable(code, parameter_count,
dispatch_handle, scratch);
// Force a safe crash if the parameter count doesn't match.
@@ -7752,7 +7765,8 @@ void MacroAssembler::LoadEntrypointFromJSDispatchTable(Register destination,
static_assert(kJSDispatchHandleShift == 0);
SllWord(index, dispatch_handle, kJSDispatchTableEntrySizeLog2);
#else
- SrlWord(index, dispatch_handle, kJSDispatchHandleShift);
+ ZeroExtendWord(index, dispatch_handle);
+ SrlWord(index, index, kJSDispatchHandleShift);
SllWord(index, index, kJSDispatchTableEntrySizeLog2);
#endif
AddWord(scratch, scratch, index);
@@ -7844,7 +7858,8 @@ void MacroAssembler::LoadParameterCountFromJSDispatchTable(
DCHECK(!AreAliased(destination, scratch));
ASM_CODE_COMMENT(this);
Register index = destination;
- SrlWord(index, dispatch_handle, kJSDispatchHandleShift);
+ ZeroExtendWord(index, dispatch_handle);
+ SrlWord(index, index, kJSDispatchHandleShift);
SllWord(index, index, kJSDispatchTableEntrySizeLog2);
Ld(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
AddWord(scratch, scratch, index);
@@ -7859,7 +7874,8 @@ void MacroAssembler::LoadEntrypointAndParameterCountFromJSDispatchTable(
ASM_CODE_COMMENT(this);
Register index = parameter_count;
Ld(scratch, ExternalReferenceAsOperand(IsolateFieldId::kJSDispatchTable));
- SrlWord(index, dispatch_handle, kJSDispatchHandleShift);
+ ZeroExtendWord(index, dispatch_handle);
+ SrlWord(index, index, kJSDispatchHandleShift);
SllWord(index, index, kJSDispatchTableEntrySizeLog2);
AddWord(scratch, scratch, index);
LoadWord(entrypoint, MemOperand(scratch, JSDispatchEntry::kEntrypointOffset));
@@ -7941,23 +7957,19 @@ void MacroAssembler::DecompressTagged(const Register& destination,
Trapper&& trapper) {
ASM_CODE_COMMENT(this);
Lwu(destination, field_operand, std::forward<Trapper>(trapper));
- AddWord(destination, kPtrComprCageBaseRegister, destination);
+ Or(destination, kPtrComprCageBaseRegister, destination);
}
void MacroAssembler::DecompressTagged(const Register& destination,
const Register& source) {
ASM_CODE_COMMENT(this);
- if (CpuFeatures::IsSupported(ZBA)) {
- adduw(destination, source, kPtrComprCageBaseRegister);
- } else {
- ZeroExtendWord(destination, source);
- AddWord(destination, kPtrComprCageBaseRegister, Operand(destination));
- }
+ ZeroExtendWord(destination, source);
+ Or(destination, kPtrComprCageBaseRegister, destination);
}
void MacroAssembler::DecompressTagged(Register dst, Tagged_t immediate) {
ASM_CODE_COMMENT(this);
- AddWord(dst, kPtrComprCageBaseRegister, static_cast<int32_t>(immediate));
+ Or(dst, kPtrComprCageBaseRegister, Operand(static_cast<uint32_t>(immediate)));
}
void MacroAssembler::DecompressProtected(const Register& destination,
@@ -7997,7 +8009,7 @@ void MacroAssembler::AtomicDecompressTagged(Register dst, const MemOperand& src,
ASM_CODE_COMMENT(this);
Lwu(dst, src, std::forward<Trapper>(trapper));
sync();
- AddWord(dst, kPtrComprCageBaseRegister, dst);
+ Or(dst, kPtrComprCageBaseRegister, dst);
}
#endif
@@ -8275,7 +8287,7 @@ void MacroAssembler::BranchRange(Label* L, Condition cond, Register value,
SubWord(scratch, value, Operand(lower_limit));
Branch(L, cond, scratch, Operand(higher_limit - lower_limit), distance);
} else {
- Branch(L, cond, scratch, Operand(higher_limit - lower_limit), distance);
+ Branch(L, cond, value, Operand(higher_limit), distance);
}
}
diff --git a/deps/v8/src/codegen/riscv/macro-assembler-riscv.h b/deps/v8/src/codegen/riscv/macro-assembler-riscv.h
index 1da4678972e..2b127f46762 100644
--- a/deps/v8/src/codegen/riscv/macro-assembler-riscv.h
+++ b/deps/v8/src/codegen/riscv/macro-assembler-riscv.h
@@ -810,10 +810,21 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
void Popcnt32(Register rd, Register rs, Register scratch);
#if V8_TARGET_ARCH_RISCV64
- void SignExtendWord(Register rd, Register rs) { sext_w(rd, rs); }
+ void SignExtendWord(Register rd, Register rs) {
+ if (rd == rs && IsRvcReg(rs) && CpuFeatures::IsSupported(ZCB)) {
+ c_sext_w(rd);
+ } else {
+ sext_w(rd, rs);
+ }
+ }
+
void ZeroExtendWord(Register rd, Register rs) {
if (CpuFeatures::IsSupported(ZBA)) {
- zextw(rd, rs);
+ if (rd == rs && IsRvcReg(rs) && CpuFeatures::IsSupported(ZCB)) {
+ c_zext_w(rd);
+ } else {
+ zextw(rd, rs);
+ }
} else {
Sll64(rd, rs, 32);
Srl64(rd, rd, 32);
@@ -1451,7 +1462,6 @@ class V8_EXPORT_PRIVATE MacroAssembler : public MacroAssemblerBase {
// Transform a SandboxedPointer from/to its encoded form, which is used when
// the pointer is stored on the heap and ensures that the pointer will always
// point into the sandbox.
- void DecodeSandboxedPointer(Register value);
void LoadSandboxedPointerField(Register destination,
const MemOperand& field_operand,
Trapper&& trapper = [](int){});
diff --git a/deps/v8/src/codegen/riscv/register-riscv.h b/deps/v8/src/codegen/riscv/register-riscv.h
index ab8f685dfb5..447f3316dfa 100644
--- a/deps/v8/src/codegen/riscv/register-riscv.h
+++ b/deps/v8/src/codegen/riscv/register-riscv.h
@@ -343,6 +343,11 @@ constexpr Register kPtrComprCageBaseRegister = s11; // callee save
constexpr Register kPtrComprCageBaseRegister = no_reg;
#endif
+template <typename T>
+inline bool IsRvcReg(T reg) {
+ return (reg.code() & 0b11000) == 0b01000;
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/codegen/riscv/reglist-riscv.h b/deps/v8/src/codegen/riscv/reglist-riscv.h
index c84e6c61627..ae208103e31 100644
--- a/deps/v8/src/codegen/riscv/reglist-riscv.h
+++ b/deps/v8/src/codegen/riscv/reglist-riscv.h
@@ -37,6 +37,14 @@ const DoubleRegList kCallerSavedFPU = {ft0, ft1, ft2, ft3, ft4, ft5, ft6,
const int kNumCallerSavedFPU = kCallerSavedFPU.Count();
+// Caller-saved vector registers. The RISC-V V psABI defines v1-v7 and v24-v31
+// as callee-saved, so only v8-v23 need to be preserved across C calls. v0 is
+// the vector mask register and is never used by V8 for SIMD values.
+const Simd128RegList kCallerSavedVR = {v8, v9, v10, v11, v12, v13, v14, v15,
+ v16, v17, v18, v19, v20, v21, v22, v23};
+
+const int kNumCallerSavedVR = kCallerSavedVR.Count();
+
// Number of registers for which space is reserved in safepoints. Must be a
// multiple of 8.
const int kNumSafepointRegisters = 32;
diff --git a/deps/v8/src/codegen/s390/macro-assembler-s390.cc b/deps/v8/src/codegen/s390/macro-assembler-s390.cc
index 56d6b331f80..aaac63946a9 100644
--- a/deps/v8/src/codegen/s390/macro-assembler-s390.cc
+++ b/deps/v8/src/codegen/s390/macro-assembler-s390.cc
@@ -2927,10 +2927,17 @@ void MacroAssembler::AddS32(Register dst, const Operand& opnd) {
// Add Pointer Size (Register dst = Register dst + Immediate opnd)
void MacroAssembler::AddS64(Register dst, const Operand& opnd) {
- if (is_int16(opnd.immediate()))
+ if (is_int16(opnd.immediate())) {
aghi(dst, opnd);
- else
+ } else if (is_int32(opnd.immediate())) {
agfi(dst, opnd);
+ } else {
+ UseScratchRegisterScope temps(this);
+ Register scratch = temps.Acquire();
+ DCHECK(dst != scratch);
+ mov(scratch, opnd);
+ agr(dst, scratch);
+ }
}
void MacroAssembler::AddS32(Register dst, Register src, int32_t opnd) {
diff --git a/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.cc b/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.cc
index 878f11cc551..dd439fe545c 100644
--- a/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.cc
+++ b/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.cc
@@ -154,6 +154,33 @@ void SharedMacroAssemblerBase::Shufps(XMMRegister dst, XMMRegister src1,
}
}
+void SharedMacroAssemblerBase::Pshufd(XMMRegister dst, XMMRegister src,
+ uint8_t shuffle) {
+#if V8_TARGET_ARCH_X64
+ if (shuffle == 0 && CpuFeatures::IsSupported(AVX2) && src.code() > 7) {
+ CpuFeatureScope avx2_scope(this, AVX2);
+ vpbroadcastd(dst, src);
+ return;
+ }
+#endif
+ if (CpuFeatures::IsSupported(AVX)) {
+ CpuFeatureScope avx_scope(this, AVX);
+ vpshufd(dst, src, shuffle);
+ } else {
+ pshufd(dst, src, shuffle);
+ }
+}
+
+void SharedMacroAssemblerBase::Pshufd(XMMRegister dst, Operand src,
+ uint8_t shuffle) {
+ if (CpuFeatures::IsSupported(AVX)) {
+ CpuFeatureScope avx_scope(this, AVX);
+ vpshufd(dst, src, shuffle);
+ } else {
+ pshufd(dst, src, shuffle);
+ }
+}
+
void SharedMacroAssemblerBase::F64x2ExtractLane(DoubleRegister dst,
XMMRegister src, uint8_t lane) {
ASM_CODE_COMMENT(this);
@@ -476,10 +503,25 @@ void SharedMacroAssemblerBase::I8x16Shl(XMMRegister dst, XMMRegister src1,
void SharedMacroAssemblerBase::I8x16ShrS(XMMRegister dst, XMMRegister src1,
uint8_t src2, XMMRegister tmp) {
ASM_CODE_COMMENT(this);
- // Unpack bytes into words, do word (16-bit) shifts, and repack.
DCHECK_NE(dst, tmp);
- uint8_t shift = truncate_to_int3(src2) + 8;
+ DCHECK_NE(src1, tmp);
+ uint8_t shift = truncate_to_int3(src2);
+ // Optimization for shift == 7, replicating the sign bit across the vector.
+ // This is a common pattern for sign extension.
+ if (shift == 7) {
+ if (dst == src1) {
+ Pxor(tmp, tmp);
+ Pcmpgtb(tmp, src1);
+ Movaps(dst, tmp);
+ } else {
+ Pxor(dst, dst);
+ Pcmpgtb(dst, src1);
+ }
+ return;
+ }
+ // Unpack bytes into words, do word (16-bit) shifts, and repack.
+ shift += 8;
Punpckhbw(tmp, src1);
Punpcklbw(dst, src1);
Psraw(tmp, shift);
@@ -728,8 +770,12 @@ void SharedMacroAssemblerBase::I16x8Q15MulRSatS(XMMRegister dst,
Psllw(scratch, scratch, uint8_t{15});
if (!CpuFeatures::IsSupported(AVX) && (dst != src1)) {
- movaps(dst, src1);
- src1 = dst;
+ if (dst == src2) {
+ std::swap(src1, src2);
+ } else {
+ movaps(dst, src1);
+ src1 = dst;
+ }
}
Pmulhrsw(dst, src1, src2);
@@ -932,8 +978,9 @@ void SharedMacroAssemblerBase::I64x2Neg(XMMRegister dst, XMMRegister src,
}
}
-void SharedMacroAssemblerBase::I64x2Abs(XMMRegister dst, XMMRegister src,
- XMMRegister scratch) {
+void SharedMacroAssemblerBase::I64x2AbsPreAvx10(XMMRegister dst,
+ XMMRegister src,
+ XMMRegister scratch) {
ASM_CODE_COMMENT(this);
if (CpuFeatures::IsSupported(AVX)) {
CpuFeatureScope avx_scope(this, AVX);
@@ -1022,8 +1069,9 @@ void SharedMacroAssemblerBase::I64x2GeS(XMMRegister dst, XMMRegister src0,
}
}
-void SharedMacroAssemblerBase::I64x2ShrS(XMMRegister dst, XMMRegister src,
- uint8_t shift, XMMRegister xmm_tmp) {
+void SharedMacroAssemblerBase::I64x2ShrSPreAvx10(XMMRegister dst,
+ XMMRegister src, uint8_t shift,
+ XMMRegister xmm_tmp) {
ASM_CODE_COMMENT(this);
DCHECK_GT(64, shift);
DCHECK_NE(xmm_tmp, dst);
@@ -1065,15 +1113,16 @@ void SharedMacroAssemblerBase::I64x2ShrS(XMMRegister dst, XMMRegister src,
Psubq(dst, xmm_tmp);
}
-void SharedMacroAssemblerBase::I64x2ShrS(XMMRegister dst, XMMRegister src,
- Register shift, XMMRegister xmm_tmp,
- XMMRegister xmm_shift,
- Register tmp_shift) {
+void SharedMacroAssemblerBase::I64x2ShrSPreAvx10(
+ XMMRegister dst, XMMRegister src, Register shift, XMMRegister xmm_tmp,
+ XMMRegister xmm_shift, Register tmp_shift) {
ASM_CODE_COMMENT(this);
DCHECK_NE(xmm_tmp, dst);
DCHECK_NE(xmm_tmp, src);
DCHECK_NE(xmm_shift, dst);
DCHECK_NE(xmm_shift, src);
+ DCHECK_NE(xmm_tmp, XMMRegister::no_reg());
+ DCHECK_NE(xmm_tmp, xmm_shift);
// tmp_shift can alias shift since we don't use shift after masking it.
// See I64x2ShrS with constant shift for explanation of this algorithm.
@@ -1095,9 +1144,11 @@ void SharedMacroAssemblerBase::I64x2ShrS(XMMRegister dst, XMMRegister src,
Psubq(dst, xmm_tmp);
}
-void SharedMacroAssemblerBase::I64x2Mul(XMMRegister dst, XMMRegister lhs,
- XMMRegister rhs, XMMRegister tmp1,
- XMMRegister tmp2) {
+void SharedMacroAssemblerBase::I64x2MulPreAvx10(XMMRegister dst,
+ XMMRegister lhs,
+ XMMRegister rhs,
+ XMMRegister tmp1,
+ XMMRegister tmp2) {
ASM_CODE_COMMENT(this);
DCHECK(!AreAliased(dst, tmp1, tmp2));
DCHECK(!AreAliased(lhs, tmp1, tmp2));
@@ -1217,9 +1268,8 @@ void SharedMacroAssemblerBase::I64x2UConvertI32x4High(XMMRegister dst,
}
}
-void SharedMacroAssemblerBase::S128Not(XMMRegister dst, XMMRegister src,
- XMMRegister scratch) {
- ASM_CODE_COMMENT(this);
+void SharedMacroAssemblerBase::S128NotPreAvx10(XMMRegister dst, XMMRegister src,
+ XMMRegister scratch) {
if (dst == src) {
Pcmpeqd(scratch, scratch);
Pxor(dst, scratch);
@@ -1229,10 +1279,11 @@ void SharedMacroAssemblerBase::S128Not(XMMRegister dst, XMMRegister src,
}
}
-void SharedMacroAssemblerBase::S128Select(XMMRegister dst, XMMRegister mask,
- XMMRegister src1, XMMRegister src2,
- XMMRegister scratch) {
- ASM_CODE_COMMENT(this);
+void SharedMacroAssemblerBase::S128SelectPreAvx10(XMMRegister dst,
+ XMMRegister mask,
+ XMMRegister src1,
+ XMMRegister src2,
+ XMMRegister scratch) {
// v128.select = v128.or(v128.and(v1, c), v128.andnot(v2, c)).
// pandn(x, y) = !x & y, so we have to flip the mask and input.
if (CpuFeatures::IsSupported(AVX)) {
diff --git a/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.h b/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.h
index 2199f8de4d7..e8368ad9246 100644
--- a/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.h
+++ b/deps/v8/src/codegen/shared-ia32-x64/macro-assembler-shared-ia32-x64.h
@@ -163,6 +163,9 @@ class V8_EXPORT_PRIVATE SharedMacroAssemblerBase : public MacroAssemblerBase {
void Shufps(XMMRegister dst, XMMRegister src1, XMMRegister src2,
uint8_t imm8);
+ void Pshufd(XMMRegister dst, XMMRegister src, uint8_t shuffle);
+ void Pshufd(XMMRegister dst, Operand src, uint8_t shuffle);
+
// Helper struct to implement functions that check for AVX support and
// dispatch to the appropriate AVX/SSE instruction.
template <typename Dst, typename Arg, typename... Args>
@@ -368,7 +371,6 @@ class V8_EXPORT_PRIVATE SharedMacroAssemblerBase : public MacroAssemblerBase {
AVX_OP(Pmovmskb, pmovmskb)
AVX_OP(Pmullw, pmullw)
AVX_OP(Pmuludq, pmuludq)
- AVX_OP(Pshufd, pshufd)
AVX_OP(Pshufhw, pshufhw)
AVX_OP(Pshuflw, pshuflw)
AVX_OP(Pslld, pslld)
@@ -525,27 +527,27 @@ class V8_EXPORT_PRIVATE SharedMacroAssemblerBase : public MacroAssemblerBase {
void I32x4UConvertI16x8High(XMMRegister dst, XMMRegister src,
XMMRegister scratch);
void I64x2Neg(XMMRegister dst, XMMRegister src, XMMRegister scratch);
- void I64x2Abs(XMMRegister dst, XMMRegister src, XMMRegister scratch);
+ void I64x2AbsPreAvx10(XMMRegister dst, XMMRegister src, XMMRegister scratch);
void I64x2GtS(XMMRegister dst, XMMRegister src0, XMMRegister src1,
XMMRegister scratch);
void I64x2GeS(XMMRegister dst, XMMRegister src0, XMMRegister src1,
XMMRegister scratch);
- void I64x2ShrS(XMMRegister dst, XMMRegister src, uint8_t shift,
- XMMRegister xmm_tmp);
- void I64x2ShrS(XMMRegister dst, XMMRegister src, Register shift,
- XMMRegister xmm_tmp, XMMRegister xmm_shift,
- Register tmp_shift);
- void I64x2Mul(XMMRegister dst, XMMRegister lhs, XMMRegister rhs,
- XMMRegister tmp1, XMMRegister tmp2);
+ void I64x2ShrSPreAvx10(XMMRegister dst, XMMRegister src, uint8_t shift,
+ XMMRegister xmm_tmp);
+ void I64x2ShrSPreAvx10(XMMRegister dst, XMMRegister src, Register shift,
+ XMMRegister xmm_tmp, XMMRegister xmm_shift,
+ Register tmp_shift);
+ void I64x2MulPreAvx10(XMMRegister dst, XMMRegister lhs, XMMRegister rhs,
+ XMMRegister tmp1, XMMRegister tmp2);
void I64x2ExtMul(XMMRegister dst, XMMRegister src1, XMMRegister src2,
XMMRegister scratch, bool low, bool is_signed);
void I64x2SConvertI32x4High(XMMRegister dst, XMMRegister src);
void I64x2UConvertI32x4High(XMMRegister dst, XMMRegister src,
XMMRegister scratch);
- void S128Not(XMMRegister dst, XMMRegister src, XMMRegister scratch);
+ void S128NotPreAvx10(XMMRegister dst, XMMRegister src, XMMRegister scratch);
// Requires dst == mask when AVX is not supported.
- void S128Select(XMMRegister dst, XMMRegister mask, XMMRegister src1,
- XMMRegister src2, XMMRegister scratch);
+ void S128SelectPreAvx10(XMMRegister dst, XMMRegister mask, XMMRegister src1,
+ XMMRegister src2, XMMRegister scratch);
void S128Load8Splat(XMMRegister dst, Operand src, XMMRegister scratch);
void S128Load16Splat(XMMRegister dst, Operand src, XMMRegister scratch);
void S128Load32Splat(XMMRegister dst, Operand src);
@@ -947,8 +949,8 @@ class V8_EXPORT_PRIVATE SharedMacroAssembler : public SharedMacroAssemblerBase {
}
}
- void I8x16Popcnt(XMMRegister dst, XMMRegister src, XMMRegister tmp1,
- XMMRegister tmp2, Register scratch) {
+ void I8x16PopcntPreAvx10(XMMRegister dst, XMMRegister src, XMMRegister tmp1,
+ XMMRegister tmp2, Register scratch) {
ASM_CODE_COMMENT(this);
DCHECK_NE(dst, tmp1);
DCHECK_NE(src, tmp1);
diff --git a/deps/v8/src/codegen/x64/assembler-x64-inl.h b/deps/v8/src/codegen/x64/assembler-x64-inl.h
index 3e53151e074..762dfa8b7b6 100644
--- a/deps/v8/src/codegen/x64/assembler-x64-inl.h
+++ b/deps/v8/src/codegen/x64/assembler-x64-inl.h
@@ -247,6 +247,8 @@ void Assembler::emit_vex3_byte1(XMMRegister reg, Operand rm, LeadingOpcode m) {
// byte 1 of 2-byte VEX
void Assembler::emit_vex2_byte1(XMMRegister reg, XMMRegister v, VectorLength l,
SIMDPrefix pp) {
+ // The 2-byte VEX prefix encodes can only address xmm0-15.
+ DCHECK_EQ(v.code() & 0xf, v.code());
uint8_t rv = static_cast<uint8_t>(~((reg.high_bit() << 4) | v.code())) << 3;
emit(rv | l | pp);
}
@@ -300,6 +302,74 @@ void Assembler::emit_vex_prefix(Register reg, Register vreg, Operand rm,
emit_vex_prefix(ireg, ivreg, rm, l, pp, mm, w);
}
+// Vector-form EVEX prefix, shared by AVX10.1 and APX.
+void Assembler::emit_evex_byte1(XMMRegister reg, XMMRegister rm,
+ LeadingOpcode m) {
+ uint8_t rxb = static_cast<uint8_t>(
+ ~((reg.high_bit() << 2) | (rm.bit4() << 1) | rm.high_bit()))
+ << 5;
+ uint8_t r1 = reg.bit4() ? 0 : 0x10;
+ emit(rxb | r1 | m);
+}
+
+void Assembler::emit_evex_byte1(XMMRegister reg, Operand rm, LeadingOpcode m) {
+ // Same base/index EGPR routing as the APX legacy-extended EVEX prefix; the
+ // only vector-specific field here is the 3-bit map id (m).
+ uint8_t r3 = (~reg.high_bit()) & 0x1;
+ uint8_t x3b3 = (~rm.rex()) & 0x3;
+ uint8_t r4 = (~reg.bit4()) & 0x1;
+#ifdef V8_ENABLE_APX_F
+ // EVEX.B4: fifth bit of the r/m base register for EGPR (r16-31) addressing.
+ uint8_t b4 = rm.rex2() & 0x1;
+#else
+ uint8_t b4 = 0;
+#endif
+ emit((r3 << 7) | (x3b3 << 5) | (r4 << 4) | (b4 << 3) | m);
+}
+
+void Assembler::emit_evex_byte2(VexW w, XMMRegister v, SIMDPrefix pp) {
+ // Register-direct r/m (ModRM.Mod == 3): EVEX.U must be 1.
+ emit(w | ((~v.code() & 0xf) << 3) | 0x4 | pp);
+}
+
+void Assembler::emit_evex_byte2(VexW w, XMMRegister v, Operand rm,
+ SIMDPrefix pp) {
+#ifdef V8_ENABLE_APX_F
+ // EVEX.U carries ~X4: fifth bit of the index register for EGPR addressing.
+ uint8_t u = (~rm.rex2() & 0x2) >> 1;
+#else
+ uint8_t u = 1;
+#endif
+ emit(w | ((~v.code() & 0xf) << 3) | (u << 2) | pp);
+}
+
+// TODO(fanchen): support b(broadcast).
+void Assembler::emit_evex_byte3(VectorLength l, XMMRegister v, OpMask aaa,
+ MaskingType z) {
+ uint8_t v1 = v.bit4() ? 0 : 0x8;
+ emit(z | (l << 3) | v1 | aaa);
+}
+
+void Assembler::emit_evex_prefix(XMMRegister reg, XMMRegister vreg,
+ XMMRegister rm, VectorLength l, SIMDPrefix pp,
+ LeadingOpcode mm, VexW w, OpMask aaa,
+ MaskingType z) {
+ emit_evex_byte0();
+ emit_evex_byte1(reg, rm, mm);
+ emit_evex_byte2(w, vreg, pp);
+ emit_evex_byte3(l, vreg, aaa, z);
+}
+
+void Assembler::emit_evex_prefix(XMMRegister reg, XMMRegister vreg, Operand rm,
+ VectorLength l, SIMDPrefix pp,
+ LeadingOpcode mm, VexW w, OpMask aaa,
+ MaskingType z) {
+ emit_evex_byte0();
+ emit_evex_byte1(reg, rm, mm);
+ emit_evex_byte2(w, vreg, rm, pp);
+ emit_evex_byte3(l, vreg, aaa, z);
+}
+
Address Assembler::target_address_at(Address pc, Address constant_pool) {
return ReadUnalignedValue<int32_t>(pc) + pc + 4;
}
diff --git a/deps/v8/src/codegen/x64/assembler-x64.cc b/deps/v8/src/codegen/x64/assembler-x64.cc
index 359a41e3ad0..33f173c19f6 100644
--- a/deps/v8/src/codegen/x64/assembler-x64.cc
+++ b/deps/v8/src/codegen/x64/assembler-x64.cc
@@ -35,6 +35,15 @@ bool UseApxSetzucc() {
bool UseApxCmovcc() {
return v8_flags.enable_apx_f_cmovcc && CpuFeatures::IsSupported(APX_F);
}
+bool UseApxCcmp() {
+ return v8_flags.enable_apx_f_ccmp && CpuFeatures::IsSupported(APX_F);
+}
+#endif
+
+#ifdef V8_ENABLE_AVX10_1
+bool UseAvx10_1() {
+ return v8_flags.enable_avx10_1 && CpuFeatures::IsSupported(AVX10_1);
+}
#endif
// -----------------------------------------------------------------------------
// Implementation of CpuFeatures
@@ -88,6 +97,15 @@ bool OSHasAPXFSupport() {
}
#endif // V8_ENABLE_APX_F
+#ifdef V8_ENABLE_AVX10_1
+bool OSHasAVX10Support() {
+ // The OS must enable saving of the opmask, ZMM_Hi256, and Hi16_ZMM
+ // state (in addition to SSE and AVX).
+ uint64_t feature_mask = xgetbv(0); // XCR_XFEATURE_ENABLED_MASK
+ return (feature_mask & 0xe6) == 0xe6;
+}
+#endif // V8_ENABLE_AVX10_1
+
#endif // V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
} // namespace
@@ -153,6 +171,9 @@ static constexpr CpuFeatureSet CpuFeaturesFromCompiler() {
#ifdef __APX_F__
features.Add(APX_F);
#endif
+#ifdef __AVX10_1_512__
+ features.Add(AVX10_1);
+#endif
return features;
}
@@ -200,6 +221,11 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
if (cpu.has_apx_f() && cpu.has_osxsave() && OSHasAPXFSupport())
SetSupported(APX_F);
#endif // V8_ENABLE_APX_F
+#ifdef V8_ENABLE_AVX10_1
+ if (cpu.has_avx10_1() && cpu.has_osxsave() && OSHasAVX10Support()) {
+ SetSupported(AVX10_1);
+ }
+#endif // V8_ENABLE_AVX10_1
// Ensure that supported cpu features make sense. E.g. it is wrong to support
// AVX but not SSE4_2, if we have --enable-avx and --no-enable-sse4-2, the
@@ -220,6 +246,9 @@ void CpuFeatures::ProbeImpl(bool cross_compile) {
#ifdef V8_ENABLE_APX_F
if (!v8_flags.enable_apx_f) SetUnsupported(APX_F);
#endif // V8_ENABLE_APX_F
+#ifdef V8_ENABLE_AVX10_1
+ if (!v8_flags.enable_avx10_1 || !IsSupported(AVX2)) SetUnsupported(AVX10_1);
+#endif // V8_ENABLE_AVX10_1
// Set a static value on whether Simd is supported.
// This variable is only used for certain archs to query SupportWasmSimd128()
@@ -247,6 +276,7 @@ void CpuFeatures::PrintInformation() {
"LZCNT=%d "
"POPCNT=%d "
"APX_F=%d "
+ "AVX10_1=%d "
"ATOM=%d\n",
CpuFeatures::IsSupported(SSE3), CpuFeatures::IsSupported(SSSE3),
CpuFeatures::IsSupported(SSE4_1), CpuFeatures::IsSupported(SSE4_2),
@@ -256,7 +286,7 @@ void CpuFeatures::PrintInformation() {
CpuFeatures::IsSupported(F16C), CpuFeatures::IsSupported(BMI1),
CpuFeatures::IsSupported(BMI2), CpuFeatures::IsSupported(LZCNT),
CpuFeatures::IsSupported(POPCNT), CpuFeatures::IsSupported(APX_F),
- CpuFeatures::IsSupported(INTEL_ATOM));
+ CpuFeatures::IsSupported(AVX10_1), CpuFeatures::IsSupported(INTEL_ATOM));
}
// -----------------------------------------------------------------------------
@@ -4705,6 +4735,79 @@ void Assembler::emit_sse_operand(XMMRegister dst) {
emit(0xD8 | dst.low_bits());
}
+void Assembler::emit_sse_operand(XMMRegister reg, Operand adr,
+ uint8_t cd8_scale) {
+ if (cd8_scale > 0) {
+ adr = adr.to_evex_cd8(cd8_scale);
+ }
+ // The high register bits (for xmm8-31) are carried by the EVEX prefix; the
+ // ModR/M reg field only encodes the low 3 bits.
+ emit_operand(reg.low_bits(), adr);
+}
+
+void Assembler::vinstr_evex(uint8_t op, XMMRegister dst, XMMRegister src1,
+ XMMRegister src2, SIMDPrefix pp, LeadingOpcode m,
+ VexW w, OpMask mask, MaskingType z,
+ CpuFeature feature) {
+ DCHECK(IsEnabled(feature));
+ EnsureSpace ensure_space(this);
+ emit_evex_prefix(dst, src1, src2, kL128, pp, m, w, mask, z);
+ emit(op);
+ emit_sse_operand(dst, src2);
+}
+
+void Assembler::vinstr_evex(uint8_t op, XMMRegister dst, XMMRegister src1,
+ Operand src2, SIMDPrefix pp, LeadingOpcode m,
+ VexW w, TupleType tuple_type, OpMask mask,
+ MaskingType z, CpuFeature feature) {
+ DCHECK(IsEnabled(feature));
+ EnsureSpace ensure_space(this);
+ emit_evex_prefix(dst, src1, src2, kL128, pp, m, w, mask, z);
+ emit(op);
+ auto cd8_scale = TupleTypeToN(tuple_type, w, /*vlen=*/16);
+ emit_sse_operand(dst, src2, cd8_scale);
+}
+
+void Assembler::vinstr_evex(uint8_t op, YMMRegister dst, YMMRegister src1,
+ YMMRegister src2, SIMDPrefix pp, LeadingOpcode m,
+ VexW w, OpMask mask, MaskingType z,
+ CpuFeature feature) {
+ DCHECK(IsEnabled(feature));
+ EnsureSpace ensure_space(this);
+ emit_evex_prefix(dst, src1, src2, kL256, pp, m, w, mask, z);
+ emit(op);
+ emit_sse_operand(dst, src2);
+}
+
+void Assembler::vinstr_evex(uint8_t op, YMMRegister dst, YMMRegister src1,
+ Operand src2, SIMDPrefix pp, LeadingOpcode m,
+ VexW w, TupleType tuple_type, OpMask mask,
+ MaskingType z, CpuFeature feature) {
+ DCHECK(IsEnabled(feature));
+ EnsureSpace ensure_space(this);
+ emit_evex_prefix(dst, src1, src2, kL256, pp, m, w, mask, z);
+ emit(op);
+ auto cd8_scale = TupleTypeToN(tuple_type, w, /*vlen=*/32);
+ emit_sse_operand(dst, src2, cd8_scale);
+}
+
+void Assembler::vpsraq(XMMRegister dst, XMMRegister src, uint8_t imm8) {
+ // Opcode 0x72 /4: reg field carries the /4 extension (xmm4); the shift dst is
+ // encoded in EVEX.vvvv, the source in ModR/M.rm.
+ vinstr_evex(0x72, xmm4, dst, src, k66, k0F, kW1);
+ emit(imm8);
+}
+
+void Assembler::vpsraq(YMMRegister dst, YMMRegister src, uint8_t imm8) {
+ vinstr_evex(0x72, ymm4, dst, src, k66, k0F, kW1);
+ emit(imm8);
+}
+
+void Assembler::vpsraq(XMMRegister dst, Operand src, uint8_t imm8) {
+ vinstr_evex(0x72, xmm4, dst, src, k66, k0F, kW1, kFull);
+ emit(imm8);
+}
+
void Assembler::db(uint8_t data) {
EnsureSpace ensure_space(this);
emit(data);
diff --git a/deps/v8/src/codegen/x64/assembler-x64.h b/deps/v8/src/codegen/x64/assembler-x64.h
index a3965ba2da8..909347e81e1 100644
--- a/deps/v8/src/codegen/x64/assembler-x64.h
+++ b/deps/v8/src/codegen/x64/assembler-x64.h
@@ -68,9 +68,17 @@ class MaglevSafepointTableBuilder;
#ifdef V8_ENABLE_APX_F
V8_EXPORT_PRIVATE bool UseApxSetzucc();
V8_EXPORT_PRIVATE bool UseApxCmovcc();
+V8_EXPORT_PRIVATE bool UseApxCcmp();
#else
V8_EXPORT_PRIVATE inline bool UseApxSetzucc() { return false; }
V8_EXPORT_PRIVATE inline bool UseApxCmovcc() { return false; }
+V8_EXPORT_PRIVATE inline bool UseApxCcmp() { return false; }
+#endif
+
+#ifdef V8_ENABLE_AVX10_1
+V8_EXPORT_PRIVATE bool UseAvx10_1();
+#else
+V8_EXPORT_PRIVATE inline bool UseAvx10_1() { return false; }
#endif
enum Condition : int {
@@ -347,6 +355,93 @@ class V8_EXPORT_PRIVATE Operand {
return label_;
}
+ // Rewrite this memory operand's displacement into the EVEX compressed
+ // displacement form (disp8*N) when possible. {*this} should carry a raw
+ // (unscaled) displacement.
+ //
+ // In an EVEX-encoded instruction the 8-bit displacement is always multiplied
+ // by a scale factor N that is determined based on the vector length, the
+ // value of EVEX.b bit and the input element size of the instruction. Here N
+ // is passed in as {cd8_scale} (a power of two, in bytes).
+ //
+ // The compressed displacement (disp8*N) encoding can only represent a
+ // displacement that is a multiple of N and whose quotient disp/N fits in an
+ // int8. Displacements that don't qualify must use the 4-byte disp32 form,
+ // which EVEX does not scale.
+ //
+ // This returns an equivalent operand with either:
+ // - mod=01 and the disp8 byte set to disp/N (compressing a disp32, or
+ // re-scaling an already-present raw disp8), or
+ // - mod=10 with an unscaled disp32 (when the value is too large or not a
+ // multiple of N).
+ // Operands with no scalable displacement (no-displacement, register-direct,
+ // or RIP-relative) are returned unchanged.
+ Operand to_evex_cd8(uint8_t cd8_scale) const {
+ // N is 0 ("no scaling") or a power of two.
+ DCHECK_EQ(cd8_scale & (cd8_scale - 1), 0);
+
+ // N == 0: no compressed-displacement scaling requested.
+ if (cd8_scale == 0) return *this;
+
+ // RIP-relative (label) operands are mod==00/rm==101 disp32 — no disp8 form
+ // exists, so CD8 scaling never applies. Leave unchanged and let
+ // emit_operand emit the RIP-relative disp32.
+ if (is_label_operand()) return *this;
+
+ // mod==00: no displacement (or a no-base disp32 that cannot shrink without
+ // changing meaning); mod==11: register-direct r/m.
+ uint8_t mod = (memory_.buf[0] & 0xc0) >> 6;
+ if (mod == 0 || mod == 3) return *this;
+
+ // Read the current (unscaled) displacement. mod==01 stores a raw disp8 in
+ // the last byte; mod==10 stores a disp32 in the last four bytes.
+ int32_t disp = 0;
+ bool is_disp8 = mod == 1;
+ if (is_disp8) {
+ int8_t disp8 = 0;
+ memcpy(&disp8, memory_.buf + memory_.len - 1, 1);
+ disp = static_cast<int32_t>(disp8);
+ } else {
+ memcpy(&disp, memory_.buf + memory_.len - 4, 4);
+ }
+
+ // disp is not a multiple of N, so it cannot be represented as disp8*N.
+ if (disp & (cd8_scale - 1)) {
+ if (is_disp8) {
+ // EVEX has no un-scaled 8-bit displacement: any mod==01 disp8 is
+ // decoded as disp8*N. An operand built with a raw disp8 (the generic
+ // Operand ctors are EVEX-unaware) would therefore be misinterpreted
+ // here, so promote it to a disp32, which EVEX does not scale: switch
+ // mod=01 -> mod=10, drop the disp8 byte and append the full 32-bit
+ // value.
+ Operand new_operand(*this);
+ new_operand.memory_.buf[0] =
+ (new_operand.memory_.buf[0] & static_cast<uint8_t>(0x3f)) | 2 << 6;
+ new_operand.memory_.len -= 1;
+ new_operand.set_disp32(disp);
+ return new_operand;
+ }
+ // Already an (unscaled) disp32 — nothing to do.
+ return *this;
+ }
+
+ // disp is a multiple of N; the compressed byte is disp/N. If it doesn't fit
+ // in an int8, keep the (unscaled) disp32 form.
+ int32_t cdisp8 = disp / cd8_scale;
+ if (!is_int8(cdisp8)) {
+ return *this;
+ }
+
+ // Emit disp8*N: set mod=10 -> mod=01 and store disp/N in a single byte,
+ // shrinking a disp32 by dropping its trailing 3 bytes.
+ Operand new_operand(*this);
+ new_operand.memory_.buf[0] =
+ (new_operand.memory_.buf[0] & static_cast<uint8_t>(0x3f)) | 1 << 6;
+ if (!is_disp8) new_operand.memory_.len -= 3;
+ new_operand.memory_.buf[new_operand.memory_.len - 1] = cdisp8;
+ return new_operand;
+ }
+
// Checks whether either base or index register is the given register.
// Does not check the "reg" part of the Operand.
bool AddressUsesRegister(Register reg) const;
@@ -659,6 +754,24 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
enum VectorLength { kL128 = 0x0, kL256 = 0x4, kLIG = kL128, kLZ = kL128 };
enum VexW { kW0 = 0x0, kW1 = 0x80, kWIG = kW0 };
enum LeadingOpcode { k0F = 0x1, k0F38 = 0x2, k0F3A = 0x3 };
+ enum OpMask { k0 = 0x0, k1 = 0x1, k2 = 0x2 };
+ enum MaskingType { kMerging = 0x0, kZeroing = 0x80 };
+ enum TupleType {
+ kFull,
+ kFullMem,
+ kMem128,
+ kTuple1_Scalar_b,
+ kTuple1_Scalar_w,
+ kTuple1_Scalar,
+ kTuple1_Fixed_32,
+ kTuple1_Fixed_64,
+ kTuple2,
+ kHalf,
+ kHalfMem,
+ kQuarterMem,
+ kMovddup,
+ kNoValue
+ };
// REX2 prefix encodings.
enum Rex2MapID { kRex2Map0 = 0x0, kRex2Map1 = 0x80 };
@@ -1441,6 +1554,61 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void vinstr(uint8_t op, Reg1 dst, Reg2 src1, Op src2, SIMDPrefix pp,
LeadingOpcode m, VexW w, CpuFeature feature = AVX2);
+ void vinstr_evex(uint8_t op, XMMRegister dst, XMMRegister src1,
+ XMMRegister src2, SIMDPrefix pp, LeadingOpcode m, VexW w,
+ OpMask mask = k0, MaskingType z = kMerging,
+ CpuFeature feature = AVX10_1);
+ void vinstr_evex(uint8_t op, XMMRegister dst, XMMRegister src1, Operand src2,
+ SIMDPrefix pp, LeadingOpcode m, VexW w, TupleType tuple_type,
+ OpMask mask = k0, MaskingType z = kMerging,
+ CpuFeature feature = AVX10_1);
+ void vinstr_evex(uint8_t op, YMMRegister dst, YMMRegister src1,
+ YMMRegister src2, SIMDPrefix pp, LeadingOpcode m, VexW w,
+ OpMask mask = k0, MaskingType z = kMerging,
+ CpuFeature feature = AVX10_1);
+ void vinstr_evex(uint8_t op, YMMRegister dst, YMMRegister src1, Operand src2,
+ SIMDPrefix pp, LeadingOpcode m, VexW w, TupleType tuple_type,
+ OpMask mask = k0, MaskingType z = kMerging,
+ CpuFeature feature = AVX10_1);
+
+ // Compressed-displacement (disp8*N) scale factor N in bytes, per Intel SDM
+ // Vol.2 §2.6.5, Tables 2-34..2-36. {vlen} is the vector length in bytes
+ // (16 for xmm/128-bit, 32 for ymm/256-bit). Broadcast (EVEX.b) is not yet
+ // supported. Most tuple types scale with the vector length; the rest are
+ // constant or depend on the element size selected by EVEX.W.
+ static uint8_t TupleTypeToN(TupleType tuple_type, VexW w, int vlen) {
+ // Element size for W-dependent tuples: 4 bytes (W0) or 8 bytes (W1).
+ const int elt = w == VexW::kW0 ? 4 : 8;
+ switch (tuple_type) {
+ case TupleType::kFull:
+ case TupleType::kFullMem:
+ return vlen;
+ case TupleType::kHalf:
+ case TupleType::kHalfMem:
+ return vlen / 2;
+ case TupleType::kQuarterMem:
+ return vlen / 4;
+ case TupleType::kMem128:
+ return 16;
+ case TupleType::kTuple1_Scalar_b:
+ return 1;
+ case TupleType::kTuple1_Scalar_w:
+ return 2;
+ case TupleType::kTuple1_Scalar:
+ return elt;
+ case TupleType::kTuple1_Fixed_32:
+ return 4;
+ case TupleType::kTuple1_Fixed_64:
+ return 8;
+ case TupleType::kTuple2:
+ return 2 * elt;
+ case TupleType::kMovddup:
+ return vlen == 16 ? 8 : vlen / 2;
+ default:
+ UNREACHABLE();
+ }
+ }
+
// SSE instructions
void sse_instr(XMMRegister dst, XMMRegister src, uint8_t escape,
uint8_t opcode);
@@ -2482,6 +2650,108 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
vinstr(0x50, dst, src1, src2, kF2, k0F38, kW0, AVX_VNNI_INT8);
}
+ // AVX10.1 instructions
+ void vpmullq(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+ vinstr_evex(0x40, dst, src1, src2, k66, k0F38, kW1);
+ }
+ void vpmullq(XMMRegister dst, XMMRegister src1, Operand src2) {
+ vinstr_evex(0x40, dst, src1, src2, k66, k0F38, kW1, kFull);
+ }
+ void vpmullq(YMMRegister dst, YMMRegister src1, YMMRegister src2) {
+ vinstr_evex(0x40, dst, src1, src2, k66, k0F38, kW1);
+ }
+ void vpmullq(YMMRegister dst, YMMRegister src1, Operand src2) {
+ vinstr_evex(0x40, dst, src1, src2, k66, k0F38, kW1, kFull);
+ }
+
+ // vpsraq — variable count (xmm/m128). The count is always a 128-bit memory
+ // operand regardless of destination width, so the tuple type is Mem128.
+ void vpsraq(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+ vinstr_evex(0xE2, dst, src1, src2, k66, k0F, kW1);
+ }
+ void vpsraq(XMMRegister dst, XMMRegister src1, Operand src2) {
+ vinstr_evex(0xE2, dst, src1, src2, k66, k0F, kW1, kMem128);
+ }
+ // vpsraq — imm8 (opcode 0x72 /4; dst goes in EVEX.vvvv)
+ void vpsraq(XMMRegister dst, XMMRegister src, uint8_t imm8);
+ void vpsraq(YMMRegister dst, YMMRegister src, uint8_t imm8);
+ void vpsraq(XMMRegister dst, Operand src, uint8_t imm8);
+
+ // vpabsq — unary (src1 unused)
+ void vpabsq(XMMRegister dst, XMMRegister src) {
+ vinstr_evex(0x1F, dst, xmm0, src, k66, k0F38, kW1);
+ }
+ void vpabsq(YMMRegister dst, YMMRegister src) {
+ vinstr_evex(0x1F, dst, ymm0, src, k66, k0F38, kW1);
+ }
+ void vpabsq(XMMRegister dst, Operand src) {
+ vinstr_evex(0x1F, dst, xmm0, src, k66, k0F38, kW1, kFull);
+ }
+
+ // vpminsq — binary
+ void vpminsq(XMMRegister dst, XMMRegister src1, XMMRegister src2) {
+ vinstr_evex(0x39, dst, src1, src2, k66, k0F38, kW1);
+ }
+ void vpminsq(YMMRegister dst, YMMRegister src1, YMMRegister src2) {
+ vinstr_evex(0x39, dst, src1, src2, k66, k0F38, kW1);
+ }
+ void vpminsq(XMMRegister dst, XMMRegister src1, Operand src2) {
+ vinstr_evex(0x39, dst, src1, src2, k66, k0F38, kW1, kFull);
+ }
+
+ // vpopcntb — unary (W0, src1 unused)
+ void vpopcntb(XMMRegister dst, XMMRegister src) {
+ vinstr_evex(0x54, dst, xmm0, src, k66, k0F38, kW0);
+ }
+ void vpopcntb(YMMRegister dst, YMMRegister src) {
+ vinstr_evex(0x54, dst, ymm0, src, k66, k0F38, kW0);
+ }
+ void vpopcntb(XMMRegister dst, Operand src) {
+ vinstr_evex(0x54, dst, xmm0, src, k66, k0F38, kW0, kFull);
+ }
+
+ // vpternlogd/q — bitwise ternary logic.
+ void vpternlogd(XMMRegister dst, XMMRegister src1, XMMRegister src2,
+ uint8_t imm8, OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW0, mask, z);
+ emit(imm8);
+ }
+ void vpternlogd(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8,
+ OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW0, kFull, mask, z);
+ emit(imm8);
+ }
+ void vpternlogd(YMMRegister dst, YMMRegister src1, YMMRegister src2,
+ uint8_t imm8, OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW0, mask, z);
+ emit(imm8);
+ }
+ void vpternlogd(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t imm8,
+ OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW0, kFull, mask, z);
+ emit(imm8);
+ }
+ void vpternlogq(XMMRegister dst, XMMRegister src1, XMMRegister src2,
+ uint8_t imm8, OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW1, mask, z);
+ emit(imm8);
+ }
+ void vpternlogq(XMMRegister dst, XMMRegister src1, Operand src2, uint8_t imm8,
+ OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW1, kFull, mask, z);
+ emit(imm8);
+ }
+ void vpternlogq(YMMRegister dst, YMMRegister src1, YMMRegister src2,
+ uint8_t imm8, OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW1, mask, z);
+ emit(imm8);
+ }
+ void vpternlogq(YMMRegister dst, YMMRegister src1, Operand src2, uint8_t imm8,
+ OpMask mask = k0, MaskingType z = kMerging) {
+ vinstr_evex(0x25, dst, src1, src2, k66, k0F3A, kW1, kFull, mask, z);
+ emit(imm8);
+ }
+
// BMI instruction
void andnq(Register dst, Register src1, Register src2) {
bmi1q(0xf2, dst, src1, src2);
@@ -2965,6 +3235,23 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
VectorLength l, SIMDPrefix pp, LeadingOpcode m,
VexW w);
+ // Emit the vector-form EVEX prefix (reuses emit_evex_byte0() above). Shared
+ // by any EVEX-encoded feature (AVX10, APX).
+ inline void emit_evex_byte1(XMMRegister reg, XMMRegister rm, LeadingOpcode m);
+ inline void emit_evex_byte1(XMMRegister reg, Operand rm, LeadingOpcode m);
+ inline void emit_evex_byte2(VexW w, XMMRegister v, SIMDPrefix pp);
+ inline void emit_evex_byte2(VexW w, XMMRegister v, Operand rm, SIMDPrefix pp);
+ inline void emit_evex_byte3(VectorLength l, XMMRegister v, OpMask aaa,
+ MaskingType z);
+ inline void emit_evex_prefix(XMMRegister reg, XMMRegister vreg,
+ XMMRegister rm, VectorLength l, SIMDPrefix pp,
+ LeadingOpcode mm, VexW w, OpMask aaa = k0,
+ MaskingType z = kMerging);
+ inline void emit_evex_prefix(XMMRegister reg, XMMRegister vreg, Operand rm,
+ VectorLength l, SIMDPrefix pp, LeadingOpcode mm,
+ VexW w, OpMask aaa = k0,
+ MaskingType z = kMerging);
+
// Emit the ModR/M byte, and optionally the SIB byte and
// 1- or 4-byte offset for a memory operand. Also encodes
// the second operand of the operation, a register or operation
@@ -3004,6 +3291,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void emit_sse_operand(XMMRegister dst, Register src);
void emit_sse_operand(Register dst, XMMRegister src);
void emit_sse_operand(XMMRegister dst);
+ void emit_sse_operand(XMMRegister reg, Operand adr, uint8_t cd8_scale);
// Emit machine code for one of the operations ADD, ADC, SUB, SBC,
// AND, OR, XOR, or CMP. The encodings of these operations are all
diff --git a/deps/v8/src/codegen/x64/interface-descriptors-x64-inl.h b/deps/v8/src/codegen/x64/interface-descriptors-x64-inl.h
index c195bf7a2c2..6861e8cbbb6 100644
--- a/deps/v8/src/codegen/x64/interface-descriptors-x64-inl.h
+++ b/deps/v8/src/codegen/x64/interface-descriptors-x64-inl.h
@@ -334,6 +334,11 @@ constexpr auto CompareAndTryPatchCodeDescriptor::registers() {
constexpr auto BinaryOpAndTryPatchCodeDescriptor::registers() {
return RegisterArray(rdx, rax, rbx, rdi);
}
+
+// static
+constexpr auto UnaryOpAndTryPatchCodeDescriptor::registers() {
+ return RegisterArray(rax, rbx, rdi);
+}
#endif // V8_ENABLE_SPARKPLUG_PLUS
// static
diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.cc b/deps/v8/src/codegen/x64/macro-assembler-x64.cc
index 00032682151..8e69877decb 100644
--- a/deps/v8/src/codegen/x64/macro-assembler-x64.cc
+++ b/deps/v8/src/codegen/x64/macro-assembler-x64.cc
@@ -434,13 +434,13 @@ void MacroAssembler::DecompressTagged(Register destination,
Operand field_operand) {
ASM_CODE_COMMENT(this);
movl(destination, field_operand);
- addq(destination, kPtrComprCageBaseRegister);
+ orq(destination, kPtrComprCageBaseRegister);
}
void MacroAssembler::DecompressTagged(Register destination, Register source) {
ASM_CODE_COMMENT(this);
movl(destination, source);
- addq(destination, kPtrComprCageBaseRegister);
+ orq(destination, kPtrComprCageBaseRegister);
}
void MacroAssembler::DecompressTagged(Register destination,
@@ -2031,6 +2031,12 @@ void MacroAssembler::Cmpeqsd(XMMRegister dst, XMMRegister src) {
void MacroAssembler::S256Not(YMMRegister dst, YMMRegister src,
YMMRegister scratch) {
ASM_CODE_COMMENT(this);
+ if (UseAvx10_1()) {
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ // 0x33 = ~src1 (independent of dst and src2).
+ vpternlogd(dst, src, src, 0x33);
+ return;
+ }
CpuFeatureScope avx2_scope(this, AVX2);
if (dst == src) {
vpcmpeqd(scratch, scratch, scratch);
@@ -2045,6 +2051,14 @@ void MacroAssembler::S256Select(YMMRegister dst, YMMRegister mask,
YMMRegister src1, YMMRegister src2,
YMMRegister scratch) {
ASM_CODE_COMMENT(this);
+ if (UseAvx10_1()) {
+ // 0xCA = dst ? src1 : src2,
+ // so the destination must already hold the mask.
+ CHECK_EQ(dst, mask);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpternlogd(dst, src1, src2, 0xca);
+ return;
+ }
CpuFeatureScope avx2_scope(this, AVX2);
// v256.select = v256.or(v256.and(v1, c), v256.andnot(v2, c)).
// pandn(x, y) = !x & y, so we have to flip the mask and input.
@@ -2069,9 +2083,143 @@ void MacroAssembler::Cmp(Register dst, int32_t src) {
}
}
+void MacroAssembler::Cmpq(Register dst, int32_t src) {
+ if (src == 0) {
+ testq(dst, dst);
+ } else {
+ cmpq(dst, Immediate(src));
+ }
+}
+
+void MacroAssembler::Cmpb(Register dst, int32_t src) {
+ if (src == 0) {
+ testb(dst, dst);
+ } else {
+ cmpb(dst, Immediate(src));
+ }
+}
+
+void MacroAssembler::I64x2Abs(XMMRegister dst, XMMRegister src,
+ XMMRegister scratch) {
+ if (UseAvx10_1()) {
+ ASM_CODE_COMMENT(this);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpabsq(dst, src);
+ return;
+ }
+ I64x2AbsPreAvx10(dst, src, scratch);
+}
+
+void MacroAssembler::I64x2ShrS(XMMRegister dst, XMMRegister src, uint8_t shift,
+ XMMRegister xmm_tmp) {
+ DCHECK_GT(64, shift);
+ if (UseAvx10_1()) {
+ ASM_CODE_COMMENT(this);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpsraq(dst, src, shift);
+ return;
+ }
+ DCHECK(xmm_tmp.is_valid());
+ DCHECK_NE(xmm_tmp, dst);
+ DCHECK_NE(xmm_tmp, src);
+ I64x2ShrSPreAvx10(dst, src, shift, xmm_tmp);
+}
+
+void MacroAssembler::I64x2ShrS(XMMRegister dst, XMMRegister src, Register shift,
+ XMMRegister xmm_tmp, XMMRegister xmm_shift,
+ Register tmp_shift) {
+ DCHECK(xmm_shift.is_valid());
+ DCHECK(tmp_shift.is_valid());
+ DCHECK_NE(xmm_shift, dst);
+ DCHECK_NE(xmm_shift, src);
+ if (UseAvx10_1()) {
+ ASM_CODE_COMMENT(this);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ Move(tmp_shift, shift);
+ And(tmp_shift, Immediate(0x3F));
+ Movd(xmm_shift, tmp_shift);
+ vpsraq(dst, src, xmm_shift);
+ return;
+ }
+
+ DCHECK(xmm_tmp.is_valid());
+ DCHECK_NE(xmm_tmp, dst);
+ DCHECK_NE(xmm_tmp, src);
+ DCHECK_NE(xmm_tmp, xmm_shift);
+ I64x2ShrSPreAvx10(dst, src, shift, xmm_tmp, xmm_shift, tmp_shift);
+}
+
+void MacroAssembler::I64x2Mul(XMMRegister dst, XMMRegister lhs, XMMRegister rhs,
+ XMMRegister tmp1, XMMRegister tmp2) {
+ if (UseAvx10_1()) {
+ ASM_CODE_COMMENT(this);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpmullq(dst, lhs, rhs);
+ return;
+ }
+ DCHECK(tmp1.is_valid());
+ DCHECK(tmp2.is_valid());
+ DCHECK(!AreAliased(dst, tmp1, tmp2));
+ DCHECK(!AreAliased(lhs, tmp1, tmp2));
+ DCHECK(!AreAliased(rhs, tmp1, tmp2));
+ I64x2MulPreAvx10(dst, lhs, rhs, tmp1, tmp2);
+}
+
+void MacroAssembler::I8x16Popcnt(XMMRegister dst, XMMRegister src,
+ Register scratch, XMMRegister tmp1,
+ XMMRegister tmp2) {
+ if (UseAvx10_1()) {
+ ASM_CODE_COMMENT(this);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpopcntb(dst, src);
+ return;
+ }
+ DCHECK(tmp1.is_valid());
+ DCHECK(tmp2.is_valid());
+ DCHECK(scratch.is_valid());
+ DCHECK(!AreAliased(dst, tmp1, tmp2));
+ DCHECK(!AreAliased(src, tmp1, tmp2));
+ I8x16PopcntPreAvx10(dst, src, tmp1, tmp2, scratch);
+}
+
+void MacroAssembler::S128Not(XMMRegister dst, XMMRegister src,
+ XMMRegister scratch) {
+ ASM_CODE_COMMENT(this);
+ if (UseAvx10_1()) {
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ // 0x33 = ~src1 (independent of dst and src2).
+ vpternlogd(dst, src, src, 0x33);
+ return;
+ }
+ S128NotPreAvx10(dst, src, scratch);
+}
+
+void MacroAssembler::S128Select(XMMRegister dst, XMMRegister mask,
+ XMMRegister src1, XMMRegister src2,
+ XMMRegister scratch) {
+ ASM_CODE_COMMENT(this);
+ if (UseAvx10_1()) {
+ // 0xCA = dst ? src1 : src2,
+ // so the destination must already hold the mask.
+ CHECK_EQ(dst, mask);
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpternlogd(dst, src1, src2, 0xca);
+ return;
+ }
+ S128SelectPreAvx10(dst, mask, src1, src2, scratch);
+}
+
void MacroAssembler::I64x4Mul(YMMRegister dst, YMMRegister lhs, YMMRegister rhs,
YMMRegister tmp1, YMMRegister tmp2) {
ASM_CODE_COMMENT(this);
+ if (UseAvx10_1()) {
+ CpuFeatureScope avx10_1_scope(this, AVX10_1);
+ vpmullq(dst, lhs, rhs);
+ return;
+ }
+
+ DCHECK(tmp1.is_valid());
+ DCHECK(tmp2.is_valid());
DCHECK(!AreAliased(dst, tmp1, tmp2));
DCHECK(!AreAliased(lhs, tmp1, tmp2));
DCHECK(!AreAliased(rhs, tmp1, tmp2));
diff --git a/deps/v8/src/codegen/x64/macro-assembler-x64.h b/deps/v8/src/codegen/x64/macro-assembler-x64.h
index c88449102d1..8f7d00cefdf 100644
--- a/deps/v8/src/codegen/x64/macro-assembler-x64.h
+++ b/deps/v8/src/codegen/x64/macro-assembler-x64.h
@@ -229,14 +229,35 @@ class V8_EXPORT_PRIVATE MacroAssembler
void Cmp(Register dst, Tagged<Smi> src);
void Cmp(Operand dst, Tagged<Smi> src);
void Cmp(Register dst, int32_t src);
+ void Cmpq(Register dst, int32_t src);
+ void Cmpb(Register dst, int32_t src);
void CmpTagged(const Register& src1, const Register& src2) {
cmp_tagged(src1, src2);
}
+ // SIMD128
+ void I64x2Abs(XMMRegister dst, XMMRegister src, XMMRegister scratch);
+ void I64x2ShrS(XMMRegister dst, XMMRegister src, uint8_t shift,
+ XMMRegister xmm_tmp);
+ void I64x2ShrS(XMMRegister dst, XMMRegister src, Register shift,
+ XMMRegister xmm_tmp, XMMRegister xmm_shift,
+ Register tmp_shift);
+ void I64x2Mul(XMMRegister dst, XMMRegister lhs, XMMRegister rhs,
+ XMMRegister tmp1 = XMMRegister::no_reg(),
+ XMMRegister tmp2 = XMMRegister::no_reg());
+ void I8x16Popcnt(XMMRegister dst, XMMRegister src, Register scratch,
+ XMMRegister tmp1 = XMMRegister::no_reg(),
+ XMMRegister tmp2 = XMMRegister::no_reg());
+ void S128Not(XMMRegister dst, XMMRegister src, XMMRegister scratch);
+ // AVX10 and SSE paths require dst == mask.
+ void S128Select(XMMRegister dst, XMMRegister mask, XMMRegister src1,
+ XMMRegister src2, XMMRegister scratch);
+
// SIMD256
void I64x4Mul(YMMRegister dst, YMMRegister lhs, YMMRegister rhs,
- YMMRegister tmp1, YMMRegister tmp2);
+ YMMRegister tmp1 = YMMRegister::no_reg(),
+ YMMRegister tmp2 = YMMRegister::no_reg());
void F64x4Min(YMMRegister dst, YMMRegister lhs, YMMRegister rhs,
YMMRegister scratch);
void F64x4Max(YMMRegister dst, YMMRegister lhs, YMMRegister rhs,
@@ -278,6 +299,7 @@ class V8_EXPORT_PRIVATE MacroAssembler
XMMRegister src3, YMMRegister tmp, YMMRegister tmp2);
void S256Not(YMMRegister dst, YMMRegister src, YMMRegister scratch);
+ // AVX10 path requires dst == mask.
void S256Select(YMMRegister dst, YMMRegister mask, YMMRegister src1,
YMMRegister src2, YMMRegister scratch);
@@ -591,6 +613,48 @@ class V8_EXPORT_PRIVATE MacroAssembler
void CompareTaggedRoot(Register with, RootIndex index);
void CompareRoot(Operand with, RootIndex index);
+#ifdef V8_ENABLE_APX_F
+ template <typename Dst, typename Src>
+ void Ccmp(Dst lhs, Src rhs, OszcFlags dfv, Condition cond, int size) {
+ switch (size) {
+ case kInt8Size:
+ ccmpb(lhs, rhs, dfv, cond);
+ break;
+ case kInt16Size:
+ ccmpw(lhs, rhs, dfv, cond);
+ break;
+ case kInt32Size:
+ ccmpl(lhs, rhs, dfv, cond);
+ break;
+ case kInt64Size:
+ ccmpq(lhs, rhs, dfv, cond);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+
+ template <typename Dst, typename Src>
+ void Ctest(Dst lhs, Src rhs, OszcFlags dfv, Condition cond, int size) {
+ switch (size) {
+ case kInt8Size:
+ ctestb(lhs, rhs, dfv, cond);
+ break;
+ case kInt16Size:
+ ctestw(lhs, rhs, dfv, cond);
+ break;
+ case kInt32Size:
+ ctestl(lhs, rhs, dfv, cond);
+ break;
+ case kInt64Size:
+ ctestq(lhs, rhs, dfv, cond);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ }
+#endif
+
// Generates function and stub prologue code.
void StubPrologue(StackFrame::Type type);
void Prologue();
diff --git a/deps/v8/src/codegen/x64/register-x64.h b/deps/v8/src/codegen/x64/register-x64.h
index bc3c23e4bfd..96e9290e5d2 100644
--- a/deps/v8/src/codegen/x64/register-x64.h
+++ b/deps/v8/src/codegen/x64/register-x64.h
@@ -146,27 +146,36 @@ constexpr int kRegisterPassedArguments = arraysize(kCArgRegs);
V(xmm14) \
V(xmm15)
+#define EXTENDED_XMM_REGISTERS(V) \
+ V(xmm16) \
+ V(xmm17) \
+ V(xmm18) \
+ V(xmm19) \
+ V(xmm20) \
+ V(xmm21) \
+ V(xmm22) \
+ V(xmm23) \
+ V(xmm24) \
+ V(xmm25) \
+ V(xmm26) \
+ V(xmm27) \
+ V(xmm28) \
+ V(xmm29) \
+ V(xmm30) \
+ V(xmm31)
+
#define DOUBLE_REGISTERS_AVX512(V) \
DOUBLE_REGISTERS(V) \
- V(xmm16) \
- V(xmm17) \
- V(xmm18) \
- V(xmm19) \
- V(xmm20) \
- V(xmm21) \
- V(xmm22) \
- V(xmm23) \
- V(xmm24) \
- V(xmm25) \
- V(xmm26) \
- V(xmm27) \
- V(xmm28) \
- V(xmm29) \
- V(xmm30) \
- V(xmm31)
+ EXTENDED_XMM_REGISTERS(V)
+
+#ifdef V8_ENABLE_AVX10_1
+#define ALL_XMM_REGISTERS(V) DOUBLE_REGISTERS_AVX512(V)
+#else
+#define ALL_XMM_REGISTERS(V) DOUBLE_REGISTERS(V)
+#endif // V8_ENABLE_AVX10_1
-#define FLOAT_REGISTERS DOUBLE_REGISTERS
-#define SIMD128_REGISTERS DOUBLE_REGISTERS
+#define FLOAT_REGISTERS ALL_XMM_REGISTERS
+#define SIMD128_REGISTERS ALL_XMM_REGISTERS
#define ALLOCATABLE_DOUBLE_REGISTERS(V) \
V(xmm0) \
@@ -203,24 +212,33 @@ constexpr int kRegisterPassedArguments = arraysize(kCArgRegs);
V(ymm14) \
V(ymm15)
+#define EXTENDED_YMM_REGISTERS(V) \
+ V(ymm16) \
+ V(ymm17) \
+ V(ymm18) \
+ V(ymm19) \
+ V(ymm20) \
+ V(ymm21) \
+ V(ymm22) \
+ V(ymm23) \
+ V(ymm24) \
+ V(ymm25) \
+ V(ymm26) \
+ V(ymm27) \
+ V(ymm28) \
+ V(ymm29) \
+ V(ymm30) \
+ V(ymm31)
+
#define YMM_REGISTERS_AVX512(V) \
YMM_REGISTERS(V) \
- V(ymm16) \
- V(ymm17) \
- V(ymm18) \
- V(ymm19) \
- V(ymm20) \
- V(ymm21) \
- V(ymm22) \
- V(ymm23) \
- V(ymm24) \
- V(ymm25) \
- V(ymm26) \
- V(ymm27) \
- V(ymm28) \
- V(ymm29) \
- V(ymm30) \
- V(ymm31)
+ EXTENDED_YMM_REGISTERS(V)
+
+#ifdef V8_ENABLE_AVX10_1
+#define ALL_YMM_REGISTERS(V) YMM_REGISTERS_AVX512(V)
+#else
+#define ALL_YMM_REGISTERS(V) YMM_REGISTERS(V)
+#endif // V8_ENABLE_AVX10_1
#ifdef V8_TARGET_OS_WIN
#define C_CALL_CALLEE_SAVE_REGISTERS rbx, rdi, rsi, r12, r13, r14, r15
@@ -243,14 +261,14 @@ constexpr bool kSimdMaskRegisters = false;
enum DoubleRegisterCode {
#define REGISTER_CODE(R) kDoubleCode_##R,
- DOUBLE_REGISTERS(REGISTER_CODE)
+ ALL_XMM_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kDoubleAfterLast
};
enum YMMRegisterCode {
#define REGISTER_CODE(R) kYMMCode_##R,
- YMM_REGISTERS(REGISTER_CODE)
+ ALL_YMM_REGISTERS(REGISTER_CODE)
#undef REGISTER_CODE
kYMMAfterLast
};
@@ -261,9 +279,18 @@ static_assert(static_cast<int>(kDoubleAfterLast) ==
class XMMRegister : public RegisterBase<XMMRegister, kDoubleAfterLast> {
public:
+ // Return the fifth bit of the register code as a 0 or 1. Used together with
+ // high_bit() to encode xmm16-31 in the EVEX prefix.
+ int bit4() const { return (code() >> 4) & 0x1; }
+#if defined(V8_ENABLE_AVX10_1) || defined(V8_ENABLE_APX_F)
+ // Return the high bit of the register code as a 0 or 1. Used often
+ // when constructing the REX prefix byte.
+ int high_bit() const { return (code() >> 3) & 0x1; }
+#else
// Return the high bit of the register code as a 0 or 1. Used often
// when constructing the REX prefix byte.
int high_bit() const { return code() >> 3; }
+#endif // V8_ENABLE_AVX10_1 || V8_ENABLE_APX_F
// Return the 3 low bits of the register code. Used when encoding registers
// in modR/M, SIB, and opcode bytes.
int low_bits() const { return code() & 0x7; }
@@ -279,6 +306,10 @@ static_assert(sizeof(XMMRegister) <= sizeof(int),
class YMMRegister : public XMMRegister {
public:
+ static constexpr YMMRegister no_reg() {
+ return YMMRegister(XMMRegister::no_reg());
+ }
+
static constexpr YMMRegister from_code(int code) {
V8_ASSUME(code >= 0 && code < XMMRegister::kNumRegisters);
return YMMRegister(code);
@@ -290,6 +321,7 @@ class YMMRegister : public XMMRegister {
private:
friend class XMMRegister;
+ explicit constexpr YMMRegister(XMMRegister reg) : XMMRegister(reg) {}
explicit constexpr YMMRegister(int code) : XMMRegister(code) {}
};
@@ -307,19 +339,19 @@ using Simd256Register = YMMRegister;
#define DECLARE_REGISTER(R) \
constexpr DoubleRegister R = DoubleRegister::from_code(kDoubleCode_##R);
-DOUBLE_REGISTERS(DECLARE_REGISTER)
+ALL_XMM_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
constexpr DoubleRegister no_dreg = DoubleRegister::no_reg();
#define DECLARE_REGISTER(R) \
constexpr YMMRegister R = YMMRegister::from_code(kYMMCode_##R);
-YMM_REGISTERS(DECLARE_REGISTER)
+ALL_YMM_REGISTERS(DECLARE_REGISTER)
#undef DECLARE_REGISTER
// Define {RegisterName} methods for the register types.
DEFINE_REGISTER_NAMES(Register, GENERAL_REGISTERS)
-DEFINE_REGISTER_NAMES(XMMRegister, DOUBLE_REGISTERS)
-DEFINE_REGISTER_NAMES(YMMRegister, YMM_REGISTERS)
+DEFINE_REGISTER_NAMES(XMMRegister, ALL_XMM_REGISTERS)
+DEFINE_REGISTER_NAMES(YMMRegister, ALL_YMM_REGISTERS)
// Give alias names to registers for calling conventions.
constexpr Register kStackPointerRegister = rsp;
diff --git a/deps/v8/src/common/assert-scope.h b/deps/v8/src/common/assert-scope.h
index 6f4ec2d5007..ca36c690d4a 100644
--- a/deps/v8/src/common/assert-scope.h
+++ b/deps/v8/src/common/assert-scope.h
@@ -110,7 +110,7 @@ class V8_NODISCARD PerThreadAssertScope
ScopeType& operator=(const ScopeType&) = delete; \
V8_EXPORT_PRIVATE ~ScopeType(); \
\
- static bool IsAllowed(Isolate* isolate); \
+ V8_EXPORT_PRIVATE static bool IsAllowed(Isolate* isolate); \
\
V8_EXPORT_PRIVATE static void Open(Isolate* isolate, \
bool* was_execution_allowed); \
diff --git a/deps/v8/src/common/globals.h b/deps/v8/src/common/globals.h
index 1e033da25a2..16b4c069f5e 100644
--- a/deps/v8/src/common/globals.h
+++ b/deps/v8/src/common/globals.h
@@ -613,25 +613,29 @@ constexpr int kJSDispatchTableEntrySizeLog2 = 4;
// The size of the virtual memory reservation for the JSDispatchTable.
// As with the other tables, a maximum table size in combination with shifted
// indices allows omitting bounds checks.
-#if defined(V8_TARGET_OS_IOS)
+#if defined(V8_TARGET_OS_IOS) && !defined(V8_ENABLE_BUILTINS_OPTIMIZATION)
// iOS has limited virtual address space (64GB); reduce table size to fit more
-// isolates.
+// isolates. However, the existing built-ins PGO profiles (generated on x64)
+// assume the default constants, so we must use the default when built-ins PGO
+// is enabled (crbug.com/545490388).
constexpr size_t kJSDispatchTableReservationSize = 128 * MB;
#else
constexpr size_t kJSDispatchTableReservationSize =
(V8_LOWER_LIMITS_MODE_BOOL ? 16 : 256) * MB;
-#endif // defined(V8_TARGET_OS_IOS)
+#endif // defined(V8_TARGET_OS_IOS) &&
+ // !defined(V8_ENABLE_BUILTINS_OPTIMIZATION)
// The maximum number of entries in a JSDispatchTable.
constexpr size_t kMaxJSDispatchEntries =
kJSDispatchTableReservationSize / kJSDispatchTableEntrySize;
#ifdef V8_TARGET_ARCH_64_BIT
-#if defined(V8_TARGET_OS_IOS)
+#if defined(V8_TARGET_OS_IOS) && !defined(V8_ENABLE_BUILTINS_OPTIMIZATION)
constexpr uint32_t kJSDispatchHandleShift = 9;
#else
constexpr uint32_t kJSDispatchHandleShift = V8_LOWER_LIMITS_MODE_BOOL ? 12 : 8;
-#endif // defined(V8_TARGET_OS_IOS)
+#endif // defined(V8_TARGET_OS_IOS) &&
+ // !defined(V8_ENABLE_BUILTINS_OPTIMIZATION)
static_assert((1 << (32 - kJSDispatchHandleShift)) == kMaxJSDispatchEntries,
"kJSDispatchTableReservationSize and kJSDispatchEntryHandleShift "
"don't match");
@@ -720,7 +724,7 @@ constexpr JSDispatchHandle kPlaceholderDispatchHandle(0x0);
constexpr JSDispatchHandle kInvalidDispatchHandle(0xffffffff
<< kJSDispatchHandleShift);
-constexpr int kEmbedderDataSlotSize = kSystemPointerSize;
+constexpr int kEmbedderDataSlotSize = 2 * kTaggedSize;
constexpr int kEmbedderDataSlotSizeInTaggedSlots =
kEmbedderDataSlotSize / kTaggedSize;
@@ -950,7 +954,10 @@ constexpr int kFeedbackIsEmbedded = -1;
// byteocode, indicating an uninitialized state.
constexpr int kUninitializedEmbeddedFeedback = 0;
-// The bytecode operand index for embedded feedback.
+// The bytecode operand indices for embedded feedback. Unary bytecodes only
+// have a single operand (the embedded feedback itself), while binary and
+// compare bytecodes carry the embedded feedback as their second operand.
+constexpr int kUnaryEmbeddedFeedbackOperandIndex = 0;
constexpr int kEmbeddedFeedbackOperandIndex = 1;
// These constants are internal duplicates for v8::Intercepted enum values.
@@ -2204,10 +2211,10 @@ static_assert(kMinAdditiveSafeInteger + kMinAdditiveSafeInteger >=
kMinSafeInteger);
constexpr int64_t kMaxAdditiveSafeIntegerFeedback =
- (int64_t{1} << 51) - 1; // 2^51 - 1
+ (int64_t{1} << 50) - 1; // 2^50 - 1
constexpr int64_t kMinAdditiveSafeIntegerFeedback =
- -(int64_t{1} << 51); // - 2^51
-constexpr int kAdditiveSafeIntegerFeedbackBitLength = 52;
+ -(int64_t{1} << 50); // - 2^50
+constexpr int kAdditiveSafeIntegerFeedbackBitLength = 51;
// Number of bits to shift left before addition to detect potential overflow.
constexpr int kAdditiveSafeIntegerFeedbackShift =
64 - kAdditiveSafeIntegerFeedbackBitLength;
@@ -2548,6 +2555,17 @@ class BinaryOperationFeedback : public AllStatic {
return Type::kAny;
}
+ static constexpr const char* TypeIndexToString(TypeIndex index) {
+ switch (index) {
+#define CASE_NAME(name) \
+ case TypeIndex::k##name: \
+ return #name;
+ BINARY_OPERATION_FEEDBACK_TYPES(CASE_NAME)
+#undef CASE_NAME
+ }
+ return "Unknown";
+ }
+
private:
static constexpr TypeIndex CalculateTypeIndex(uint32_t feedback_value) {
#define CALCULATE_TYPE_INDEX(name) \
@@ -2688,6 +2706,17 @@ class CompareOperationFeedback : public AllStatic {
return Type::kAny;
}
+ static constexpr const char* TypeIndexToString(TypeIndex index) {
+ switch (index) {
+#define CASE_NAME(name) \
+ case TypeIndex::k##name: \
+ return #name;
+ COMPARE_OPERATION_FEEDBACK_TYPES(CASE_NAME)
+#undef CASE_NAME
+ }
+ return "Unknown";
+ }
+
static constexpr uint32_t kNumTypeIndices =
static_cast<uint32_t>(TypeIndex::kLastTypeIndex) + 1;
// round up to 2^x for better memory access
@@ -2958,6 +2987,14 @@ enum class CachedTieringDecision : int32_t {
#define TYPED_EXP_STUB_LIST(V, ...) \
V(None, ##__VA_ARGS__) \
V(Number, ##__VA_ARGS__)
+
+#define TYPED_UNARY_STUB_LIST(V, ...) \
+ V(None, ##__VA_ARGS__) \
+ V(SignedSmall, ##__VA_ARGS__)
+
+#define TYPED_NEGATE_STUB_LIST(V, ...) \
+ TYPED_UNARY_STUB_LIST(V, ##__VA_ARGS__) \
+ V(Number, ##__VA_ARGS__)
#else
#define IF_SPARKPLUG_PLUS(V, ...)
@@ -2968,6 +3005,8 @@ enum class CachedTieringDecision : int32_t {
#define TYPED_ADD_STUB_LIST(V, ...)
#define TYPED_EXP_STUB_LIST(V, ...)
#define TYPED_BITWISE_BINOP_STUB_LIST(V, ...)
+#define TYPED_UNARY_STUB_LIST(V, ...)
+#define TYPED_NEGATE_STUB_LIST(V, ...)
#endif // V8_ENABLE_SPARKPLUG_PLUS
enum class SpeculationMode {
diff --git a/deps/v8/src/common/operation.h b/deps/v8/src/common/operation.h
index fa9c81dc001..8dbc3a050b1 100644
--- a/deps/v8/src/common/operation.h
+++ b/deps/v8/src/common/operation.h
@@ -79,6 +79,18 @@ constexpr inline bool IsBinaryOperation(Operation op) {
return !IsUnaryOperation(op);
}
+constexpr inline bool IsComparisonOperation(Operation op) {
+ switch (op) {
+#define COMPARISON_CASE(name) \
+ case Operation::k##name: \
+ return true;
+ COMPARISON_OPERATION_LIST(COMPARISON_CASE)
+#undef COMPARISON_CASE
+ default:
+ return false;
+ }
+}
+
inline std::ostream& operator<<(std::ostream& os, const Operation& operation) {
switch (operation) {
#define CASE(name) \
diff --git a/deps/v8/src/common/ptr-compr-inl.h b/deps/v8/src/common/ptr-compr-inl.h
index 3da41510a52..05e9f829900 100644
--- a/deps/v8/src/common/ptr-compr-inl.h
+++ b/deps/v8/src/common/ptr-compr-inl.h
@@ -124,7 +124,7 @@ Address V8HeapCompressionSchemeImpl<Cage>::DecompressTagged(
#else
Address cage_base = GetPtrComprCageBaseAddress(on_heap_addr);
#endif // V8_COMPRESS_POINTERS
- Address result = cage_base + static_cast<Address>(raw_value);
+ Address result = cage_base | static_cast<Address>(raw_value);
V8_ASSUME(static_cast<uint32_t>(result) == raw_value);
return result;
}
diff --git a/deps/v8/src/common/segmented-table-inl.h b/deps/v8/src/common/segmented-table-inl.h
deleted file mode 100644
index 94a6d82e8e3..00000000000
--- a/deps/v8/src/common/segmented-table-inl.h
+++ /dev/null
@@ -1,295 +0,0 @@
-// Copyright 2024 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_COMMON_SEGMENTED_TABLE_INL_H_
-#define V8_COMMON_SEGMENTED_TABLE_INL_H_
-
-#include "src/common/segmented-table.h"
-// Include the non-inl header before the rest of the headers.
-
-#include "src/base/emulated-virtual-address-subspace.h"
-#include "src/common/assert-scope.h"
-#include "src/sandbox/testing.h"
-#include "src/utils/allocation.h"
-
-namespace v8 {
-namespace internal {
-
-template <typename Entry, size_t size>
-typename SegmentedTable<Entry, size>::Segment
-SegmentedTable<Entry, size>::Segment::At(uint32_t offset) {
- DCHECK(IsAligned(offset, kSegmentSize));
- uint32_t number = offset / kSegmentSize;
- return Segment(number);
-}
-
-template <typename Entry, size_t size>
-typename SegmentedTable<Entry, size>::Segment
-SegmentedTable<Entry, size>::Segment::Containing(uint32_t entry_index) {
- uint32_t number = entry_index / kEntriesPerSegment;
- return Segment(number);
-}
-
-template <typename Entry, size_t size>
-Entry& SegmentedTable<Entry, size>::at(uint32_t index) {
- return base_[index];
-}
-
-template <typename Entry, size_t size>
-const Entry& SegmentedTable<Entry, size>::at(uint32_t index) const {
- return base_[index];
-}
-
-template <typename Entry, size_t size>
-typename SegmentedTable<Entry, size>::WriteIterator
-SegmentedTable<Entry, size>::iter_at(uint32_t index) {
- return WriteIterator(base_, index);
-}
-
-template <typename Entry, size_t size>
-bool SegmentedTable<Entry, size>::is_initialized() const {
- DCHECK(!base_ || reinterpret_cast<Address>(base_) == vas_->base());
- return vas_ != nullptr;
-}
-
-template <typename Entry, size_t size>
-Address SegmentedTable<Entry, size>::base() const {
- DCHECK(is_initialized());
- return reinterpret_cast<Address>(base_);
-}
-
-template <typename Entry, size_t size>
-void SegmentedTable<Entry, size>::Initialize() {
- DCHECK(!is_initialized());
- DCHECK_EQ(vas_, nullptr);
-
- VirtualAddressSpace* root_space = GetPlatformVirtualAddressSpace();
-
-#ifdef V8_TARGET_ARCH_64_BIT
- static_assert(kUseContiguousMemory);
- DCHECK(IsAligned(kReservationSize, root_space->allocation_granularity()));
-
- std::optional<VirtualAddressSpace::MemoryProtectionKeyId> pkey;
- if (kUseContiguousMemory && kIsWriteProtected && ThreadIsolation::Enabled()) {
-#if V8_HAS_PKU_JIT_WRITE_PROTECT
- pkey = ThreadIsolation::pkey();
-#else
- UNREACHABLE();
-#endif // V8_HAS_PKU_JIT_WRITE_PROTECT
- }
-
- if (root_space->CanAllocateSubspaces()) {
- auto subspace = root_space->AllocateSubspace(
- VirtualAddressSpace::kNoHint, kReservationSize, kAlignment,
- PagePermissions::kReadWrite, pkey);
- vas_ = subspace.release();
- } else {
- // This may be required on old Windows versions that don't support
- // VirtualAlloc2, which is required for subspaces. In that case, just
- // use a fully-backed emulated subspace.
- DCHECK(!pkey);
- Address reservation_base = root_space->AllocatePages(
- VirtualAddressSpace::kNoHint, kReservationSize, kAlignment,
- PagePermissions::kNoAccess);
- if (reservation_base) {
- vas_ = new base::EmulatedVirtualAddressSubspace(
- root_space, reservation_base, kReservationSize, kReservationSize);
- }
- }
- if (!vas_) {
- V8::FatalProcessOutOfMemory(
- nullptr, "SegmentedTable::InitializeTable (subspace allocation)");
- }
- vas_->SetName(kPointerTableAddressSpaceName);
-#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
- // In-sandbox corruption of handles can lead to out-of-bounds accesses into
- // our tables, but these will stay inside the table's reserved region and hit
- // PROT_NONE mappings, so they are safe. They can be both read- and write
- // accesses though as we also write new pointers into existing table entries.
- // Writing is fine as long as the value is not attacker controlled. It's only
- // when we write attacker-controlled data that we (likely) have a security
- // problem (but then it doesn't matter whether it's out-of-bounds or not).
- SandboxTesting::RegisterSafeMemoryRegion(
- vas_->base(), vas_->size(), SandboxTesting::kReadAndWriteAccessIsSafe);
-#endif // V8_ENABLE_MEMORY_CORRUPTION_API
-#else
- static_assert(!kUseContiguousMemory);
- vas_ = root_space;
-#endif // V8_TARGET_ARCH_64_BIT
-
- base_ = reinterpret_cast<Entry*>(vas_->base());
-
- if (kUseSegmentPool) {
- for (size_t i = 0; i < kSegmentPoolSize; ++i) {
- DCHECK_EQ(segment_pool_[i].load(std::memory_order_acquire), 0);
- segment_pool_[i].store(kSegmentPoolFreeEntry, std::memory_order_release);
- }
-
- segment_pool_grow_mutex_ = new base::Mutex();
- }
-}
-
-template <typename Entry, size_t size>
-void SegmentedTable<Entry, size>::TearDown() {
- DCHECK(is_initialized());
-
-#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
- SandboxTesting::UnregisterSafeMemoryRegion(vas_->base());
-#endif
-
- if (segment_pool_grow_mutex_) {
- delete segment_pool_grow_mutex_;
- }
-
- base_ = nullptr;
-#ifdef V8_TARGET_ARCH_64_BIT
- delete vas_;
-#endif
- vas_ = nullptr;
-}
-
-template <typename Entry, size_t size>
-typename SegmentedTable<Entry, size>::FreelistHead
-SegmentedTable<Entry, size>::InitializeFreeList(Segment segment,
- uint32_t start_offset) {
- DCHECK_LT(start_offset, kEntriesPerSegment);
- uint32_t num_entries = kEntriesPerSegment - start_offset;
-
- uint32_t first = segment.first_entry() + start_offset;
- uint32_t last = segment.last_entry();
- {
- WriteIterator it = iter_at(first);
- while (it.index() != last) {
- it->MakeFreelistEntry(it.index() + 1);
- ++it;
- }
- it->MakeFreelistEntry(0);
- }
-
- return FreelistHead(first, num_entries);
-}
-
-template <typename Entry, size_t size>
-std::optional<typename SegmentedTable<Entry, size>::Segment>
-SegmentedTable<Entry, size>::TryGetSegmentFromPool() {
- DCHECK(kUseSegmentPool);
- DCHECK(segment_pool_grow_mutex_);
- for (int i = 0; i < static_cast<int>(kSegmentPoolSize); ++i) {
- uint32_t segment = segment_pool_[i].load(std::memory_order_relaxed);
- if (segment != kSegmentPoolFreeEntry) {
- if (segment_pool_[i].compare_exchange_weak(segment, kSegmentPoolFreeEntry,
- std::memory_order_acq_rel)) {
- return Segment::At(segment);
- } else {
- // Retry if CAS failed. This is needed to ensure the pool really is
- // empty when this method returns {}.
- --i;
- }
- }
- }
- return {};
-}
-
-template <typename Entry, size_t size>
-std::optional<typename SegmentedTable<Entry, size>::Segment>
-SegmentedTable<Entry, size>::TryAllocateSegment() {
- if constexpr (!kUseSegmentPool) {
- Address start =
- vas_->AllocatePages(VirtualAddressSpace::kNoHint, kSegmentSize,
- kSegmentSize, PagePermissions::kReadWrite);
- if (!start) {
- return {};
- }
- uint32_t offset = static_cast<uint32_t>(start - vas_->base());
- return Segment::At(offset);
- }
-
- if (auto segment = TryGetSegmentFromPool()) {
- return segment;
- }
-
- base::MutexGuard guard(*segment_pool_grow_mutex_);
- // Try again to get a segment from the pool with the mutex held. Either
- // another thread filled the pool before us and we should get a segment here,
- // or the pool is guaranteed to be empty and we can proceed to fill it.
- if (auto segment = TryGetSegmentFromPool()) {
- return segment;
- }
-
- return FillSegmentsPool(true);
-}
-
-template <typename Entry, size_t size>
-std::optional<typename SegmentedTable<Entry, size>::Segment>
-SegmentedTable<Entry, size>::FillSegmentsPool(bool return_a_segment) {
- std::optional<Segment> res;
- for (size_t i = 0; i < kSegmentPoolSize; ++i) {
- DCHECK_EQ(segment_pool_[i].load(std::memory_order_acquire),
- kSegmentPoolFreeEntry);
- Address start =
- vas_->AllocatePages(VirtualAddressSpace::kNoHint, kSegmentSize,
- kAlignment, PagePermissions::kReadWrite);
- if (!start) continue;
- uint32_t offset = static_cast<uint32_t>(start - vas_->base());
- DCHECK_NE(offset, kSegmentPoolFreeEntry);
- if (return_a_segment && !res) {
- res.emplace(Segment::At(offset));
- } else {
- segment_pool_[i].store(offset, std::memory_order_release);
- }
- }
- return res;
-}
-
-template <typename Entry, size_t size>
-std::pair<typename SegmentedTable<Entry, size>::Segment,
- typename SegmentedTable<Entry, size>::FreelistHead>
-SegmentedTable<Entry, size>::AllocateAndInitializeSegment() {
- if (auto res = TryAllocateAndInitializeSegment()) {
- return *res;
- }
- V8::FatalProcessOutOfMemory(nullptr,
- "SegmentedTable::AllocateAndInitializeSegment");
-}
-
-template <typename Entry, size_t size>
-std::optional<std::pair<typename SegmentedTable<Entry, size>::Segment,
- typename SegmentedTable<Entry, size>::FreelistHead>>
-SegmentedTable<Entry, size>::TryAllocateAndInitializeSegment() {
- auto segment = TryAllocateSegment();
- if (!segment) return {};
- DCHECK_IMPLIES(!kUseContiguousMemory,
- (*segment).number() > kNumReadOnlySegments);
- FreelistHead freelist = InitializeFreeList(*segment);
- return {{*segment, freelist}};
-}
-
-template <typename Entry, size_t size>
-void SegmentedTable<Entry, size>::FreeTableSegment(Segment segment) {
- if (kUseSegmentPool) {
- DCHECK_NE(segment.offset(), kSegmentPoolFreeEntry);
- base::MutexGuard guard(*segment_pool_grow_mutex_);
- for (size_t i = 0; i < kSegmentPoolSize; ++i) {
- uint32_t cur = segment_pool_[i].load(std::memory_order_relaxed);
- if (cur == kSegmentPoolFreeEntry) {
- if (segment_pool_[i].compare_exchange_weak(cur, segment.offset(),
- std::memory_order_acq_rel)) {
- return;
- }
- }
- }
- }
- Address segment_start = vas_->base() + segment.offset();
- vas_->FreePages(segment_start, kSegmentSize);
-}
-
-template <typename Entry, size_t size>
-SegmentedTable<Entry, size>::WriteIterator::WriteIterator(Entry* base,
- uint32_t index)
- : base_(base), index_(index), write_scope_("pointer table write") {}
-
-} // namespace internal
-} // namespace v8
-
-#endif // V8_COMMON_SEGMENTED_TABLE_INL_H_
diff --git a/deps/v8/src/common/segmented-table.h b/deps/v8/src/common/segmented-table.h
deleted file mode 100644
index 6b0d233a665..00000000000
--- a/deps/v8/src/common/segmented-table.h
+++ /dev/null
@@ -1,257 +0,0 @@
-// Copyright 2024 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_COMMON_SEGMENTED_TABLE_H_
-#define V8_COMMON_SEGMENTED_TABLE_H_
-
-#include "include/v8-internal.h"
-#include "src/base/macros.h"
-#include "src/common/code-memory-access.h"
-
-namespace v8 {
-namespace internal {
-
-/**
- * A thread-safe table with a fixed maximum size split into segments.
- *
- * The table provides thread-safe methods to allocate and free of segments and
- * an inline freelist implementation. Allocation and Freeing of entries is
- * implemented in subclasses since it depends on if the table is manually
- * managed or GCed.
- *
- * For the purpose of memory management, the table is partitioned into Segments
- * (for example 64kb memory chunks) that are grouped together in "Spaces". All
- * segments in a space share a freelist, and so entry allocation and garbage
- * collection happen on the level of spaces.
- *
- * The Entry type defines how the freelist is represented. For that, it must
- * implement the following methods:
- * - void MakeFreelistEntry(uint32_t next_entry_index)
- * - uint32_t GetNextFreelistEntry()
- */
-template <typename Entry, size_t size>
-class V8_EXPORT_PRIVATE SegmentedTable {
- protected:
- static constexpr bool kIsWriteProtected = Entry::IsWriteProtected;
- static constexpr int kEntrySize = sizeof(Entry);
-
-#ifdef V8_TARGET_ARCH_64_BIT
- // On 64 bit, we use a large address space reservation for the table memory.
- static constexpr bool kUseContiguousMemory = true;
- static constexpr size_t kReservationSize = size;
- static constexpr size_t kMaxCapacity = kReservationSize / kEntrySize;
- static constexpr bool kUseSegmentPool = false;
- static constexpr size_t kSegmentSize = kUseSegmentPool ? 16 * KB : 64 * KB;
-#else
- // On 32 bit, segments are individually mapped.
- static constexpr bool kUseContiguousMemory = false;
- static constexpr bool kUseSegmentPool = false;
-#ifdef V8_TARGET_OS_WIN
- // On windows the allocation granularity is 64KB.
- static constexpr size_t kSegmentSize = 64 * KB;
-#else
- static constexpr size_t kSegmentSize = 16 * KB;
-#endif
-#endif // V8_TARGET_ARCH_64_BIT
-
- // The sandbox relies on not being able to access any SegmentedTable out of
- // bounds.
- static_assert(kUseContiguousMemory || !V8_ENABLE_SANDBOX_BOOL);
-
- // For managing the table's backing memory, the table is partitioned into
- // segments of this size. Segments can then be allocated and freed using the
- // AllocateAndInitializeSegment() and FreeTableSegment() routines.
- static constexpr size_t kSegmentPoolSize = 4;
- static constexpr uint32_t kSegmentPoolFreeEntry =
- std::numeric_limits<uint32_t>::max();
- static constexpr size_t kEntriesPerSegment = kSegmentSize / kEntrySize;
- static constexpr size_t kAlignment = kSegmentSize;
- static constexpr size_t kNumReadOnlySegments = 64 * KB / kSegmentSize;
-
- // Struct representing a segment of the table.
- struct Segment {
- public:
- // Initialize a segment given its number.
- explicit Segment(uint32_t number) : number_(number) {}
-
- // Returns the segment starting at the specified offset from the base of the
- // table.
- static Segment At(uint32_t offset);
-
- // Returns the segment containing the entry at the given index.
- static Segment Containing(uint32_t entry_index);
-
- // The segments of a table are numbered sequentially. This method returns
- // the number of this segment.
- uint32_t number() const { return number_; }
-
- // Returns the offset of this segment from the table base.
- uint32_t offset() const { return number_ * kSegmentSize; }
-
- // Returns the index of the first entry in this segment.
- uint32_t first_entry() const { return number_ * kEntriesPerSegment; }
-
- // Return the index of the last entry in this segment.
- uint32_t last_entry() const {
- return first_entry() + kEntriesPerSegment - 1;
- }
-
- // Segments are ordered by their id/offset.
- bool operator<(const Segment& other) const {
- return number_ < other.number_;
- }
-
- private:
- // A segment is identified by its number, which is its offset from the base
- // of the table divided by the segment size.
- const uint32_t number_;
- };
-
- // Struct representing the head of the freelist.
- //
- // A segmented table uses simple, singly-linked lists to manage free entries.
- // Each entry on the freelist contains the 32-bit index of the next entry. The
- // last entry points to zero.
- struct FreelistHead {
- constexpr FreelistHead() : next_(0), length_(0) {}
- constexpr FreelistHead(uint32_t next, uint32_t length)
- : next_(next), length_(length) {}
-
- // Returns the index of the next entry on the freelist.
- // If the freelist is empty, this returns zero.
- uint32_t next() const { return next_; }
-
- // Returns the total length of the freelist.
- uint32_t length() const { return length_; }
-
- bool is_empty() const { return length_ == 0; }
-
- private:
- uint32_t next_;
- uint32_t length_;
- };
-
- // We expect the FreelistHead struct to fit into a single atomic word.
- // Otherwise, access to it would be slow.
- static_assert(std::atomic<FreelistHead>::is_always_lock_free);
-
- SegmentedTable() = default;
- SegmentedTable(const SegmentedTable&) = delete;
- SegmentedTable& operator=(const SegmentedTable&) = delete;
-
- // This Iterator also acts as a scope object to temporarily lift any
- // write-protection (if kIsWriteProtected is true).
- class WriteIterator {
- public:
- explicit WriteIterator(Entry* base, uint32_t index);
-
- uint32_t index() const { return index_; }
- Entry* operator->() {
- DCHECK(!crossed_segment_);
- return &base_[index_];
- }
- Entry& operator*() {
- DCHECK(!crossed_segment_);
- return base_[index_];
- }
- WriteIterator& operator++() {
- index_++;
-#ifdef DEBUG
- if (IsAligned(index_, kEntriesPerSegment)) {
- crossed_segment_ = true;
- }
-#endif
- return *this;
- }
- WriteIterator& operator--() {
- DCHECK_GT(index_, 0);
-#ifdef DEBUG
- if (IsAligned(index_, kEntriesPerSegment)) {
- crossed_segment_ = true;
- }
-#endif
- index_--;
- return *this;
- }
-
- private:
- Entry* base_;
- uint32_t index_;
- std::conditional_t<kIsWriteProtected, CFIMetadataWriteScope,
- NopRwxMemoryWriteScope>
- write_scope_;
-#ifdef DEBUG
- bool crossed_segment_ = false;
-#endif
- };
-
- // Access the entry at the specified index.
- Entry& at(uint32_t index);
- const Entry& at(uint32_t index) const;
-
- // Returns an iterator that can be used to perform multiple write operations
- // without switching the write-protections all the time (if kIsWriteProtected
- // is true).
- WriteIterator iter_at(uint32_t index);
-
- // Returns true if this table has been initialized.
- bool is_initialized() const;
-
- // Returns the base address of this table.
- Address base() const;
-
- // Allocate a new segment in this table.
- //
- // The segment is initialized with freelist entries.
- std::pair<Segment, FreelistHead> AllocateAndInitializeSegment();
- // Same as above but fails if there is no space left.
- std::optional<std::pair<Segment, FreelistHead>>
- TryAllocateAndInitializeSegment();
- std::optional<Segment> TryAllocateSegment();
- std::optional<Segment> TryGetSegmentFromPool();
- std::optional<Segment> FillSegmentsPool(bool return_a_segment);
-
- // Initialize a table segment with a freelist.
- //
- // Note that you don't need to call this function on segments allocated with
- // `AllocateAndInitializeSegment()` since those already get initialized.
- FreelistHead InitializeFreeList(Segment segment, uint32_t start_offset = 0);
-
- // Free the specified segment of this table.
- //
- // The memory of this segment will afterwards be inaccessible.
- void FreeTableSegment(Segment segment);
-
- // Initializes the table by reserving the backing memory, allocating an
- // initial segment, and populating the freelist.
- void Initialize();
-
- // Deallocates all memory associated with this table.
- void TearDown();
-
- // The pointer to the base of the virtual address space backing this table.
- // All entry accesses happen through this pointer.
- // It is equivalent to |vas_->base()| and is effectively const after
- // initialization since the backing memory is never reallocated.
- Entry* base_ = nullptr;
-
- // The virtual address space backing this table.
- // This is used to manage the underlying OS pages, in particular to allocate
- // and free the segments that make up the table.
- VirtualAddressSpace* vas_ = nullptr;
-
- // The segment pool contains allocated but not yet initialized pages. It is
- // only used in combination with VirtualAddressSubSpaces. The pool reduces
- // lock-contention on startup. Since we split allocations into smaller
- // segments it takes less time to initialize the freelists.
- base::Mutex* segment_pool_grow_mutex_ = nullptr;
- std::array<std::atomic<uint32_t>, kSegmentPoolSize> segment_pool_ = {};
- // Used during set-up of read only segments.
- uint32_t read_only_segments_used_ = 0;
-};
-
-} // namespace internal
-} // namespace v8
-
-#endif // V8_COMMON_SEGMENTED_TABLE_H_
diff --git a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
index 0948612f653..00b43f29734 100644
--- a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
+++ b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.cc
@@ -357,6 +357,16 @@ void OptimizingCompileDispatcher::InstallOptimizedFunctions() {
}
}
+void OptimizingCompileDispatcher::InstallOptimizedFunctionsIfReady(
+ DirectHandle<JSFunction> function,
+ std::optional<BytecodeOffset> osr_offset) {
+ HandleScope handle_scope(isolate_);
+
+ if (output_queue_.IsJobReady(function, osr_offset)) {
+ InstallOptimizedFunctions();
+ }
+}
+
int OptimizingCompileDispatcher::InstallGeneratedBuiltins(int installed_count) {
return output_queue_.InstallGeneratedBuiltins(isolate_, installed_count);
}
@@ -481,6 +491,23 @@ OptimizingCompileOutputQueue::Dequeue() {
return job;
}
+bool OptimizingCompileOutputQueue::IsJobReady(
+ DirectHandle<JSFunction> function,
+ std::optional<BytecodeOffset> osr_offset) {
+ base::MutexGuard guard(&mutex_);
+ for (auto it = queue_.begin(); it != queue_.end(); ++it) {
+ TurbofanCompilationJob* job = *it;
+ OptimizedCompilationInfo* info = job->compilation_info();
+ if (*info->closure() == *function) {
+ if (!osr_offset ||
+ (info->is_osr() && info->osr_offset() == *osr_offset)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
size_t OptimizingCompileOutputQueue::size() const { return queue_.size(); }
bool OptimizingCompileOutputQueue::empty() const { return queue_.empty(); }
diff --git a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h
index 21a8ac76ce7..baf94a40e0b 100644
--- a/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h
+++ b/deps/v8/src/compiler-dispatcher/optimizing-compile-dispatcher.h
@@ -13,11 +13,14 @@
#include "src/base/vector.h"
#include "src/common/globals.h"
#include "src/flags/flags.h"
+#include "src/handles/handles.h"
#include "src/utils/allocation.h"
+#include "src/utils/utils.h"
namespace v8 {
namespace internal {
+class JSFunction;
class LocalHeap;
class TurbofanCompilationJob;
class RuntimeCallStats;
@@ -156,6 +159,8 @@ class OptimizingCompileOutputQueue {
public:
void Enqueue(TurbofanCompilationJob* job);
std::unique_ptr<TurbofanCompilationJob> Dequeue();
+ bool IsJobReady(DirectHandle<JSFunction> function,
+ std::optional<BytecodeOffset> osr_offset);
int InstallGeneratedBuiltins(Isolate* isolate, int installed_count);
@@ -163,7 +168,7 @@ class OptimizingCompileOutputQueue {
bool empty() const;
private:
- // Queue of recompilation tasks ready to be installed (excluding OSR).
+ // Queue of recompilation tasks ready to be installed.
std::deque<TurbofanCompilationJob*> queue_;
// Used for job based recompilation which has multiple producers on
@@ -193,6 +198,9 @@ class V8_EXPORT_PRIVATE OptimizingCompileDispatcher {
void WaitUntilCompilationJobsDone();
void InstallOptimizedFunctions();
+ void InstallOptimizedFunctionsIfReady(
+ DirectHandle<JSFunction> function,
+ std::optional<BytecodeOffset> osr_offset);
// Install generated builtins in the output queue in contiguous finalization
// order, starting with installed_count. Returns the finalization order of the
diff --git a/deps/v8/src/compiler/access-builder.cc b/deps/v8/src/compiler/access-builder.cc
index ad4c9149188..1b16c5723ff 100644
--- a/deps/v8/src/compiler/access-builder.cc
+++ b/deps/v8/src/compiler/access-builder.cc
@@ -334,8 +334,8 @@ FieldAccess AccessBuilder::ForJSFunctionFeedbackCell() {
Handle<Name>(), OptionalMapRef(),
Type::Internal(), MachineType::TaggedPointer(),
kPointerWriteBarrier, "JSFunctionFeedbackCell"};
- // The feedback cell is only set when the JSFunction is allocated, or via
- // LiveEdit, but that doesn't concern optimized code, so treat it as const.
+ // The feedback cell is only set when the JSFunction is allocated, so treat
+ // it as const.
access.is_immutable = true;
return access;
}
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 492552c9388..b729592d8b5 100644
--- a/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc
+++ b/deps/v8/src/compiler/backend/arm/instruction-selector-arm.cc
@@ -1666,6 +1666,10 @@ void InstructionSelector::VisitUint64Add128(OpIndex node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitUint64Sub128(OpIndex node) { UNIMPLEMENTED(); }
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ UNREACHABLE();
+}
+
void InstructionSelector::VisitUint32MulHigh(OpIndex node) {
auto [left, right] = Inputs<WordBinopOp>(node);
ArmOperandGenerator g(this);
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 e6f536ccbb8..627857e448f 100644
--- a/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc
+++ b/deps/v8/src/compiler/backend/arm64/code-generator-arm64.cc
@@ -1394,7 +1394,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kArchAtomicStoreWithWriteBarrier: {
DCHECK_EQ(AddressingModeField::decode(instr->opcode()), kMode_MRR);
- RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode =
+ AtomicStoreRecordWriteModeField::decode(instr->opcode());
// Indirect pointer writes must use a different opcode.
DCHECK_NE(mode, RecordWriteMode::kValueIsIndirectPointer);
Register object = i.InputRegister(0);
@@ -2818,7 +2819,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kAtomicExchangeWithWriteBarrier: {
if constexpr (COMPRESS_POINTERS_BOOL) {
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(, Register32);
- __ Add(i.OutputRegister(), i.OutputRegister(),
+ __ Orr(i.OutputRegister(), i.OutputRegister(),
kPtrComprCageBaseRegister);
} else {
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(, Register);
@@ -3369,9 +3370,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
const int lane_size = LaneSizeBits(LaneSizeField::decode(opcode));
VectorFormat format = VectorFormatFillQ(lane_size);
if (instr->InputAt(1)->IsImmediate()) {
- __ Sshr(i.OutputSimd128Register().Format(format),
- i.InputSimd128Register(0).Format(format),
- i.InputIntFromLaneSize(1, lane_size));
+ 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();
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 2a7f231ecec..a8840c9b992 100644
--- a/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc
+++ b/deps/v8/src/compiler/backend/arm64/instruction-scheduler-arm64.cc
@@ -820,158 +820,373 @@ int InstructionScheduler::GetTargetInstructionFlags(
}
int InstructionScheduler::GetInstructionLatency(const Instruction* instr) {
- // Basic latency modeling for arm64 instructions. They have been determined
- // in an empirical way.
- switch (instr->arch_opcode()) {
- case kArm64Add:
- case kArm64Add32:
- case kArm64And:
- case kArm64And32:
- case kArm64Bic:
- case kArm64Bic32:
- case kArm64Cmn:
- case kArm64Cmn32:
- case kArm64Cmp:
- case kArm64Cmp32:
- case kArm64Eon:
- case kArm64Eon32:
- case kArm64Eor:
- case kArm64Eor32:
- case kArm64Not:
- case kArm64Not32:
- case kArm64Or:
- case kArm64Or32:
- case kArm64Orn:
- case kArm64Orn32:
- case kArm64Sub:
- case kArm64Sub32:
- case kArm64Tst:
- case kArm64Tst32:
- if (instr->addressing_mode() != kMode_None) {
- return 3;
- } else {
- return 1;
- }
+ // Approximate the latencies of a modern (~2026) Cortex-A core.
+ constexpr int kDefaultScalarLatency = 1;
+ constexpr int kLongScalarLatency = 3;
+ constexpr int kVeryLongScalarLatency = 12;
+ constexpr int kScalarModLatency = kVeryLongScalarLatency + kLongScalarLatency;
+ constexpr int kScalarLoadLatency = 4;
- case kArm64Clz:
- case kArm64Clz32:
- case kArm64Sbfx:
- case kArm64Sbfx32:
- case kArm64Sxtb32:
- case kArm64Sxth32:
- case kArm64Sxtw:
- case kArm64Ubfiz:
- case kArm64Ubfiz32:
- case kArm64Sbfiz:
- case kArm64Ubfx:
- case kArm64Ubfx32:
- return 1;
+ constexpr int kDefaultScalarFPLatency = 3;
+ constexpr int kLongScalarFPLatency = 4;
+ constexpr int kScalarFPConversionLatency = 4;
+ constexpr int kCheckedScalarFPConversionLatency = 6;
+ constexpr int kVeryLongScalarFPLatency = 12;
+ constexpr int kScalarFPLoadLatency = 4;
- case kArm64Lsl:
- case kArm64Lsl32:
- case kArm64Lsr:
- case kArm64Lsr32:
- case kArm64Asr:
- case kArm64Asr32:
- case kArm64Ror:
- case kArm64Ror32:
- return 1;
-
- case kArm64LdrDecompressTaggedSigned:
- case kArm64LdrDecompressTagged:
- case kArm64LdrDecompressProtected:
- case kArm64Ldr:
- case kArm64LdrD:
- case kArm64LdrS:
- case kArm64LdrW:
- case kArm64Ldrb:
- case kArm64Ldrh:
- case kArm64Ldrsb:
- case kArm64Ldrsh:
- case kArm64Ldrsw:
- return 11;
-
- case kArm64Str:
- case kArm64StrD:
- case kArm64StrS:
- case kArm64StrW:
- case kArm64Strb:
- case kArm64Strh:
- return 1;
+#ifdef V8_ENABLE_SIMD128
+ constexpr int kDefaultSimdLatency = 2;
+ constexpr int kSimdExtractLatency = 3;
+ constexpr int kSimdMultiplyLatency = 4;
+ constexpr int kSimdReductionLatency = 4;
+ constexpr int kSimdConversionLatency = 3;
+ constexpr int kSimdConversionChainLatency = 4;
+ constexpr int kSimdPseudoMinMaxLatency = 4;
+ constexpr int kSimdBooleanReductionLatency = 6;
+ constexpr int kLongSimdLatency = 6;
+ constexpr int kVeryLongSimdLatency = 12;
+#endif // V8_ENABLE_SIMD128
+ constexpr int kSimdLoadLatency = 4;
- case kArm64Madd32:
- case kArm64Mneg32:
- case kArm64Msub32:
+ switch (instr->arch_opcode()) {
+ case kArm64Mul:
case kArm64Mul32:
- return 3;
-
case kArm64Madd:
- case kArm64Mneg:
+ case kArm64Madd32:
case kArm64Msub:
- case kArm64Mul:
- return 5;
+ case kArm64Msub32:
+ case kArm64Mneg:
+ case kArm64Mneg32:
+ case kArm64Smulh:
+ case kArm64Umulh:
+ return kLongScalarLatency;
+ case kArm64Idiv:
case kArm64Idiv32:
+ case kArm64Udiv:
case kArm64Udiv32:
- return 12;
+ return kVeryLongScalarLatency;
- case kArm64Idiv:
- case kArm64Udiv:
- return 20;
+ // Integer mod lowers to a div followed by a dependent msub.
+ case kArm64Imod:
+ case kArm64Imod32:
+ case kArm64Umod:
+ case kArm64Umod32:
+ return kScalarModLatency;
+ case kArm64Smull:
+ case kArm64Umull:
+ if (instr->InputAt(0)->IsRegister()) return kLongScalarLatency;
+#ifdef V8_ENABLE_SIMD128
+ return kSimdMultiplyLatency;
+#else
+ return kLongScalarLatency;
+#endif // V8_ENABLE_SIMD128
+
+#ifdef V8_ENABLE_SIMD128
+ case kArm64Smull2:
+ case kArm64Umull2:
+ return kSimdMultiplyLatency;
+#endif // V8_ENABLE_SIMD128
+
+ case kArm64Float16RoundDown:
+ case kArm64Float16RoundUp:
+ case kArm64Float16RoundTruncate:
+ case kArm64Float16RoundTiesEven:
+ case kArm64Float32Move:
+ case kArm64Float32MoveU32:
+ case kArm64Float32Cmp:
case kArm64Float32Add:
case kArm64Float32Sub:
- case kArm64Float64Add:
- case kArm64Float64Sub:
- return 5;
-
case kArm64Float32Abs:
- case kArm64Float32Cmp:
+ case kArm64Float32Abd:
case kArm64Float32Neg:
- case kArm64Float64Abs:
+ case kArm64Float32RoundDown:
+ case kArm64Float32Max:
+ case kArm64Float32Min:
case kArm64Float64Cmp:
+ case kArm64Float64Add:
+ case kArm64Float64Sub:
+ case kArm64Float64Max:
+ case kArm64Float64Min:
+ case kArm64Float64Abs:
+ case kArm64Float64Abd:
case kArm64Float64Neg:
- return 3;
-
- case kArm64Float32Div:
- case kArm64Float32Sqrt:
- return 12;
-
- case kArm64Float64Div:
- case kArm64Float64Sqrt:
- return 19;
-
- case kArm64Float32RoundDown:
- case kArm64Float32RoundTiesEven:
- case kArm64Float32RoundTruncate:
- case kArm64Float32RoundUp:
case kArm64Float64RoundDown:
+ case kArm64Float32RoundUp:
+ case kArm64Float64RoundUp:
case kArm64Float64RoundTiesAway:
- case kArm64Float64RoundTiesEven:
+ case kArm64Float32RoundTruncate:
case kArm64Float64RoundTruncate:
- case kArm64Float64RoundUp:
- return 5;
-
+ case kArm64Float32RoundTiesEven:
+ case kArm64Float64RoundTiesEven:
+ case kArm64Float64SilenceNaN:
case kArm64Float32ToFloat64:
case kArm64Float64ToFloat32:
+ case kArm64Float64ExtractLowWord32:
+ case kArm64Float64ExtractHighWord32:
+ case kArm64Float64InsertLowWord32:
+ case kArm64Float64InsertHighWord32:
+ case kArm64Float64Move:
+ case kArm64Float64MoveU64:
+ case kArm64U64MoveFloat64:
+ return kDefaultScalarFPLatency;
+
case kArm64Float64ToFloat16RawBits:
case kArm64Float16RawBitsToFloat64:
+ case kArm64Float32ToInt32:
case kArm64Float64ToInt32:
+ case kArm64Float32ToUint32:
case kArm64Float64ToUint32:
case kArm64Float32ToInt64:
case kArm64Float64ToInt64:
case kArm64Float32ToUint64:
case kArm64Float64ToUint64:
+ case kArm64Int32ToFloat32:
case kArm64Int32ToFloat64:
case kArm64Int64ToFloat32:
case kArm64Int64ToFloat64:
+ case kArm64Uint32ToFloat32:
case kArm64Uint32ToFloat64:
case kArm64Uint64ToFloat32:
case kArm64Uint64ToFloat64:
- return 5;
+ // Some FP/int conversions emit overflow checks or overflow fixups after
+ // the conversion. Cost those as a short dependent chain.
+ return instr->OutputCount() > 1 || instr->misc()
+ ? kCheckedScalarFPConversionLatency
+ : kScalarFPConversionLatency;
+
+ case kArm64Float32Mul:
+ case kArm64Float32Fnmul:
+ case kArm64Float64Mul:
+ case kArm64Float64Fnmul:
+ return kLongScalarFPLatency;
+
+ case kArm64Float32Div:
+ case kArm64Float64Div:
+ case kArm64Float32Sqrt:
+ case kArm64Float64Sqrt:
+ return kVeryLongScalarFPLatency;
+
+ // Float64Mod calls the C++ helper sequence rather than emitting one FP
+ // arithmetic instruction.
+ case kArm64Float64Mod:
+ return kVeryLongScalarFPLatency;
+
+#ifdef V8_ENABLE_SIMD128
+ case kArm64S128Const:
+ case kArm64S128And:
+ case kArm64S128Or:
+ case kArm64S128Xor:
+ case kArm64S128Not:
+ case kArm64S128Select:
+ case kArm64S128AndNot:
+ case kArm64S128OrNot:
+ case kArm64S128Dup:
+ case kArm64S128Rev16:
+ case kArm64S128Rev32:
+ case kArm64S128Rev64:
+ case kArm64S128ZipLeft:
+ case kArm64S128ZipRight:
+ case kArm64S128UnzipLeft:
+ case kArm64S128UnzipRight:
+ case kArm64S128TransposeLeft:
+ case kArm64S128TransposeRight:
+ case kArm64S128LowZipRight:
+ case kArm64S128LowUnzipLeft:
+ case kArm64S128LowUnzipRight:
+ case kArm64Ssra:
+ case kArm64Usra:
+ case kArm64S128ExtractNarrow:
+ case kArm64S128MoveLane:
+ case kArm64S128MoveReg:
+ case kArm64Sxtl:
+ case kArm64Sxtl2:
+ case kArm64Uxtl:
+ case kArm64Uxtl2:
+ case kArm64FSplat:
+ case kArm64FAbs:
+ case kArm64FNeg:
+ case kArm64ISplat:
+ case kArm64IAbs:
+ case kArm64INeg:
+ case kArm64IShl:
+ case kArm64IShll:
+ case kArm64IShrS:
+ case kArm64IShrU:
+ case kArm64FAdd:
+ case kArm64FSub:
+ case kArm64FMin:
+ case kArm64FMax:
+ case kArm64FEq:
+ case kArm64FNe:
+ case kArm64FLt:
+ case kArm64FLe:
+ case kArm64FGt:
+ case kArm64FGe:
+ case kArm64IAdd:
+ case kArm64ISub:
+ case kArm64IEq:
+ case kArm64INe:
+ case kArm64IGtS:
+ case kArm64IGeS:
+ case kArm64ILtS:
+ case kArm64ILeS:
+ case kArm64IMinS:
+ case kArm64IMaxS:
+ case kArm64IMinU:
+ case kArm64IMaxU:
+ case kArm64IGtU:
+ case kArm64IGeU:
+ case kArm64IAddSatS:
+ case kArm64ISubSatS:
+ case kArm64IAddSatU:
+ case kArm64ISubSatU:
+ case kArm64RoundingAverageU:
+ case kArm64Saddw:
+ case kArm64Saddw2:
+ case kArm64Uaddw:
+ case kArm64Uaddw2:
+ case kArm64Saddl:
+ case kArm64Saddl2:
+ case kArm64Uaddl:
+ case kArm64Uaddl2:
+ case kArm64Ssubw:
+ case kArm64Ssubw2:
+ case kArm64Usubw:
+ case kArm64Usubw2:
+ case kArm64Ssubl:
+ case kArm64Ssubl2:
+ case kArm64Usubl:
+ case kArm64Usubl2:
+ case kArm64Bcax:
+ case kArm64Eor3:
+ case kArm64Xar:
+ return kDefaultSimdLatency;
+
+ // pmin/pmax lower to compare plus bitselect.
+ case kArm64Pmin:
+ case kArm64Pmax:
+ return kSimdPseudoMinMaxLatency;
+
+ case kArm64S128Extract:
+ case kArm64FExtractLane:
+ case kArm64FReplaceLane:
+ case kArm64IExtractLane:
+ case kArm64IExtractLaneU:
+ case kArm64IExtractLaneS:
+ case kArm64IReplaceLane:
+ return kSimdExtractLatency;
+
+ case kArm64IMul:
+ case kArm64I16x8Q15MulRSatS:
+ case kArm64FMul:
+ case kArm64FMulElement:
+ case kArm64Ffma:
+ case kArm64Ffms:
+ case kArm64Smlal:
+ case kArm64Smlal2:
+ case kArm64Umlal:
+ case kArm64Umlal2:
+ case kArm64Mla:
+ case kArm64Mls:
+ case kArm64I32x4DotI8x16AddS:
+ return kSimdMultiplyLatency;
+
+ case kArm64IAddv:
+ case kArm64IAddp:
+ case kArm64IAddpScalar:
+ case kArm64FAddp:
+ case kArm64FAddpScalar:
+ case kArm64Sadalp:
+ case kArm64Saddlp:
+ case kArm64Uadalp:
+ case kArm64Uaddlp:
+ return kSimdReductionLatency;
+
+ // These boolean reductions emit a reduction, scalar move, compare and set.
+ case kArm64V128AnyTrue:
+ case kArm64AllTrue:
+ return kSimdBooleanReductionLatency;
+
+ case kArm64F16x8SConvertI16x8:
+ case kArm64F16x8UConvertI16x8:
+ case kArm64I16x8UConvertF16x8:
+ case kArm64I16x8SConvertF16x8:
+ case kArm64F16x8DemoteF32x4Zero:
+ case kArm64F32x4PromoteLowF16x8:
+ case kArm64F64x2PromoteLowF32x4:
+ case kArm64F32x4SConvertI32x4:
+ case kArm64F32x4UConvertI32x4:
+ case kArm64F32x4DemoteF64x2Zero:
+ case kArm64I32x4SConvertF32x4:
+ case kArm64I32x4UConvertF32x4:
+ return kSimdConversionLatency;
+
+ // These widen/narrow around the conversion, forming a short dependent
+ // sequence instead of a single conversion instruction.
+ case kArm64F64x2ConvertLowI32x4S:
+ case kArm64F64x2ConvertLowI32x4U:
+ return kSimdConversionChainLatency;
+
+ case kArm64I8x16UConvertI16x8:
+ case kArm64I8x16SConvertI16x8:
+ case kArm64I16x8SConvertI32x4:
+ case kArm64I16x8UConvertI32x4:
+ case kArm64I32x4TruncSatF64x2SZero:
+ case kArm64I32x4TruncSatF64x2UZero:
+ case kArm64F16x8DemoteF64x2Zero:
+ case kArm64I32x4BitMask:
+ case kArm64I64x2BitMask:
+ case kArm64I8x16Swizzle:
+ case kArm64S32x4Shuffle:
+ case kArm64I8x16Shuffle:
+ return kLongSimdLatency;
+
+ case kArm64FSqrt:
+ case kArm64FDiv:
+ return kVeryLongSimdLatency;
+
+ // These are lowered, in the macroassembler, to several instructions.
+ case kArm64I16x8BitMask:
+ case kArm64I8x16BitMask:
+ return kVeryLongSimdLatency;
+
+ case kArm64LoadSplat:
+ case kArm64LoadLane:
+ return kSimdLoadLatency + 1;
+ case kArm64S128LoadPairDeinterleave:
+ return kSimdLoadLatency + 3;
+#endif // V8_ENABLE_SIMD128
+
+ case kArm64Ldrb:
+ case kArm64Ldrsb:
+ case kArm64LdrsbW:
+ case kArm64Ldrh:
+ case kArm64Ldrsh:
+ case kArm64LdrshW:
+ case kArm64Ldrsw:
+ case kArm64LdrW:
+ case kArm64Ldr:
+ case kArm64LdrDecompressTaggedSigned:
+ case kArm64LdrDecompressTagged:
+ case kArm64LdrDecompressProtected:
+ case kArm64LdarDecompressTaggedSigned:
+ case kArm64LdarDecompressTagged:
+ case kArm64LdrDecodeSandboxedPointer:
+ case kArm64Peek:
+ return kScalarLoadLatency;
+
+ case kArm64LdrH:
+ case kArm64LdrS:
+ case kArm64LdrD:
+ return kScalarFPLoadLatency;
+
+ case kArm64LdrQ:
+ return kSimdLoadLatency;
default:
- return 2;
+ return kDefaultScalarLatency;
}
}
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 19bea28c0fe..24d079ce524 100644
--- a/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc
+++ b/deps/v8/src/compiler/backend/arm64/instruction-selector-arm64.cc
@@ -1545,375 +1545,62 @@ void InstructionSelector::VisitUnalignedStore(OpIndex node) { UNREACHABLE(); }
namespace turboshaft {
-class CompareSequence {
- public:
- void InitialCompare(OpIndex op, OpIndex l, OpIndex r,
- RegisterRepresentation rep) {
- DCHECK(!HasCompare());
- cmp_ = op;
- left_ = l;
- right_ = r;
- opcode_ = GetOpcode(rep);
- }
- bool HasCompare() const { return cmp_.valid(); }
- OpIndex cmp() const { return cmp_; }
- OpIndex left() const { return left_; }
- OpIndex right() const { return right_; }
- InstructionCode opcode() const { return opcode_; }
- uint32_t num_ccmps() const { return num_ccmps_; }
- FlagsContinuation::compare_chain_t& ccmps() { return ccmps_; }
- void AddConditionalCompare(RegisterRepresentation rep,
- FlagsCondition ccmp_condition,
- FlagsCondition default_flags, OpIndex ccmp_lhs,
- OpIndex ccmp_rhs) {
- InstructionCode code = GetOpcode(rep);
- ccmps_.at(num_ccmps_) = FlagsContinuation::ConditionalCompare{
- code, ccmp_condition, default_flags, ccmp_lhs, ccmp_rhs};
- ++num_ccmps_;
- }
- bool IsFloatCmp() const {
- return opcode() == kArm64Float32Cmp || opcode() == kArm64Float64Cmp;
- }
-
- private:
- InstructionCode GetOpcode(RegisterRepresentation rep) const {
- switch (rep.MapTaggedToWord().value()) {
- case RegisterRepresentation::Word32():
- return kArm64Cmp32;
- case RegisterRepresentation::Word64():
- return kArm64Cmp;
- case RegisterRepresentation::Float32():
- return kArm64Float32Cmp;
- case RegisterRepresentation::Float64():
- return kArm64Float64Cmp;
- default:
- UNREACHABLE();
- }
- }
-
- OpIndex cmp_;
- OpIndex left_;
- OpIndex right_;
- InstructionCode opcode_;
- FlagsContinuation::compare_chain_t ccmps_;
- uint32_t num_ccmps_ = 0;
-};
-
-class CompareChainNode final : public ZoneObject {
- public:
- enum class NodeKind : uint8_t { kFlagSetting, kLogicalCombine };
-
- explicit CompareChainNode(OpIndex n, FlagsCondition condition)
- : node_kind_(NodeKind::kFlagSetting),
- user_condition_(condition),
- node_(n) {}
-
- explicit CompareChainNode(OpIndex n, CompareChainNode* l, CompareChainNode* r)
- : node_kind_(NodeKind::kLogicalCombine), node_(n), lhs_(l), rhs_(r) {
- // Canonicalise the chain with cmps on the right.
- if (lhs_->IsFlagSetting() && !rhs_->IsFlagSetting()) {
- std::swap(lhs_, rhs_);
- }
- }
- void SetCondition(FlagsCondition condition) {
- DCHECK(IsLogicalCombine());
- user_condition_ = condition;
- if (requires_negation_) {
- NegateFlags();
- }
- }
- void MarkRequiresNegation() {
- if (IsFlagSetting()) {
- NegateFlags();
- } else {
- requires_negation_ = !requires_negation_;
- }
- }
- void NegateFlags() {
- user_condition_ = NegateFlagsCondition(user_condition_);
- requires_negation_ = false;
- }
- bool IsLegalFirstCombine() const {
- DCHECK(IsLogicalCombine());
- // We need two cmps feeding the first logic op.
- return lhs_->IsFlagSetting() && rhs_->IsFlagSetting();
- }
- bool IsFlagSetting() const { return node_kind_ == NodeKind::kFlagSetting; }
- bool IsLogicalCombine() const {
- return node_kind_ == NodeKind::kLogicalCombine;
- }
- OpIndex node() const { return node_; }
- FlagsCondition user_condition() const { return user_condition_; }
- CompareChainNode* lhs() const {
- DCHECK(IsLogicalCombine());
- return lhs_;
- }
- CompareChainNode* rhs() const {
- DCHECK(IsLogicalCombine());
- return rhs_;
+using compare_chain::CompareChainNode;
+using compare_chain::CompareSequence;
+
+static InstructionCode Arm64GetCmpOpcode(RegisterRepresentation rep,
+ bool is_test) {
+ DCHECK(!is_test); // ARM64 doesn't use TEST pattern in compare chains.
+ switch (rep.MapTaggedToWord().value()) {
+ case RegisterRepresentation::Word32():
+ return kArm64Cmp32;
+ case RegisterRepresentation::Word64():
+ return kArm64Cmp;
+ case RegisterRepresentation::Float32():
+ return kArm64Float32Cmp;
+ case RegisterRepresentation::Float64():
+ return kArm64Float64Cmp;
+ default:
+ UNREACHABLE();
}
+}
- private:
- NodeKind node_kind_;
- FlagsCondition user_condition_;
- bool requires_negation_ = false;
- OpIndex node_;
- CompareChainNode* lhs_ = nullptr;
- CompareChainNode* rhs_ = nullptr;
-};
-
-static std::optional<FlagsCondition> GetFlagsCondition(
- OpIndex node, InstructionSelector* selector) {
- if (const ComparisonOp* comparison =
- selector->Get(node).TryCast<ComparisonOp>()) {
- if (comparison->rep == RegisterRepresentation::Word32() ||
- comparison->rep == RegisterRepresentation::Word64() ||
- comparison->rep == RegisterRepresentation::Tagged()) {
- switch (comparison->kind) {
- case ComparisonOp::Kind::kEqual:
- return FlagsCondition::kEqual;
- case ComparisonOp::Kind::kSignedLessThan:
- return FlagsCondition::kSignedLessThan;
- case ComparisonOp::Kind::kSignedLessThanOrEqual:
- return FlagsCondition::kSignedLessThanOrEqual;
- case ComparisonOp::Kind::kUnsignedLessThan:
- return FlagsCondition::kUnsignedLessThan;
- case ComparisonOp::Kind::kUnsignedLessThanOrEqual:
- return FlagsCondition::kUnsignedLessThanOrEqual;
- default:
- UNREACHABLE();
- }
- } else if (comparison->rep == RegisterRepresentation::Float32() ||
- comparison->rep == RegisterRepresentation::Float64()) {
- switch (comparison->kind) {
- case ComparisonOp::Kind::kEqual:
- return FlagsCondition::kEqual;
- case ComparisonOp::Kind::kSignedLessThan:
- return FlagsCondition::kFloatLessThan;
- case ComparisonOp::Kind::kSignedLessThanOrEqual:
- return FlagsCondition::kFloatLessThanOrEqual;
- default:
- UNREACHABLE();
- }
- }
- }
- return std::nullopt;
+static bool IsFloatCmp(InstructionCode opcode) {
+ return opcode == kArm64Float32Cmp || opcode == kArm64Float64Cmp;
}
-// Search through AND, OR and comparisons.
-// To make life a little easier, we currently don't handle combining two logic
-// operations. There are restrictions on what logical combinations can be
-// performed with ccmp, so this implementation builds a ccmp chain from the LHS
-// of the tree while combining one more compare from the RHS at each step. So,
-// currently, if we discover a pattern like this:
-// logic(logic(cmp, cmp), logic(cmp, cmp))
-// The search will fail from the outermost logic operation, but it will succeed
-// for the two inner operations. This will result in, suboptimal, codegen:
-// cmp
-// ccmp
-// cset x
-// cmp
-// ccmp
-// cset y
-// logic x, y
-static std::optional<CompareChainNode*> FindCompareChain(
- OpIndex user, OpIndex node, InstructionSelector* selector, Zone* zone,
- ZoneVector<CompareChainNode*>& nodes) {
- const Operation& op = selector->Get(node);
- if (op.Is<Opmask::kWord32BitwiseAnd>() || op.Is<Opmask::kWord32BitwiseOr>()) {
- const WordBinopOp& binop = op.Cast<WordBinopOp>();
- auto maybe_lhs =
- FindCompareChain(node, binop.left(), selector, zone, nodes);
- auto maybe_rhs =
- FindCompareChain(node, binop.right(), selector, zone, nodes);
- if (maybe_lhs.has_value() && maybe_rhs.has_value()) {
- CompareChainNode* lhs = maybe_lhs.value();
- CompareChainNode* rhs = maybe_rhs.value();
- // Ensure we don't try to combine a logic operation with two logic inputs.
- if (lhs->IsFlagSetting() || rhs->IsFlagSetting()) {
- nodes.push_back(std::move(zone->New<CompareChainNode>(node, lhs, rhs)));
- return nodes.back();
- }
- }
- // Ensure we remove any valid sub-trees that now cannot be used.
- nodes.clear();
- return std::nullopt;
- } else if (user.valid() && selector->CanCover(user, node)) {
- std::optional<FlagsCondition> user_condition =
- GetFlagsCondition(node, selector);
- if (!user_condition.has_value()) {
- return std::nullopt;
- }
- const ComparisonOp& comparison = selector->Cast<ComparisonOp>(node);
- if (comparison.kind == ComparisonOp::Kind::kEqual &&
- selector->MatchIntegralZero(comparison.right())) {
- auto maybe_negated =
- FindCompareChain(node, comparison.left(), selector, zone, nodes);
- if (maybe_negated.has_value()) {
- CompareChainNode* negated = maybe_negated.value();
- negated->MarkRequiresNegation();
- return negated;
- }
- }
- return zone->New<CompareChainNode>(node, user_condition.value());
+// ARM64-specific: ccmp has a much smaller immediate range (5-bit) than cmp
+// (12-bit), so swap the initial cmp/ccmp pair if the ccmp operand's immediate
+// could be used by cmp but not by ccmp.
+static void Arm64AdjustInitialOrder(const CompareChainNode*& lhs,
+ const CompareChainNode*& rhs,
+ InstructionSelector* selector) {
+ Arm64OperandGenerator g(selector);
+ OpIndex cmp_right = selector->Get(lhs->node()).input(1);
+ OpIndex ccmp_right = selector->Get(rhs->node()).input(1);
+ if (g.CanBeImmediate(cmp_right, kConditionalCompareImm) &&
+ !g.CanBeImmediate(ccmp_right, kConditionalCompareImm)) {
+ // If the ccmp could use the cmp immediate, swap them.
+ std::swap(lhs, rhs);
+ } else if (g.CanBeImmediate(ccmp_right, kArithmeticImm) &&
+ !g.CanBeImmediate(ccmp_right, kConditionalCompareImm)) {
+ // If the ccmp can't use its immediate, but a cmp could, swap them.
+ std::swap(lhs, rhs);
}
- return std::nullopt;
}
-// Overview -------------------------------------------------------------------
-//
-// A compare operation will generate a 'user condition', which is the
-// FlagCondition of the opcode. For this algorithm, we generate the default
-// flags from the LHS of the logic op, while the RHS is used to predicate the
-// new ccmp. Depending on the logical user, those conditions are either used
-// as-is or negated:
-// > For OR, the generated ccmp will negate the LHS condition for its predicate
-// while the default flags are taken from the RHS.
-// > For AND, the generated ccmp will take the LHS condition for its predicate
-// while the default flags are a negation of the RHS.
-//
-// The new ccmp will now generate a user condition of its own, and this is
-// always forwarded from the RHS.
-//
-// Chaining compares, including with OR, needs to be equivalent to combining
-// all the results with AND, and NOT.
-//
-// AND Example ----------------------------------------------------------------
-//
-// cmpA cmpB
-// | |
-// condA condB
-// | |
-// --- AND ---
-//
-// As the AND becomes the ccmp, it is predicated on condA and the cset is
-// predicated on condB. The user of the ccmp is always predicated on the
-// condition from the RHS of the logic operation. The default flags are
-// not(condB) so cset only produces one when both condA and condB are true:
-// cmpA
-// ccmpB not(condB), condA
-// cset condB
-//
-// OR Example -----------------------------------------------------------------
-//
-// cmpA cmpB
-// | |
-// condA condB
-// | |
-// --- OR ---
-//
-// cmpA cmpB
-// equivalent -> | |
-// not(condA) not(condB)
-// | |
-// ----- AND -----
-// |
-// NOT
-//
-// In this case, the input conditions to the AND (the ccmp) have been negated
-// so the user condition and default flags have been negated compared to the
-// previous example. The cset still uses condB because it is negated twice:
-// cmpA
-// ccmpB condB, not(condA)
-// cset condB
-//
-// Combining AND and OR -------------------------------------------------------
-//
-// cmpA cmpB cmpC
-// | | |
-// condA condB condC
-// | | |
-// --- AND --- |
-// | |
-// OR -----------
-//
-// equivalent -> cmpA cmpB cmpC
-// | | |
-// condA condB not(condC)
-// | | |
-// --- AND --- |
-// | |
-// NOT |
-// | |
-// AND -------------
-// |
-// NOT
-//
-// For this example the 'user condition', coming out, of the first ccmp is
-// condB but it is negated as the input predicate for the next ccmp as that
-// one is performing an OR:
-// cmpA
-// ccmpB not(condB), condA
-// ccmpC condC, not(condB)
-// cset condC
-//
-void CombineFlagSettingOps(CompareChainNode* logic_node,
- InstructionSelector* selector,
- CompareSequence* sequence) {
- const CompareChainNode* lhs = logic_node->lhs();
- const CompareChainNode* rhs = logic_node->rhs();
-
+// ARM64-specific: swap ccmp lhs/rhs if lhs is a small immediate so it can
+// be encoded as an immediate operand.
+static void Arm64AdjustCcmpOperands(OpIndex& ccmp_lhs, OpIndex& ccmp_rhs,
+ FlagsCondition& user_condition,
+ FlagsCondition& default_flags,
+ InstructionSelector* selector) {
Arm64OperandGenerator g(selector);
- if (!sequence->HasCompare()) {
- // This is the beginning of the conditional compare chain.
- DCHECK(lhs->IsFlagSetting());
- DCHECK(rhs->IsFlagSetting());
-
- {
- // ccmp has a much smaller immediate range than cmp, so swap the
- // operations if possible.
- OpIndex cmp = lhs->node();
- OpIndex ccmp = rhs->node();
- const Operation& cmp_op = selector->Get(cmp);
- const Operation& ccmp_op = selector->Get(ccmp);
- OpIndex cmp_right = cmp_op.input(1);
- OpIndex ccmp_right = ccmp_op.input(1);
- if (g.CanBeImmediate(cmp_right, kConditionalCompareImm) &&
- !g.CanBeImmediate(ccmp_right, kConditionalCompareImm)) {
- // If the ccmp could use the cmp immediate, swap them.
- std::swap(lhs, rhs);
- } else if (g.CanBeImmediate(ccmp_right, kArithmeticImm) &&
- !g.CanBeImmediate(ccmp_right, kConditionalCompareImm)) {
- // If the ccmp can't use its immediate, but a cmp could, swap them.
- std::swap(lhs, rhs);
- }
- }
- OpIndex cmp = lhs->node();
- const ComparisonOp& cmp_op = selector->Cast<ComparisonOp>(cmp);
-
- // Initialize chain with the compare which will hold the continuation.
- sequence->InitialCompare(cmp, cmp_op.left(), cmp_op.right(), cmp_op.rep);
- }
-
- bool is_logical_or =
- selector->Get(logic_node->node()).Is<Opmask::kWord32BitwiseOr>();
- FlagsCondition ccmp_condition =
- is_logical_or ? NegateFlagsCondition(lhs->user_condition())
- : lhs->user_condition();
- FlagsCondition default_flags =
- is_logical_or ? rhs->user_condition()
- : NegateFlagsCondition(rhs->user_condition());
-
- // We canonicalise the chain so that the rhs is always a cmp, whereas lhs
- // will either be the initial cmp or the previous logic, now ccmp, op and
- // only provides ccmp_condition.
- FlagsCondition user_condition = rhs->user_condition();
- OpIndex ccmp = rhs->node();
- const ComparisonOp& ccmp_op = selector->Cast<ComparisonOp>(ccmp);
- OpIndex ccmp_lhs = ccmp_op.left();
- OpIndex ccmp_rhs = ccmp_op.right();
-
- // Switch ccmp lhs/rhs if lhs is a small immediate.
if (g.CanBeImmediate(ccmp_lhs, kConditionalCompareImm)) {
user_condition = CommuteFlagsCondition(user_condition);
default_flags = CommuteFlagsCondition(default_flags);
std::swap(ccmp_lhs, ccmp_rhs);
}
-
- sequence->AddConditionalCompare(ccmp_op.rep, ccmp_condition, default_flags,
- ccmp_lhs, ccmp_rhs);
- // Ensure the user_condition is kept up-to-date for the next ccmp/cset.
- logic_node->SetCondition(user_condition);
}
static void VisitCompareChain(InstructionSelector* selector, OpIndex left_node,
@@ -1972,44 +1659,15 @@ static bool TryMatchConditionalCompareChain(InstructionSelector* selector,
if (!cont->IsBranch() && !cont->IsTrap()) return false;
DCHECK(cont->condition() == kNotEqual || cont->condition() == kEqual);
- // Instead of:
- // cmp x0, y0
- // cset cc0
- // cmp x1, y1
- // cset cc1
- // and/orr
- // Try to merge logical combinations of flags into:
- // cmp x0, y0
- // ccmp x1, y1 ..
- // cset ..
- // So, for AND:
- // (cset cc1 (ccmp x1 y1 !cc1 cc0 (cmp x0, y0)))
- // and for ORR:
- // (cset cc1 (ccmp x1 y1 cc1 !cc0 (cmp x0, y0))
-
- // Look for a potential chain.
- ZoneVector<CompareChainNode*> logic_nodes(zone);
- auto root =
- FindCompareChain(OpIndex::Invalid(), node, selector, zone, logic_nodes);
- if (!root.has_value()) return false;
-
- if (logic_nodes.size() > FlagsContinuation::kMaxCompareChainSize) {
- return false;
- }
- if (!logic_nodes.front()->IsLegalFirstCombine()) {
- return false;
- }
-
CompareSequence sequence;
- for (CompareChainNode* logic_node : logic_nodes) {
- CombineFlagSettingOps(logic_node, selector, &sequence);
+ FlagsCondition condition;
+ if (!compare_chain::TryBuildConditionalCompareChain(
+ selector, zone, node, cont, &sequence, &condition, Arm64GetCmpOpcode,
+ /*supports_float_cmp=*/true, /*supports_test_pattern=*/false,
+ Arm64AdjustInitialOrder, Arm64AdjustCcmpOperands)) {
+ return false;
}
- DCHECK_LE(sequence.num_ccmps(), FlagsContinuation::kMaxCompareChainSize);
- FlagsCondition final_cond = logic_nodes.back()->user_condition();
- FlagsCondition condition = cont->condition() == kNotEqual
- ? final_cond
- : NegateFlagsCondition(final_cond);
FlagsContinuation new_cont =
cont->IsBranch() ? FlagsContinuation::ForConditionalBranch(
sequence.ccmps(), sequence.num_ccmps(), condition,
@@ -2019,7 +1677,7 @@ static bool TryMatchConditionalCompareChain(InstructionSelector* selector,
cont->trap_id());
ImmediateMode imm_mode =
- sequence.IsFloatCmp() ? kNoImmediate : kArithmeticImm;
+ IsFloatCmp(sequence.opcode()) ? kNoImmediate : kArithmeticImm;
VisitCompareChain(selector, sequence.left(), sequence.right(),
selector->Get(sequence.cmp()).Cast<ComparisonOp>().rep,
sequence.opcode(), imm_mode, &new_cont);
@@ -2029,6 +1687,33 @@ static bool TryMatchConditionalCompareChain(InstructionSelector* selector,
} // end namespace turboshaft
+// Per-arch ccmp cascade hooks (driven by TryCascadeCcmpFuseOrEmit in
+// instruction-selector.cc). ccmp is native on ARM64, so always available.
+bool InstructionSelector::SupportsCcmpBranchCascade() const { return true; }
+
+bool InstructionSelector::CcmpCascadeConstantOk(OpIndex node,
+ bool is_ccmp_operand) {
+ // Gate on the range each operand is actually emitted with: ccmp's immediate
+ // range is much narrower than cmp's. A constant in between would be emitted
+ // as a register by VisitCompareChain, but the now-dead fused block never
+ // materializes it (use without a definition).
+ Arm64OperandGenerator g(this);
+ return g.CanBeImmediate(
+ node, is_ccmp_operand ? kConditionalCompareImm : kArithmeticImm);
+}
+
+InstructionCode InstructionSelector::CcmpCmpOpcode(
+ RegisterRepresentation rep) const {
+ return Arm64GetCmpOpcode(rep, /*is_test=*/false);
+}
+
+void InstructionSelector::EmitCcmpCompareChain(
+ compare_chain::CompareSequence& sequence, RegisterRepresentation rep,
+ FlagsContinuation* cont) {
+ VisitCompareChain(this, sequence.left(), sequence.right(), rep,
+ sequence.opcode(), kArithmeticImm, cont);
+}
+
static void VisitLogical(InstructionSelector* selector, Zone* zone,
OpIndex node, WordRepresentation rep,
ArchOpcode opcode, bool left_can_cover,
@@ -2380,6 +2065,15 @@ void InstructionSelector::VisitWord64Shl(OpIndex node) {
g.UseImmediate64(shift_by));
return;
}
+ if (base::IsInRange(shift_by, 1, 31) && CanCover(node, shift_op.left())) {
+ // A bitfield insert (sbfiz/ubfiz) sign/zero-extends the low 32 bits of
+ // the input and shifts them into place in a single instruction.
+ Emit(lhs.Is<Opmask::kChangeInt32ToInt64>() ? kArm64Sbfiz : kArm64Ubfiz,
+ g.DefineAsRegister(node),
+ g.UseRegister(lhs.Cast<ChangeOp>().input()),
+ g.UseImmediate(static_cast<int32_t>(shift_by)), g.UseImmediate(32));
+ return;
+ }
}
VisitRRO(this, kArm64Lsl, node, kShift64Imm);
}
@@ -2955,6 +2649,10 @@ void InstructionSelector::VisitUint64Sub128(OpIndex node) {
VisitWideAddSub(this, node, false);
}
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ UNIMPLEMENTED();
+}
+
#if V8_ENABLE_SIMD128
namespace {
@@ -3647,10 +3345,9 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, OpIndex node,
case kSignedGreaterThanOrEqual: {
// Here we handle sign tests, aka. comparisons with zero.
if (value != 0) return false;
- // We don't generate TBZ/TBNZ for deoptimisations, as they have a
- // shorter range than conditional branches and generating them for
- // deoptimisations results in more veneers.
- if (cont->IsDeoptimize()) return false;
+ // Deoptimisations are handled like branches: TBZ/TBNZ have a shorter
+ // range than conditional branches, but deopt exits normally land
+ // within it, and the assembler veneers the rare out-of-range case.
Arm64OperandGenerator g(selector);
cont->Overwrite(MapForTbz(cond));
@@ -3682,7 +3379,8 @@ bool TryEmitCbzOrTbz(InstructionSelector* selector, OpIndex node,
// Emit a tbz/tbnz if we are comparing with a single-bit mask:
// Branch(WordEqual(WordAnd(x, 1 << N), 1 << N), true, false)
uint64_t actual_value;
- if (cont->IsBranch() && base::bits::IsPowerOfTwo(value) &&
+ if ((cont->IsBranch() || cont->IsDeoptimize()) &&
+ base::bits::IsPowerOfTwo(value) &&
selector->MatchUnsignedIntegralConstant(bitwise_and->right(),
&actual_value) &&
actual_value == value && selector->CanCover(user, node)) {
@@ -4274,13 +3972,12 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
if (write_barrier_kind == kSkippedWriteBarrier) {
code = kArchAtomicStoreSkippedWriteBarrier;
- code |= RecordWriteModeField::encode(RecordWriteMode::kValueIsAny);
temps[temp_count++] = g.TempRegister();
} else {
RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
code = kArchAtomicStoreWithWriteBarrier;
- code |= RecordWriteModeField::encode(record_write_mode);
+ code |= AtomicStoreRecordWriteModeField::encode(record_write_mode);
}
} else {
switch (rep) {
@@ -4366,10 +4063,12 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
ConsumeEqualZero(&user, &value, cont);
// Remove Word64->Word32 truncation.
+ bool needs_truncation = false;
if (V<Word64> value64;
MatchTruncateWord64ToWord32(value, &value64) && CanCover(user, value)) {
user = value;
value = value64;
+ needs_truncation = true;
}
// Try to match bit checks to create TBZ/TBNZ instructions.
@@ -4377,9 +4076,12 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
// If there are several uses of the given operation, we will generate a TBZ
// instruction for each. This is useful even if there are other uses of the
// arithmetic result, because it moves dependencies further back.
+ // Deoptimizations take this path too: their exits are laid out at the end
+ // of the code and are normally within TBZ/TBNZ range; when a function
+ // outgrows it, the assembler routes the branch through a veneer.
const Operation& value_op = Get(value);
- if (cont->IsBranch()) {
+ if (cont->IsBranch() || cont->IsDeoptimize()) {
if (value_op.Is<Opmask::kWord64Equal>()) {
const ComparisonOp& equal = value_op.Cast<ComparisonOp>();
if (MatchIntegralZero(equal.right())) {
@@ -4404,12 +4106,13 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
if (const WordBinopOp* value_binop = value_op.TryCast<WordBinopOp>()) {
TestAndBranchMatcherTurboshaft matcher(this, *value_binop);
- if (matcher.Matches()) {
+ if (matcher.Matches() && (!needs_truncation || matcher.bit() < 32)) {
// If the mask has only one bit set, we can use tbz/tbnz.
DCHECK((cont->condition() == kEqual) ||
(cont->condition() == kNotEqual));
InstructionCode opcode = value_binop->rep.MapTaggedToWord() ==
- RegisterRepresentation::Word32()
+ RegisterRepresentation::Word32() ||
+ needs_truncation
? kArm64TestAndBranch32
: kArm64TestAndBranch;
Arm64OperandGenerator gen(this);
@@ -4537,7 +4240,10 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
}
return VisitWordCompare(this, value, kArm64Tst32, cont, kLogical32Imm);
} else if (value_op.Is<Opmask::kWord64BitwiseAnd>()) {
- return VisitWordCompare(this, value, kArm64Tst, cont, kLogical64Imm);
+ InstructionCode opcode = needs_truncation ? kArm64Tst32 : kArm64Tst;
+ ImmediateMode immediate_mode =
+ needs_truncation ? kLogical32Imm : kLogical64Imm;
+ return VisitWordCompare(this, value, opcode, cont, immediate_mode);
} else if (value_op.Is<Opmask::kWord32BitwiseOr>()) {
if (TryMatchConditionalCompareChain(this, zone(), value, cont)) {
return;
@@ -4554,6 +4260,12 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
Emit(cont->Encode(kArm64CompareAndBranch32), g.NoOutput(),
g.UseRegister(value), g.Label(cont->true_block()),
g.Label(cont->false_block()));
+ } else if (cont->IsDeoptimize()) {
+ // Deoptimization checks compare-and-branch too, saving the tst:
+ // their exits are laid out at the end of the code, within cbz/cbnz
+ // range, and AssembleArchDeoptBranch assembles this pseudo
+ // instruction exactly as AssembleArchBranch does.
+ EmitWithContinuation(kArm64CompareAndBranch32, g.UseRegister(value), cont);
} else {
VisitCompare(this, cont->Encode(kArm64Tst32), g.UseRegister(value),
g.UseRegister(value), cont);
@@ -4637,12 +4349,12 @@ void InstructionSelector::VisitWord32Equal(OpIndex node) {
Arm64OperandGenerator g(this);
const RootsTable& roots_table = isolate()->roots_table();
RootIndex root_index;
- Handle<HeapObject> right;
+ Handle<HeapObject> heap_object;
// HeapConstants and CompressedHeapConstants can be treated the same when
// using them as an input to a 32-bit comparison. Check whether either is
// present.
- if (MatchHeapConstant(node, &right) && !right.is_null() &&
- roots_table.IsRootHandle(right, &root_index)) {
+ if (MatchHeapConstant(right, &heap_object) && !heap_object.is_null() &&
+ roots_table.IsRootHandle(heap_object, &root_index)) {
if (RootsTable::IsReadOnly(root_index)) {
Tagged_t ptr =
MacroAssemblerBase::ReadOnlyRootPtr(root_index, isolate());
diff --git a/deps/v8/src/compiler/backend/bitcast-elider.cc b/deps/v8/src/compiler/backend/bitcast-elider.cc
index 9ea483cc629..5796c722ae5 100644
--- a/deps/v8/src/compiler/backend/bitcast-elider.cc
+++ b/deps/v8/src/compiler/backend/bitcast-elider.cc
@@ -21,8 +21,25 @@ bool IsBitcast(Node* node) {
}
bool OwnedByWord32Op(Node* node) {
-#if V8_TARGET_ARCH_LOONG64 || V8_TARGET_ARCH_MIPS64 || V8_TARGET_ARCH_RISCV64
+#if defined(V8_TARGET_ARCH_MIPS64) || defined(V8_TARGET_ARCH_RISCV64)
return false;
+#elif defined(V8_TARGET_ARCH_LOONG64)
+ for (Node* const use : node->uses()) {
+ switch (use->opcode()) {
+ case IrOpcode::kWord32Equal:
+ case IrOpcode::kWord32Shl:
+ case IrOpcode::kWord32Shr:
+ case IrOpcode::kWord32Sar:
+ case IrOpcode::kWord32Rol:
+ case IrOpcode::kWord32Ror:
+ case IrOpcode::kInt32Add:
+ case IrOpcode::kInt32Sub:
+ break;
+ default:
+ return false;
+ }
+ }
+ return true;
#else
for (Node* const use : node->uses()) {
switch (use->opcode()) {
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 32b8743a1b4..26fd003e45c 100644
--- a/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc
+++ b/deps/v8/src/compiler/backend/ia32/code-generator-ia32.cc
@@ -1030,8 +1030,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kArchStoreWithWriteBarrier: // Fall thrugh.
case kArchAtomicStoreWithWriteBarrier: {
- RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
- AtomicMemoryOrder order = AtomicMemoryOrderField::decode(instr->opcode());
+ RecordWriteMode mode =
+ arch_opcode == kArchStoreWithWriteBarrier
+ ? RecordWriteModeField::decode(instr->opcode())
+ : AtomicStoreRecordWriteModeField::decode(instr->opcode());
Register object = i.InputRegister(0);
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
@@ -1048,11 +1050,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
auto ool = zone()->New<OutOfLineRecordWrite>(
this, object, operand, value, scratch, mode, DetermineStubCallMode());
if (arch_opcode == kArchStoreWithWriteBarrier ||
- order == AtomicMemoryOrder::kAcqRel) {
+ AtomicMemoryOrderField::decode(instr->opcode()) ==
+ AtomicMemoryOrder::kAcqRel) {
__ mov(operand, value);
} else {
DCHECK_EQ(arch_opcode, kArchAtomicStoreWithWriteBarrier);
- DCHECK_EQ(order, AtomicMemoryOrder::kSeqCst);
+ DCHECK_EQ(AtomicMemoryOrderField::decode(instr->opcode()),
+ AtomicMemoryOrder::kSeqCst);
__ mov(scratch, value);
__ xchg(scratch, operand);
}
@@ -1072,7 +1076,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Operand operand = i.MemoryOperand(&index);
Register value = i.InputRegister(index);
Register scratch = i.TempRegister(0);
- AtomicMemoryOrder order = AtomicMemoryOrderField::decode(instr->opcode());
if (v8_flags.debug_code) {
// Checking that |value| is not a cleared weakref: our write barrier
@@ -1088,11 +1091,13 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ bind(ool->exit());
if (arch_opcode == kArchStoreSkippedWriteBarrier ||
- order == AtomicMemoryOrder::kAcqRel) {
+ AtomicMemoryOrderField::decode(instr->opcode()) ==
+ AtomicMemoryOrder::kAcqRel) {
__ mov(operand, value);
} else {
DCHECK_EQ(arch_opcode, kArchAtomicStoreSkippedWriteBarrier);
- DCHECK_EQ(order, AtomicMemoryOrder::kSeqCst);
+ DCHECK_EQ(AtomicMemoryOrderField::decode(instr->opcode()),
+ AtomicMemoryOrder::kSeqCst);
__ mov(scratch, value);
__ xchg(scratch, operand);
}
@@ -3066,8 +3071,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case kIA32I8x16Popcnt: {
__ I8x16Popcnt(i.OutputSimd128Register(), i.InputSimd128Register(0),
- kScratchDoubleReg, i.TempSimd128Register(0),
- i.TempRegister(1));
+ i.TempRegister(1), kScratchDoubleReg,
+ i.TempSimd128Register(0));
break;
}
case kIA32S128Const: {
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 4d376def9d8..cd90ecc9698 100644
--- a/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc
+++ b/deps/v8/src/compiler/backend/ia32/instruction-selector-ia32.cc
@@ -1055,7 +1055,9 @@ void VisitStoreCommon(InstructionSelector* selector,
: kArchStoreWithWriteBarrier;
RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
- code |= RecordWriteModeField::encode(record_write_mode);
+ code |= is_atomic
+ ? AtomicStoreRecordWriteModeField::encode(record_write_mode)
+ : RecordWriteModeField::encode(record_write_mode);
}
code |= AddressingModeField::encode(addressing_mode);
if (atomic_order.has_value()) {
@@ -1728,6 +1730,10 @@ void InstructionSelector::VisitUint64Add128(OpIndex node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitUint64Sub128(OpIndex node) { UNIMPLEMENTED(); }
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ UNREACHABLE();
+}
+
void InstructionSelector::VisitInt32MulHigh(OpIndex node) {
VisitMulHigh(this, node, kIA32ImulHigh);
}
diff --git a/deps/v8/src/compiler/backend/instruction-selector-impl.h b/deps/v8/src/compiler/backend/instruction-selector-impl.h
index d4104a74d47..3676b15d36b 100644
--- a/deps/v8/src/compiler/backend/instruction-selector-impl.h
+++ b/deps/v8/src/compiler/backend/instruction-selector-impl.h
@@ -488,6 +488,186 @@ class OperandGenerator : public turboshaft::OperationMatcher {
InstructionSelector* selector_;
};
+// Compare chain support for conditional compare (ccmp) instruction selection.
+// Shared between ARM64 and x64 (APX) backends.
+namespace compare_chain {
+
+class CompareChainNode final : public ZoneObject {
+ public:
+ enum class NodeKind : uint8_t { kFlagSetting, kLogicalCombine };
+
+ CompareChainNode(turboshaft::OpIndex n, FlagsCondition condition,
+ bool is_test = false)
+ : node_kind_(NodeKind::kFlagSetting),
+ user_condition_(condition),
+ is_test_(is_test),
+ node_(n) {}
+
+ CompareChainNode(turboshaft::OpIndex n, CompareChainNode* l,
+ CompareChainNode* r)
+ : node_kind_(NodeKind::kLogicalCombine), node_(n), lhs_(l), rhs_(r) {
+ // Canonicalise the chain with cmps on the right.
+ if (lhs_->IsFlagSetting() && !rhs_->IsFlagSetting()) {
+ std::swap(lhs_, rhs_);
+ }
+ }
+ void SetCondition(FlagsCondition condition) {
+ DCHECK(IsLogicalCombine());
+ user_condition_ = condition;
+ if (requires_negation_) {
+ NegateFlags();
+ }
+ }
+ void MarkRequiresNegation() {
+ if (IsFlagSetting()) {
+ NegateFlags();
+ } else {
+ requires_negation_ = !requires_negation_;
+ }
+ }
+ void NegateFlags() {
+ user_condition_ = NegateFlagsCondition(user_condition_);
+ requires_negation_ = false;
+ }
+ bool IsLegalFirstCombine() const {
+ DCHECK(IsLogicalCombine());
+ // We need two cmps feeding the first logic op.
+ return lhs_->IsFlagSetting() && rhs_->IsFlagSetting();
+ }
+ bool IsFlagSetting() const { return node_kind_ == NodeKind::kFlagSetting; }
+ bool IsLogicalCombine() const {
+ return node_kind_ == NodeKind::kLogicalCombine;
+ }
+ bool IsTest() const { return is_test_; }
+ turboshaft::OpIndex node() const { return node_; }
+ FlagsCondition user_condition() const { return user_condition_; }
+ CompareChainNode* lhs() const {
+ DCHECK(IsLogicalCombine());
+ return lhs_;
+ }
+ CompareChainNode* rhs() const {
+ DCHECK(IsLogicalCombine());
+ return rhs_;
+ }
+
+ private:
+ NodeKind node_kind_;
+ FlagsCondition user_condition_;
+ bool requires_negation_ = false;
+ bool is_test_ = false;
+ turboshaft::OpIndex node_;
+ CompareChainNode* lhs_ = nullptr;
+ CompareChainNode* rhs_ = nullptr;
+};
+
+// `supports_float_cmp` indicates whether the target architecture has a
+// conditional compare that can consume floating-point comparisons (e.g.
+// ARM64's fccmp). x64 has no float ccmp and must pass false, otherwise a
+// matched float chain would reach the arch get_opcode with a Float rep and
+// hit UNREACHABLE().
+std::optional<FlagsCondition> GetFlagsCondition(turboshaft::OpIndex node,
+ InstructionSelector* selector,
+ bool supports_float_cmp);
+
+// Search through AND, OR and comparisons to find a chain of comparisons
+// that can be combined into conditional compare instructions.
+// `supports_test_pattern` indicates whether the target architecture can fold an
+// `(x & mask) == 0` comparison into a TEST-style conditional compare (x64's
+// ctest). ARM64 has no TEST in its ccmp chain and must pass false, otherwise a
+// matched TEST node would reach the arch get_opcode with is_test=true and hit
+// its DCHECK (debug) or silently emit a wrong cmp (release).
+std::optional<CompareChainNode*> FindCompareChain(
+ turboshaft::OpIndex user, turboshaft::OpIndex node,
+ InstructionSelector* selector, Zone* zone,
+ ZoneVector<CompareChainNode*>& nodes, bool supports_float_cmp,
+ bool supports_test_pattern);
+
+// Extract the operands for a flag-setting node. For TEST nodes,
+// the operands come from the inner BitwiseAnd; for CMP nodes,
+// they come directly from the ComparisonOp.
+void GetFlagSettingOperands(const CompareChainNode* node,
+ InstructionSelector* selector,
+ turboshaft::OpIndex* out_lhs,
+ turboshaft::OpIndex* out_rhs,
+ turboshaft::RegisterRepresentation* out_rep);
+
+class CompareSequence {
+ public:
+ void InitialCompare(turboshaft::OpIndex op, turboshaft::OpIndex l,
+ turboshaft::OpIndex r, InstructionCode opcode) {
+ DCHECK(!HasCompare());
+ cmp_ = op;
+ left_ = l;
+ right_ = r;
+ opcode_ = opcode;
+ }
+ bool HasCompare() const { return cmp_.valid(); }
+ turboshaft::OpIndex cmp() const { return cmp_; }
+ turboshaft::OpIndex left() const { return left_; }
+ turboshaft::OpIndex right() const { return right_; }
+ InstructionCode opcode() const { return opcode_; }
+ uint32_t num_ccmps() const { return num_ccmps_; }
+ FlagsContinuation::compare_chain_t& ccmps() { return ccmps_; }
+ void AddConditionalCompare(InstructionCode code,
+ FlagsCondition ccmp_condition,
+ FlagsCondition default_flags,
+ turboshaft::OpIndex ccmp_lhs,
+ turboshaft::OpIndex ccmp_rhs) {
+ ccmps_.at(num_ccmps_) = FlagsContinuation::ConditionalCompare{
+ code, ccmp_condition, default_flags, ccmp_lhs, ccmp_rhs};
+ ++num_ccmps_;
+ }
+
+ private:
+ turboshaft::OpIndex cmp_;
+ turboshaft::OpIndex left_;
+ turboshaft::OpIndex right_;
+ InstructionCode opcode_;
+ FlagsContinuation::compare_chain_t ccmps_;
+ uint32_t num_ccmps_ = 0;
+};
+
+using GetOpcodeFunc =
+ InstructionCode (*)(turboshaft::RegisterRepresentation rep, bool is_test);
+
+// Callback to optionally reorder the initial cmp/ccmp pair based on
+// architecture-specific immediate range constraints.
+// Called when sequence->HasCompare() is false (i.e., the first logic node).
+// May swap lhs and rhs if doing so is beneficial for immediate encoding.
+using AdjustInitialOrderFunc = void (*)(const CompareChainNode*& lhs,
+ const CompareChainNode*& rhs,
+ InstructionSelector* selector);
+
+// Callback to optionally adjust ccmp operands (e.g., swap lhs/rhs when
+// lhs fits in a smaller immediate range on ARM64).
+// Called for each conditional compare added to the chain.
+// May swap ccmp_lhs/ccmp_rhs and commute user_condition/default_flags.
+using AdjustCcmpOperandsFunc = void (*)(turboshaft::OpIndex& ccmp_lhs,
+ turboshaft::OpIndex& ccmp_rhs,
+ FlagsCondition& user_condition,
+ FlagsCondition& default_flags,
+ InstructionSelector* selector);
+
+void CombineFlagSettingOps(CompareChainNode* logic_node,
+ InstructionSelector* selector,
+ CompareSequence* sequence, GetOpcodeFunc get_opcode,
+ AdjustInitialOrderFunc adjust_initial_order,
+ AdjustCcmpOperandsFunc adjust_ccmp_operands);
+
+// Build a conditional compare chain from the given node.
+// Finds the compare chain, validates it, runs CombineFlagSettingOps on all
+// logic nodes, and computes the final condition. The caller is responsible
+// for emitting the actual instructions via an arch-specific VisitCompareChain.
+bool TryBuildConditionalCompareChain(
+ InstructionSelector* selector, Zone* zone, turboshaft::OpIndex node,
+ FlagsContinuation* cont, CompareSequence* sequence,
+ FlagsCondition* condition, GetOpcodeFunc get_opcode,
+ bool supports_float_cmp, bool supports_test_pattern,
+ AdjustInitialOrderFunc adjust_initial_order,
+ AdjustCcmpOperandsFunc adjust_ccmp_operands);
+
+} // namespace compare_chain
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/compiler/backend/instruction-selector.cc b/deps/v8/src/compiler/backend/instruction-selector.cc
index 1fb5e860f4c..e490345743c 100644
--- a/deps/v8/src/compiler/backend/instruction-selector.cc
+++ b/deps/v8/src/compiler/backend/instruction-selector.cc
@@ -93,6 +93,10 @@ InstructionSelector::InstructionSelector(
node_count_(node_count),
phi_states_(zone)
#endif
+#if V8_TARGET_ARCH_ARM64 || defined(V8_ENABLE_APX_F)
+ ,
+ ccmp_cascade_info_(zone)
+#endif
{
turboshaft_use_map_.emplace(*schedule_, zone);
trapping_loads_to_remove_.emplace(static_cast<int>(node_count), zone);
@@ -2119,7 +2123,7 @@ void InstructionSelector::VisitProjection(OpIndex node) {
MarkAsUsed(projection.input());
}
} else if (value_op.Is<Word64AddSub128BinopOp>() ||
- value_op.Is<Word64MulWideOp>()) {
+ value_op.Is<Word64MulWideOp>() || value_op.Is<Word64Add3Op>()) {
MarkAsUsed(projection.input());
} else if (value_op.Is<DidntThrowOp>()) {
// Nothing to do here?
@@ -2736,6 +2740,178 @@ void InstructionSelector::VisitRetain(OpIndex node) {
Emit(kArchNop, g.NoOutput(), g.UseAny(retain.retained()));
}
+#if V8_TARGET_ARCH_ARM64 || defined(V8_ENABLE_APX_F)
+namespace {
+// Returns the sole Goto target of `block` iff `block` contains nothing but a
+// single Goto; otherwise nullptr.
+Block* GetSingleGotoTarget(const Block* block, const Graph* graph) {
+ const Operation& first = block->FirstOperation(*graph);
+ const GotoOp* goto_op = first.TryCast<GotoOp>();
+ if (!goto_op) return nullptr;
+ DCHECK_EQ(&first, &block->LastOperation(*graph));
+ return goto_op->destination;
+}
+
+// Follows a chain of empty single-Goto blocks (edge-split pads).
+// Returns the final real target, or the direct predecessor of `stop_before`
+// on the chain if provided.
+constexpr int kMaxGotoDepth = 16;
+const Block* ResolveThroughEmptyGotos(const Block* block, const Graph* graph,
+ const Block* stop_before = nullptr) {
+ for (int depth = 0; depth < kMaxGotoDepth; ++depth) {
+ Block* next = GetSingleGotoTarget(block, graph);
+ if (!next || next == stop_before) break;
+ block = next;
+ }
+ return block;
+}
+} // namespace
+
+// Rewrites `if (x==C1) goto T1; else if (x==C2) goto T2; else goto F;` (T1/T2
+// identical or merging with matching phi inputs) into a single ccmp chain. CFG
+// analysis is arch-independent; ccmp emission goes through the per-arch hooks.
+//
+// The two branch blocks:
+// * Block A is the head block. Its branch tests `x==C1` with if_true=T1 and
+// if_false=Block B.
+// * Block B is Block A's if_false successor. Its branch tests `x==C2` with
+// if_true=T2 and if_false=F.
+//
+// Blocks are visited in reversed RPO, so Block B is visited before Block A.
+// That ordering drives the two stages, keyed on ccmp_cascade_info_:
+// * Case 1 (visiting Block B): validate the pattern, record Block A in the map
+// for Case 2 to consume, and rewrite Block B into a plain Goto to F. Block A
+// is only recorded here, not yet rewritten.
+// * Case 2 (visiting Block A): Block A is found in the map, so emit the fused
+// ccmp branch in place of Block A's original branch.
+bool InstructionSelector::TryCascadeCcmpFuseOrEmit(OpIndex node, Block* tbranch,
+ Block* fbranch) {
+ if (!SupportsCcmpBranchCascade()) return false;
+
+ const Block* block = current_block();
+ const Graph* graph = turboshaft_graph();
+
+ // Case 2: Current block is the head of a cascade (info stored by Case 1).
+ if (ccmp_cascade_info_.find(block->index().id()) !=
+ ccmp_cascade_info_.end()) {
+ EmitCascadeCcmpBranch(node);
+ return true;
+ }
+
+ // Case 1: Check if current block is the fused block (Block B).
+ if (block->PredecessorCount() != 1) return false;
+
+ const Block* block_a = block->LastPredecessor();
+
+ const Operation& a_last_op = block_a->LastOperation(*graph);
+ const BranchOp* branch_a = a_last_op.TryCast<BranchOp>();
+ if (!branch_a) return false;
+ if (branch_a->if_false != block) return false;
+
+ const BranchOp& branch_b = Cast<BranchOp>(node);
+
+ const ComparisonOp* cmp_a =
+ graph->Get(branch_a->condition()).TryCast<Opmask::kWord32Equal>();
+ const ComparisonOp* cmp_b =
+ graph->Get(branch_b.condition()).TryCast<Opmask::kWord32Equal>();
+ if (!cmp_a || !cmp_b) return false;
+ if (cmp_a->left() != cmp_b->left()) return false;
+
+ // Both comparisons must be exclusively used by their branch.
+ // If a comparison has other users (e.g. deoptimization frame states),
+ // the CCMP chain won't materialize the boolean result those users need.
+ if (!cmp_a->saturated_use_count.Is(1)) return false;
+ if (!cmp_b->saturated_use_count.Is(1)) return false;
+
+ // Only fuse when both RHS constants are cheap immediates. cmp_a is the
+ // initial compare, cmp_b the fused ccmp (tighter immediate range).
+ if (!CcmpCascadeConstantOk(cmp_a->right(), /*is_ccmp_operand=*/false)) {
+ return false;
+ }
+ if (!CcmpCascadeConstantOk(cmp_b->right(), /*is_ccmp_operand=*/true)) {
+ return false;
+ }
+
+ Block* t1 = branch_a->if_true;
+ Block* t2 = tbranch;
+ Block* final_false = fbranch;
+
+ // Both true edges must reach the same block (resolving through edge-split
+ // pads).
+ const Block* merge = ResolveThroughEmptyGotos(t1, graph);
+ if (merge != ResolveThroughEmptyGotos(t2, graph)) {
+ return false;
+ }
+
+ if (final_false->PredecessorCount() != 1) return false;
+
+ // Fusing routes x==C2 through T1's edge and drops the T2 edge, so the merge
+ // block's phis must take the same input from both edges; otherwise the
+ // T2-edge value is picked wrong and orphaned (use without a definition).
+ if (t1 != t2 && merge->HasPhis(*graph)) {
+ const Block* pred1 = ResolveThroughEmptyGotos(t1, graph, merge);
+ const Block* pred2 = ResolveThroughEmptyGotos(t2, graph, merge);
+ int idx1 = merge->GetPredecessorIndex(pred1);
+ int idx2 = merge->GetPredecessorIndex(pred2);
+ DCHECK_NE(idx1, Block::kInvalidPredecessorIndex);
+ DCHECK_NE(idx2, Block::kInvalidPredecessorIndex);
+ for (const Operation& phi_op : graph->operations(*merge)) {
+ const PhiOp* phi = phi_op.TryCast<PhiOp>();
+ if (!phi) continue;
+ if (phi->input(idx1) != phi->input(idx2)) return false;
+ }
+ }
+
+ for (const auto& pure_op :
+ base::IterateWithoutLast(graph->operations(*block))) {
+ if (!pure_op.Effects().hoistable_before_a_branch()) return false;
+ }
+
+ // Record Block A for Case 2 to consume, and make Block B a Goto to F:
+ // reaching Block B means the ccmp already proved x != C1 && x != C2, so its
+ // branch is dead.
+ ccmp_cascade_info_[block_a->index().id()] = {t1, final_false};
+ VisitGoto(final_false);
+
+ return true;
+}
+
+// Case 2 emission: builds the two-element ccmp chain (`x==C1` head, `x==C2`
+// fused) and branches to the head's original targets. Block B was already
+// rewritten to Goto->F by Case 1.
+void InstructionSelector::EmitCascadeCcmpBranch(OpIndex node) {
+ const Graph* graph = turboshaft_graph();
+ const BranchOp& head_branch = Cast<BranchOp>(node);
+ const ComparisonOp& head_cmp =
+ graph->Get(head_branch.condition()).Cast<ComparisonOp>();
+
+ const Block* fused_block = head_branch.if_false;
+ const BranchOp& fused_branch =
+ fused_block->LastOperation(*graph).Cast<BranchOp>();
+ const ComparisonOp& fused_cmp =
+ graph->Get(fused_branch.condition()).Cast<ComparisonOp>();
+
+ compare_chain::CompareSequence sequence;
+ sequence.InitialCompare(head_branch.condition(), head_cmp.left(),
+ head_cmp.right(), CcmpCmpOpcode(head_cmp.rep));
+
+ FlagsCondition head_cond = FlagsCondition::kEqual;
+ FlagsCondition fused_cond = FlagsCondition::kEqual;
+ FlagsCondition ccmp_condition = NegateFlagsCondition(head_cond);
+ FlagsCondition default_flags = fused_cond;
+
+ sequence.AddConditionalCompare(CcmpCmpOpcode(fused_cmp.rep), ccmp_condition,
+ default_flags, fused_cmp.left(),
+ fused_cmp.right());
+
+ FlagsContinuation cont = FlagsContinuation::ForConditionalBranch(
+ sequence.ccmps(), sequence.num_ccmps(), fused_cond, head_branch.if_true,
+ head_branch.if_false);
+
+ EmitCcmpCompareChain(sequence, head_cmp.rep, &cont);
+}
+#endif // V8_TARGET_ARCH_ARM64 || V8_ENABLE_APX_F
+
void InstructionSelector::VisitControl(const Block* block) {
#ifdef DEBUG
// SSA deconstruction requires targets of branches not to have phis.
@@ -2780,6 +2956,10 @@ void InstructionSelector::VisitControl(const Block* block) {
Block* fbranch = branch.if_false;
if (tbranch == fbranch) {
VisitGoto(tbranch);
+#if V8_TARGET_ARCH_ARM64 || defined(V8_ENABLE_APX_F)
+ } else if (TryCascadeCcmpFuseOrEmit(node, tbranch, fbranch)) {
+ // Cascade CCMP handled the branch.
+#endif
} else {
VisitBranch(node, tbranch, fbranch);
}
@@ -3321,6 +3501,10 @@ void InstructionSelector::VisitNode(OpIndex node) {
}
UNREACHABLE();
}
+ case Opcode::kWord64Add3: {
+ MarkPairProjectionsAsWord64(node);
+ return VisitUint64Add3WithCarry(node);
+ }
case Opcode::kWord64MulWide: {
const Word64MulWideOp& wideop = op.Cast<Word64MulWideOp>();
MarkPairProjectionsAsWord64(node);
@@ -4234,6 +4418,342 @@ InstructionSelector InstructionSelector::ForTurboshaft(
#undef VISIT_UNSUPPORTED_OP
+namespace compare_chain {
+
+std::optional<FlagsCondition> GetFlagsCondition(OpIndex node,
+ InstructionSelector* selector,
+ bool supports_float_cmp) {
+ if (const ComparisonOp* comparison =
+ selector->Get(node).TryCast<ComparisonOp>()) {
+ if (comparison->rep == RegisterRepresentation::Word32() ||
+ comparison->rep == RegisterRepresentation::Word64() ||
+ comparison->rep == RegisterRepresentation::Tagged()) {
+ switch (comparison->kind) {
+ case ComparisonOp::Kind::kEqual:
+ return FlagsCondition::kEqual;
+ case ComparisonOp::Kind::kSignedLessThan:
+ return FlagsCondition::kSignedLessThan;
+ case ComparisonOp::Kind::kSignedLessThanOrEqual:
+ return FlagsCondition::kSignedLessThanOrEqual;
+ case ComparisonOp::Kind::kUnsignedLessThan:
+ return FlagsCondition::kUnsignedLessThan;
+ case ComparisonOp::Kind::kUnsignedLessThanOrEqual:
+ return FlagsCondition::kUnsignedLessThanOrEqual;
+ default:
+ UNREACHABLE();
+ }
+ } else if (supports_float_cmp &&
+ (comparison->rep == RegisterRepresentation::Float32() ||
+ comparison->rep == RegisterRepresentation::Float64())) {
+ switch (comparison->kind) {
+ case ComparisonOp::Kind::kEqual:
+ return FlagsCondition::kEqual;
+ case ComparisonOp::Kind::kSignedLessThan:
+ return FlagsCondition::kFloatLessThan;
+ case ComparisonOp::Kind::kSignedLessThanOrEqual:
+ return FlagsCondition::kFloatLessThanOrEqual;
+ default:
+ UNREACHABLE();
+ }
+ }
+ }
+ return std::nullopt;
+}
+
+// Search through AND, OR and comparisons.
+// To make life a little easier, we currently don't handle combining two logic
+// operations. There are restrictions on what logical combinations can be
+// performed with ccmp, so this implementation builds a ccmp chain from the LHS
+// of the tree while combining one more compare from the RHS at each step. So,
+// currently, if we discover a pattern like this:
+// logic(logic(cmp, cmp), logic(cmp, cmp))
+// The search will fail from the outermost logic operation, but it will succeed
+// for the two inner operations. This will result in, suboptimal, codegen:
+// cmp
+// ccmp
+// cset x
+// cmp
+// ccmp
+// cset y
+// logic x, y
+std::optional<CompareChainNode*> FindCompareChain(
+ OpIndex user, OpIndex node, InstructionSelector* selector, Zone* zone,
+ ZoneVector<CompareChainNode*>& nodes, bool supports_float_cmp,
+ bool supports_test_pattern) {
+ const Operation& op = selector->Get(node);
+ if (op.Is<Opmask::kWord32BitwiseAnd>() || op.Is<Opmask::kWord32BitwiseOr>()) {
+ const WordBinopOp& binop = op.Cast<WordBinopOp>();
+ auto maybe_lhs =
+ FindCompareChain(node, binop.left(), selector, zone, nodes,
+ supports_float_cmp, supports_test_pattern);
+ auto maybe_rhs =
+ FindCompareChain(node, binop.right(), selector, zone, nodes,
+ supports_float_cmp, supports_test_pattern);
+ if (maybe_lhs.has_value() && maybe_rhs.has_value()) {
+ CompareChainNode* lhs = maybe_lhs.value();
+ CompareChainNode* rhs = maybe_rhs.value();
+ // Ensure we don't try to combine a logic operation with two logic inputs.
+ if (lhs->IsFlagSetting() || rhs->IsFlagSetting()) {
+ nodes.push_back(zone->New<CompareChainNode>(node, lhs, rhs));
+ return nodes.back();
+ }
+ }
+ // Ensure we remove any valid sub-trees that now cannot be used.
+ nodes.clear();
+ return std::nullopt;
+ } else if (user.valid() && selector->CanCover(user, node)) {
+ std::optional<FlagsCondition> user_condition =
+ GetFlagsCondition(node, selector, supports_float_cmp);
+ if (!user_condition.has_value()) {
+ return std::nullopt;
+ }
+ const ComparisonOp& comparison = selector->Cast<ComparisonOp>(node);
+ if (comparison.kind == ComparisonOp::Kind::kEqual &&
+ selector->MatchIntegralZero(comparison.right())) {
+ // Check if this is a TEST pattern: Equal(BitwiseAnd(x, mask), 0).
+ // If so, create a TEST leaf node instead of recursing into the
+ // BitwiseAnd (which would be treated as a logical combiner).
+ // Only architectures with a TEST-style conditional compare (x64's ctest)
+ // may do this; others fall through to the negation path below.
+ const Operation& left_op = selector->Get(comparison.left());
+ if (supports_test_pattern && left_op.Is<Opmask::kWord32BitwiseAnd>() &&
+ selector->CanCover(node, comparison.left())) {
+ return zone->New<CompareChainNode>(node, FlagsCondition::kEqual,
+ /*is_test=*/true);
+ }
+
+ auto maybe_negated =
+ FindCompareChain(node, comparison.left(), selector, zone, nodes,
+ supports_float_cmp, supports_test_pattern);
+ if (maybe_negated.has_value()) {
+ CompareChainNode* negated = maybe_negated.value();
+ negated->MarkRequiresNegation();
+ return negated;
+ }
+ }
+ return zone->New<CompareChainNode>(node, user_condition.value());
+ }
+ return std::nullopt;
+}
+
+void GetFlagSettingOperands(const CompareChainNode* node,
+ InstructionSelector* selector, OpIndex* out_lhs,
+ OpIndex* out_rhs, RegisterRepresentation* out_rep) {
+ OpIndex cmp = node->node();
+ const ComparisonOp& cmp_op = selector->Cast<ComparisonOp>(cmp);
+ if (node->IsTest()) {
+ // TEST pattern: Equal(BitwiseAnd(x, mask), 0)
+ // Operands are the BitwiseAnd's inputs.
+ const WordBinopOp& and_op =
+ selector->Get(cmp_op.left()).Cast<WordBinopOp>();
+ *out_lhs = and_op.left();
+ *out_rhs = and_op.right();
+ *out_rep = cmp_op.rep;
+ } else {
+ *out_lhs = cmp_op.left();
+ *out_rhs = cmp_op.right();
+ *out_rep = cmp_op.rep;
+ }
+}
+
+// Overview -------------------------------------------------------------------
+//
+// A compare operation will generate a 'user condition', which is the
+// FlagCondition of the opcode. For this algorithm, we generate the default
+// flags from the LHS of the logic op, while the RHS is used to predicate the
+// new ccmp. Depending on the logical user, those conditions are either used
+// as-is or negated:
+// > For OR, the generated ccmp will negate the LHS condition for its predicate
+// while the default flags are taken from the RHS.
+// > For AND, the generated ccmp will take the LHS condition for its predicate
+// while the default flags are a negation of the RHS.
+//
+// The new ccmp will now generate a user condition of its own, and this is
+// always forwarded from the RHS.
+//
+// Chaining compares, including with OR, needs to be equivalent to combining
+// all the results with AND, and NOT.
+//
+// AND Example ----------------------------------------------------------------
+//
+// cmpA cmpB
+// | |
+// condA condB
+// | |
+// --- AND ---
+//
+// As the AND becomes the ccmp, it is predicated on condA and the cset is
+// predicated on condB. The user of the ccmp is always predicated on the
+// condition from the RHS of the logic operation. The default flags are
+// not(condB) so cset only produces one when both condA and condB are true:
+// cmpA
+// ccmpB not(condB), condA
+// cset condB
+//
+// OR Example -----------------------------------------------------------------
+//
+// cmpA cmpB
+// | |
+// condA condB
+// | |
+// --- OR ---
+//
+// cmpA cmpB
+// equivalent -> | |
+// not(condA) not(condB)
+// | |
+// ----- AND -----
+// |
+// NOT
+//
+// In this case, the input conditions to the AND (the ccmp) have been negated
+// so the user condition and default flags have been negated compared to the
+// previous example. The cset still uses condB because it is negated twice:
+// cmpA
+// ccmpB condB, not(condA)
+// cset condB
+//
+// Combining AND and OR -------------------------------------------------------
+//
+// cmpA cmpB cmpC
+// | | |
+// condA condB condC
+// | | |
+// --- AND --- |
+// | |
+// OR -----------
+//
+// equivalent -> cmpA cmpB cmpC
+// | | |
+// condA condB not(condC)
+// | | |
+// --- AND --- |
+// | |
+// NOT |
+// | |
+// AND -------------
+// |
+// NOT
+//
+// For this example the 'user condition', coming out, of the first ccmp is
+// condB but it is negated as the input predicate for the next ccmp as that
+// one is performing an OR:
+// cmpA
+// ccmpB not(condB), condA
+// ccmpC condC, not(condB)
+// cset condC
+//
+void CombineFlagSettingOps(CompareChainNode* logic_node,
+ InstructionSelector* selector,
+ CompareSequence* sequence, GetOpcodeFunc get_opcode,
+ AdjustInitialOrderFunc adjust_initial_order,
+ AdjustCcmpOperandsFunc adjust_ccmp_operands) {
+ const CompareChainNode* lhs = logic_node->lhs();
+ const CompareChainNode* rhs = logic_node->rhs();
+
+ if (!sequence->HasCompare()) {
+ // This is the beginning of the conditional compare chain.
+ DCHECK(lhs->IsFlagSetting());
+ DCHECK(rhs->IsFlagSetting());
+
+ // Allow architecture to reorder the initial cmp/ccmp pair for better
+ // immediate encoding (e.g., ARM64 ccmp has smaller immediate range).
+ if (adjust_initial_order) {
+ adjust_initial_order(lhs, rhs, selector);
+ }
+
+ OpIndex lhs_l, lhs_r;
+ RegisterRepresentation lhs_rep;
+ GetFlagSettingOperands(lhs, selector, &lhs_l, &lhs_r, &lhs_rep);
+ InstructionCode opcode = get_opcode(lhs_rep, lhs->IsTest());
+ sequence->InitialCompare(lhs->node(), lhs_l, lhs_r, opcode);
+ }
+
+ bool is_logical_or =
+ selector->Get(logic_node->node()).Is<Opmask::kWord32BitwiseOr>();
+ FlagsCondition ccmp_condition =
+ is_logical_or ? NegateFlagsCondition(lhs->user_condition())
+ : lhs->user_condition();
+ FlagsCondition default_flags =
+ is_logical_or ? rhs->user_condition()
+ : NegateFlagsCondition(rhs->user_condition());
+
+ // We canonicalise the chain so that the rhs is always a cmp, whereas lhs
+ // will either be the initial cmp or the previous logic, now ccmp, op and
+ // only provides ccmp_condition.
+ FlagsCondition user_condition = rhs->user_condition();
+
+ OpIndex rhs_l, rhs_r;
+ RegisterRepresentation rhs_rep;
+ GetFlagSettingOperands(rhs, selector, &rhs_l, &rhs_r, &rhs_rep);
+
+ // Allow architecture to adjust ccmp operands (e.g., ARM64 swaps lhs/rhs
+ // if lhs is a small immediate to use the immediate encoding).
+ if (adjust_ccmp_operands) {
+ adjust_ccmp_operands(rhs_l, rhs_r, user_condition, default_flags, selector);
+ }
+
+ InstructionCode code = get_opcode(rhs_rep, rhs->IsTest());
+ sequence->AddConditionalCompare(code, ccmp_condition, default_flags, rhs_l,
+ rhs_r);
+ // Ensure the user_condition is kept up-to-date for the next ccmp/cset.
+ logic_node->SetCondition(user_condition);
+}
+
+bool TryBuildConditionalCompareChain(
+ InstructionSelector* selector, Zone* zone, OpIndex node,
+ FlagsContinuation* cont, CompareSequence* sequence,
+ FlagsCondition* condition, GetOpcodeFunc get_opcode,
+ bool supports_float_cmp, bool supports_test_pattern,
+ AdjustInitialOrderFunc adjust_initial_order,
+ AdjustCcmpOperandsFunc adjust_ccmp_operands) {
+ if (!cont->IsBranch() && !cont->IsTrap()) return false;
+ DCHECK(cont->condition() == kNotEqual || cont->condition() == kEqual);
+
+ // Instead of:
+ // cmp x0, y0
+ // cset cc0
+ // cmp x1, y1
+ // cset cc1
+ // and/orr
+ // Try to merge logical combinations of flags into:
+ // cmp x0, y0
+ // ccmp x1, y1 ..
+ // cset ..
+ // So, for AND:
+ // (cset cc1 (ccmp x1 y1 !cc1 cc0 (cmp x0, y0)))
+ // and for ORR:
+ // (cset cc1 (ccmp x1 y1 cc1 !cc0 (cmp x0, y0))
+
+ // Look for a potential chain.
+ ZoneVector<CompareChainNode*> logic_nodes(zone);
+ auto root =
+ FindCompareChain(OpIndex::Invalid(), node, selector, zone, logic_nodes,
+ supports_float_cmp, supports_test_pattern);
+ if (!root.has_value()) return false;
+
+ if (logic_nodes.size() > FlagsContinuation::kMaxCompareChainSize) {
+ return false;
+ }
+ if (!logic_nodes.front()->IsLegalFirstCombine()) {
+ return false;
+ }
+
+ for (CompareChainNode* logic_node : logic_nodes) {
+ CombineFlagSettingOps(logic_node, selector, sequence, get_opcode,
+ adjust_initial_order, adjust_ccmp_operands);
+ }
+ DCHECK_LE(sequence->num_ccmps(), FlagsContinuation::kMaxCompareChainSize);
+
+ FlagsCondition final_cond = logic_nodes.back()->user_condition();
+ *condition = cont->condition() == kNotEqual
+ ? final_cond
+ : NegateFlagsCondition(final_cond);
+ return true;
+}
+
+} // namespace compare_chain
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/compiler/backend/instruction-selector.h b/deps/v8/src/compiler/backend/instruction-selector.h
index 2b060cdba20..4aeb35da9ab 100644
--- a/deps/v8/src/compiler/backend/instruction-selector.h
+++ b/deps/v8/src/compiler/backend/instruction-selector.h
@@ -44,6 +44,9 @@ class SwitchInfo;
struct CaseInfo;
class TurbofanStateObjectDeduplicator;
class TurboshaftStateObjectDeduplicator;
+namespace compare_chain {
+class CompareSequence;
+} // namespace compare_chain
// The flags continuation is a way to combine a branch or a materialization
// of a boolean value with an instruction that sets the flags register.
@@ -687,6 +690,8 @@ class V8_EXPORT_PRIVATE InstructionSelector final
return block->IsLoop();
}
+ const turboshaft::Block* current_block() const { return current_block_; }
+
size_t PredecessorCount(const turboshaft::Block* block) const {
return block->PredecessorCount();
}
@@ -1400,6 +1405,7 @@ class V8_EXPORT_PRIVATE InstructionSelector final
void VisitWord64MulWide(turboshaft::OpIndex node, bool is_signed);
void VisitUint64Add128(turboshaft::OpIndex node);
void VisitUint64Sub128(turboshaft::OpIndex node);
+ void VisitUint64Add3WithCarry(turboshaft::OpIndex node);
void TryPrepareScheduleFirstProjection(turboshaft::OpIndex maybe_projection);
@@ -1634,6 +1640,38 @@ class V8_EXPORT_PRIVATE InstructionSelector final
// for non-phi nodes.
ZoneVector<Upper32BitsState> phi_states_;
#endif
+
+// CCMP branch-cascade fusion is compiled only where a ccmp emission path
+// exists: ARM64 (native) and x64 with APX (runtime-gated on APX availability).
+#if V8_TARGET_ARCH_ARM64 || defined(V8_ENABLE_APX_F)
+ struct CascadeCcmpInfo {
+ turboshaft::Block* true_target;
+ turboshaft::Block* final_false;
+ };
+ // Arch-independent driver: detects the `x==C1 ? T1 : x==C2 ? T2 : F` cascade
+ // and rewrites it into a ccmp chain. Driver and Case-2 emission live in
+ // instruction-selector.cc; only the hooks below are per-arch.
+ bool TryCascadeCcmpFuseOrEmit(turboshaft::OpIndex node,
+ turboshaft::Block* tbranch,
+ turboshaft::Block* fbranch);
+ void EmitCascadeCcmpBranch(turboshaft::OpIndex head_branch_node);
+ // Per-arch hooks (in instruction-selector-<arch>.cc). Whether ccmp chains can
+ // be emitted at all (APX-gated on x64, always true on ARM64).
+ bool SupportsCcmpBranchCascade() const;
+ // Whether the constant fits the immediate range for its role, so it can be
+ // folded into the chain. `is_ccmp_operand` selects the fused compare's
+ // narrower ccmp range vs the initial compare's regular cmp range; a constant
+ // outside its range would be emitted as a register operand that the now-dead
+ // fused block never materializes (use without a definition).
+ bool CcmpCascadeConstantOk(turboshaft::OpIndex node, bool is_ccmp_operand);
+ // Arch integer-compare opcode seeding the chain.
+ InstructionCode CcmpCmpOpcode(turboshaft::RegisterRepresentation rep) const;
+ // Emits the arch ccmp compare-chain for the built sequence.
+ void EmitCcmpCompareChain(compare_chain::CompareSequence& sequence,
+ turboshaft::RegisterRepresentation rep,
+ FlagsContinuation* cont);
+ ZoneUnorderedMap<uint32_t, CascadeCcmpInfo> ccmp_cascade_info_;
+#endif // V8_TARGET_ARCH_ARM64 || V8_ENABLE_APX_F
};
} // namespace compiler
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 5456aff2c1f..9bc155f8218 100644
--- a/deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
+++ b/deps/v8/src/compiler/backend/loong64/code-generator-loong64.cc
@@ -1172,7 +1172,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchAtomicStoreWithWriteBarrier: {
DCHECK_EQ(AddressingModeField::decode(instr->opcode()), kMode_MRR);
MacroAssembler::BlockTrampolinePoolScope block_trampoline_pool(masm());
- RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode =
+ AtomicStoreRecordWriteModeField::decode(instr->opcode());
// Indirect pointer writes must use a different opcode.
DCHECK_NE(mode, RecordWriteMode::kValueIsIndirectPointer);
Register object = i.InputRegister(0);
@@ -1376,12 +1377,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kLoong64Add_d:
__ Add_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
+ case kLoong64AddOvf_w: {
+ if (instr->InputAt(1)->IsImmediate()) {
+ __ Add_w(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+ } else {
+ __ Add_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+ }
+ break;
+ }
case kLoong64AddOvf_d: {
UseScratchRegisterScope temps(masm());
DCHECK(temps.hasAvailable());
temps.Exclude(t8);
+ Register scratch = t8;
+ if (instr->flags_mode() == kFlags_set) {
+ scratch = i.OutputRegister(instr->OutputCount() - 1);
+ }
__ AddOverflow_d(i.OutputRegister(), i.InputRegister(0),
- i.InputOperand(1), t8);
+ i.InputOperand(1), scratch);
break;
}
case kLoong64Add128: {
@@ -1401,12 +1414,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kLoong64Sub_d:
__ Sub_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
+ case kLoong64SubOvf_w: {
+ if (instr->InputAt(1)->IsImmediate()) {
+ __ Sub_w(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+ } else {
+ __ Sub_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
+ }
+ break;
+ }
case kLoong64SubOvf_d: {
UseScratchRegisterScope temps(masm());
DCHECK(temps.hasAvailable());
temps.Exclude(t8);
+ Register scratch = t8;
+ if (instr->flags_mode() == kFlags_set) {
+ scratch = i.OutputRegister(instr->OutputCount() - 1);
+ }
__ SubOverflow_d(i.OutputRegister(), i.InputRegister(0),
- i.InputOperand(1), t8);
+ i.InputOperand(1), scratch);
break;
}
case kLoong64Sub128: {
@@ -1425,16 +1450,24 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
UseScratchRegisterScope temps(masm());
DCHECK(temps.hasAvailable());
temps.Exclude(t8);
+ Register scratch = t8;
+ if (instr->flags_mode() == kFlags_set) {
+ scratch = i.OutputRegister(instr->OutputCount() - 1);
+ }
__ MulOverflow_w(i.OutputRegister(), i.InputRegister(0),
- i.InputOperand(1), t8);
+ i.InputOperand(1), scratch);
break;
}
case kLoong64MulOvf_d: {
UseScratchRegisterScope temps(masm());
DCHECK(temps.hasAvailable());
temps.Exclude(t8);
+ Register scratch = t8;
+ if (instr->flags_mode() == kFlags_set) {
+ scratch = i.OutputRegister(instr->OutputCount() - 1);
+ }
__ MulOverflow_d(i.OutputRegister(), i.InputRegister(0),
- i.InputOperand(1), t8);
+ i.InputOperand(1), scratch);
break;
}
case kLoong64Mulh_w:
@@ -1603,15 +1636,11 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kLoong64Rotr_d:
__ Rotr_d(i.OutputRegister(), i.InputRegister(0), i.InputOperand(1));
break;
- case kLoong64Tst: {
- UseScratchRegisterScope temps(masm());
- DCHECK(temps.hasAvailable());
- temps.Exclude(t8);
- __ And(t8, i.InputRegister(0), i.InputOperand(1));
+ case kLoong64Tst:
// Pseudo-instruction used for cmp/branch. No opcode emitted here.
break;
- }
case kLoong64Cmp32:
+ case kLoong64Cmp32Eq:
case kLoong64Cmp64:
// Pseudo-instruction used for cmp/branch. No opcode emitted here.
break;
@@ -2304,8 +2333,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ amswap_db_w(i.OutputRegister(), i.InputRegister(2),
i.TempRegister(0));
__ Bstrpick_d(i.OutputRegister(), i.OutputRegister(), 31, 0);
- __ add_d(i.OutputRegister(), i.OutputRegister(),
- kPtrComprCageBaseRegister);
+ __ Or(i.OutputRegister(), i.OutputRegister(),
+ kPtrComprCageBaseRegister);
} else {
__ amswap_db_d(i.OutputRegister(), i.InputRegister(2),
i.TempRegister(0));
@@ -4470,6 +4499,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
Label* tlabel, Label* flabel, bool fallthru) {
#undef __
#define __ masm->
+ MacroAssemblerBase::BlockTrampolinePoolScope block_trampoline_pool(masm);
Loong64OperandConverter i(gen, instr);
// LOONG64 does not have condition code flags, so compare and branch are
@@ -4481,27 +4511,53 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
if (instr->arch_opcode() == kLoong64Tst) {
Condition cc = FlagsConditionToConditionTst(condition);
- __ Branch(tlabel, cc, t8, Operand(zero_reg));
- UseScratchRegisterScope temps(masm);
- temps.Include(t8);
- } else if (instr->arch_opcode() == kLoong64Add_d ||
- instr->arch_opcode() == kLoong64Sub_d) {
UseScratchRegisterScope temps(masm);
Register scratch = temps.Acquire();
- Register scratch2 = temps.Acquire();
- Condition cc = FlagsConditionToConditionOvf(condition);
- __ srai_d(scratch, i.OutputRegister(), 32);
- __ srai_w(scratch2, i.OutputRegister(), 31);
- __ Branch(tlabel, cc, scratch2, Operand(scratch));
+
+ __ Tst(scratch, i.InputRegister(0), i.InputOperand(1));
+ __ Branch(tlabel, cc, scratch, Operand(zero_reg));
+ } else if (instr->arch_opcode() == kLoong64AddOvf_w ||
+ instr->arch_opcode() == kLoong64SubOvf_w) {
+ if (!instr->InputAt(1)->IsImmediate()) {
+ UseScratchRegisterScope temps(masm);
+ Register scratch = temps.Acquire();
+ Condition cc = FlagsConditionToConditionOvf(condition);
+ __ slli_w(scratch, i.OutputRegister(), 0);
+ __ Branch(tlabel, cc, i.OutputRegister(), Operand(scratch));
+ } else {
+ DCHECK(!AreAliased(i.OutputRegister(), i.InputRegister(0)));
+ bool is_add = (instr->arch_opcode() == kLoong64AddOvf_w);
+ int64_t imm = i.ToConstant(instr->InputAt(1)).ToInt64();
+ // Define mapping from {is_add, imm < 0, is_overflow} to branch condition.
+ static const Condition cond_map[2][2][2] = {
+ {
+ /* Add_w */
+ {lt, ge}, // imm>=0: [kOverflow, !kOverflow]
+ {gt, le} // imm<0: [kOverflow, !kOverflow]
+ },
+ {
+ /* Sub_w */
+ {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)));
+ } else if (!is_overflow) {
+ __ Branch(tlabel);
+ }
+ }
} else if (instr->arch_opcode() == kLoong64AddOvf_d ||
instr->arch_opcode() == kLoong64SubOvf_d) {
+ DCHECK_LE(instr->OutputCount(), 1);
switch (condition) {
- // Overflow occurs if overflow register is negative
+ // Overflow occurs if overflow register is 1.
case kOverflow:
- __ Branch(tlabel, lt, t8, Operand(zero_reg));
+ __ Branch(tlabel, ne, t8, Operand(zero_reg));
break;
case kNotOverflow:
- __ Branch(tlabel, ge, t8, Operand(zero_reg));
+ __ Branch(tlabel, eq, t8, Operand(zero_reg));
break;
default:
UNSUPPORTED_COND(instr->arch_opcode(), condition);
@@ -4510,6 +4566,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
temps.Include(t8);
} else if (instr->arch_opcode() == kLoong64MulOvf_w ||
instr->arch_opcode() == kLoong64MulOvf_d) {
+ DCHECK_LE(instr->OutputCount(), 1);
// Overflow occurs if overflow register is not zero
switch (condition) {
case kOverflow:
@@ -4529,6 +4586,14 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
Register left = i.InputRegister(0);
Operand right = i.InputOperand(1);
__ Branch(tlabel, cc, left, right);
+ } else if (instr->arch_opcode() == kLoong64Cmp32Eq) {
+ Condition cc = FlagsConditionToConditionCmp(condition);
+ Register left = i.InputRegister(0);
+ Operand right = i.InputOperand(1);
+ UseScratchRegisterScope temps(masm);
+ Register scratch = temps.Acquire();
+ __ Sub_w(scratch, left, right);
+ __ Branch(tlabel, cc, scratch, Operand(zero_reg));
} else if (instr->arch_opcode() == kArchStackPointerGreaterThan) {
Condition cc = FlagsConditionToConditionCmp(condition);
DCHECK((cc == ls) || (cc == hi));
@@ -4608,36 +4673,64 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
if (instr->arch_opcode() == kLoong64Tst) {
Condition cc = FlagsConditionToConditionTst(condition);
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ __ Tst(scratch, i.InputRegister(0), i.InputOperand(1));
if (cc == eq) {
- __ Sltu(result, t8, 1);
+ __ Sltu(result, scratch, 1);
} else {
- __ Sltu(result, zero_reg, t8);
+ __ Sltu(result, zero_reg, scratch);
}
- UseScratchRegisterScope temps(masm());
- temps.Include(t8);
return;
- } else if (instr->arch_opcode() == kLoong64Add_d ||
- instr->arch_opcode() == kLoong64Sub_d) {
- UseScratchRegisterScope temps(masm());
- Register scratch = temps.Acquire();
- Condition cc = FlagsConditionToConditionOvf(condition);
- // Check for overflow creates 1 or 0 for result.
- __ srli_d(scratch, i.OutputRegister(), 63);
- __ srli_w(result, i.OutputRegister(), 31);
- __ xor_(result, scratch, result);
- if (cc == eq) // Toggle result for not overflow.
- __ xori(result, result, 1);
+ } else if (instr->arch_opcode() == kLoong64AddOvf_w ||
+ instr->arch_opcode() == kLoong64SubOvf_w) {
+ if (!instr->InputAt(1)->IsImmediate()) {
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ // Check for overflow creates 1 or 0 for result.
+ __ slli_w(scratch, i.OutputRegister(), 0);
+ __ xor_(scratch, scratch, i.OutputRegister());
+ if (condition == kNotOverflow) {
+ __ sltui(result, scratch, 1);
+ } else {
+ DCHECK(condition == kOverflow);
+ __ sltu(result, zero_reg, scratch);
+ }
+ return;
+ }
+ DCHECK(!AreAliased(i.OutputRegister(), i.InputRegister(0)));
+ bool is_add = (instr->arch_opcode() == kLoong64AddOvf_w);
+ int64_t imm = i.ToConstant(instr->InputAt(1)).ToInt64();
+ if (imm == 0) {
+ __ li(result, condition == kNotOverflow);
+ return;
+ }
+ // Define mapping from {is_add, imm < 0, is_overflow} to branch condition.
+ static const Condition cond_map[2][2][2] = {
+ {
+ /* Add_w */
+ {lt, gt}, // imm > 0: [kOverflow, !kOverflow]
+ {gt, lt} // imm < 0: [kOverflow, !kOverflow]
+ },
+ {
+ /* Sub_w */
+ {gt, lt}, // imm > 0: [kOverflow, !kOverflow]
+ {lt, gt} // imm < 0: [kOverflow, !kOverflow]
+ }};
+ bool is_overflow = (condition == kOverflow);
+ Condition cc = cond_map[is_add][imm < 0][is_overflow];
+ if (cc == lt) {
+ __ slt(result, i.OutputRegister(), i.InputRegister(0));
+ } else {
+ __ Sgt(result, i.OutputRegister(), i.InputRegister(0));
+ }
return;
} else if (instr->arch_opcode() == kLoong64AddOvf_d ||
instr->arch_opcode() == kLoong64SubOvf_d) {
- // Overflow occurs if overflow register is negative
- __ slt(result, t8, zero_reg);
UseScratchRegisterScope temps(masm());
temps.Include(t8);
} else if (instr->arch_opcode() == kLoong64MulOvf_w ||
instr->arch_opcode() == kLoong64MulOvf_d) {
- // Overflow occurs if overflow register is not zero
- __ Sgtu(result, t8, zero_reg);
UseScratchRegisterScope temps(masm());
temps.Include(t8);
} else if (instr->arch_opcode() == kLoong64Cmp32 ||
@@ -4647,6 +4740,16 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
Operand right = i.InputOperand(1);
__ CompareWord(cc, result, left, right);
return;
+ } else if (instr->arch_opcode() == kLoong64Cmp32Eq) {
+ Register left = i.InputRegister(0);
+ Operand right = i.InputOperand(1);
+ __ Sub_w(result, left, right);
+ if (condition == kEqual) {
+ __ sltui(result, result, 1);
+ } else {
+ __ sltu(result, zero_reg, result);
+ }
+ return;
} else if (instr->arch_opcode() == kLoong64Float64Cmp ||
instr->arch_opcode() == kLoong64Float32Cmp) {
bool predicate;
@@ -4741,14 +4844,15 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
if (instr->arch_opcode() == kLoong64Tst) {
DCHECK_GE(instr->InputCount(), 4);
Condition cc = FlagsConditionToConditionTst(condition);
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
- __ SelectWord(result, t8, v_true, v_false);
- UseScratchRegisterScope temps(masm());
- temps.Include(t8);
+ __ Tst(scratch, i.InputRegister(0), i.InputOperand(1));
+ __ SelectWord(result, scratch, v_true, v_false);
return;
} else if (instr->arch_opcode() == kLoong64Cmp64 ||
instr->arch_opcode() == kLoong64Cmp32 ||
@@ -4800,92 +4904,96 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
__ bind(&done);
}
return;
- } else if (instr->arch_opcode() == kLoong64Add_d ||
- instr->arch_opcode() == kLoong64Sub_d) {
- DCHECK_GE(instr->InputCount(), 4);
- Condition cc = FlagsConditionToConditionOvf(condition);
+ } else if (instr->arch_opcode() == kLoong64Cmp32Eq) {
+ Condition cc = FlagsConditionToConditionCmp(condition);
+ Register left = i.InputRegister(0);
+ Operand right = i.InputOperand(1);
+ UseScratchRegisterScope temps(masm());
+ Register scratch1 = temps.Acquire();
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
- cc = ne;
}
- UseScratchRegisterScope temps(masm());
- Register scratch1 = temps.Acquire();
- Register scratch2 = temps.Acquire();
- __ srai_d(scratch1, i.OutputRegister(), 32);
- __ srai_w(scratch2, i.OutputRegister(), 31);
- if (v_false == zero_reg) {
- __ xor_(scratch1, scratch1, scratch2);
- __ maskeqz(result, v_true, scratch1);
- } else if (v_true == zero_reg) {
- __ xor_(scratch1, scratch1, scratch2);
- __ masknez(result, v_false, scratch1);
- } else if (result == v_true || result == v_false) {
- if (result == v_false) {
- v_false = v_true;
- cc = NegateCondition(cc);
+ __ Sub_w(scratch1, left, right);
+ __ SelectWord(result, scratch1, v_true, v_false);
+ } else if (instr->arch_opcode() == kLoong64AddOvf_w ||
+ instr->arch_opcode() == kLoong64SubOvf_w) {
+ DCHECK_GE(instr->InputCount(), 4);
+ if (!instr->InputAt(1)->IsImmediate()) {
+ Condition cc = FlagsConditionToConditionOvf(condition);
+ if (cc == eq) {
+ Register temp = v_true;
+ v_true = v_false;
+ v_false = temp;
+ cc = ne;
}
- Label done;
- __ Branch(&done, cc, scratch2, Operand(scratch1));
- __ Move(result, v_false);
- __ bind(&done);
+ UseScratchRegisterScope temps(masm());
+ Register scratch1 = temps.Acquire();
+ __ slli_w(scratch1, i.OutputRegister(), 0);
+ __ xor_(scratch1, scratch1, i.OutputRegister());
+ __ SelectWord(result, scratch1, v_true, v_false);
+ return;
+ }
+ DCHECK(!AreAliased(i.OutputRegister(), i.InputRegister(0)));
+ bool is_add = (instr->arch_opcode() == kLoong64AddOvf_w);
+ int64_t imm = i.ToConstant(instr->InputAt(1)).ToInt64();
+ if (imm == 0) {
+ if (condition == kOverflow) {
+ __ mov(result, v_false);
+ } else {
+ __ mov(result, v_true);
+ }
+ return;
+ }
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ // Define mapping from {is_add, imm < 0, is_overflow} to branch condition.
+ static const Condition cond_map[2][2][2] = {
+ {
+ /* Add_w */
+ {lt, gt}, // imm > 0: [kOverflow, !kOverflow]
+ {gt, lt} // imm < 0: [kOverflow, !kOverflow]
+ },
+ {
+ /* Sub_w */
+ {gt, lt}, // imm > 0: [kOverflow, !kOverflow]
+ {lt, gt} // imm < 0: [kOverflow, !kOverflow]
+ }};
+ bool is_overflow = (condition == kOverflow);
+ Condition cc = cond_map[is_add][imm < 0][is_overflow];
+ if (cc == lt) {
+ __ slt(scratch, i.OutputRegister(), i.InputRegister(0));
} else {
- Label true_label, done;
- __ Branch(&true_label, cc, scratch2, Operand(scratch1));
- __ Move(result, v_false);
- __ Branch(&done);
- __ bind(&true_label);
- __ Move(result, v_true);
- __ bind(&done);
+ __ Sgt(scratch, i.OutputRegister(), i.InputRegister(0));
}
- return;
+ __ SelectWord(result, scratch, v_true, v_false);
} else if (instr->arch_opcode() == kLoong64AddOvf_d ||
instr->arch_opcode() == kLoong64SubOvf_d) {
DCHECK_GE(instr->InputCount(), 4);
- // Overflow occurs if overflow register is negative
- Condition cc = lt;
- if (condition == kNotOverflow) {
+ Register ovf_reg = t8;
+ Condition cc = FlagsConditionToConditionOvf(condition);
+ if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
+ cc = ne;
}
- if (v_false == zero_reg) {
- __ slt(t8, t8, zero_reg);
- __ maskeqz(result, v_true, t8);
- } else if (v_true == zero_reg) {
- __ slt(t8, t8, zero_reg);
- __ masknez(result, v_false, t8);
- } else if (result == v_true || result == v_false) {
- if (result == v_false) {
- v_false = v_true;
- cc = NegateCondition(cc);
- }
- Label done;
- __ Branch(&done, cc, t8, Operand(zero_reg));
- __ Move(result, v_false);
- __ bind(&done);
- } else {
- Label true_label, done;
- __ Branch(&true_label, cc, t8, Operand(zero_reg));
- __ Move(result, v_false);
- __ Branch(&done);
- __ bind(&true_label);
- __ Move(result, v_true);
- __ bind(&done);
- }
+ // Overflow occurs if overflow register is 1.
+ __ SelectWord(result, ovf_reg, v_true, v_false);
UseScratchRegisterScope temps(masm());
temps.Include(t8);
} else if (instr->arch_opcode() == kLoong64MulOvf_w ||
instr->arch_opcode() == kLoong64MulOvf_d) {
DCHECK_GE(instr->InputCount(), 4);
Condition cc = FlagsConditionToConditionOvf(condition);
+ Register ovf_reg = t8;
if (cc == eq) {
Register temp = v_true;
v_true = v_false;
v_false = temp;
}
- __ SelectWord(result, t8, v_true, v_false);
+ __ SelectWord(result, ovf_reg, v_true, v_false);
UseScratchRegisterScope temps(masm());
temps.Include(t8);
return;
@@ -5004,7 +5112,9 @@ void CodeGenerator::AssembleConstructFrame() {
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
#if V8_ENABLE_WEBASSEMBLY
- if (info()->IsWasm() && required_slots * kSystemPointerSize > 4 * KB) {
+ int32_t stack_space =
+ required_slots * kSystemPointerSize + GetStackCheckOffset();
+ if (info()->IsWasm() && stack_space > 4 * KB) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
// have enough space on the stack to call the runtime for the stack
@@ -5014,12 +5124,11 @@ void CodeGenerator::AssembleConstructFrame() {
// If the frame is bigger than the stack, we throw the stack overflow
// exception unconditionally. Thereby we can avoid the integer overflow
// check in the condition code.
- if (required_slots * kSystemPointerSize < v8_flags.stack_size * KB) {
+ if (stack_space < v8_flags.stack_size * KB) {
UseScratchRegisterScope temps(masm());
Register stack_limit = temps.Acquire();
__ LoadStackLimit(stack_limit, StackLimitKind::kRealStackLimit);
- __ Add_d(stack_limit, stack_limit,
- Operand(required_slots * kSystemPointerSize));
+ __ Add_d(stack_limit, stack_limit, Operand(stack_space));
__ Branch(&done, uge, sp, Operand(stack_limit));
}
@@ -5034,8 +5143,7 @@ void CodeGenerator::AssembleConstructFrame() {
DoubleRegList fp_regs_to_save;
for (auto reg : wasm::kFpParamRegisters) fp_regs_to_save.set(reg);
__ MultiPushFPUOrLSX(fp_regs_to_save);
- __ li(WasmHandleStackOverflowDescriptor::GapRegister(),
- required_slots * kSystemPointerSize);
+ __ li(WasmHandleStackOverflowDescriptor::GapRegister(), stack_space);
__ Add_d(
WasmHandleStackOverflowDescriptor::FrameBaseRegister(), fp,
Operand(call_descriptor->ParameterSlotCount() * kSystemPointerSize +
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 08c3b6093ea..92396bc25a9 100644
--- a/deps/v8/src/compiler/backend/loong64/instruction-codes-loong64.h
+++ b/deps/v8/src/compiler/backend/loong64/instruction-codes-loong64.h
@@ -54,10 +54,12 @@ namespace compiler {
V(Loong64Add_d) \
V(Loong64Add_w) \
V(Loong64AddOvf_d) \
+ V(Loong64AddOvf_w) \
V(Loong64Add128) \
V(Loong64Sub_d) \
V(Loong64Sub_w) \
V(Loong64SubOvf_d) \
+ V(Loong64SubOvf_w) \
V(Loong64Sub128) \
V(Loong64Mul_d) \
V(Loong64MulOvf_w) \
@@ -104,6 +106,7 @@ namespace compiler {
V(Loong64Mov) \
V(Loong64Tst) \
V(Loong64Cmp32) \
+ V(Loong64Cmp32Eq) \
V(Loong64Cmp64) \
V(Loong64Float32Cmp) \
V(Loong64Float32Add) \
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 b9b0b7b8edd..735b1d90d80 100644
--- a/deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc
+++ b/deps/v8/src/compiler/backend/loong64/instruction-selector-loong64.cc
@@ -81,7 +81,9 @@ class Loong64OperandGenerator final : public OperandGenerator {
bool CanBeImmediate(OpIndex node, InstructionCode mode) {
const ConstantOp* constant = selector()->Get(node).TryCast<ConstantOp>();
if (!constant) return false;
- if (constant->kind == ConstantOp::Kind::kCompressedHeapObject) {
+ bool match_heap_constant =
+ constant->kind == ConstantOp::Kind::kCompressedHeapObject;
+ if (match_heap_constant) {
if (!COMPRESS_POINTERS_BOOL) return false;
// For builtin code we need static roots
if (selector()->isolate()->bootstrapper() && !V8_STATIC_ROOTS_BOOL) {
@@ -109,8 +111,10 @@ class Loong64OperandGenerator final : public OperandGenerator {
case kArchAtomicStoreWithWriteBarrier:
case kArchAtomicStoreSkippedWriteBarrier:
return false;
- case kLoong64Cmp32:
- case kLoong64Cmp64:
+ case kLoong64AddOvf_w:
+ case kLoong64SubOvf_w:
+ case kLoong64AddOvf_d:
+ case kLoong64SubOvf_d:
return true;
case kLoong64Sll_w:
case kLoong64Srl_w:
@@ -120,14 +124,29 @@ class Loong64OperandGenerator final : public OperandGenerator {
case kLoong64Srl_d:
case kLoong64Sra_d:
return is_uint6(value);
- case kLoong64And:
- case kLoong64And32:
case kLoong64Or:
case kLoong64Or32:
case kLoong64Xor:
case kLoong64Xor32:
- case kLoong64Tst:
return is_uint12(value);
+ case kLoong64And:
+ case kLoong64And32: {
+ if (is_uint12(value)) return true;
+
+ uint64_t mask = value;
+ uint64_t mask_width = base::bits::CountPopulation(mask);
+ uint64_t mask_clz = base::bits::CountLeadingZeros64(mask);
+ return (mask_width != 0) && ((mask_width + mask_clz) == 64);
+ }
+ case kLoong64Tst: {
+ if (is_uint12(value)) return true;
+
+ uint64_t mask = value;
+ uint64_t mask_width = base::bits::CountPopulation(mask);
+ uint64_t mask_clz = base::bits::CountLeadingZeros64(mask);
+ uint64_t mask_ctz = base::bits::CountTrailingZeros64(mask);
+ return (mask_width != 0) && ((mask_width + mask_clz + mask_ctz) == 64);
+ }
case kLoong64Ld_w:
case kLoong64St_w:
case kLoong64Ld_d:
@@ -138,6 +157,9 @@ class Loong64OperandGenerator final : public OperandGenerator {
case kLoong64Word64AtomicStoreWord64:
case kLoong64StoreCompressTagged:
return (is_int12(value) || (is_int16(value) && ((value & 0b11) == 0)));
+ case kLoong64Cmp32:
+ case kLoong64Cmp32Eq:
+ return is_int12(static_cast<int32_t>(value));
default:
return is_int12(value);
}
@@ -320,6 +342,21 @@ bool TryMatchImmediate(InstructionSelector* selector,
return false;
}
+OpIndex TryMatchWord32(InstructionSelector* selector, OpIndex user,
+ OpIndex node) {
+ if (!selector->CanCover(user, node)) return node;
+ if (const TaggedBitcastOp* cast = selector->TryCast<TaggedBitcastOp>(node)) {
+ return TryMatchWord32(selector, node, cast->input());
+ }
+ if (const ChangeOp* change = selector->TryCast<ChangeOp>(node)) {
+ RegisterRepresentation from = change->from;
+ if (from.IsWord() || from.IsTaggedOrCompressed()) {
+ return TryMatchWord32(selector, node, change->input());
+ }
+ }
+ return node;
+}
+
static void VisitBinop(InstructionSelector* selector, turboshaft::OpIndex node,
InstructionCode opcode, bool has_reverse_opcode,
InstructionCode reverse_opcode,
@@ -336,12 +373,28 @@ static void VisitBinop(InstructionSelector* selector, turboshaft::OpIndex node,
if (TryMatchImmediate(selector, &opcode, right_node, &input_count,
&inputs[1])) {
- inputs[0] = g.UseRegister(left_node);
+ // If right node is an immediate, we will use left to check overflow
+ // so we hope left isn't overlapped by output.
+ if (!cont->IsNone() &&
+ (cont->condition() == FlagsCondition::kOverflow ||
+ cont->condition() == FlagsCondition::kNotOverflow)) {
+ inputs[0] = g.UseUniqueRegister(left_node);
+ } else {
+ inputs[0] = g.UseRegister(left_node);
+ }
input_count++;
} else if (has_reverse_opcode &&
TryMatchImmediate(selector, &reverse_opcode, left_node,
&input_count, &inputs[1])) {
- inputs[0] = g.UseRegister(right_node);
+ // If right node is an immediate, we will use left to check overflow
+ // so we hope left isn't overlapped by output.
+ if (!cont->IsNone() &&
+ (cont->condition() == FlagsCondition::kOverflow ||
+ cont->condition() == FlagsCondition::kNotOverflow)) {
+ inputs[0] = g.UseUniqueRegister(right_node);
+ } else {
+ inputs[0] = g.UseRegister(right_node);
+ }
opcode = reverse_opcode;
input_count++;
} else {
@@ -453,6 +506,28 @@ void EmitLoad(InstructionSelector* selector, turboshaft::OpIndex node,
return;
}
+ const Operation& index_op = selector->Get(index);
+ if (index_op.Is<Opmask::kWord64Add>() && selector->CanCover(node, index)) {
+ const WordBinopOp& add = index_op.Cast<WordBinopOp>();
+ const Operation& lhs = selector->Get(add.left());
+ // Select Alsl_d for (left << imm + right(imm)).
+ if (lhs.Is<Opmask::kWord64ShiftLeft>() &&
+ selector->CanCover(index, add.left()) &&
+ g.CanBeImmediate(add.right(), opcode)) {
+ 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;
+ }
+ }
+ }
+
if (g.CanBeImmediate(index, opcode)) {
selector->Emit(opcode | AddressingModeField::encode(kMode_MRI),
g.DefineAsRegister(output.valid() ? output : node),
@@ -924,6 +999,14 @@ void InstructionSelector::VisitWord32And(turboshaft::OpIndex node) {
return;
}
}
+ auto left = bitwise_and.left();
+ auto right = bitwise_and.right();
+ if (g.CanBeImmediate(right, kLoong64And32)) {
+ left = TryMatchWord32(this, node, left);
+ Emit(kLoong64And32, g.DefineAsRegister(node), g.UseRegister(left),
+ g.UseImmediate(right));
+ return;
+ }
VisitBinop(this, node, kLoong64And32, true, kLoong64And32);
}
@@ -1054,6 +1137,7 @@ void InstructionSelector::VisitWord64Xor(OpIndex node) {
}
void InstructionSelector::VisitWord32Shl(OpIndex node) {
+ Loong64OperandGenerator g(this);
const ShiftOp& shift_op = Get(node).Cast<ShiftOp>();
const Operation& lhs = Get(shift_op.left());
if (uint64_t constant_left;
@@ -1072,7 +1156,6 @@ void InstructionSelector::VisitWord32Shl(OpIndex node) {
if ((mask_width != 0) && (mask_msb + mask_width == 32)) {
DCHECK_EQ(0u, base::bits::CountTrailingZeros32(mask));
DCHECK_NE(0u, shift_by);
- Loong64OperandGenerator g(this);
if ((shift_by + mask_width) >= 32) {
// If the mask is contiguous and reaches or extends beyond the top
// bit, only the shift is needed.
@@ -1084,10 +1167,14 @@ void InstructionSelector::VisitWord32Shl(OpIndex node) {
}
}
}
- VisitRRO(this, kLoong64Sll_w, node);
+ auto left = TryMatchWord32(this, node, shift_op.left());
+ auto right = shift_op.right();
+ Emit(kLoong64Sll_w, g.DefineAsRegister(node), g.UseRegister(left),
+ g.UseOperand(right, kLoong64Sll_w));
}
void InstructionSelector::VisitWord32Shr(OpIndex node) {
+ Loong64OperandGenerator g(this);
const ShiftOp& shift_op = Get(node).Cast<ShiftOp>();
const Operation& lhs = Get(shift_op.left());
if (uint64_t constant_right;
@@ -1104,7 +1191,6 @@ void InstructionSelector::VisitWord32Shr(OpIndex node) {
unsigned mask_width = base::bits::CountPopulation(mask);
unsigned mask_msb = base::bits::CountLeadingZeros32(mask);
if ((mask_msb + mask_width + lsb) == 32) {
- Loong64OperandGenerator g(this);
DCHECK_EQ(lsb, base::bits::CountTrailingZeros32(mask));
Emit(kLoong64Bstrpick_w, g.DefineAsRegister(node),
g.UseRegister(bitwise_and.left()), g.TempImmediate(lsb),
@@ -1113,14 +1199,17 @@ void InstructionSelector::VisitWord32Shr(OpIndex node) {
}
}
}
- VisitRRO(this, kLoong64Srl_w, node);
+ auto left = TryMatchWord32(this, node, shift_op.left());
+ auto right = shift_op.right();
+ Emit(kLoong64Srl_w, g.DefineAsRegister(node), g.UseRegister(left),
+ g.UseOperand(right, kLoong64Srl_w));
}
void InstructionSelector::VisitWord32Sar(turboshaft::OpIndex node) {
+ Loong64OperandGenerator g(this);
const ShiftOp& shift = Get(node).Cast<ShiftOp>();
const Operation& lhs = Get(shift.left());
if (CanCover(node, shift.left())) {
- Loong64OperandGenerator g(this);
if (lhs.Is<Opmask::kWord32ShiftLeft>()) {
const ShiftOp& bitwise_shl = lhs.Cast<ShiftOp>();
if (int64_t constant_right, right;
@@ -1145,7 +1234,10 @@ void InstructionSelector::VisitWord32Sar(turboshaft::OpIndex node) {
return;
}
}
- VisitRRO(this, kLoong64Sra_w, node);
+ auto left = TryMatchWord32(this, node, shift.left());
+ auto right = shift.right();
+ Emit(kLoong64Sra_w, g.DefineAsRegister(node), g.UseRegister(left),
+ g.UseOperand(right, kLoong64Sra_w));
}
void InstructionSelector::VisitWord64Shl(OpIndex node) {
@@ -1331,7 +1423,16 @@ void InstructionSelector::VisitInt32Add(OpIndex node) {
}
}
}
- VisitBinop(this, node, kLoong64Add_w, true, kLoong64Add_w);
+ auto left = TryMatchWord32(this, node, add.left());
+ auto right = TryMatchWord32(this, node, add.right());
+
+ if (g.CanBeImmediate(left, kLoong64Add_w) &&
+ !g.CanBeImmediate(right, kLoong64Add_w)) {
+ std::swap(left, right);
+ }
+
+ Emit(kLoong64Add_w, g.DefineAsRegister(node), g.UseRegister(left),
+ g.UseOperand(right, kLoong64Add_w));
}
void InstructionSelector::VisitInt64Add(OpIndex node) {
@@ -1376,7 +1477,12 @@ void InstructionSelector::VisitInt64Add(OpIndex node) {
}
void InstructionSelector::VisitInt32Sub(OpIndex node) {
- VisitBinop(this, node, kLoong64Sub_w);
+ Loong64OperandGenerator g(this);
+ const WordBinopOp& sub = this->Get(node).Cast<WordBinopOp>();
+ auto left = TryMatchWord32(this, node, sub.left());
+ auto right = TryMatchWord32(this, node, sub.right());
+ Emit(kLoong64Sub_w, g.DefineAsRegister(node), g.UseRegister(left),
+ g.UseOperand(right, kLoong64Sub_w));
}
void InstructionSelector::VisitInt64Sub(OpIndex node) {
@@ -1502,9 +1608,12 @@ void VisitWideAddSub(InstructionSelector* selector, OpIndex node, bool is_add) {
InstructionCode opcode_no_high = is_add ? kLoong64Add_d : kLoong64Sub_d;
if (!out_high.valid() || !selector->IsUsed(out_high.value())) {
- InstructionOperand b_low_op = g.UseOperand(op.right_low(), opcode_no_high);
- selector->Emit(opcode_no_high, g.DefineAsRegister(out_low.value()),
- g.UseRegister(op.left_low()), b_low_op);
+ if (out_low.valid() && selector->IsUsed(out_low.value())) {
+ InstructionOperand b_low_op =
+ g.UseOperand(op.right_low(), opcode_no_high);
+ selector->Emit(opcode_no_high, g.DefineAsRegister(out_low.value()),
+ g.UseRegister(op.left_low()), b_low_op);
+ }
return;
}
@@ -1819,13 +1928,8 @@ void InstructionSelector::VisitChangeInt32ToInt64(OpIndex node) {
}
EmitLoad(this, change_op.input(), opcode, node);
return;
- } else if (input_op.Is<Opmask::kWord32ShiftRightArithmetic>() &&
- CanCover(node, change_op.input())) {
- // TODO(LOONG_dev): May also optimize 'TruncateInt64ToInt32' here.
- EmitIdentity(node);
}
- Emit(kLoong64Sll_w, g.DefineAsRegister(node),
- g.UseRegister(change_op.input()), g.TempImmediate(0));
+ EmitIdentity(node);
}
bool InstructionSelector::ZeroExtendsWord32ToWord64NoPhis(OpIndex node) {
@@ -2200,17 +2304,8 @@ static Instruction* VisitCompare(InstructionSelector* selector,
}
#ifdef V8_COMPRESS_POINTERS
if (opcode == kLoong64Cmp32) {
- if (right.IsImmediate()) {
- InstructionOperand temps[1] = {g.TempRegister()};
- return selector->EmitWithContinuation(opcode, 0, nullptr, input_count,
- inputs, arraysize(temps), temps,
- cont);
- } else {
- InstructionOperand temps[2] = {g.TempRegister(), g.TempRegister()};
- return selector->EmitWithContinuation(opcode, 0, nullptr, input_count,
- inputs, arraysize(temps), temps,
- cont);
- }
+ return selector->EmitWithContinuation(opcode, 0, nullptr, input_count,
+ inputs, cont);
}
#endif
return selector->EmitWithContinuation(opcode, 0, nullptr, input_count, inputs,
@@ -2262,9 +2357,17 @@ Instruction* VisitWordCompare(InstructionSelector* selector, OpIndex node,
auto left = op.input(0);
auto right = op.input(1);
- // Match immediates on left or right side of comparison.
+ // If one of the two inputs is an immediate, make sure it's on the right.
+ if (!g.CanBeImmediate(right, opcode) && g.CanBeImmediate(left, opcode)) {
+ cont->Commute();
+ std::swap(left, right);
+ }
if (g.CanBeImmediate(right, opcode)) {
if (opcode == kLoong64Tst) {
+ auto imm = g.GetOptionalIntegerConstant(right);
+ if (imm.has_value() && is_uint32(*imm)) {
+ left = TryMatchWord32(selector, node, left);
+ }
return VisitCompare(selector, opcode, g.UseRegister(left),
g.UseImmediate(right), cont);
} else {
@@ -2292,36 +2395,6 @@ Instruction* VisitWordCompare(InstructionSelector* selector, OpIndex node,
UNREACHABLE();
}
}
- } else if (g.CanBeImmediate(left, opcode)) {
- if (!commutative) cont->Commute();
- if (opcode == kLoong64Tst) {
- return VisitCompare(selector, opcode, g.UseRegister(right),
- g.UseImmediate(left), cont);
- } else {
- switch (cont->condition()) {
- case kEqual:
- case kNotEqual:
- if (cont->IsSet()) {
- return VisitCompare(selector, opcode, g.UseUniqueRegister(right),
- g.UseImmediate(left), cont);
- } else {
- return VisitCompare(selector, opcode, g.UseUniqueRegister(right),
- g.UseImmediate(left), cont);
- }
- case kSignedLessThan:
- case kSignedGreaterThanOrEqual:
- case kSignedLessThanOrEqual:
- case kSignedGreaterThan:
- case kUnsignedLessThan:
- case kUnsignedGreaterThanOrEqual:
- case kUnsignedLessThanOrEqual:
- case kUnsignedGreaterThan:
- return VisitCompare(selector, opcode, g.UseUniqueRegister(right),
- g.UseImmediate(left), cont);
- default:
- UNREACHABLE();
- }
- }
} else {
return VisitCompare(selector, opcode, g.UseUniqueRegister(left),
g.UseUniqueRegister(right), cont);
@@ -2337,6 +2410,29 @@ void VisitWord32Compare(InstructionSelector* selector, OpIndex node,
const Operation& lhs = selector->Get(op.input(0));
const Operation& rhs = selector->Get(op.input(1));
const ComparisonOp& cmp = selector->Get(node).template Cast<ComparisonOp>();
+
+ bool has_imm = false;
+ int32_t imm = 0;
+ InstructionOperand right;
+ if (selector->isolate() &&
+ (V8_STATIC_ROOTS_BOOL ||
+ (COMPRESS_POINTERS_BOOL && !selector->isolate()->bootstrapper()))) {
+ const RootsTable& roots_table = selector->isolate()->roots_table();
+ RootIndex root_index;
+ Handle<HeapObject> right;
+ // HeapConstants and CompressedHeapConstants can be treated the same when
+ // using them as an input to a 32-bit comparison. Check whether either is
+ // present.
+ if (selector->MatchHeapConstant(op.input(1), &right) && !right.is_null() &&
+ roots_table.IsRootHandle(right, &root_index) &&
+ RootsTable::IsReadOnly(root_index)) {
+ Tagged_t ptr =
+ MacroAssemblerBase::ReadOnlyRootPtr(root_index, selector->isolate());
+ imm = ptr;
+ has_imm = true;
+ }
+ }
+
// LoongArch64 doesn't support Word32 compare instructions. Instead it relies
// that the values in registers are correctly sign-extended and uses Word64
// comparison.
@@ -2352,9 +2448,11 @@ void VisitWord32Compare(InstructionSelector* selector, OpIndex node,
lhs.outputs_rep()[0] == RegisterRepresentation::Tagged() ||
lhs.outputs_rep()[0] == RegisterRepresentation::Compressed()) {
need_sign_extension = true;
- leftOp = g.TempRegister();
- selector->Emit(kLoong64Sll_w, leftOp, g.UseRegister(op.input(0)),
- g.TempImmediate(0));
+ if (cont->IsNone() || cont->condition() != any_of(kEqual, kNotEqual)) {
+ leftOp = g.TempRegister();
+ selector->Emit(kLoong64Sll_w, leftOp, g.UseRegister(op.input(0)),
+ g.TempImmediate(0));
+ }
}
if ((USE_SIMULATOR_BOOL && rhs.Is<DidntThrowOp>()) ||
cmp.rep == RegisterRepresentation::Tagged() ||
@@ -2362,15 +2460,26 @@ void VisitWord32Compare(InstructionSelector* selector, OpIndex node,
rhs.outputs_rep()[0] == RegisterRepresentation::Tagged() ||
rhs.outputs_rep()[0] == RegisterRepresentation::Compressed()) {
need_sign_extension = true;
- rightOp = g.TempRegister();
- selector->Emit(kLoong64Sll_w, rightOp, g.UseRegister(op.input(1)),
- g.TempImmediate(0));
+ if (cont->IsNone() || cont->condition() != any_of(kEqual, kNotEqual)) {
+ rightOp = g.TempRegister();
+ selector->Emit(kLoong64Sll_w, rightOp, g.UseRegister(op.input(1)),
+ g.TempImmediate(0));
+ }
}
if (need_sign_extension) {
- Instruction* instr =
- VisitCompare(selector, kLoong64Cmp32, leftOp, rightOp, cont);
- selector->UpdateSourcePosition(instr, node);
+ if (cont->IsNone() || cont->condition() != any_of(kEqual, kNotEqual)) {
+ Instruction* instr =
+ VisitCompare(selector, kLoong64Cmp32, leftOp, rightOp, cont);
+ selector->UpdateSourcePosition(instr, node);
+ } else {
+ Instruction* instr = VisitCompare(
+ selector, kLoong64Cmp32Eq, g.UseRegister(op.input(0)),
+ has_imm ? g.UseImmediate(imm)
+ : g.UseOperand(selector->Index(rhs), kLoong64Cmp32Eq),
+ cont);
+ selector->UpdateSourcePosition(instr, node);
+ }
return;
}
@@ -2501,14 +2610,13 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
if (write_barrier_kind == kSkippedWriteBarrier) {
code = kArchAtomicStoreSkippedWriteBarrier;
- code |= RecordWriteModeField::encode(RecordWriteMode::kValueIsAny);
temps[temp_count++] = g.TempRegister();
temps[temp_count++] = g.TempRegister();
} else {
RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
code = kArchAtomicStoreWithWriteBarrier;
- code |= RecordWriteModeField::encode(record_write_mode);
+ code |= AtomicStoreRecordWriteModeField::encode(record_write_mode);
}
} else {
switch (rep) {
@@ -2725,6 +2833,9 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
if (const ComparisonOp* comparison = value_op.TryCast<ComparisonOp>()) {
switch (comparison->rep.value()) {
case RegisterRepresentation::Word32():
+#ifdef V8_COMPRESS_POINTERS
+ case RegisterRepresentation::Tagged():
+#endif
cont->OverwriteAndNegateIfEqual(
GetComparisonFlagCondition(*comparison));
return VisitWord32Compare(this, value, cont);
@@ -2783,19 +2894,21 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
binop && CanDoBranchIfOverflowFusion(node)) {
const bool is64 = binop->rep == WordRepresentation::Word64();
switch (binop->kind) {
- case OverflowCheckedBinopOp::Kind::kSignedAdd:
+ case OverflowCheckedBinopOp::Kind::kSignedAdd: {
cont->OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(
- this, node, is64 ? kLoong64AddOvf_d : kLoong64Add_d, cont);
- case OverflowCheckedBinopOp::Kind::kSignedSub:
+ ArchOpcode opcode = is64 ? kLoong64AddOvf_d : kLoong64AddOvf_w;
+ return VisitBinop(this, node, opcode, cont);
+ }
+ case OverflowCheckedBinopOp::Kind::kSignedSub: {
cont->OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(
- this, node, is64 ? kLoong64SubOvf_d : kLoong64Sub_d, cont);
- case OverflowCheckedBinopOp::Kind::kSignedMul:
+ ArchOpcode opcode = is64 ? kLoong64SubOvf_d : kLoong64SubOvf_w;
+ return VisitBinop(this, node, opcode, cont);
+ }
+ case OverflowCheckedBinopOp::Kind::kSignedMul: {
cont->OverwriteAndNegateIfEqual(kOverflow);
- return VisitBinop(this, node,
- is64 ? kLoong64MulOvf_d : kLoong64MulOvf_w,
- cont);
+ ArchOpcode opcode = is64 ? kLoong64MulOvf_d : kLoong64MulOvf_w;
+ return VisitBinop(this, node, opcode, true, opcode, cont);
+ }
}
}
}
@@ -2882,17 +2995,17 @@ void InstructionSelector::VisitWord32Equal(OpIndex node) {
Loong64OperandGenerator g(this);
const RootsTable& roots_table = isolate()->roots_table();
RootIndex root_index;
- Handle<HeapObject> right;
+ Handle<HeapObject> heap_object;
// HeapConstants and CompressedHeapConstants can be treated the same when
// using them as an input to a 32-bit comparison. Check whether either is
// present.
- if (MatchHeapConstant(node, &right) && !right.is_null() &&
- roots_table.IsRootHandle(right, &root_index)) {
+ if (MatchHeapConstant(right, &heap_object) && !heap_object.is_null() &&
+ roots_table.IsRootHandle(heap_object, &root_index)) {
if (RootsTable::IsReadOnly(root_index)) {
Tagged_t ptr =
MacroAssemblerBase::ReadOnlyRootPtr(root_index, isolate());
- if (g.CanBeImmediate(ptr, kLoong64Cmp32)) {
- VisitCompare(this, kLoong64Cmp32, g.UseRegister(left),
+ if (g.CanBeImmediate(ptr, kLoong64Cmp32Eq)) {
+ VisitCompare(this, kLoong64Cmp32Eq, g.UseRegister(left),
g.TempImmediate(int32_t(ptr)), &cont);
return;
}
@@ -2928,22 +3041,23 @@ void InstructionSelector::VisitInt32AddWithOverflow(OpIndex node) {
OptionalOpIndex ovf = FindProjection(node, 1);
if (ovf.valid() && IsUsed(ovf.value())) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf.value());
- return VisitBinop(this, node, kLoong64Add_d, &cont);
+ return VisitBinop(this, node, kLoong64AddOvf_w, true, kLoong64AddOvf_w,
+ &cont);
}
FlagsContinuation cont;
- VisitBinop(this, node, kLoong64Add_d, &cont);
+ VisitBinop(this, node, kLoong64AddOvf_w, true, kLoong64AddOvf_w, &cont);
}
void InstructionSelector::VisitInt32SubWithOverflow(OpIndex node) {
OptionalOpIndex ovf = FindProjection(node, 1);
if (ovf.valid()) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf.value());
- return VisitBinop(this, node, kLoong64Sub_d, &cont);
+ return VisitBinop(this, node, kLoong64SubOvf_w, &cont);
}
FlagsContinuation cont;
- VisitBinop(this, node, kLoong64Sub_d, &cont);
+ VisitBinop(this, node, kLoong64SubOvf_w, &cont);
}
void InstructionSelector::VisitInt32MulWithOverflow(OpIndex node) {
@@ -2972,11 +3086,12 @@ void InstructionSelector::VisitInt64AddWithOverflow(OpIndex node) {
OptionalOpIndex ovf = FindProjection(node, 1);
if (ovf.valid()) {
FlagsContinuation cont = FlagsContinuation::ForSet(kOverflow, ovf.value());
- return VisitBinop(this, node, kLoong64AddOvf_d, &cont);
+ return VisitBinop(this, node, kLoong64AddOvf_d, true, kLoong64AddOvf_d,
+ &cont);
}
FlagsContinuation cont;
- VisitBinop(this, node, kLoong64AddOvf_d, &cont);
+ VisitBinop(this, node, kLoong64AddOvf_d, true, kLoong64AddOvf_d, &cont);
}
void InstructionSelector::VisitInt64SubWithOverflow(OpIndex node) {
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 0a33c998003..750cceb960d 100644
--- a/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc
+++ b/deps/v8/src/compiler/backend/mips64/code-generator-mips64.cc
@@ -902,7 +902,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchStoreWithWriteBarrier: // Fall through.
case kArchAtomicStoreWithWriteBarrier: {
DCHECK_EQ(AddressingModeField::decode(instr->opcode()), kMode_None);
- RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode =
+ arch_opcode == kArchStoreWithWriteBarrier
+ ? RecordWriteModeField::decode(instr->opcode())
+ : AtomicStoreRecordWriteModeField::decode(instr->opcode());
Register object = i.InputRegister(0);
Register index = i.InputRegister(1);
Register value = i.InputRegister(2);
@@ -4316,7 +4319,9 @@ void CodeGenerator::AssembleConstructFrame() {
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
#if V8_ENABLE_WEBASSEMBLY
- if (info()->IsWasm() && required_slots * kSystemPointerSize > 4 * KB) {
+ int32_t stack_space =
+ required_slots * kSystemPointerSize + GetStackCheckOffset();
+ if (info()->IsWasm() && stack_space > 4 * KB) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
// have enough space on the stack to call the runtime for the stack
@@ -4326,11 +4331,10 @@ void CodeGenerator::AssembleConstructFrame() {
// If the frame is bigger than the stack, we throw the stack overflow
// exception unconditionally. Thereby we can avoid the integer overflow
// check in the condition code.
- if (required_slots * kSystemPointerSize < v8_flags.stack_size * KB) {
+ if (stack_space < v8_flags.stack_size * KB) {
__ LoadStackLimit(kScratchReg,
MacroAssembler::StackLimitKind::kRealStackLimit);
- __ Daddu(kScratchReg, kScratchReg,
- Operand(required_slots * kSystemPointerSize));
+ __ Daddu(kScratchReg, kScratchReg, Operand(stack_space));
__ Branch(&done, uge, sp, Operand(kScratchReg));
}
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 062c5d3aeea..b23b324c393 100644
--- a/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc
+++ b/deps/v8/src/compiler/backend/mips64/instruction-selector-mips64.cc
@@ -807,9 +807,12 @@ void VisitWideAddSub(InstructionSelector* selector, OpIndex node, bool is_add) {
InstructionCode opcode_no_high = is_add ? kMips64Dadd : kMips64Dsub;
if (!out_high.valid() || !selector->IsUsed(out_high.value())) {
- InstructionOperand b_low_op = g.UseOperand(op.right_low(), opcode_no_high);
- selector->Emit(opcode_no_high, g.DefineAsRegister(out_low.value()),
- g.UseRegister(op.left_low()), b_low_op);
+ if (out_low.valid() && selector->IsUsed(out_low.value())) {
+ InstructionOperand b_low_op =
+ g.UseOperand(op.right_low(), opcode_no_high);
+ selector->Emit(opcode_no_high, g.DefineAsRegister(out_low.value()),
+ g.UseRegister(op.left_low()), b_low_op);
+ }
return;
}
@@ -1831,7 +1834,7 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
InstructionOperand temps[] = {g.TempRegister(), g.TempRegister()};
size_t const temp_count = arraysize(temps);
code = kArchAtomicStoreWithWriteBarrier;
- code |= RecordWriteModeField::encode(record_write_mode);
+ code |= AtomicStoreRecordWriteModeField::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/move-optimizer.cc b/deps/v8/src/compiler/backend/move-optimizer.cc
index d9183e2a92e..dd4348850ca 100644
--- a/deps/v8/src/compiler/backend/move-optimizer.cc
+++ b/deps/v8/src/compiler/backend/move-optimizer.cc
@@ -6,6 +6,10 @@
#include "src/codegen/register-configuration.h"
+#if V8_TARGET_ARCH_ARM64
+#include "src/codegen/macro-assembler.h"
+#endif
+
namespace v8 {
namespace internal {
namespace compiler {
@@ -510,6 +514,38 @@ bool IsSlot(const InstructionOperand& op) {
return op.IsStackSlot() || op.IsFPStackSlot();
}
+#if V8_TARGET_ARCH_ARM64
+// On arm64, a constant that materializes in one MOVZ/MOVN/ORR-immediate
+// instruction costs exactly as much as a register-register copy, so replacing
+// its rematerialization with a copy from the first destination only makes the
+// second move depend on the first. Copies into stack slots still win: STR from
+// the first destination beats materialize-into-scratch + STR.
+bool IsOneInstrConstant(const InstructionSequence* code,
+ const InstructionOperand& op) {
+ if (!op.IsConstant()) return false;
+ Constant constant =
+ code->GetConstant(ConstantOperand::cast(op).virtual_register());
+ uint64_t imm;
+ unsigned size;
+ switch (constant.type()) {
+ case Constant::kInt32:
+ imm = static_cast<uint32_t>(constant.ToInt32());
+ size = kWRegSizeInBits;
+ break;
+ case Constant::kInt64:
+ imm = static_cast<uint64_t>(constant.ToInt64());
+ size = kXRegSizeInBits;
+ break;
+ default:
+ return false;
+ }
+ unsigned n, imm_s, imm_r;
+ return MacroAssembler::IsImmMovz(imm, size) ||
+ MacroAssembler::IsImmMovn(imm, size) ||
+ Assembler::IsImmLogical(imm, size, &n, &imm_s, &imm_r);
+}
+#endif // V8_TARGET_ARCH_ARM64
+
bool Is64BitsWide(const InstructionOperand& op) {
MachineRepresentation rep = LocationOperand::cast(&op)->representation();
#if V8_COMPRESS_POINTERS
@@ -581,6 +617,14 @@ void MoveOptimizer::FinalizeMoves(Instruction* instr) {
group_begin = load;
continue;
}
+#if V8_TARGET_ARCH_ARM64
+ // Rematerializing a one-instruction constant costs the same as copying it
+ // from {group_begin} and leaves the two moves independent.
+ if (!IsSlot(load->destination()) &&
+ IsOneInstrConstant(code(), load->source())) {
+ continue;
+ }
+#endif
// Insert new move into slot 1.
ParallelMove* slot_1 = instr->GetOrCreateParallelMove(
static_cast<Instruction::GapPosition>(1), code_zone());
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 20417bbe66d..7f20bd01fa2 100644
--- a/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
+++ b/deps/v8/src/compiler/backend/ppc/instruction-selector-ppc.cc
@@ -1194,6 +1194,10 @@ void InstructionSelector::VisitUint64Add128(OpIndex node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitUint64Sub128(OpIndex node) { UNIMPLEMENTED(); }
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ UNREACHABLE();
+}
+
void InstructionSelector::VisitUint32MulHigh(OpIndex node) {
PPCOperandGenerator g(this);
const WordBinopOp& op = Cast<WordBinopOp>(node);
diff --git a/deps/v8/src/compiler/backend/register-allocation.h b/deps/v8/src/compiler/backend/register-allocation.h
index c131774ad77..e8465947f99 100644
--- a/deps/v8/src/compiler/backend/register-allocation.h
+++ b/deps/v8/src/compiler/backend/register-allocation.h
@@ -6,6 +6,7 @@
#define V8_COMPILER_BACKEND_REGISTER_ALLOCATION_H_
#include "src/base/logging.h"
+#include "src/codegen/machine-type.h"
#include "src/codegen/register-configuration.h"
#include "src/zone/zone.h"
@@ -13,7 +14,14 @@ namespace v8 {
namespace internal {
namespace compiler {
-enum class RegisterKind { kGeneral, kDouble, kSimd128 };
+enum class RegisterKind { kGeneral, kDouble, kSimd128, kSimd256 };
+
+inline RegisterKind RegisterKindFor(MachineRepresentation rep) {
+ if (IsSimd256(rep)) return RegisterKind::kSimd256;
+ if (IsSimd128(rep)) return RegisterKind::kSimd128;
+ if (IsFloatingPoint(rep)) return RegisterKind::kDouble;
+ return RegisterKind::kGeneral;
+}
inline int GetRegisterCount(const RegisterConfiguration* config,
RegisterKind kind) {
@@ -24,6 +32,8 @@ inline int GetRegisterCount(const RegisterConfiguration* config,
return config->num_double_registers();
case RegisterKind::kSimd128:
return config->num_simd128_registers();
+ case RegisterKind::kSimd256:
+ UNREACHABLE();
}
UNREACHABLE();
}
@@ -37,6 +47,8 @@ inline int GetAllocatableRegisterCount(const RegisterConfiguration* config,
return config->num_allocatable_double_registers();
case RegisterKind::kSimd128:
return config->num_allocatable_simd128_registers();
+ case RegisterKind::kSimd256:
+ UNREACHABLE();
}
UNREACHABLE();
}
@@ -50,6 +62,8 @@ inline const int* GetAllocatableRegisterCodes(
return config->allocatable_double_codes();
case RegisterKind::kSimd128:
return config->allocatable_simd128_codes();
+ case RegisterKind::kSimd256:
+ UNREACHABLE();
}
UNREACHABLE();
}
diff --git a/deps/v8/src/compiler/backend/register-allocator.cc b/deps/v8/src/compiler/backend/register-allocator.cc
index a2fb9009cc6..6e85eca1299 100644
--- a/deps/v8/src/compiler/backend/register-allocator.cc
+++ b/deps/v8/src/compiler/backend/register-allocator.cc
@@ -1000,8 +1000,9 @@ void LinearScanAllocator::PrintRangeRow(std::ostream& os,
if (range->spilled()) {
prefix = snprintf(buffer, max_prefix_length, "|%s", kind_string);
} else {
- prefix = snprintf(buffer, max_prefix_length, "|%s",
- RegisterName(range->assigned_register()));
+ prefix = snprintf(
+ buffer, max_prefix_length, "|%s",
+ RegisterName(range->assigned_register(), range->representation()));
}
os << buffer;
position += std::min(prefix, max_prefix_length - 1);
@@ -2936,19 +2937,30 @@ void RegisterAllocator::Spill(LiveRange* range, SpillMode spill_mode) {
range->Spill();
}
-const char* RegisterAllocator::RegisterName(int register_code) const {
+const char* RegisterAllocator::RegisterName(int register_code,
+ RegisterKind kind) const {
if (register_code == kUnassignedRegister) return "unassigned";
- switch (mode()) {
+ switch (kind) {
case RegisterKind::kGeneral:
return i::RegisterName(Register::from_code(register_code));
case RegisterKind::kDouble:
return i::RegisterName(DoubleRegister::from_code(register_code));
case RegisterKind::kSimd128:
return i::RegisterName(Simd128Register::from_code(register_code));
+ case RegisterKind::kSimd256:
+#if V8_TARGET_ARCH_X64
+ return i::RegisterName(Simd256Register::from_code(register_code));
+#else
+ UNREACHABLE();
+#endif
}
UNREACHABLE();
}
+const char* RegisterAllocator::RegisterName(int register_code,
+ MachineRepresentation rep) const {
+ return RegisterName(register_code, RegisterKindFor(rep));
+}
LinearScanAllocator::LinearScanAllocator(RegisterAllocationData* data,
RegisterKind kind, Zone* local_zone)
: RegisterAllocator(data, kind),
@@ -3019,7 +3031,8 @@ void LinearScanAllocator::SpillNotLiveRanges(RangeRegisterSmallMap& to_be_live,
// them and reschedule but the code does not allow to do this.
if (toplevel->IsFixed()) {
TRACE("Keeping reactivated fixed range for %s\n",
- RegisterName(toplevel->assigned_register()));
+ RegisterName(toplevel->assigned_register(),
+ toplevel->representation()));
++it;
} else {
// When spilling a previously spilled/reloaded range, we add back the
@@ -3071,7 +3084,8 @@ void LinearScanAllocator::SpillNotLiveRanges(RangeRegisterSmallMap& to_be_live,
// Was life and in correct register, simply pass through.
TRACE("Keeping %d:%d in %s\n", toplevel->vreg(),
active_range->relative_id(),
- RegisterName(active_range->assigned_register()));
+ RegisterName(active_range->assigned_register(),
+ active_range->representation()));
++it;
} else {
// Was life but wrong register. Split and schedule for
@@ -3393,7 +3407,7 @@ void LinearScanAllocator::ComputeStateFromManyPredecessors(
taken_registers[reg] = true;
}
TRACE("Reset %d as live due vote %zu in %s\n", val.first->vreg(),
- val.second.count, RegisterName(reg));
+ val.second.count, RegisterName(reg, val.first->representation()));
auto [_, inserted] = to_be_live.emplace(val.first, reg);
DCHECK(inserted);
USE(inserted);
@@ -3460,9 +3474,10 @@ void LinearScanAllocator::UpdateDeferredFixedRanges(SpillMode spill_mode,
}
// They overlap. So we need to split active and reschedule it
// for allocation.
- TRACE("Resolving conflict of %d with deferred fixed for register %s\n",
- other->TopLevel()->vreg(),
- RegisterName(other->assigned_register()));
+ TRACE(
+ "Resolving conflict of %d with deferred fixed for register %s\n",
+ other->TopLevel()->vreg(),
+ RegisterName(other->assigned_register(), other->representation()));
LiveRange* split_off =
other->SplitAt(next_start, data()->allocation_zone());
// Try to get the same register after the deferred block.
@@ -3861,7 +3876,8 @@ void LinearScanAllocator::SetLiveRangeAssignedRegister(LiveRange* range,
void LinearScanAllocator::AddToActive(LiveRange* range) {
TRACE("Add live range %d:%d in %s to active\n", range->TopLevel()->vreg(),
- range->relative_id(), RegisterName(range->assigned_register()));
+ range->relative_id(),
+ RegisterName(range->assigned_register(), range->representation()));
active_live_ranges().push_back(range);
next_active_ranges_change_ =
std::min(next_active_ranges_change_, range->NextEndAfter(range->Start()));
@@ -4039,21 +4055,23 @@ void LinearScanAllocator::GetSIMD128RegisterSet(int* num_regs, int* num_codes,
void LinearScanAllocator::FindFreeRegistersForRange(
LiveRange* range, base::Vector<LifetimePosition> positions) {
- int num_regs = num_registers();
- int num_codes = num_allocatable_registers();
- const int* codes = allocatable_register_codes();
+ int num_regs_for_rep = num_registers();
+ int num_codes_unused = num_allocatable_registers();
+ const int* codes_unused = allocatable_register_codes();
MachineRepresentation rep = range->representation();
if (kFPAliasing == AliasingKind::kCombine &&
(rep == MachineRepresentation::kFloat32 ||
rep == MachineRepresentation::kSimd128)) {
- GetFPRegisterSet(rep, &num_regs, &num_codes, &codes);
+ GetFPRegisterSet(rep, &num_regs_for_rep, &num_codes_unused, &codes_unused);
} else if (kFPAliasing == AliasingKind::kIndependent &&
(rep == MachineRepresentation::kSimd128)) {
- GetSIMD128RegisterSet(&num_regs, &num_codes, &codes);
+ GetSIMD128RegisterSet(&num_regs_for_rep, &num_codes_unused, &codes_unused);
}
- DCHECK_GE(positions.length(), num_regs);
+ DCHECK_GE(positions.length(), num_regs_for_rep);
- for (int i = 0; i < num_regs; ++i) {
+ // All registers are considered free until the end initially, and refined
+ // below by checking registers already assigned to active and inactive ranges.
+ for (int i = 0; i < num_regs_for_rep; ++i) {
positions[i] = LifetimePosition::MaxPosition();
}
@@ -4062,7 +4080,7 @@ void LinearScanAllocator::FindFreeRegistersForRange(
if (kFPAliasing != AliasingKind::kCombine || !check_fp_aliasing()) {
positions[cur_reg] = LifetimePosition::GapFromInstructionIndex(0);
TRACE("Register %s is free until pos %d (1) due to %d\n",
- RegisterName(cur_reg),
+ RegisterName(cur_reg, cur_active->representation()),
LifetimePosition::GapFromInstructionIndex(0).value(),
cur_active->TopLevel()->vreg());
} else {
@@ -4073,11 +4091,15 @@ void LinearScanAllocator::FindFreeRegistersForRange(
while (aliases--) {
int aliased_reg = alias_base_index + aliases;
positions[aliased_reg] = LifetimePosition::GapFromInstructionIndex(0);
+ TRACE("Register %s is free until pos %d (1) due to %d\n",
+ RegisterName(aliased_reg, rep),
+ LifetimePosition::GapFromInstructionIndex(0).value(),
+ cur_active->TopLevel()->vreg());
}
}
}
- for (int cur_reg = 0; cur_reg < num_regs; ++cur_reg) {
+ for (int cur_reg = 0; cur_reg < num_registers(); ++cur_reg) {
SlowDCheckInactiveLiveRangesIsSorted(cur_reg);
for (LiveRange* cur_inactive : inactive_live_ranges(cur_reg)) {
DCHECK_GT(cur_inactive->End(), range->Start());
@@ -4095,7 +4117,8 @@ void LinearScanAllocator::FindFreeRegistersForRange(
if (!next_intersection.IsValid()) continue;
if (kFPAliasing != AliasingKind::kCombine || !check_fp_aliasing()) {
positions[cur_reg] = std::min(positions[cur_reg], next_intersection);
- TRACE("Register %s is free until pos %d (2)\n", RegisterName(cur_reg),
+ TRACE("Register %s is free until pos %d (2)\n",
+ RegisterName(cur_reg, cur_inactive->representation()),
positions[cur_reg].value());
} else {
int alias_base_index = -1;
@@ -4106,6 +4129,8 @@ void LinearScanAllocator::FindFreeRegistersForRange(
int aliased_reg = alias_base_index + aliases;
positions[aliased_reg] =
std::min(positions[aliased_reg], next_intersection);
+ TRACE("Register %s is free until pos %d (2)\n",
+ RegisterName(aliased_reg, rep), positions[aliased_reg].value());
}
}
}
@@ -4142,15 +4167,15 @@ bool LinearScanAllocator::TryAllocatePreferredReg(
current->RegisterFromBundle(&hint_register)) {
TRACE(
"Found reg hint %s (free until [%d) for live range %d:%d (end %d[).\n",
- RegisterName(hint_register), free_until_pos[hint_register].value(),
- current->TopLevel()->vreg(), current->relative_id(),
- current->End().value());
+ RegisterName(hint_register, current->representation()),
+ free_until_pos[hint_register].value(), current->TopLevel()->vreg(),
+ current->relative_id(), current->End().value());
// The desired register is free until the end of the current live range.
if (free_until_pos[hint_register] >= current->End()) {
TRACE("Assigning preferred reg %s to live range %d:%d\n",
- RegisterName(hint_register), current->TopLevel()->vreg(),
- current->relative_id());
+ RegisterName(hint_register, current->representation()),
+ current->TopLevel()->vreg(), current->relative_id());
SetLiveRangeAssignedRegister(current, hint_register);
return true;
}
@@ -4192,7 +4217,8 @@ int LinearScanAllocator::PickRegisterThatIsAvailableLongest(
// We use the first register that has no fixed uses to ensure we use
// byte addressable registers in ia32 first.
int candidate_free = free_until_pos[code].ToInstructionIndex();
- TRACE("Register %s in free until %d\n", RegisterName(code), candidate_free);
+ TRACE("Register %s in free until %d\n",
+ RegisterName(code, current->representation()), candidate_free);
if ((candidate_free > current_free) ||
(candidate_free == current_free && reg != hint_reg &&
(data()->HasFixedUse(current->representation(), reg) &&
@@ -4242,7 +4268,8 @@ bool LinearScanAllocator::TryAllocateFreeReg(
// Register reg is available at the range start and is free until the range
// end.
DCHECK_GE(pos, current->End());
- TRACE("Assigning free reg %s to live range %d:%d\n", RegisterName(reg),
+ TRACE("Assigning free reg %s to live range %d:%d\n",
+ RegisterName(reg, current->representation()),
current->TopLevel()->vreg(), current->relative_id());
SetLiveRangeAssignedRegister(current, reg);
@@ -4407,7 +4434,8 @@ void LinearScanAllocator::AllocateBlockedReg(LiveRange* current,
// Register reg is not blocked for the whole range.
DCHECK(block_pos[reg] >= current->End());
- TRACE("Assigning blocked reg %s to live range %d:%d\n", RegisterName(reg),
+ TRACE("Assigning blocked reg %s to live range %d:%d\n",
+ RegisterName(reg, current->representation()),
current->TopLevel()->vreg(), current->relative_id());
SetLiveRangeAssignedRegister(current, reg);
@@ -4601,7 +4629,7 @@ void LinearScanAllocator::SpillBetweenUntil(LiveRange* range,
// Try to use the same register as before.
TRACE("Setting control flow hint for %d:%d to %s\n",
third_part->TopLevel()->vreg(), third_part->relative_id(),
- RegisterName(range->controlflow_hint()));
+ RegisterName(range->controlflow_hint(), range->representation()));
third_part->set_controlflow_hint(range->controlflow_hint());
}
diff --git a/deps/v8/src/compiler/backend/register-allocator.h b/deps/v8/src/compiler/backend/register-allocator.h
index 86d0ad627d3..f97e57ed03f 100644
--- a/deps/v8/src/compiler/backend/register-allocator.h
+++ b/deps/v8/src/compiler/backend/register-allocator.h
@@ -7,6 +7,7 @@
#include "src/base/bits.h"
#include "src/base/compiler-specific.h"
+#include "src/codegen/machine-type.h"
#include "src/codegen/register-configuration.h"
#include "src/common/globals.h"
#include "src/compiler/backend/instruction.h"
@@ -944,13 +945,27 @@ class V8_EXPORT_PRIVATE LiveRange : public NON_EXPORTED_BASE(ZoneObject) {
void VerifyIntervals() const;
#endif
- using SpilledField = base::BitField<bool, 0, 1>;
- // Bits (1,7[ are used by TopLevelLiveRange.
- using AssignedRegisterField = base::BitField<int32_t, 7, 6>;
- using RepresentationField = base::BitField<MachineRepresentation, 13, 8>;
- using RecombineField = base::BitField<bool, 21, 1>;
- using ControlFlowRegisterHint = base::BitField<uint8_t, 22, 6>;
- // Bits 28-31 are used by TopLevelLiveRange.
+ using RepresentationField = base::BitField<MachineRepresentation, 0, 5>;
+ using SpilledField = RepresentationField::Next<bool, 1>;
+ using RecombineField = SpilledField::Next<bool, 1>;
+
+ // Padding to put AssignedRegisterField on a byte boundary, could be used for
+ // something in the future.
+ using UnusedField = RecombineField::Next<bool, 1>;
+ using AssignedRegisterField = UnusedField::Next<int32_t, 6>;
+ using ControlFlowRegisterHint = AssignedRegisterField::Next<uint8_t, 6>;
+
+ // RepresentationField starts at bit 0 (Byte 0) and AssignedRegisterField
+ // starts at bit 8 (Byte 1). This allows zero-shift hardware byte-loads
+ // for representation and assigned register lookups.
+ static_assert(RepresentationField::kShift == 0);
+ static_assert(AssignedRegisterField::kShift == 8);
+ // RepresentationField can represent all MachineRepresentations.
+ static_assert(RepresentationField::is_valid(
+ MachineRepresentation::kLastRepresentation));
+
+ template <class T, int size>
+ using NextBitField = ControlFlowRegisterHint::Next<T, size>;
// Unique among children of the same virtual register.
int relative_id_;
@@ -1256,13 +1271,14 @@ class V8_EXPORT_PRIVATE TopLevelLiveRange final : public LiveRange {
kSpillLater,
};
- using HasSlotUseField = base::BitField<SlotUseKind, 1, 2>;
- using IsPhiField = base::BitField<bool, 3, 1>;
- using IsNonLoopPhiField = base::BitField<bool, 4, 1>;
- using SpillTypeField = base::BitField<SpillType, 5, 2>;
- using DeferredFixedField = base::BitField<bool, 28, 1>;
- using SpillAtLoopHeaderNotBeneficialField = base::BitField<bool, 29, 1>;
- using SpillRangeModeField = base::BitField<SpillRangeMode, 30, 2>;
+ using HasSlotUseField = NextBitField<SlotUseKind, 2>;
+ using IsPhiField = HasSlotUseField::Next<bool, 1>;
+ using IsNonLoopPhiField = IsPhiField::Next<bool, 1>;
+ using SpillTypeField = IsNonLoopPhiField::Next<SpillType, 2>;
+ using DeferredFixedField = SpillTypeField::Next<bool, 1>;
+ using SpillAtLoopHeaderNotBeneficialField = DeferredFixedField::Next<bool, 1>;
+ using SpillRangeModeField =
+ SpillAtLoopHeaderNotBeneficialField::Next<SpillRangeMode, 2>;
int vreg_;
int last_child_id_;
@@ -1533,7 +1549,9 @@ class RegisterAllocator : public ZoneObject {
LiveRange** begin_spill_out);
const ZoneVector<TopLevelLiveRange*>& GetFixedRegisters() const;
- const char* RegisterName(int allocation_index) const;
+ const char* RegisterName(int allocation_index, RegisterKind kind) const;
+ const char* RegisterName(int allocation_index,
+ MachineRepresentation rep) const;
private:
RegisterAllocationData* const data_;
@@ -1668,6 +1686,9 @@ class LinearScanAllocator final : public RegisterAllocator {
int* num_codes, const int** codes) const;
void GetSIMD128RegisterSet(int* num_regs, int* num_codes,
const int** codes) const;
+ // Computes the lifetime position until which each register of range's
+ // representation is free (or `MaxPosition` if it has no conflicts).
+ // Results are populated in `free_until_pos`.
void FindFreeRegistersForRange(LiveRange* range,
base::Vector<LifetimePosition> free_until_pos);
void ProcessCurrentRange(LiveRange* current, SpillMode spill_mode);
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 d9d5238457c..28c7bf6ab86 100644
--- a/deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc
+++ b/deps/v8/src/compiler/backend/riscv/code-generator-riscv.cc
@@ -459,8 +459,8 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate,
*predicate = true;
return GE;
case kFloatLessThanOrUnordered:
- *predicate = true;
- return LT;
+ *predicate = false;
+ return GE;
case kFloatGreaterThanOrUnordered:
*predicate = false;
return LE;
@@ -468,8 +468,8 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate,
*predicate = false;
return LT;
case kFloatLessThanOrEqualOrUnordered:
- *predicate = true;
- return LE;
+ *predicate = false;
+ return GT;
default:
*predicate = true;
break;
@@ -477,6 +477,44 @@ FPUCondition FlagsConditionToConditionCmpFPU(bool* predicate,
UNREACHABLE();
}
+// Emits the actual floating-point comparison for a kRiscvCmpS/kRiscvCmpD
+// instruction, materializing its boolean result (0 or 1) into {dst}.
+// The comparison itself is a pseudo-instruction (like the integer kRiscvCmp):
+// nothing is emitted at the instruction site. Instead, the comparison and the
+// FPUCondition-to-machine mapping are resolved together here, at the single
+// flags consumer (branch, boolean materialization, or select), using the
+// consumer's final FlagsCondition {condition} (which ComputeBranchInfo may
+// have negated for branches). This makes it structurally impossible for
+// complementary conditions to observe a comparison that was emitted for a
+// different condition.
+// The returned predicate tells the consumer how to interpret {dst}: when
+// false, the comparison result must be inverted to obtain the condition's
+// truth value (this is how conditions involving "unordered" are expressed
+// with RISC-V's NaN-false flt/fle/feq instructions).
+void EmitFPCompare(MacroAssembler* masm, RiscvOperandConverter& i,
+ Instruction* instr, FlagsCondition condition, Register dst,
+ bool* predicate) {
+ FPUCondition cc = FlagsConditionToConditionCmpFPU(predicate, condition);
+ if (instr->arch_opcode() == kRiscvCmpS) {
+ FPURegister left = i.InputOrZeroSingleRegister(0);
+ FPURegister right = i.InputOrZeroSingleRegister(1);
+ if ((left == kSingleRegZero || right == kSingleRegZero) &&
+ !masm->IsSingleZeroRegSet()) {
+ masm->LoadFPRImmediate(kSingleRegZero, 0.0f);
+ }
+ masm->CompareF32(dst, cc, left, right);
+ } else {
+ DCHECK_EQ(instr->arch_opcode(), kRiscvCmpD);
+ FPURegister left = i.InputOrZeroDoubleRegister(0);
+ FPURegister right = i.InputOrZeroDoubleRegister(1);
+ if ((left == kDoubleRegZero || right == kDoubleRegZero) &&
+ !masm->IsDoubleZeroRegSet()) {
+ masm->LoadFPRImmediate(kDoubleRegZero, 0.0);
+ }
+ masm->CompareF64(dst, cc, left, right);
+ }
+}
+
#if V8_ENABLE_WEBASSEMBLY
class WasmOutOfLineTrap : public OutOfLineCode {
public:
@@ -772,6 +810,23 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
DCHECK(instr->arch_opcode() == kRiscvCmp32 ||
instr->arch_opcode() == kRiscvCmp);
}
+#if V8_TARGET_ARCH_RISCV64
+ if (COMPRESS_POINTERS_BOOL) {
+ // 32-bit comparisons must compare sign-extended values, since 32-bit
+ // producers may leave dirty upper bits in their result registers.
+ if (instr->arch_opcode() == kRiscvCmpZero32 ||
+ instr->arch_opcode() == kRiscvCmp32) {
+ Register temp = i.TempRegister(0);
+ __ SignExtendWord(temp, left);
+ left = temp;
+ if (instr->arch_opcode() == kRiscvCmp32 && i.InputOperand(1).is_reg()) {
+ Register temp1 = i.TempRegister(1);
+ __ SignExtendWord(temp1, i.InputOperand(1).rm());
+ right = Operand(temp1);
+ }
+ }
+ }
+#endif
if ((output_rep == MachineRepresentation::kFloat32) ||
(output_rep == MachineRepresentation::kFloat64)) {
UNREACHABLE();
@@ -797,11 +852,10 @@ void CodeGenerator::AssembleArchSelect(Instruction* instr,
}
} else {
bool predicate;
- FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition());
+ EmitFPCompare(masm(), i, instr, condition, kScratchReg, &predicate);
auto true_op = i.InputOperand(true_value_index);
auto false_op = i.InputOperand(false_value_index);
Label true_label, end_label;
- // floating-point compare result is set in kScratchReg
if (predicate) {
__ BranchTrueF(kScratchReg, &true_label);
} else {
@@ -1712,26 +1766,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
// Pseudo-instruction used for cmpzero/branch. No opcode emitted here.
break;
- case kRiscvCmpS: {
- FPURegister left = i.InputOrZeroSingleRegister(0);
- FPURegister right = i.InputOrZeroSingleRegister(1);
- bool predicate;
- FPUCondition cc =
- FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition());
-
- if ((left == kSingleRegZero || right == kSingleRegZero) &&
- !__ IsSingleZeroRegSet()) {
- __ LoadFPRImmediate(kSingleRegZero, 0.0f);
- }
- switch (FlagsModeField::decode(instr->opcode())) {
- case kFlags_set:
- __ CompareF32(i.OutputRegister(), cc, left, right);
- break;
- default:
- __ CompareF32(kScratchReg, cc, left, right);
- break;
- }
- } break;
+ case kRiscvCmpS:
+ // Pseudo-instruction used for FP cmp/branch. No opcode emitted here;
+ // the comparison is emitted by the flags consumer via EmitFPCompare.
+ break;
case kRiscvAddS:
// TODO(plind): add special case: combine mult & add.
__ fadd_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0),
@@ -1760,25 +1798,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
__ fsqrt_s(i.OutputDoubleRegister(), i.InputDoubleRegister(0));
break;
}
- case kRiscvCmpD: {
- FPURegister left = i.InputOrZeroDoubleRegister(0);
- FPURegister right = i.InputOrZeroDoubleRegister(1);
- bool predicate;
- FPUCondition cc =
- FlagsConditionToConditionCmpFPU(&predicate, instr->flags_condition());
- if ((left == kDoubleRegZero || right == kDoubleRegZero) &&
- !__ IsDoubleZeroRegSet()) {
- __ LoadFPRImmediate(kDoubleRegZero, 0.0);
- }
- switch (FlagsModeField::decode(instr->opcode())) {
- case kFlags_set:
- __ CompareF64(i.OutputRegister(), cc, left, right);
- break;
- default:
- __ CompareF64(kScratchReg, cc, left, right);
- break;
- }
- } break;
+ case kRiscvCmpD:
+ // Pseudo-instruction used for FP cmp/branch. No opcode emitted here;
+ // the comparison is emitted by the flags consumer via EmitFPCompare.
+ break;
#if V8_TARGET_ARCH_RISCV32
case kRiscvAddPair:
__ AddPair(i.OutputRegister(0), i.OutputRegister(1), i.InputRegister(0),
@@ -2510,8 +2533,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kAtomicExchangeWithWriteBarrier: {
if constexpr (COMPRESS_POINTERS_BOOL) {
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Ll, Sc);
- __ AddWord(i.OutputRegister(), i.OutputRegister(),
- kPtrComprCageBaseRegister);
+ __ ZeroExtendWord(i.OutputRegister(), i.OutputRegister());
+ __ Or(i.OutputRegister(), i.OutputRegister(),
+ kPtrComprCageBaseRegister);
} else {
ASSEMBLE_ATOMIC_EXCHANGE_INTEGER(Lld, Scd);
}
@@ -2795,9 +2819,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kRiscvAtomicStoreCompressTagged: {
- size_t index = 0;
- MemOperand mem = i.MemoryOperand(&index);
- __ AtomicStoreTaggedField(i.InputOrZeroRegister(index), mem, trapper);
+ MemOperand mem = i.MemoryOperand(1);
+ __ AtomicStoreTaggedField(i.InputOrZeroRegister(0), mem, trapper);
break;
}
case kRiscvLoadDecompressTrapping: {
@@ -3054,9 +3077,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kRiscvI8x16ShrU: {
__ VU.SetSimd128(E8);
if (instr->InputAt(1)->IsRegister()) {
- __ andi(i.InputRegister(1), i.InputRegister(1), 8 - 1);
+ __ andi(kScratchReg, i.InputRegister(1), 8 - 1);
__ vsrl_vx(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputRegister(1));
+ kScratchReg);
} else {
__ vsrl_vi(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1) % 8);
@@ -3066,9 +3089,9 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kRiscvI16x8ShrU: {
__ VU.SetSimd128(E16);
if (instr->InputAt(1)->IsRegister()) {
- __ andi(i.InputRegister(1), i.InputRegister(1), 16 - 1);
+ __ andi(kScratchReg, i.InputRegister(1), 16 - 1);
__ vsrl_vx(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputRegister(1));
+ kScratchReg);
} else {
__ vsrl_vi(i.OutputSimd128Register(), i.InputSimd128Register(0),
i.InputInt5(1) % 16);
@@ -4853,8 +4876,7 @@ void AssembleBranchToLabels(CodeGenerator* gen, MacroAssembler* masm,
} else if (instr->arch_opcode() == kRiscvCmpS ||
instr->arch_opcode() == kRiscvCmpD) {
bool predicate;
- FlagsConditionToConditionCmpFPU(&predicate, condition);
- // floating-point compare result is set in kScratchReg
+ EmitFPCompare(masm, i, instr, condition, kScratchReg, &predicate);
if (predicate) {
__ BranchTrueF(kScratchReg, tlabel);
} else {
@@ -5230,7 +5252,7 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
} else if (instr->arch_opcode() == kRiscvCmpD ||
instr->arch_opcode() == kRiscvCmpS) {
bool predicate;
- FlagsConditionToConditionCmpFPU(&predicate, condition);
+ EmitFPCompare(masm(), i, instr, condition, result, &predicate);
// RISCV compare returns 0 or 1, do nothing when predicate; otherwise
// toggle result (i.e., 0 -> 1, 1 -> 0)
if (!predicate) {
@@ -5282,6 +5304,7 @@ void CodeGenerator::AssembleArchBinarySearchSwitchRange(
void CodeGenerator::AssembleArchBinarySearchSwitch(Instruction* instr) {
RiscvOperandConverter i(this, instr);
Register input = i.InputRegister(0);
+ Register scratch = input;
std::vector<std::pair<int32_t, Label*>> cases;
for (size_t index = 2; index < instr->InputCount(); index += 2) {
cases.push_back({i.InputInt32(index + 0), GetLabel(i.InputRpo(index + 1))});
@@ -5295,9 +5318,11 @@ void CodeGenerator::AssembleArchBinarySearchSwitch(Instruction* instr) {
// AssembleArchBinarySearchSwitch, we perform the sign extension once here,
// rather than repeatedly in JumpIfEqual and JumpIfLessThan. This reduces the
// total number of sign extension operations and improves efficiency.
- __ SignExtendWord(input, input);
+ UseScratchRegisterScope temps(masm());
+ scratch = temps.Acquire();
+ __ SignExtendWord(scratch, input);
#endif
- AssembleArchBinarySearchSwitchRange(input, i.InputRpo(1), cases.data(),
+ AssembleArchBinarySearchSwitchRange(scratch, i.InputRpo(1), cases.data(),
cases.data() + cases.size());
}
@@ -5390,7 +5415,10 @@ void CodeGenerator::AssembleConstructFrame() {
if (required_slots > 0) {
DCHECK(frame_access_state()->has_frame());
- if (info()->IsWasm() && required_slots > 128) {
+#if V8_ENABLE_WEBASSEMBLY
+ int32_t stack_space =
+ required_slots * kSystemPointerSize + GetStackCheckOffset();
+ if (info()->IsWasm() && stack_space > 4 * KB) {
// For WebAssembly functions with big frames we have to do the stack
// overflow check before we construct the frame. Otherwise we may not
// have enough space on the stack to call the runtime for the stack
@@ -5400,12 +5428,11 @@ void CodeGenerator::AssembleConstructFrame() {
// If the frame is bigger than the stack, we throw the stack overflow
// exception unconditionally. Thereby we can avoid the integer overflow
// check in the condition code.
- if ((required_slots * kSystemPointerSize) < (v8_flags.stack_size * KB)) {
+ if (stack_space < (v8_flags.stack_size * KB)) {
UseScratchRegisterScope temps(masm());
Register stack_limit = temps.Acquire();
__ LoadStackLimit(stack_limit, StackLimitKind::kRealStackLimit);
- __ AddWord(stack_limit, stack_limit,
- Operand(required_slots * kSystemPointerSize));
+ __ AddWord(stack_limit, stack_limit, Operand(stack_space));
__ Branch(&done, uge, sp, Operand(stack_limit));
}
@@ -5423,8 +5450,7 @@ void CodeGenerator::AssembleConstructFrame() {
for (auto reg : wasm::kSimd128ParamRegisters)
simd128_regs_to_save.set(reg);
__ SaveVectorRegisters(simd128_regs_to_save);
- __ li(WasmHandleStackOverflowDescriptor::GapRegister(),
- required_slots * kSystemPointerSize);
+ __ li(WasmHandleStackOverflowDescriptor::GapRegister(), stack_space);
__ AddWord(
WasmHandleStackOverflowDescriptor::FrameBaseRegister(), fp,
Operand(call_descriptor->ParameterSlotCount() * kSystemPointerSize +
@@ -5455,6 +5481,7 @@ void CodeGenerator::AssembleConstructFrame() {
}
__ bind(&done);
}
+#endif // V8_ENABLE_WEBASSEMBLY
}
const int returns = frame()->GetReturnSlotCount();
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 c5cbf94880a..fa77fe299e7 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv.h
+++ b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv.h
@@ -188,7 +188,7 @@ static void VisitSimdShift(InstructionSelector* selector, ArchOpcode opcode,
OpIndex node) {
RiscvOperandGenerator g(selector);
const Operation& op = selector->Get(node);
- OpIndex rhs = op.input(0);
+ OpIndex rhs = op.input(1);
if (selector->Get(rhs).TryCast<ConstantOp>()) {
selector->Emit(opcode, g.DefineAsRegister(node), g.UseRegister(op.input(0)),
g.UseImmediate(op.input(1)));
@@ -447,8 +447,11 @@ static Instruction* VisitCompare(InstructionSelector* selector,
inputs[input_count++] = left;
inputs[input_count++] = right;
if (cont->IsSelect()) {
- inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->true_value());
- inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->false_value());
+ // Keep the values live until the end so that we can use operations that
+ // write registers to generate the condition, without accidentally
+ // overwriting the inputs.
+ inputs[input_count++] = g.UseRegisterAtEnd(cont->true_value());
+ inputs[input_count++] = g.UseRegisterAtEnd(cont->false_value());
}
#ifdef V8_COMPRESS_POINTERS
if (opcode == kRiscvCmp32) {
@@ -605,8 +608,8 @@ void EmitWordCompareZero(InstructionSelector* selector, OpIndex value,
InstructionOperand inputs[4];
inputs[input_count++] = g.UseRegisterOrImmediateZero(value);
if (cont->IsSelect()) {
- inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->true_value());
- inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->false_value());
+ inputs[input_count++] = g.UseRegisterAtEnd(cont->true_value());
+ inputs[input_count++] = g.UseRegisterAtEnd(cont->false_value());
}
selector->EmitWithContinuation(kRiscvCmpZero, 0, nullptr, input_count, inputs,
cont);
@@ -622,8 +625,8 @@ void EmitWord32CompareZero(InstructionSelector* selector, OpIndex value,
inputs[input_count++] = g.UseRegisterOrImmediateZero(value);
InstructionOperand temps[] = {g.TempRegister()};
if (cont->IsSelect()) {
- inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->true_value());
- inputs[input_count++] = g.UseRegisterOrImmediateZero(cont->false_value());
+ inputs[input_count++] = g.UseRegisterAtEnd(cont->true_value());
+ inputs[input_count++] = g.UseRegisterAtEnd(cont->false_value());
}
selector->EmitWithContinuation(kRiscvCmpZero32, 0, nullptr, input_count,
inputs, arraysize(temps), temps, cont);
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 e1649ea3324..a85d103593c 100644
--- a/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv64.cc
+++ b/deps/v8/src/compiler/backend/riscv/instruction-selector-riscv64.cc
@@ -1098,7 +1098,7 @@ void VisitWideAddSub(InstructionSelector* selector, OpIndex node, bool is_add) {
OptionalOpIndex out_high = selector->FindProjection(node, 1);
if (!out_high.valid() || !selector->IsUsed(out_high.value())) {
- if (out_low.valid()) {
+ if (out_low.valid() && selector->IsUsed(out_low.value())) {
InstructionOperand b_low_op =
g.UseOperand(op.right_low(), opcode_no_high);
selector->Emit(opcode_no_high, g.DefineAsRegister(out_low.value()),
@@ -1984,7 +1984,13 @@ void VisitAtomicStore(InstructionSelector* selector, OpIndex node,
case MachineRepresentation::kTaggedPointer: // Fall through.
case MachineRepresentation::kTagged:
DCHECK_EQ(AtomicWidthSize(width), kTaggedSize);
- code = kRiscvStoreCompressTagged;
+ code = kRiscvAtomicStoreCompressTagged;
+ break;
+ case MachineRepresentation::kCompressedPointer: // Fall through.
+ case MachineRepresentation::kCompressed:
+ DCHECK(COMPRESS_POINTERS_BOOL);
+ DCHECK_EQ(width, AtomicWidth::kWord32);
+ code = kRiscvAtomicStoreCompressTagged;
break;
default:
UNREACHABLE();
@@ -2277,12 +2283,12 @@ void InstructionSelector::VisitWord32Equal(OpIndex node) {
RiscvOperandGenerator g(this);
const RootsTable& roots_table = isolate()->roots_table();
RootIndex root_index;
- Handle<HeapObject> right;
+ Handle<HeapObject> heap_object;
// HeapConstants and CompressedHeapConstants can be treated the same when
// using them as an input to a 32-bit comparison. Check whether either is
// present.
- if (MatchHeapConstant(node, &right) && !right.is_null() &&
- roots_table.IsRootHandle(right, &root_index)) {
+ if (MatchHeapConstant(right, &heap_object) && !heap_object.is_null() &&
+ roots_table.IsRootHandle(heap_object, &root_index)) {
if (RootsTable::IsReadOnly(root_index)) {
Tagged_t ptr =
MacroAssemblerBase::ReadOnlyRootPtr(root_index, isolate());
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 273c30dd4a2..c922d6c5610 100644
--- a/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc
+++ b/deps/v8/src/compiler/backend/s390/instruction-selector-s390.cc
@@ -3372,6 +3372,10 @@ void InstructionSelector::VisitUint64Add128(OpIndex node) { UNIMPLEMENTED(); }
void InstructionSelector::VisitUint64Sub128(OpIndex node) { UNIMPLEMENTED(); }
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ UNREACHABLE();
+}
+
void InstructionSelector::AddOutputToSelectContinuation(OperandGenerator* g,
int first_input_index,
OpIndex node) {
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 e1a79565aef..b0be9bc5878 100644
--- a/deps/v8/src/compiler/backend/x64/code-generator-x64.cc
+++ b/deps/v8/src/compiler/backend/x64/code-generator-x64.cc
@@ -2084,10 +2084,12 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kArchAtomicStoreWithWriteBarrier: {
// {EmitTSANAwareStore} calls RecordTrapInfoIfNeeded. No need to do it
// here.
- RecordWriteMode mode = RecordWriteModeField::decode(instr->opcode());
+ RecordWriteMode mode =
+ arch_opcode == kArchStoreWithWriteBarrier
+ ? RecordWriteModeField::decode(instr->opcode())
+ : AtomicStoreRecordWriteModeField::decode(instr->opcode());
// Indirect pointer writes must use a different opcode.
DCHECK_NE(mode, RecordWriteMode::kValueIsIndirectPointer);
- AtomicMemoryOrder order = AtomicMemoryOrderField::decode(instr->opcode());
Register object = i.InputRegister(0);
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
@@ -2111,6 +2113,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
MachineRepresentation::kTagged, instr);
} else {
DCHECK_EQ(arch_opcode, kArchAtomicStoreWithWriteBarrier);
+ AtomicMemoryOrder order =
+ AtomicMemoryOrderField::decode(instr->opcode());
EmitTSANAwareStore(zone(), this, masm(), operand, value, i,
DetermineStubCallMode(),
MachineRepresentation::kTagged, instr, order);
@@ -2139,7 +2143,6 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
size_t index = 0;
Operand operand = i.MemoryOperand(&index);
Register value = i.InputRegister(index);
- AtomicMemoryOrder order = AtomicMemoryOrderField::decode(instr->opcode());
DCHECK(v8_flags.verify_write_barriers);
auto ool = zone()->New<OutOfLineVerifySkippedWriteBarrier>(
@@ -2154,6 +2157,8 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
MachineRepresentation::kTagged, instr);
} else {
DCHECK_EQ(arch_opcode, kArchAtomicStoreSkippedWriteBarrier);
+ AtomicMemoryOrder order =
+ AtomicMemoryOrderField::decode(instr->opcode());
EmitTSANAwareStore(zone(), this, masm(), operand, value, i,
DetermineStubCallMode(),
MachineRepresentation::kTagged, instr, order);
@@ -2299,6 +2304,48 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kX64Sub128:
ASSEMBLE_BINOP_WIDE(subq, sbbq);
break;
+ case kX64Add64_3: {
+ DCHECK_EQ(i.InputRegister(0), i.OutputRegister(0));
+ size_t last_input_index = instr->InputCount() - 1;
+ DCHECK(HasRegisterInput(instr, last_input_index));
+ 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++) {
+ if (HasRegisterInput(instr, j)) {
+ CHECK_NE(i.InputRegister(j), temp);
+ if (i.InputRegister(j) == out_high) {
+ use_temp = true;
+ out_high = temp;
+ }
+ }
+ }
+ }
+
+ // 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);
+ __ addq(out_low, b);
+ } else {
+ ASSEMBLE_RHS(addq, out_low, index);
+ }
+ DCHECK_EQ(index, last_input_index);
+ 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;
+ }
+
case kX64And32:
ASSEMBLE_BINOP(andl);
break;
@@ -5183,14 +5230,15 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case LaneSize::kL64: {
// I64x2ShrS
- // TODO(zhin): there is vpsraq but requires AVX512
XMMRegister dst = i.OutputSimd128Register();
XMMRegister src = i.InputSimd128Register(0);
if (HasImmediateInput(instr, 1)) {
__ I64x2ShrS(dst, src, i.InputInt6(1), kScratchDoubleReg);
} else {
- __ I64x2ShrS(dst, src, i.InputRegister(1), kScratchDoubleReg,
- i.TempSimd128Register(0), kScratchRegister);
+ XMMRegister temp = UseAvx10_1() ? XMMRegister::no_reg()
+ : i.TempSimd128Register(0);
+ __ I64x2ShrS(dst, src, i.InputRegister(1), temp,
+ kScratchDoubleReg, kScratchRegister);
}
break;
}
@@ -5361,9 +5409,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case LaneSize::kL64: {
// I64x2Mul
+ XMMRegister temp =
+ UseAvx10_1() ? XMMRegister::no_reg() : i.TempSimd128Register(0);
__ I64x2Mul(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.InputSimd128Register(1), i.TempSimd128Register(0),
- kScratchDoubleReg);
+ i.InputSimd128Register(1), temp, kScratchDoubleReg);
break;
}
default:
@@ -5383,9 +5432,10 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
}
case LaneSize::kL64: {
// I64x4Mul
+ YMMRegister temp =
+ UseAvx10_1() ? YMMRegister::no_reg() : i.TempSimd256Register(0);
__ I64x4Mul(i.OutputSimd256Register(), i.InputSimd256Register(0),
- i.InputSimd256Register(1), i.TempSimd256Register(0),
- kScratchSimd256Reg);
+ i.InputSimd256Register(1), temp, kScratchSimd256Reg);
break;
}
default:
@@ -6866,9 +6916,14 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
break;
}
case kX64I8x16Popcnt: {
- __ I8x16Popcnt(i.OutputSimd128Register(), i.InputSimd128Register(0),
- i.TempSimd128Register(0), kScratchDoubleReg,
- kScratchRegister);
+ if (UseAvx10_1()) {
+ __ I8x16Popcnt(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ kScratchRegister);
+ } else {
+ __ I8x16Popcnt(i.OutputSimd128Register(), i.InputSimd128Register(0),
+ kScratchRegister, i.TempSimd128Register(0),
+ kScratchDoubleReg);
+ }
break;
}
case kX64S128Load8Splat: {
@@ -7386,7 +7441,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
// Decompress pointer.
if constexpr (COMPRESS_POINTERS_BOOL) {
DCHECK_EQ(i.InputRegister(0), i.OutputRegister(0));
- __ addq(i.InputRegister(0), kPtrComprCageBaseRegister);
+ __ orq(i.InputRegister(0), kPtrComprCageBaseRegister);
}
if (v8_flags.disable_write_barriers) break;
// Emit write barrier.
@@ -7824,6 +7879,28 @@ constexpr Condition FlagsConditionToCondition(FlagsCondition condition) {
UNREACHABLE();
}
+#ifdef V8_ENABLE_APX_F
+// Map FlagsCondition to one implementation of EVEX-CCMP dfv.
+OszcFlags EncodeDefaultFlagsValue(FlagsCondition condition) {
+ switch (condition) {
+ case kUnorderedEqual:
+ case kEqual:
+ case kSignedLessThanOrEqual:
+ case kUnsignedLessThanOrEqual:
+ return OszcFlags({OszcBit::kZF});
+ case kSignedLessThan:
+ return OszcFlags({OszcBit::kSF});
+ case kUnsignedLessThan:
+ return OszcFlags({OszcBit::kCF});
+ case kOverflow:
+ return OszcFlags({OszcBit::kOF});
+ default:
+ return OszcFlags();
+ }
+ UNREACHABLE();
+}
+#endif // V8_ENABLE_APX_F
+
} // namespace
// Assembles branches after this instruction.
@@ -7959,16 +8036,165 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
__ bind(&done);
}
+#ifdef V8_ENABLE_APX_F
+namespace {
+void AssembleConditionalCompareChain(Instruction* instr, int64_t num_ccmps,
+ size_t ccmp_base_index,
+ CodeGenerator* gen) {
+ X64OperandConverter i(gen, instr);
+
+ for (int n = 0; n < num_ccmps; ++n) {
+ size_t opcode_index = ccmp_base_index + kCcmpOffsetOfOpcode;
+ size_t compare_lhs_index = ccmp_base_index + kCcmpOffsetOfLhs;
+ size_t compare_rhs_index = ccmp_base_index + kCcmpOffsetOfRhs;
+ size_t default_condition_index =
+ ccmp_base_index + kCcmpOffsetOfDefaultFlags;
+ size_t compare_condition_index =
+ ccmp_base_index + kCcmpOffsetOfCompareCondition;
+ ccmp_base_index += kNumCcmpOperands;
+ DCHECK_LT(ccmp_base_index, instr->InputCount() - 1);
+
+ InstructionCode code = static_cast<InstructionCode>(
+ i.ToConstant(instr->InputAt(opcode_index)).ToInt64());
+
+ FlagsCondition default_condition = static_cast<FlagsCondition>(
+ i.ToConstant(instr->InputAt(default_condition_index)).ToInt64());
+ OszcFlags dfv = EncodeDefaultFlagsValue(default_condition);
+ FlagsCondition compare_condition = static_cast<FlagsCondition>(
+ i.ToConstant(instr->InputAt(compare_condition_index)).ToInt64());
+ Condition cc = FlagsConditionToCondition(compare_condition);
+
+ const bool lhs_is_reg = HasRegisterInput(instr, compare_lhs_index);
+ const bool rhs_is_imm = HasImmediateInput(instr, compare_rhs_index);
+ const bool rhs_is_reg = HasRegisterInput(instr, compare_rhs_index);
+
+ int kSize;
+ bool is_test = false;
+ switch (ArchOpcodeField::decode(code)) {
+ case kX64Cmp8:
+ kSize = kInt8Size;
+ break;
+ case kX64Cmp16:
+ kSize = kInt16Size;
+ break;
+ case kX64Cmp32:
+ kSize = kInt32Size;
+ break;
+ case kX64Cmp:
+ kSize = kInt64Size;
+ break;
+ case kX64Test8:
+ kSize = kInt8Size;
+ is_test = true;
+ break;
+ case kX64Test16:
+ kSize = kInt16Size;
+ is_test = true;
+ break;
+ case kX64Test32:
+ kSize = kInt32Size;
+ is_test = true;
+ break;
+ case kX64Test:
+ kSize = kInt64Size;
+ is_test = true;
+ break;
+ default:
+ UNREACHABLE();
+ }
+
+ if (lhs_is_reg) {
+ Register lhs = i.InputRegister(compare_lhs_index);
+ if (rhs_is_imm) {
+ Immediate rhs = i.InputImmediate(compare_rhs_index);
+ if (is_test) {
+ gen->masm()->Ctest(lhs, rhs, dfv, cc, kSize);
+ } else {
+ gen->masm()->Ccmp(lhs, rhs, dfv, cc, kSize);
+ }
+ } else if (rhs_is_reg) {
+ Register rhs = i.InputRegister(compare_rhs_index);
+ if (is_test) {
+ gen->masm()->Ctest(lhs, rhs, dfv, cc, kSize);
+ } else {
+ gen->masm()->Ccmp(lhs, rhs, dfv, cc, kSize);
+ }
+ } else {
+ Operand rhs = i.InputOperand(compare_rhs_index);
+ if (is_test) {
+ // CTEST has no (Register, Operand) encoding; swap since TEST is
+ // symmetric: A AND B sets the same flags as B AND A.
+ gen->masm()->Ctest(rhs, lhs, dfv, cc, kSize);
+ } else {
+ gen->masm()->Ccmp(lhs, rhs, dfv, cc, kSize);
+ }
+ }
+ } else {
+ Operand lhs = i.InputOperand(compare_lhs_index);
+ if (rhs_is_imm) {
+ Immediate rhs = i.InputImmediate(compare_rhs_index);
+ if (is_test) {
+ gen->masm()->Ctest(lhs, rhs, dfv, cc, kSize);
+ } else {
+ gen->masm()->Ccmp(lhs, rhs, dfv, cc, kSize);
+ }
+ } else if (rhs_is_reg) {
+ Register rhs = i.InputRegister(compare_rhs_index);
+ if (is_test) {
+ gen->masm()->Ctest(lhs, rhs, dfv, cc, kSize);
+ } else {
+ gen->masm()->Ccmp(lhs, rhs, dfv, cc, kSize);
+ }
+ } else {
+ UNREACHABLE();
+ }
+ }
+ }
+}
+} // namespace
+#endif // V8_ENABLE_APX_F
+
#ifdef V8_ENABLE_WEBASSEMBLY
void CodeGenerator::AssembleArchConditionalTrap(Instruction* instr,
FlagsCondition condition) {
+#ifdef V8_ENABLE_APX_F
+ DCHECK_GE(instr->InputCount(), 6);
+ X64OperandConverter i(this, instr);
+ size_t num_ccmps_index =
+ instr->InputCount() - kConditionalTrapEndOffsetOfNumCcmps;
+ int64_t num_ccmps = i.ToConstant(instr->InputAt(num_ccmps_index)).ToInt64();
+ size_t ccmp_base_index = instr->InputCount() -
+ kConditionalTrapEndOffsetOfCondition -
+ kNumCcmpOperands * num_ccmps;
+ AssembleConditionalCompareChain(instr, num_ccmps, ccmp_base_index, this);
+ Condition cc = FlagsConditionToCondition(condition);
+ auto ool = zone()->New<WasmOutOfLineTrap>(this, instr);
+ Label* tlabel = ool->entry();
+ __ j(cc, tlabel);
+#else
UNREACHABLE();
+#endif // V8_ENABLE_APX_F
}
#endif // V8_ENABLE_WEBASSEMBLY
void CodeGenerator::AssembleArchConditionalBranch(Instruction* instr,
BranchInfo* branch) {
+#ifdef V8_ENABLE_APX_F
+ DCHECK_GE(instr->InputCount(), 6);
+ X64OperandConverter i(this, instr);
+ size_t num_ccmps_index =
+ instr->InputCount() - kConditionalBranchEndOffsetOfNumCcmps;
+ int64_t num_ccmps = i.ToConstant(instr->InputAt(num_ccmps_index)).ToInt64();
+ size_t ccmp_base_index = instr->InputCount() -
+ kConditionalBranchEndOffsetOfCondition -
+ kNumCcmpOperands * num_ccmps;
+ AssembleConditionalCompareChain(instr, num_ccmps, ccmp_base_index, this);
+ Condition cc = FlagsConditionToCondition(branch->condition);
+ __ j(cc, branch->true_label);
+ if (!branch->fallthru) __ jmp(branch->false_label);
+#else
UNREACHABLE();
+#endif // V8_ENABLE_APX_F
}
void CodeGenerator::AssembleArchBinarySearchSwitchRange(
diff --git a/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h b/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h
index dd86a3e4852..2d8d8c4878e 100644
--- a/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h
+++ b/deps/v8/src/compiler/backend/x64/instruction-codes-x64.h
@@ -94,6 +94,7 @@ namespace compiler {
#define TARGET_ARCH_OPCODE_LIST(V) \
TARGET_ARCH_OPCODE_WITH_MEMORY_ACCESS_MODE_LIST(V) \
V(X64Add) \
+ V(X64Add64_3) \
V(X64Add128) \
V(X64Add32) \
V(X64Sub128) \
diff --git a/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc b/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc
index c64048aea1f..74a9645efbe 100644
--- a/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc
+++ b/deps/v8/src/compiler/backend/x64/instruction-scheduler-x64.cc
@@ -35,6 +35,7 @@ int InstructionScheduler::GetTargetInstructionFlags(
case kX64Add:
case kX64Add32:
case kX64Add128:
+ case kX64Add64_3:
case kX64Sub128:
case kX64And:
case kX64And32:
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 7d097c878d1..af76d6991e4 100644
--- a/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc
+++ b/deps/v8/src/compiler/backend/x64/instruction-selector-x64.cc
@@ -565,6 +565,7 @@ class X64OperandGenerator final : public OperandGenerator {
case kX64Or:
case kX64Xor:
case kX64Add:
+ case kX64Add64_3:
case kX64Add128:
case kX64Sub128:
case kX64Sub:
@@ -1532,7 +1533,9 @@ void VisitStoreCommon(InstructionSelector* selector,
: kArchStoreWithWriteBarrier;
const RecordWriteMode record_write_mode =
WriteBarrierKindToRecordWriteMode(write_barrier_kind);
- code |= RecordWriteModeField::encode(record_write_mode);
+ code |= is_atomic
+ ? AtomicStoreRecordWriteModeField::encode(record_write_mode)
+ : RecordWriteModeField::encode(record_write_mode);
}
code |= AddressingModeField::encode(addressing_mode);
code |= AccessModeField::encode(access_mode);
@@ -2546,6 +2549,44 @@ void InstructionSelector::VisitUint64Sub128(OpIndex node) {
VisitWideAddSub(this, node, false);
}
+void InstructionSelector::VisitUint64Add3WithCarry(OpIndex node) {
+ X64OperandGenerator g(this);
+ InstructionOperand inputs[8];
+ size_t input_count = 0;
+ InstructionOperand outputs[2];
+ size_t output_count = 0;
+ const auto& op = this->Get(node).Cast<Word64Add3Op>();
+ InstructionCode opcode = kX64Add64_3;
+
+ 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)) {
+ AddressingMode addressing_mode = g.GetEffectiveAddressMemoryOperand(
+ b, inputs, &input_count,
+ X64OperandGenerator::RegisterUseKind::kUseUniqueRegister);
+ opcode |= AddressingModeField::encode(addressing_mode);
+ } else {
+ inputs[input_count++] = g.UseUnique(b);
+ }
+ inputs[input_count++] = g.UseUniqueRegister(op.third());
+ DCHECK_GE(arraysize(inputs), input_count);
+
+ OptionalOpIndex out_low = FindProjection(node, 0);
+ outputs[output_count++] =
+ 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);
+}
+
void InstructionSelector::VisitInt32Div(OpIndex node) {
VisitDiv(this, node, kX64Idiv32);
}
@@ -3322,6 +3363,121 @@ void InstructionSelector::EmitPrepareResults(
bool InstructionSelector::IsTailCallAddressImmediate() { return true; }
namespace {
+#ifdef V8_ENABLE_APX_F
+using compare_chain::CompareSequence;
+
+static InstructionCode X64GetCmpOpcode(RegisterRepresentation rep,
+ bool is_test) {
+ if (is_test) {
+ switch (rep.MapTaggedToWord().value()) {
+ case RegisterRepresentation::Word32():
+ return kX64Test32;
+ case RegisterRepresentation::Word64():
+ return kX64Test;
+ default:
+ UNREACHABLE();
+ }
+ }
+ switch (rep.MapTaggedToWord().value()) {
+ case RegisterRepresentation::Word32():
+ return kX64Cmp32;
+ case RegisterRepresentation::Word64():
+ return kX64Cmp;
+ default:
+ UNREACHABLE();
+ }
+}
+
+static void VisitCompareChain(InstructionSelector* selector, OpIndex left_node,
+ OpIndex right_node, RegisterRepresentation rep,
+ InstructionCode opcode, FlagsContinuation* cont) {
+ DCHECK(cont->IsConditionalTrap() || cont->IsConditionalBranch());
+ X64OperandGenerator g(selector);
+ constexpr uint32_t kMaxFlagSetInputs = 2;
+ constexpr uint32_t kMaxCcmpOperands =
+ FlagsContinuation::kMaxCompareChainSize * kNumCcmpOperands;
+ constexpr uint32_t kExtraCcmpInputs = 2;
+ constexpr uint32_t kMaxInputs =
+ kMaxFlagSetInputs + kMaxCcmpOperands + kExtraCcmpInputs;
+ InstructionOperand inputs[kMaxInputs];
+ size_t input_count = 0;
+
+ auto use_lhs = [&](OpIndex n, bool rhs_is_imm) -> InstructionOperand {
+ // LHS can be stack slot only when RHS is immediate.
+ if (rhs_is_imm) return g.Use(n);
+ return g.UseRegister(n);
+ };
+ auto use_rhs = [&](OpIndex n) -> InstructionOperand {
+ // RHS can be immediate, register, or stack slot.
+ if (g.CanBeImmediate(n)) return g.UseImmediate(n);
+ return g.Use(n);
+ };
+
+ bool initial_rhs_is_imm = g.CanBeImmediate(right_node);
+ inputs[input_count++] = use_lhs(left_node, initial_rhs_is_imm);
+ inputs[input_count++] = use_rhs(right_node);
+
+ auto& compares = cont->compares();
+ for (unsigned i = 0; i < cont->num_conditional_compares(); ++i) {
+ auto compare = compares[i];
+ // opcode
+ inputs[input_count + kCcmpOffsetOfOpcode] = g.TempImmediate(compare.code);
+
+ // lhs, rhs
+ bool current_rhs_is_imm = g.CanBeImmediate(compare.rhs);
+ inputs[input_count + kCcmpOffsetOfLhs] =
+ use_lhs(compare.lhs, current_rhs_is_imm);
+ inputs[input_count + kCcmpOffsetOfRhs] = use_rhs(compare.rhs);
+
+ // dfv (encode FlagsCondition)
+ inputs[input_count + kCcmpOffsetOfDefaultFlags] =
+ g.TempImmediate(compare.default_flags);
+
+ // compare condition for this CCMP
+ inputs[input_count + kCcmpOffsetOfCompareCondition] =
+ g.TempImmediate(compare.compare_condition);
+
+ input_count += kNumCcmpOperands;
+ }
+
+ // final condition + num ccmps
+ inputs[input_count++] = g.TempImmediate(cont->final_condition());
+ inputs[input_count++] =
+ g.TempImmediate(static_cast<int32_t>(cont->num_conditional_compares()));
+
+ DCHECK_GE(arraysize(inputs), input_count);
+ selector->EmitWithContinuation(opcode, 0, nullptr, input_count, inputs, cont);
+}
+
+static bool TryMatchConditionalCompareChain(InstructionSelector* selector,
+ Zone* zone, OpIndex node,
+ FlagsContinuation* cont) {
+ if (!UseApxCcmp()) return false;
+
+ CompareSequence sequence;
+ FlagsCondition condition;
+ if (!compare_chain::TryBuildConditionalCompareChain(
+ selector, zone, node, cont, &sequence, &condition, X64GetCmpOpcode,
+ /*supports_float_cmp=*/false, /*supports_test_pattern=*/true, nullptr,
+ nullptr)) {
+ return false;
+ }
+
+ FlagsContinuation new_cont =
+ cont->IsBranch() ? FlagsContinuation::ForConditionalBranch(
+ sequence.ccmps(), sequence.num_ccmps(), condition,
+ cont->true_block(), cont->false_block())
+ : FlagsContinuation::ForConditionalTrap(
+ sequence.ccmps(), sequence.num_ccmps(), condition,
+ cont->trap_id());
+
+ VisitCompareChain(selector, sequence.left(), sequence.right(),
+ selector->Get(sequence.cmp()).Cast<ComparisonOp>().rep,
+ sequence.opcode(), &new_cont);
+
+ return true;
+}
+#endif // V8_ENABLE_APX_F
void VisitCompareWithMemoryOperand(InstructionSelector* selector,
InstructionCode opcode, OpIndex left,
@@ -3872,6 +4028,35 @@ void VisitAtomicCompareExchange(InstructionSelector* selector, OpIndex node,
} // namespace
+#ifdef V8_ENABLE_APX_F
+// Per-arch ccmp cascade hooks (driven by TryCascadeCcmpFuseOrEmit in
+// instruction-selector.cc). ccmp is an APX instruction on x64, so APX-gated.
+bool InstructionSelector::SupportsCcmpBranchCascade() const {
+ return UseApxCcmp();
+}
+
+bool InstructionSelector::CcmpCascadeConstantOk(OpIndex node,
+ bool /*is_ccmp_operand*/) {
+ // Only fuse immediates: non-immediate constants would force LEA
+ // materialization (code bloat, regression). The gate uses the same
+ // CanBeImmediate predicate the emission does for both roles, so no role
+ // distinction is needed here.
+ return CanBeImmediate(this, node);
+}
+
+InstructionCode InstructionSelector::CcmpCmpOpcode(
+ RegisterRepresentation rep) const {
+ return X64GetCmpOpcode(rep, /*is_test=*/false);
+}
+
+void InstructionSelector::EmitCcmpCompareChain(CompareSequence& sequence,
+ RegisterRepresentation rep,
+ FlagsContinuation* cont) {
+ VisitCompareChain(this, sequence.left(), sequence.right(), rep,
+ sequence.opcode(), cont);
+}
+#endif // V8_ENABLE_APX_F
+
// Shared routine for word comparison against zero.
void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
FlagsContinuation* cont) {
@@ -3975,7 +4160,18 @@ void InstructionSelector::VisitWordCompareZero(OpIndex user, OpIndex value,
} else if (value_op.Is<Opmask::kWord32Sub>()) {
return VisitWordCompare(this, value, kX64Cmp32, cont);
} else if (value_op.Is<Opmask::kWord32BitwiseAnd>()) {
+#ifdef V8_ENABLE_APX_F
+ if (TryMatchConditionalCompareChain(this, zone(), value, cont)) {
+ return;
+ }
+#endif
return VisitWordCompare(this, value, kX64Test32, cont);
+#ifdef V8_ENABLE_APX_F
+ } else if (value_op.Is<Opmask::kWord32BitwiseOr>()) {
+ if (TryMatchConditionalCompareChain(this, zone(), value, cont)) {
+ return;
+ }
+#endif
} else if (const ProjectionOp* projection =
value_op.TryCast<ProjectionOp>()) {
// Check if this is the overflow output projection of an
@@ -4905,7 +5101,7 @@ void InstructionSelector::VisitF16x8ReplaceLane(OpIndex node) {
Emit(kX64FReplaceLane | LaneSizeField::encode(LaneSize::kL16) |
VectorLengthField::encode(VectorLength::kV128),
g.DefineSameAsFirst(node), g.UseRegister(op.into()),
- g.UseImmediate(op.lane), g.Use(op.new_lane()));
+ g.UseImmediate(op.lane), g.UseRegister(op.new_lane()));
}
void InstructionSelector::VisitF32x4ReplaceLane(OpIndex node) {
@@ -5137,13 +5333,19 @@ void InstructionSelector::VisitS128Select(OpIndex node) {
const Simd128TernaryOp& op = Cast<Simd128TernaryOp>(node);
DCHECK_EQ(op.input_count, 3);
+ const bool input1_is_zero = IsV128ZeroConst(this, op.input(1));
+ const bool input2_is_zero = IsV128ZeroConst(this, op.input(2));
+ // AVX10 vpternlogd requires dst to alias the mask.
+ const bool same_as_mask =
+ !IsSupported(AVX) || (UseAvx10_1() && !input1_is_zero && !input2_is_zero);
InstructionOperand dst =
- IsSupported(AVX) ? g.DefineAsRegister(node) : g.DefineSameAsFirst(node);
- if (IsV128ZeroConst(this, op.input(2))) {
+ same_as_mask ? g.DefineSameAsFirst(node) : g.DefineAsRegister(node);
+
+ if (input2_is_zero) {
// select(cond, input1, 0) -> and(cond, input1)
Emit(kX64SAnd | VectorLengthField::encode(VectorLength::kV128), dst,
g.UseRegister(op.input(0)), g.UseRegister(op.input(1)));
- } else if (IsV128ZeroConst(this, op.input(1))) {
+ } else if (input1_is_zero) {
// select(cond, 0, input2) -> and(not(cond), input2)
Emit(kX64SAndNot | VectorLengthField::encode(VectorLength::kV128), dst,
g.UseRegister(op.input(0)), g.UseRegister(op.input(2)));
@@ -5158,9 +5360,12 @@ void InstructionSelector::VisitS256Select(OpIndex node) {
#ifdef V8_ENABLE_SIMD256
X64OperandGenerator g(this);
const Simd256TernaryOp& op = Cast<Simd256TernaryOp>(node);
- Emit(kX64SSelect | VectorLengthField::encode(VectorLength::kV256),
- g.DefineAsRegister(node), g.UseRegister(op.input(0)),
- g.UseRegister(op.input(1)), g.UseRegister(op.input(2)));
+ // vpternlogd requires dst to alias the mask.
+ InstructionOperand dst =
+ UseAvx10_1() ? g.DefineSameAsFirst(node) : g.DefineAsRegister(node);
+ Emit(kX64SSelect | VectorLengthField::encode(VectorLength::kV256), dst,
+ g.UseRegister(op.input(0)), g.UseRegister(op.input(1)),
+ g.UseRegister(op.input(2)));
#else
UNREACHABLE();
#endif
@@ -5295,11 +5500,19 @@ void InstructionSelector::VisitI64x2ShrS(OpIndex node) {
VectorLengthField::encode(VectorLength::kV128),
dst, g.UseRegister(op.input()), g.UseImmediate(op.shift()));
} else {
- InstructionOperand temps[] = {g.TempSimd128Register()};
+ int temp_count = 0;
+ InstructionOperand temps[1];
+ InstructionOperand input;
+ if (UseAvx10_1()) {
+ input = g.UseRegister(op.input());
+ } else {
+ input = g.UseUniqueRegister(op.input());
+ temps[temp_count++] = g.TempSimd128Register();
+ }
+
Emit(kX64IShrS | LaneSizeField::encode(LaneSize::kL64) |
VectorLengthField::encode(VectorLength::kV128),
- dst, g.UseUniqueRegister(op.input()), g.UseRegister(op.shift()),
- arraysize(temps), temps);
+ dst, input, g.UseRegister(op.shift()), temp_count, temps);
}
}
@@ -5307,10 +5520,18 @@ void InstructionSelector::VisitI64x2Mul(OpIndex node) {
X64OperandGenerator g(this);
const Simd128BinopOp& op = Cast<Simd128BinopOp>(node);
DCHECK_EQ(op.input_count, 2);
+
+ InstructionCode opcode = kX64IMul | LaneSizeField::encode(LaneSize::kL64) |
+ VectorLengthField::encode(VectorLength::kV128);
+
+ if (UseAvx10_1()) {
+ Emit(opcode, g.DefineAsRegister(node), g.UseRegister(op.left()),
+ g.UseRegister(op.right()));
+ return;
+ }
+
InstructionOperand temps[] = {g.TempSimd128Register()};
- Emit(kX64IMul | LaneSizeField::encode(LaneSize::kL64) |
- VectorLengthField::encode(VectorLength::kV128),
- g.DefineAsRegister(node), g.UseUniqueRegister(op.left()),
+ Emit(opcode, g.DefineAsRegister(node), g.UseUniqueRegister(op.left()),
g.UseUniqueRegister(op.right()), arraysize(temps), temps);
}
@@ -5319,10 +5540,18 @@ void InstructionSelector::VisitI64x4Mul(OpIndex node) {
X64OperandGenerator g(this);
const Simd256BinopOp& op = Cast<Simd256BinopOp>(node);
DCHECK_EQ(op.input_count, 2);
+
+ InstructionCode opcode = kX64IMul | LaneSizeField::encode(LaneSize::kL64) |
+ VectorLengthField::encode(VectorLength::kV256);
+
+ if (UseAvx10_1()) {
+ Emit(opcode, g.DefineAsRegister(node), g.UseRegister(op.left()),
+ g.UseRegister(op.right()));
+ return;
+ }
+
InstructionOperand temps[] = {g.TempSimd256Register()};
- Emit(kX64IMul | LaneSizeField::encode(LaneSize::kL64) |
- VectorLengthField::encode(VectorLength::kV256),
- g.DefineAsRegister(node), g.UseUniqueRegister(op.left()),
+ Emit(opcode, g.DefineAsRegister(node), g.UseUniqueRegister(op.left()),
g.UseUniqueRegister(op.right()), arraysize(temps), temps);
#else
UNREACHABLE();
@@ -5929,6 +6158,11 @@ void InstructionSelector::VisitI8x16Popcnt(OpIndex node) {
X64OperandGenerator g(this);
const Simd128UnaryOp& op = Cast<Simd128UnaryOp>(node);
DCHECK_EQ(op.input_count, 1);
+
+ if (UseAvx10_1()) {
+ Emit(kX64I8x16Popcnt, g.DefineAsRegister(node), g.UseRegister(op.input()));
+ return;
+ }
InstructionOperand temps[] = {g.TempSimd128Register()};
Emit(kX64I8x16Popcnt, g.DefineAsRegister(node),
g.UseUniqueRegister(op.input()), arraysize(temps), temps);
@@ -6090,14 +6324,19 @@ void InstructionSelector::VisitI64x2Abs(OpIndex node) {
X64OperandGenerator g(this);
const Simd128UnaryOp& op = Cast<Simd128UnaryOp>(node);
DCHECK_EQ(op.input_count, 1);
- if (CpuFeatures::IsSupported(AVX)) {
- Emit(kX64IAbs | LaneSizeField::encode(LaneSize::kL64) |
- VectorLengthField::encode(VectorLength::kV128),
- g.DefineAsRegister(node), g.UseUniqueRegister(op.input()));
+
+ InstructionCode opcode = kX64IAbs | LaneSizeField::encode(LaneSize::kL64) |
+ VectorLengthField::encode(VectorLength::kV128);
+
+ if (UseAvx10_1()) {
+ Emit(opcode, g.DefineAsRegister(node), g.UseRegister(op.input()));
+ return;
+ }
+
+ if (IsSupported(AVX)) {
+ Emit(opcode, g.DefineAsRegister(node), g.UseUniqueRegister(op.input()));
} else {
- Emit(kX64IAbs | LaneSizeField::encode(LaneSize::kL64) |
- VectorLengthField::encode(VectorLength::kV128),
- g.DefineSameAsFirst(node), g.UseRegister(op.input()));
+ Emit(opcode, g.DefineSameAsFirst(node), g.UseRegister(op.input()));
}
}
diff --git a/deps/v8/src/compiler/bytecode-graph-builder.cc b/deps/v8/src/compiler/bytecode-graph-builder.cc
index c0ecd4acd72..a2c973d6647 100644
--- a/deps/v8/src/compiler/bytecode-graph-builder.cc
+++ b/deps/v8/src/compiler/bytecode-graph-builder.cc
@@ -254,7 +254,7 @@ class BytecodeGraphBuilder {
std::initializer_list<Node*> args, FeedbackSource source) {
BuildCall(receiver_mode, args.begin(), args.size(), source);
}
- void BuildUnaryOp(const Operator* op);
+ void BuildUnaryOpWithEmbeddedFeedback(const Operator* op);
void BuildCompareOp(const Operator* op);
void BuildCompareOpWithEmbeddedFeedback(const Operator* op);
void BuildBinaryOpWithEmbeddedFeedback(const Operator* op);
@@ -267,8 +267,10 @@ class BytecodeGraphBuilder {
// Optional early lowering to the simplified operator level. Note that
// the result has already been wired into the environment just like
// any other invocation of {NewNode} would do.
- JSTypeHintLowering::LoweringResult TryBuildSimplifiedUnaryOp(
+ JSTypeHintLowering::LoweringResult TryBuildSimplifiedTypeOf(
const Operator* op, Node* operand, FeedbackSlot slot);
+ JSTypeHintLowering::LoweringResult TryBuildSimplifiedUnaryOp(
+ const Operator* op, Node* operand);
JSTypeHintLowering::LoweringResult TryBuildSimplifiedBinaryOp(
const Operator* op, Node* left, Node* right, FeedbackSlot slot);
JSTypeHintLowering::LoweringResult TryBuildSimplifiedBinaryOp(
@@ -540,7 +542,6 @@ class BytecodeGraphBuilder {
static constexpr int kBinaryOperationHintIndex = 1;
static constexpr int kCompareOperationHintIndex = 1;
static constexpr int kCountOperationHintIndex = 0;
- static constexpr int kUnaryOperationHintIndex = 0;
};
// The abstract execution environment simulates the content of the interpreter
@@ -1374,6 +1375,7 @@ void BytecodeGraphBuilder::BuildFunctionEntryStackCheck() {
}
void BytecodeGraphBuilder::BuildIterationBodyStackCheck() {
+ if (V8_UNLIKELY(v8_flags.disable_loop_stack_checks)) return;
Node* node =
NewNode(javascript()->StackCheck(StackCheckKind::kJSIterationBody));
environment()->RecordAfterState(node, Environment::kAttachFrameState);
@@ -3121,15 +3123,14 @@ void BytecodeGraphBuilder::VisitThrowIfNotSuperConstructor() {
constructor);
}
-void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
- DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()));
+void BytecodeGraphBuilder::BuildUnaryOpWithEmbeddedFeedback(
+ const Operator* op) {
+ DCHECK(JSOperator::IsUnaryWithEmbeddedFeedback(op->opcode()));
PrepareEagerCheckpoint();
Node* operand = environment()->LookupAccumulator();
- FeedbackSlot slot =
- bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex);
JSTypeHintLowering::LoweringResult lowering =
- TryBuildSimplifiedUnaryOp(op, operand, slot);
+ TryBuildSimplifiedUnaryOp(op, operand);
if (lowering.IsExit()) return;
Node* node = nullptr;
@@ -3138,7 +3139,7 @@ void BytecodeGraphBuilder::BuildUnaryOp(const Operator* op) {
} else {
DCHECK(!lowering.Changed());
DCHECK(IrOpcode::IsFeedbackCollectingOpcode(op->opcode()));
- node = NewNode(op, operand, feedback_vector_node());
+ node = NewNode(op, operand);
}
environment()->BindAccumulator(node, Environment::kAttachFrameState);
@@ -3214,27 +3215,31 @@ CallFeedbackRelation BytecodeGraphBuilder::ComputeCallFeedbackRelation(
}
void BytecodeGraphBuilder::VisitBitwiseNot() {
- FeedbackSource feedback = CreateFeedbackSource(
- bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
- BuildUnaryOp(javascript()->BitwiseNot(feedback));
+ const BinaryOperationHint hint =
+ bytecode_iterator()
+ .GetEmbeddedOperationHint<v8::internal::BinaryOperationFeedback>();
+ BuildUnaryOpWithEmbeddedFeedback(javascript()->BitwiseNot(hint));
}
void BytecodeGraphBuilder::VisitDec() {
- FeedbackSource feedback = CreateFeedbackSource(
- bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
- BuildUnaryOp(javascript()->Decrement(feedback));
+ const BinaryOperationHint hint =
+ bytecode_iterator()
+ .GetEmbeddedOperationHint<v8::internal::BinaryOperationFeedback>();
+ BuildUnaryOpWithEmbeddedFeedback(javascript()->Decrement(hint));
}
void BytecodeGraphBuilder::VisitInc() {
- FeedbackSource feedback = CreateFeedbackSource(
- bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
- BuildUnaryOp(javascript()->Increment(feedback));
+ const BinaryOperationHint hint =
+ bytecode_iterator()
+ .GetEmbeddedOperationHint<v8::internal::BinaryOperationFeedback>();
+ BuildUnaryOpWithEmbeddedFeedback(javascript()->Increment(hint));
}
void BytecodeGraphBuilder::VisitNegate() {
- FeedbackSource feedback = CreateFeedbackSource(
- bytecode_iterator().GetSlotOperand(kUnaryOperationHintIndex));
- BuildUnaryOp(javascript()->Negate(feedback));
+ const BinaryOperationHint hint =
+ bytecode_iterator()
+ .GetEmbeddedOperationHint<v8::internal::BinaryOperationFeedback>();
+ BuildUnaryOpWithEmbeddedFeedback(javascript()->Negate(hint));
}
void BytecodeGraphBuilder::VisitAdd() {
@@ -3469,7 +3474,7 @@ void BytecodeGraphBuilder::VisitTypeOf() {
FeedbackSlot slot = bytecode_iterator().GetSlotOperand(0);
JSTypeHintLowering::LoweringResult lowering =
- TryBuildSimplifiedUnaryOp(simplified()->TypeOf(), operand, slot);
+ TryBuildSimplifiedTypeOf(simplified()->TypeOf(), operand, slot);
if (lowering.IsExit()) return;
Node* node = nullptr;
@@ -4439,15 +4444,27 @@ void BytecodeGraphBuilder::BuildJumpIfForInDone() {
BuildJumpIf(condition);
}
+JSTypeHintLowering::LoweringResult
+BytecodeGraphBuilder::TryBuildSimplifiedTypeOf(const Operator* op,
+ Node* operand,
+ FeedbackSlot slot) {
+ Node* effect = environment()->GetEffectDependency();
+ Node* control = environment()->GetControlDependency();
+ JSTypeHintLowering::LoweringResult result =
+ type_hint_lowering().ReduceTypeOfOperation(op, operand, effect, control,
+ slot);
+ ApplyEarlyReduction(result);
+ return result;
+}
+
JSTypeHintLowering::LoweringResult
BytecodeGraphBuilder::TryBuildSimplifiedUnaryOp(const Operator* op,
- Node* operand,
- FeedbackSlot slot) {
+ Node* operand) {
Node* effect = environment()->GetEffectDependency();
Node* control = environment()->GetControlDependency();
JSTypeHintLowering::LoweringResult result =
- type_hint_lowering().ReduceUnaryOperation(op, operand, effect, control,
- slot);
+ type_hint_lowering().ReduceUnaryOperationWithEmbeddedHint(
+ op, operand, effect, control);
ApplyEarlyReduction(result);
return result;
}
diff --git a/deps/v8/src/compiler/code-assembler.cc b/deps/v8/src/compiler/code-assembler.cc
index a3bc06e8a9d..db36c41b3b5 100644
--- a/deps/v8/src/compiler/code-assembler.cc
+++ b/deps/v8/src/compiler/code-assembler.cc
@@ -1204,6 +1204,10 @@ void CodeAssembler::StoreRoot(RootIndex root_index, TNode<Object> value) {
StoreFullTaggedNoWriteBarrier(isolate_root, IntPtrConstant(offset), value);
}
+void CodeAssembler::Retain(TNode<Object> value) {
+ raw_assembler()->Retain(value);
+}
+
Node* CodeAssembler::Projection(int index, Node* value) {
DCHECK_LT(index, value->op()->ValueOutputCount());
return raw_assembler()->Projection(index, value);
diff --git a/deps/v8/src/compiler/code-assembler.h b/deps/v8/src/compiler/code-assembler.h
index 78f4dd9a2eb..06a61b2fa0c 100644
--- a/deps/v8/src/compiler/code-assembler.h
+++ b/deps/v8/src/compiler/code-assembler.h
@@ -1369,6 +1369,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<Int32T> TruncateFloat32ToInt32(TNode<Float32T> value);
TNode<Int64T> TruncateFloat64ToInt64(TNode<Float64T> value);
+ // No-op that guarantees that the value is kept alive till this point even
+ // if GC happens.
+ void Retain(TNode<Object> value);
+
// Projections
template <int index, class T1, class T2>
TNode<std::tuple_element_t<index, std::tuple<T1, T2>>> Projection(
diff --git a/deps/v8/src/compiler/compilation-dependencies.cc b/deps/v8/src/compiler/compilation-dependencies.cc
index 5b1b14b036e..cb6ccaaed42 100644
--- a/deps/v8/src/compiler/compilation-dependencies.cc
+++ b/deps/v8/src/compiler/compilation-dependencies.cc
@@ -867,11 +867,12 @@ class FieldConstnessDependency final : public CompilationDependency {
class GlobalPropertyDependency final : public CompilationDependency {
public:
GlobalPropertyDependency(PropertyCellRef cell, PropertyCellType type,
- bool read_only)
+ bool read_only, OptionalMapRef value_map)
: CompilationDependency(kGlobalProperty),
cell_(cell),
type_(type),
- read_only_(read_only) {
+ read_only_(read_only),
+ value_map_(value_map) {
DCHECK_EQ(type_, cell_.property_details().cell_type());
DCHECK_EQ(read_only_, cell_.property_details().IsReadOnly());
}
@@ -884,8 +885,24 @@ class GlobalPropertyDependency final : public CompilationDependency {
*(broker->isolate()->factory()->property_cell_hole_value())) {
return false;
}
- return type_ == cell->property_details().cell_type() &&
- read_only_ == cell->property_details().IsReadOnly();
+ if (type_ != cell->property_details().cell_type() ||
+ read_only_ != cell->property_details().IsReadOnly()) {
+ return false;
+ }
+ // A same-map store can replace the value between the broker's read of the
+ // value and its read of the value's map. The replaced object can then
+ // transition without changing the cell details, and the recorded map stays
+ // stable, so neither existing check catches it.
+ if (value_map_.has_value()) {
+ DisallowGarbageCollection no_gc;
+ Tagged<Object> value = cell->value();
+ if (!IsHeapObject(value) ||
+ Cast<HeapObject>(value)->map() != *value_map_->object()) {
+ TRACE_BROKER_MISSING(broker, "Value map change detected in " << cell);
+ return false;
+ }
+ }
+ return true;
}
void Install(JSHeapBroker* broker, PendingDependencies* deps) const override {
SLOW_DCHECK(IsValid(broker));
@@ -895,11 +912,16 @@ class GlobalPropertyDependency final : public CompilationDependency {
private:
size_t Hash() const override {
ObjectRef::Hash h;
- return base::hash_combine(h(cell_), static_cast<int>(type_), read_only_);
+ return base::hash_combine(h(cell_), static_cast<int>(type_), read_only_,
+ value_map_.has_value() ? h(*value_map_) : 0);
}
bool Equals(const CompilationDependency* that) const override {
const GlobalPropertyDependency* const zat = that->AsGlobalProperty();
+ if (value_map_.has_value() != zat->value_map_.has_value()) return false;
+ if (value_map_.has_value() && !value_map_->equals(*zat->value_map_)) {
+ return false;
+ }
return cell_.equals(zat->cell_) && type_ == zat->type_ &&
read_only_ == zat->read_only_;
}
@@ -907,6 +929,8 @@ class GlobalPropertyDependency final : public CompilationDependency {
const PropertyCellRef cell_;
const PropertyCellType type_;
const bool read_only_;
+ // Snapshotted value map for kConstantType heap objects; empty otherwise.
+ const OptionalMapRef value_map_;
};
class ContextCellDependency final : public CompilationDependency {
@@ -1287,7 +1311,15 @@ CompilationDependencies::FieldConstnessDependencyOffTheRecord(
void CompilationDependencies::DependOnGlobalProperty(PropertyCellRef cell) {
PropertyCellType type = cell.property_details().cell_type();
bool read_only = cell.property_details().IsReadOnly();
- RecordDependency(zone_->New<GlobalPropertyDependency>(cell, type, read_only));
+ // Read the map through the broker so validation checks the same map the
+ // compiler used.
+ OptionalMapRef value_map;
+ if (type == PropertyCellType::kConstantType) {
+ ObjectRef value = cell.value(broker_);
+ if (value.IsHeapObject()) value_map = value.AsHeapObject().map(broker_);
+ }
+ RecordDependency(
+ zone_->New<GlobalPropertyDependency>(cell, type, read_only, value_map));
}
bool CompilationDependencies::DependOnContextCell(ContextRef script_context,
diff --git a/deps/v8/src/compiler/heap-refs.cc b/deps/v8/src/compiler/heap-refs.cc
index 3926884df4d..627f0824144 100644
--- a/deps/v8/src/compiler/heap-refs.cc
+++ b/deps/v8/src/compiler/heap-refs.cc
@@ -14,6 +14,7 @@
#include "src/objects/heap-object.h"
#include "src/objects/instance-type-inl.h"
#include "src/objects/js-proxy-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/sandbox/bounded-size-inl.h"
#ifdef ENABLE_SLOW_DCHECKS
@@ -347,7 +348,13 @@ std::optional<Tagged<Object>> GetOwnFastConstantDataPropertyFromHeap(
}
if (field_index.is_inobject()) {
+ // The main thread can store into this field while we read it. The race is
+ // benign: the snapshot protocol keeps the load in bounds, and
+ // OwnConstantDataPropertyDependency revalidates the value on the main
+ // thread.
+ TSAN_IGNORE_READS_BEGIN;
constant = holder.object()->RawInobjectPropertyAt(map, field_index);
+ TSAN_IGNORE_READS_END;
if (!constant.has_value()) {
TRACE_BROKER_MISSING(
broker, "Constant field in " << holder << " is unsafe to read");
@@ -740,8 +747,8 @@ void JSFunctionData::Cache(JSHeapBroker* broker) {
ObjectData* proto_or_map = prototype_or_initial_map_;
if (proto_or_map->IsTuple2()) {
Tagged<Tuple2> tuple = Cast<Tuple2>(*proto_or_map->object());
- proto_or_map =
- broker->GetOrCreateData(tuple->value1(), kAssumeMemoryFence);
+ proto_or_map = broker->GetOrCreateData(tuple->value1(kAcquireLoad),
+ kAssumeMemoryFence);
}
has_initial_map_ = proto_or_map->IsMap();
diff --git a/deps/v8/src/compiler/js-call-reducer.cc b/deps/v8/src/compiler/js-call-reducer.cc
index 0e2d9bfd0a7..0b4cc9238b1 100644
--- a/deps/v8/src/compiler/js-call-reducer.cc
+++ b/deps/v8/src/compiler/js-call-reducer.cc
@@ -7215,9 +7215,31 @@ Reduction JSCallReducer::ReduceGeneratorPrototypeNext(Node* node) {
return NoChange();
}
+ // Don't inline Generator.prototype.next across native contexts.
+ HeapObjectMatcher m(n.target());
+ if (m.HasResolvedValue() && m.Ref(broker()).IsJSFunction()) {
+ JSFunctionRef function = m.Ref(broker()).AsJSFunction();
+ if (!function.native_context(broker()).equals(native_context())) {
+ return NoChange();
+ }
+ }
+
MapInference inference(broker(), receiver, effect);
+ bool can_use_static_maps = false;
if (inference.HaveMaps() &&
inference.AllOfInstanceTypesAre(JS_GENERATOR_OBJECT_TYPE)) {
+ can_use_static_maps = true;
+ for (MapRef map : inference.GetMaps()) {
+ OptionalObjectRef ctor = map.GetConstructor(broker());
+ if (!ctor.has_value() || !ctor->IsJSFunction() ||
+ !ctor->AsJSFunction().native_context(broker()).equals(
+ native_context())) {
+ return inference.NoChange();
+ }
+ }
+ }
+
+ if (can_use_static_maps) {
inference.RelyOnMapsPreferStability(dependencies(), jsgraph(), &effect,
control, p.feedback());
} else {
@@ -7246,6 +7268,24 @@ Reduction JSCallReducer::ReduceGeneratorPrototypeNext(Node* node) {
simplified()->CheckIf(DeoptimizeReason::kWrongInstanceType,
p.feedback()),
is_generator, effect, control);
+
+ Node* receiver_context = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForJSGeneratorObjectContext()),
+ receiver, effect, control);
+ Node* receiver_context_map = effect =
+ graph()->NewNode(simplified()->LoadField(AccessBuilder::ForMap()),
+ receiver_context, effect, control);
+ Node* receiver_native_context = effect = graph()->NewNode(
+ simplified()->LoadField(AccessBuilder::ForMapNativeContext()),
+ receiver_context_map, effect, control);
+ Node* target_native_context =
+ jsgraph()->ConstantNoHole(native_context(), broker());
+ Node* check_realm =
+ graph()->NewNode(simplified()->ReferenceEqual(),
+ receiver_native_context, target_native_context);
+ effect = graph()->NewNode(
+ simplified()->CheckIf(DeoptimizeReason::kWrongValue, p.feedback()),
+ check_realm, effect, control);
}
// Check if the {receiver} is running or already closed.
diff --git a/deps/v8/src/compiler/js-generic-lowering.cc b/deps/v8/src/compiler/js-generic-lowering.cc
index de87f0ce86b..22d24ff791a 100644
--- a/deps/v8/src/compiler/js-generic-lowering.cc
+++ b/deps/v8/src/compiler/js-generic-lowering.cc
@@ -133,18 +133,15 @@ void JSGenericLowering::ReplaceWithRuntimeCall(Node* node,
NodeProperties::ChangeOp(node, common()->Call(call_descriptor));
}
-void JSGenericLowering::ReplaceUnaryOpWithBuiltinCall(
- Node* node, Builtin builtin_without_feedback,
- Builtin builtin_with_feedback) {
- DCHECK(JSOperator::IsUnaryWithFeedback(node->opcode()));
- node->RemoveInput(JSUnaryOpNode::FeedbackVectorIndex());
- ReplaceWithBuiltinCall(node, builtin_without_feedback);
+void JSGenericLowering::ReplaceUnaryOpWithBuiltinCall(Node* node,
+ Builtin builtin) {
+ DCHECK(JSOperator::IsUnaryWithEmbeddedFeedback(node->opcode()));
+ ReplaceWithBuiltinCall(node, builtin);
}
-#define DEF_UNARY_LOWERING(Name) \
- void JSGenericLowering::LowerJS##Name(Node* node) { \
- ReplaceUnaryOpWithBuiltinCall(node, Builtin::k##Name, \
- Builtin::k##Name##_WithFeedback); \
+#define DEF_UNARY_LOWERING(Name) \
+ void JSGenericLowering::LowerJS##Name(Node* node) { \
+ ReplaceUnaryOpWithBuiltinCall(node, Builtin::k##Name); \
}
DEF_UNARY_LOWERING(BitwiseNot)
DEF_UNARY_LOWERING(Decrement)
diff --git a/deps/v8/src/compiler/js-generic-lowering.h b/deps/v8/src/compiler/js-generic-lowering.h
index 156b0ac5473..10cc7af118b 100644
--- a/deps/v8/src/compiler/js-generic-lowering.h
+++ b/deps/v8/src/compiler/js-generic-lowering.h
@@ -45,9 +45,7 @@ class JSGenericLowering final : public AdvancedReducer {
Operator::Properties properties);
void ReplaceWithRuntimeCall(Node* node, Runtime::FunctionId f, int args = -1);
- void ReplaceUnaryOpWithBuiltinCall(Node* node,
- Builtin builtin_without_feedback,
- Builtin builtin_with_feedback);
+ void ReplaceUnaryOpWithBuiltinCall(Node* node, Builtin builtin);
void ReplaceBinaryOpWithBuiltinCall(Node* node,
Builtin builtin_without_feedback,
Builtin builtin_with_feedback);
diff --git a/deps/v8/src/compiler/js-heap-broker.cc b/deps/v8/src/compiler/js-heap-broker.cc
index d5cf37bfd3f..2da827a08d6 100644
--- a/deps/v8/src/compiler/js-heap-broker.cc
+++ b/deps/v8/src/compiler/js-heap-broker.cc
@@ -23,6 +23,7 @@
#include "src/objects/literal-objects-inl.h"
#include "src/objects/map-updater.h"
#include "src/objects/megadom-handler-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-cell.h"
@@ -436,7 +437,6 @@ NamedAccessFeedback::NamedAccessFeedback(
bool has_deprecated_map_without_migration_target)
: ProcessedFeedback(kNamedAccess, slot_kind),
name_(name.UnpackIfThin(broker)),
- original_name_maybe_thin_(name),
maps_(maps),
handlers_(handlers),
has_deprecated_map_without_migration_target_(
@@ -728,7 +728,8 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForInstanceOf(
nexus.GetConstructorFeedback();
DirectHandle<JSObject> constructor;
if (maybe_constructor.ToHandle(&constructor)) {
- optional_constructor = MakeRefAssumeMemoryFence(this, *constructor);
+ // Written by generated code so this needs TryMakeRef.
+ optional_constructor = TryMakeRef(this, *constructor);
}
}
return *zone()->New<InstanceOfFeedback>(optional_constructor, nexus.kind());
@@ -753,9 +754,11 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForArrayOrObjectLiteral(
return NewInsufficientFeedback(nexus.kind());
}
- AllocationSiteRef site =
- MakeRefAssumeMemoryFence(this, Cast<AllocationSite>(object));
- return *zone()->New<LiteralFeedback>(site, nexus.kind());
+ // Written by generated code so this needs TryMakeRef.
+ OptionalAllocationSiteRef site =
+ TryMakeRef(this, Cast<AllocationSite>(object));
+ if (!site.has_value()) return NewInsufficientFeedback(nexus.kind());
+ return *zone()->New<LiteralFeedback>(*site, nexus.kind());
}
ProcessedFeedback const& JSHeapBroker::ReadFeedbackForRegExpLiteral(
@@ -783,8 +786,10 @@ ProcessedFeedback const& JSHeapBroker::ReadFeedbackForTemplateObject(
return NewInsufficientFeedback(nexus.kind());
}
- JSArrayRef array = MakeRefAssumeMemoryFence(this, Cast<JSArray>(object));
- return *zone()->New<TemplateObjectFeedback>(array, nexus.kind());
+ // Written by generated code so this needs TryMakeRef.
+ OptionalJSArrayRef array = TryMakeRef(this, Cast<JSArray>(object));
+ if (!array.has_value()) return NewInsufficientFeedback(nexus.kind());
+ return *zone()->New<TemplateObjectFeedback>(*array, nexus.kind());
}
ProcessedFeedback const& JSHeapBroker::ReadFeedbackForCall(
diff --git a/deps/v8/src/compiler/js-native-context-specialization.cc b/deps/v8/src/compiler/js-native-context-specialization.cc
index 00de1e7ecce..f96471ced31 100644
--- a/deps/v8/src/compiler/js-native-context-specialization.cc
+++ b/deps/v8/src/compiler/js-native-context-specialization.cc
@@ -1457,12 +1457,6 @@ Reduction JSNativeContextSpecialization::ReduceMegaDOMPropertyAccess(
}
FunctionTemplateInfoRef function_template_info = feedback.info();
- int16_t range_start =
- function_template_info.allowed_receiver_instance_type_range_start();
- int16_t range_end =
- function_template_info.allowed_receiver_instance_type_range_end();
- DCHECK_IMPLIES(range_start == 0, range_end == 0);
- DCHECK_LE(range_start, range_end);
// TODO(mslekova): This could be a new InstanceTypeCheck operator
// that gets lowered later on (e.g. during generic lowering).
@@ -1473,21 +1467,7 @@ Reduction JSNativeContextSpecialization::ReduceMegaDOMPropertyAccess(
simplified()->LoadField(AccessBuilder::ForMapInstanceType()),
receiver_map, effect, control);
- if (v8_flags.experimental_embedder_instance_types && range_start != 0) {
- // Embedder instance ID is set, doing a simple range check.
- Node* diff_to_start =
- graph()->NewNode(simplified()->NumberSubtract(), receiver_instance_type,
- jsgraph()->ConstantNoHole(range_start));
- Node* range_length = jsgraph()->ConstantNoHole(range_end - range_start);
-
- // TODO(mslekova): Once we have the InstanceTypeCheck operator, we could
- // lower it to Uint32LessThan later on to perform what is done in bounds.h.
- Node* check = graph()->NewNode(simplified()->NumberLessThanOrEqual(),
- diff_to_start, range_length);
- effect = graph()->NewNode(
- simplified()->CheckIf(DeoptimizeReason::kWrongInstanceType), check,
- effect, control);
- } else if (function_template_info.is_signature_undefined(broker())) {
+ if (function_template_info.is_signature_undefined(broker())) {
// Signature is undefined, enough to check if the receiver is a JSApiObject.
Node* check =
graph()->NewNode(simplified()->NumberEqual(), receiver_instance_type,
@@ -1636,8 +1616,7 @@ Reduction JSNativeContextSpecialization::ReduceNamedAccess(
// Ensure that {key} matches the specified name (if {key} is given).
if (key != nullptr) {
- effect = BuildCheckEqualsName(feedback.original_name_maybe_thin(), key,
- effect, &control);
+ effect = BuildCheckEqualsName(feedback.name(), key, effect, &control);
}
// Collect call nodes to rewire exception edges.
diff --git a/deps/v8/src/compiler/js-operator.cc b/deps/v8/src/compiler/js-operator.cc
index cb1f985dfe3..ac42be61445 100644
--- a/deps/v8/src/compiler/js-operator.cc
+++ b/deps/v8/src/compiler/js-operator.cc
@@ -264,8 +264,7 @@ std::ostream& operator<<(std::ostream& os, FeedbackParameter const& p) {
}
FeedbackParameter const& FeedbackParameterOf(const Operator* op) {
- DCHECK(JSOperator::IsUnaryWithFeedback(op->opcode()) ||
- JSOperator::IsBinaryWithFeedback(op->opcode()) ||
+ DCHECK(JSOperator::IsBinaryWithFeedback(op->opcode()) ||
op->opcode() == IrOpcode::kJSCreateEmptyLiteralArray ||
op->opcode() == IrOpcode::kJSInstanceOf ||
op->opcode() == IrOpcode::kJSDefineKeyedOwnPropertyInLiteral ||
@@ -315,7 +314,8 @@ std::ostream& operator<<(std::ostream& os, EmbeddedHintParameter const& p) {
}
EmbeddedHintParameter const& EmbeddedHintParameterOf(const Operator* op) {
- DCHECK(JSOperator::IsBinaryWithEmbeddedFeedback(op->opcode()));
+ DCHECK(JSOperator::IsBinaryWithEmbeddedFeedback(op->opcode()) ||
+ JSOperator::IsUnaryWithEmbeddedFeedback(op->opcode()));
return OpParameter<EmbeddedHintParameter>(op);
}
@@ -948,15 +948,15 @@ JSOperatorBuilder::JSOperatorBuilder(Zone* zone)
CACHED_OP_LIST(CACHED_OP)
#undef CACHED_OP
-#define UNARY_OP(JSName, Name) \
- const Operator* JSOperatorBuilder::Name(FeedbackSource const& feedback) { \
- FeedbackParameter parameters(feedback); \
- return zone()->New<Operator1<FeedbackParameter>>( \
- IrOpcode::k##JSName, Operator::kNoProperties, #JSName, 2, 1, 1, 1, 1, \
- 2, parameters); \
+#define UNOP_WITH_EMBEDDED_FEEDBACK(JSName, Name) \
+ const Operator* JSOperatorBuilder::Name(BinaryOperationHint hint) { \
+ EmbeddedHintParameter hint_parameter(hint); \
+ return zone()->New<Operator1<EmbeddedHintParameter>>( \
+ IrOpcode::k##JSName, Operator::kNoProperties, #JSName, 1, 1, 1, 1, 1, \
+ 2, hint_parameter); \
}
-JS_UNOP_WITH_FEEDBACK(UNARY_OP)
-#undef UNARY_OP
+JS_UNOP_WITH_EMBEDDED_FEEDBACK(UNOP_WITH_EMBEDDED_FEEDBACK)
+#undef UNOP_WITH_EMBEDDED_FEEDBACK
#define BINARY_OP(JSName, Name) \
const Operator* JSOperatorBuilder::Name(FeedbackSource const& feedback) { \
diff --git a/deps/v8/src/compiler/js-operator.h b/deps/v8/src/compiler/js-operator.h
index d59a2683778..15a49e40b04 100644
--- a/deps/v8/src/compiler/js-operator.h
+++ b/deps/v8/src/compiler/js-operator.h
@@ -41,8 +41,8 @@ class Operator;
struct JSOperatorGlobalCache;
// Macro lists.
-#define JS_UNOP_WITH_FEEDBACK(V) \
- JS_BITWISE_UNOP_LIST(V) \
+#define JS_UNOP_WITH_EMBEDDED_FEEDBACK(V) \
+ JS_BITWISE_UNOP_LIST(V) \
JS_ARITH_UNOP_LIST(V)
#define JS_BINOP_WITH_FEEDBACK(V) \
@@ -58,36 +58,36 @@ struct JSOperatorGlobalCache;
// Predicates.
class JSOperator final : public AllStatic {
public:
- static constexpr bool IsUnaryWithFeedback(Operator::Opcode opcode) {
+ static constexpr bool IsBinaryWithFeedback(Operator::Opcode opcode) {
#define CASE(Name, ...) \
case IrOpcode::k##Name: \
return true;
switch (opcode) {
- JS_UNOP_WITH_FEEDBACK(CASE);
+ JS_BINOP_WITH_FEEDBACK(CASE);
default:
return false;
}
#undef CASE
}
- static constexpr bool IsBinaryWithFeedback(Operator::Opcode opcode) {
+ static constexpr bool IsBinaryWithEmbeddedFeedback(Operator::Opcode opcode) {
#define CASE(Name, ...) \
case IrOpcode::k##Name: \
return true;
switch (opcode) {
- JS_BINOP_WITH_FEEDBACK(CASE);
+ JS_BINOP_WITH_EMBEDDED_FEEDBACK(CASE);
default:
return false;
}
#undef CASE
}
- static constexpr bool IsBinaryWithEmbeddedFeedback(Operator::Opcode opcode) {
+ static constexpr bool IsUnaryWithEmbeddedFeedback(Operator::Opcode opcode) {
#define CASE(Name, ...) \
case IrOpcode::k##Name: \
return true;
switch (opcode) {
- JS_BINOP_WITH_EMBEDDED_FEEDBACK(CASE);
+ JS_UNOP_WITH_EMBEDDED_FEEDBACK(CASE);
default:
return false;
}
@@ -1044,10 +1044,10 @@ class V8_EXPORT_PRIVATE JSOperatorBuilder final
const Operator* ShiftRight(BinaryOperationHint hint);
const Operator* ShiftRightLogical(BinaryOperationHint hint);
- const Operator* BitwiseNot(FeedbackSource const& feedback);
- const Operator* Decrement(FeedbackSource const& feedback);
- const Operator* Increment(FeedbackSource const& feedback);
- const Operator* Negate(FeedbackSource const& feedback);
+ const Operator* BitwiseNot(BinaryOperationHint hint);
+ const Operator* Decrement(BinaryOperationHint hint);
+ const Operator* Increment(BinaryOperationHint hint);
+ const Operator* Negate(BinaryOperationHint hint);
const Operator* ToLength();
const Operator* ToName();
@@ -1288,23 +1288,6 @@ class JSNodeWrapperBase : public NodeWrapper {
NodeProperties::GetValueInput(node(), TheIndex)); \
}
-class JSUnaryOpNode final : public JSNodeWrapperBase {
- public:
- explicit constexpr JSUnaryOpNode(Node* node) : JSNodeWrapperBase(node) {
- DCHECK(JSOperator::IsUnaryWithFeedback(node->opcode()));
- }
-
-#define INPUTS(V) \
- V(Value, value, 0, Object) \
- V(FeedbackVector, feedback_vector, 1, HeapObject)
- INPUTS(DEFINE_INPUT_ACCESSORS)
-#undef INPUTS
-};
-
-#define V(JSName, ...) using JSName##Node = JSUnaryOpNode;
-JS_UNOP_WITH_FEEDBACK(V)
-#undef V
-
class JSBinaryOpNode final : public JSNodeWrapperBase {
public:
explicit constexpr JSBinaryOpNode(Node* node) : JSNodeWrapperBase(node) {
diff --git a/deps/v8/src/compiler/js-type-hint-lowering.cc b/deps/v8/src/compiler/js-type-hint-lowering.cc
index 25e13162c2b..8278123cee8 100644
--- a/deps/v8/src/compiler/js-type-hint-lowering.cc
+++ b/deps/v8/src/compiler/js-type-hint-lowering.cc
@@ -10,6 +10,7 @@
#include "src/compiler/opcodes.h"
#include "src/compiler/operator-properties.h"
#include "src/compiler/simplified-operator.h"
+#include "src/flags/flags.h"
#include "src/objects/type-hints.h"
namespace v8 {
@@ -28,7 +29,9 @@ bool BinaryOperationHintToNumberOperationHint(
*number_hint = NumberOperationHint::kSignedSmallInputs;
return true;
case BinaryOperationHint::kAdditiveSafeInteger:
- *number_hint = NumberOperationHint::kAdditiveSafeInteger;
+ *number_hint = v8_flags.turbofan_additive_safe_int_feedback
+ ? NumberOperationHint::kAdditiveSafeInteger
+ : NumberOperationHint::kNumber;
return true;
case BinaryOperationHint::kNumber:
*number_hint = NumberOperationHint::kNumber;
@@ -385,108 +388,126 @@ CompareOperationHint JSTypeHintLowering::GetCompareOperationHint(
return broker()->GetFeedbackForCompareOperation(source);
}
-JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceUnaryOperation(
+JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceTypeOfOperation(
const Operator* op, Node* operand, Node* effect, Node* control,
FeedbackSlot slot) const {
+ DCHECK_EQ(op->opcode(), IrOpcode::kTypeOf);
if (Node* node = BuildDeoptIfFeedbackIsInsufficient(
slot, effect, control,
DeoptimizeReason::kInsufficientTypeFeedbackForUnaryOperation)) {
return LoweringResult::Exit(node);
}
- // Note: Unary and binary operations collect the same kind of feedback.
FeedbackSource feedback(feedback_vector(), slot);
- Node* node;
- Node* check = nullptr;
+ TypeOfFeedback::Result hint = broker()->GetFeedbackForTypeOf(feedback);
+ switch (hint) {
+ case TypeOfFeedback::kNumber:
+ case TypeOfFeedback::kSmi: {
+ Node* check = jsgraph()->graph()->NewNode(
+ jsgraph()->simplified()->CheckNumber(FeedbackSource()), operand,
+ effect, control);
+ Node* node =
+ jsgraph()->ConstantNoHole(broker()->number_string(), broker());
+ return LoweringResult::SideEffectFree(node, check, control);
+ }
+ case TypeOfFeedback::kString: {
+ Node* check = jsgraph()->graph()->NewNode(
+ jsgraph()->simplified()->CheckString(FeedbackSource()), operand,
+ effect, control);
+ Node* node =
+ jsgraph()->ConstantNoHole(broker()->string_string(), broker());
+ return LoweringResult::SideEffectFree(node, check, control);
+ }
+ case TypeOfFeedback::kFunction: {
+ Node* condition = jsgraph()->graph()->NewNode(
+ jsgraph()->simplified()->ObjectIsDetectableCallable(), operand);
+ Node* check = jsgraph()->graph()->NewNode(
+ jsgraph()->simplified()->CheckIf(
+ DeoptimizeReason::kNotDetectableReceiver, FeedbackSource()),
+ condition, effect, control);
+ Node* node =
+ jsgraph()->ConstantNoHole(broker()->function_string(), broker());
+ return LoweringResult::SideEffectFree(node, check, control);
+ }
+ default:
+ break;
+ }
+ return LoweringResult::NoChange();
+}
+
+JSTypeHintLowering::LoweringResult
+JSTypeHintLowering::ReduceUnaryOperationWithEmbeddedHint(const Operator* op,
+ Node* operand,
+ Node* effect,
+ Node* control) const {
+ auto embedded_hint = EmbeddedHintParameterOf(op);
+ if (Node* node = BuildDeoptIfFeedbackIsInsufficient(
+ embedded_hint, effect, control,
+ DeoptimizeReason::kInsufficientTypeFeedbackForUnaryOperation)) {
+ return LoweringResult::Exit(node);
+ }
+
+ BinaryOperationHint hint =
+ std::get<BinaryOperationHint>(embedded_hint.hint());
+
switch (op->opcode()) {
case IrOpcode::kJSBitwiseNot: {
// Lower to a speculative xor with -1 if we have some kind of Number
// feedback.
JSSpeculativeBinopBuilder b(
- this, jsgraph()->javascript()->BitwiseXor(feedback), operand,
- jsgraph()->SmiConstant(-1), effect, control, slot);
- node = b.TryBuildNumberBinop();
+ this, jsgraph()->javascript()->BitwiseXor(hint), operand,
+ jsgraph()->SmiConstant(-1), effect, control, embedded_hint);
+ if (Node* node = b.TryBuildNumberBinop()) {
+ return LoweringResult::SideEffectFree(node, node, control);
+ }
break;
}
case IrOpcode::kJSDecrement: {
// Lower to a speculative subtraction of 1 if we have some kind of Number
// feedback.
- JSSpeculativeBinopBuilder b(
- this, jsgraph()->javascript()->Subtract(feedback), operand,
- jsgraph()->SmiConstant(1), effect, control, slot);
- node = b.TryBuildNumberBinop();
+ JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Subtract(hint),
+ operand, jsgraph()->SmiConstant(1), effect,
+ control, embedded_hint);
+ if (Node* node = b.TryBuildNumberBinop()) {
+ return LoweringResult::SideEffectFree(node, node, control);
+ }
break;
}
case IrOpcode::kJSIncrement: {
// Lower to a speculative addition of 1 if we have some kind of Number
// feedback.
- JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Add(feedback),
+ JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Add(hint),
operand, jsgraph()->SmiConstant(1), effect,
- control, slot);
- node = b.TryBuildNumberBinop();
+ control, embedded_hint);
+ if (Node* node = b.TryBuildNumberBinop()) {
+ return LoweringResult::SideEffectFree(node, node, control);
+ }
break;
}
case IrOpcode::kJSNegate: {
// Lower to a speculative multiplication with -1 if we have some kind of
// Number feedback.
- JSSpeculativeBinopBuilder b(
- this, jsgraph()->javascript()->Multiply(feedback), operand,
- jsgraph()->SmiConstant(-1), effect, control, slot);
- node = b.TryBuildNumberBinop();
- if (!node) {
- if (jsgraph()->machine()->Is64()) {
- if (GetBinaryOperationHint(slot) == BinaryOperationHint::kBigInt) {
- op = jsgraph()->simplified()->SpeculativeBigIntNegate(
- BigIntOperationHint::kBigInt);
- node = jsgraph()->graph()->NewNode(op, operand, effect, control);
- }
- }
+ JSSpeculativeBinopBuilder b(this, jsgraph()->javascript()->Multiply(hint),
+ operand, jsgraph()->SmiConstant(-1), effect,
+ control, embedded_hint);
+ if (Node* node = b.TryBuildNumberBinop()) {
+ return LoweringResult::SideEffectFree(node, node, control);
}
- break;
- }
- case IrOpcode::kTypeOf: {
- TypeOfFeedback::Result hint = broker()->GetFeedbackForTypeOf(feedback);
- switch (hint) {
- case TypeOfFeedback::kNumber:
- case TypeOfFeedback::kSmi:
- check = jsgraph()->graph()->NewNode(
- jsgraph()->simplified()->CheckNumber(FeedbackSource()), operand,
- effect, control);
- node = jsgraph()->ConstantNoHole(broker()->number_string(), broker());
- break;
- case TypeOfFeedback::kString:
- check = jsgraph()->graph()->NewNode(
- jsgraph()->simplified()->CheckString(FeedbackSource()), operand,
- effect, control);
- node = jsgraph()->ConstantNoHole(broker()->string_string(), broker());
- break;
- case TypeOfFeedback::kFunction: {
- Node* condition = jsgraph()->graph()->NewNode(
- jsgraph()->simplified()->ObjectIsDetectableCallable(), operand);
- check = jsgraph()->graph()->NewNode(
- jsgraph()->simplified()->CheckIf(
- DeoptimizeReason::kNotDetectableReceiver, FeedbackSource()),
- condition, effect, control);
- node =
- jsgraph()->ConstantNoHole(broker()->function_string(), broker());
- break;
- }
- default:
- node = nullptr;
- break;
+ if (jsgraph()->machine()->Is64() &&
+ hint == BinaryOperationHint::kBigInt) {
+ Node* node = jsgraph()->graph()->NewNode(
+ jsgraph()->simplified()->SpeculativeBigIntNegate(
+ BigIntOperationHint::kBigInt),
+ operand, effect, control);
+ return LoweringResult::SideEffectFree(node, node, control);
}
break;
}
default:
UNREACHABLE();
}
-
- if (node != nullptr) {
- return LoweringResult::SideEffectFree(node, check ? check : node, control);
- } else {
- return LoweringResult::NoChange();
- }
+ return LoweringResult::NoChange();
}
JSTypeHintLowering::LoweringResult JSTypeHintLowering::ReduceBinaryOperation(
@@ -569,7 +590,7 @@ JSTypeHintLowering::ReduceBinaryOperationWithEmbeddedHint(const Operator* op,
case IrOpcode::kJSStrictEqual: {
if (Node* node = BuildDeoptIfFeedbackIsInsufficient(
EmbeddedHintParameterOf(op), effect, control,
- DeoptimizeReason::kInsufficientTypeFeedbackForBinaryOperation)) {
+ DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation)) {
return LoweringResult::Exit(node);
}
break;
@@ -773,9 +794,7 @@ Node* JSTypeHintLowering::BuildDeoptIfFeedbackIsInsufficient(
if (feedback_is_sufficient) return nullptr;
Node* deoptimize = jsgraph()->graph()->NewNode(
- jsgraph()->common()->Deoptimize(
- DeoptimizeReason::kInsufficientTypeFeedbackForCompareOperation,
- FeedbackSource()),
+ jsgraph()->common()->Deoptimize(reason, FeedbackSource()),
jsgraph()->Dead(), effect, control);
Node* frame_state =
NodeProperties::FindFrameStateBefore(deoptimize, jsgraph()->Dead());
diff --git a/deps/v8/src/compiler/js-type-hint-lowering.h b/deps/v8/src/compiler/js-type-hint-lowering.h
index 274258a21e8..a32c5e92f6e 100644
--- a/deps/v8/src/compiler/js-type-hint-lowering.h
+++ b/deps/v8/src/compiler/js-type-hint-lowering.h
@@ -102,9 +102,14 @@ class JSTypeHintLowering {
};
// Potential reduction of unary operations (e.g. negation).
- LoweringResult ReduceUnaryOperation(const Operator* op, Node* operand,
- Node* effect, Node* control,
- FeedbackSlot slot) const;
+ LoweringResult ReduceTypeOfOperation(const Operator* op, Node* operand,
+ Node* effect, Node* control,
+ FeedbackSlot slot) const;
+
+ LoweringResult ReduceUnaryOperationWithEmbeddedHint(const Operator* op,
+ Node* operand,
+ Node* effect,
+ Node* control) const;
// Potential reduction of binary (arithmetic, logical, shift and relational
// comparison) operations.
diff --git a/deps/v8/src/compiler/js-typed-lowering.cc b/deps/v8/src/compiler/js-typed-lowering.cc
index 4b0e999c362..77b5ff4320a 100644
--- a/deps/v8/src/compiler/js-typed-lowering.cc
+++ b/deps/v8/src/compiler/js-typed-lowering.cc
@@ -582,9 +582,11 @@ Reduction JSTypedLowering::ReduceJSBitwiseNot(Node* node) {
Type input_type = NodeProperties::GetType(input);
if (input_type.Is(Type::PlainPrimitive())) {
// JSBitwiseNot(x) => NumberBitwiseXor(ToInt32(x), -1)
- const FeedbackParameter& p = FeedbackParameterOf(node->op());
+ const EmbeddedHintParameter& p = EmbeddedHintParameterOf(node->op());
node->InsertInput(graph()->zone(), 1, jsgraph()->SmiConstant(-1));
- NodeProperties::ChangeOp(node, javascript()->BitwiseXor(p.feedback()));
+ NodeProperties::ChangeOp(
+ node,
+ javascript()->BitwiseXor(std::get<BinaryOperationHint>(p.hint())));
JSBinopReduction r(this, node);
r.ConvertInputsToNumber();
r.ConvertInputsToUI32(kSigned, kSigned);
@@ -598,9 +600,10 @@ Reduction JSTypedLowering::ReduceJSDecrement(Node* node) {
Type input_type = NodeProperties::GetType(input);
if (input_type.Is(Type::PlainPrimitive())) {
// JSDecrement(x) => NumberSubtract(ToNumber(x), 1)
- const FeedbackParameter& p = FeedbackParameterOf(node->op());
+ const EmbeddedHintParameter& p = EmbeddedHintParameterOf(node->op());
node->InsertInput(graph()->zone(), 1, jsgraph()->OneConstant());
- NodeProperties::ChangeOp(node, javascript()->Subtract(p.feedback()));
+ NodeProperties::ChangeOp(
+ node, javascript()->Subtract(std::get<BinaryOperationHint>(p.hint())));
JSBinopReduction r(this, node);
r.ConvertInputsToNumber();
DCHECK_EQ(simplified()->NumberSubtract(), r.NumberOp());
@@ -614,9 +617,10 @@ Reduction JSTypedLowering::ReduceJSIncrement(Node* node) {
Type input_type = NodeProperties::GetType(input);
if (input_type.Is(Type::PlainPrimitive())) {
// JSIncrement(x) => NumberAdd(ToNumber(x), 1)
- const FeedbackParameter& p = FeedbackParameterOf(node->op());
+ const EmbeddedHintParameter& p = EmbeddedHintParameterOf(node->op());
node->InsertInput(graph()->zone(), 1, jsgraph()->OneConstant());
- NodeProperties::ChangeOp(node, javascript()->Add(p.feedback()));
+ NodeProperties::ChangeOp(
+ node, javascript()->Add(std::get<BinaryOperationHint>(p.hint())));
JSBinopReduction r(this, node);
r.ConvertInputsToNumber();
DCHECK_EQ(simplified()->NumberAdd(), r.NumberOp());
@@ -630,9 +634,10 @@ Reduction JSTypedLowering::ReduceJSNegate(Node* node) {
Type input_type = NodeProperties::GetType(input);
if (input_type.Is(Type::PlainPrimitive())) {
// JSNegate(x) => NumberMultiply(ToNumber(x), -1)
- const FeedbackParameter& p = FeedbackParameterOf(node->op());
+ const EmbeddedHintParameter& p = EmbeddedHintParameterOf(node->op());
node->InsertInput(graph()->zone(), 1, jsgraph()->SmiConstant(-1));
- NodeProperties::ChangeOp(node, javascript()->Multiply(p.feedback()));
+ NodeProperties::ChangeOp(
+ node, javascript()->Multiply(std::get<BinaryOperationHint>(p.hint())));
JSBinopReduction r(this, node);
r.ConvertInputsToNumber();
return r.ChangeToPureOperator(r.NumberOp(), Type::Number());
diff --git a/deps/v8/src/compiler/linear-scheduler.cc b/deps/v8/src/compiler/linear-scheduler.cc
deleted file mode 100644
index 21947fd7f5e..00000000000
--- a/deps/v8/src/compiler/linear-scheduler.cc
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2013 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/linear-scheduler.h"
-
-#include "src/compiler/node-properties.h"
-#include "src/compiler/node.h"
-#include "src/compiler/turbofan-graph.h"
-#include "src/zone/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-LinearScheduler::LinearScheduler(Zone* zone, TFGraph* graph)
- : graph_(graph), control_level_(zone), early_schedule_position_(zone) {
- ComputeControlLevel();
-}
-
-void LinearScheduler::ComputeControlLevel() {
- Node* start = graph_->start();
- SetControlLevel(start, 0);
-
- // Do BFS from the start node and compute the level of
- // each control node.
- std::queue<Node*> queue({start});
- while (!queue.empty()) {
- Node* node = queue.front();
- int level = GetControlLevel(node);
- queue.pop();
- for (Edge const edge : node->use_edges()) {
- if (!NodeProperties::IsControlEdge(edge)) continue;
- Node* use = edge.from();
- if (use->opcode() == IrOpcode::kLoopExit &&
- node->opcode() == IrOpcode::kLoop) {
- continue;
- }
- if (control_level_.find(use) == control_level_.end() &&
- use->opcode() != IrOpcode::kEnd) {
- SetControlLevel(use, level + 1);
- queue.push(use);
- }
- }
- }
-}
-
-Node* LinearScheduler::GetEarlySchedulePosition(Node* node) {
- DCHECK(!NodeProperties::IsControl(node));
-
- auto it = early_schedule_position_.find(node);
- if (it != early_schedule_position_.end()) return it->second;
-
- std::stack<NodeState> stack;
- stack.push({node, nullptr, 0});
- Node* early_schedule_position = nullptr;
- while (!stack.empty()) {
- NodeState& top = stack.top();
- if (NodeProperties::IsPhi(top.node)) {
- // For phi node, the early schedule position is its control node.
- early_schedule_position = NodeProperties::GetControlInput(top.node);
- } else if (top.node->InputCount() == 0) {
- // For node without inputs, the early schedule position is start node.
- early_schedule_position = graph_->start();
- } else {
- // For others, the early schedule position is one of its inputs' early
- // schedule position with maximal level.
- if (top.input_index == top.node->InputCount()) {
- // All inputs are visited, set early schedule position.
- early_schedule_position = top.early_schedule_position;
- } else {
- // Visit top's input and find its early schedule position.
- Node* input = top.node->InputAt(top.input_index);
- Node* input_early_schedule_position = nullptr;
- if (NodeProperties::IsControl(input)) {
- input_early_schedule_position = input;
- } else {
- auto early_pos_it = early_schedule_position_.find(input);
- if (early_pos_it != early_schedule_position_.end()) {
- input_early_schedule_position = early_pos_it->second;
- }
- }
- if (input_early_schedule_position != nullptr) {
- if (top.early_schedule_position == nullptr ||
- GetControlLevel(top.early_schedule_position) <
- GetControlLevel(input_early_schedule_position)) {
- top.early_schedule_position = input_early_schedule_position;
- }
- top.input_index += 1;
- } else {
- top.input_index += 1;
- stack.push({input, nullptr, 0});
- }
- continue;
- }
- }
-
- // Found top's early schedule position, set it to the cache and pop it out
- // of the stack.
- SetEarlySchedulePosition(top.node, early_schedule_position);
- stack.pop();
- // Update early schedule position of top's use.
- if (!stack.empty()) {
- NodeState& use = stack.top();
- if (use.early_schedule_position == nullptr ||
- GetControlLevel(use.early_schedule_position) <
- GetControlLevel(early_schedule_position)) {
- use.early_schedule_position = early_schedule_position;
- }
- }
- }
-
- DCHECK(early_schedule_position != nullptr);
- return early_schedule_position;
-}
-
-bool LinearScheduler::SameBasicBlock(Node* node0, Node* node1) {
- Node* early_schedule_position0 = NodeProperties::IsControl(node0)
- ? node0
- : GetEarlySchedulePosition(node0);
- Node* early_schedule_position1 = NodeProperties::IsControl(node1)
- ? node1
- : GetEarlySchedulePosition(node1);
- return early_schedule_position0 == early_schedule_position1;
-}
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/src/compiler/linear-scheduler.h b/deps/v8/src/compiler/linear-scheduler.h
deleted file mode 100644
index 3b47d4d3a7c..00000000000
--- a/deps/v8/src/compiler/linear-scheduler.h
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2013 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_COMPILER_LINEAR_SCHEDULER_H_
-#define V8_COMPILER_LINEAR_SCHEDULER_H_
-
-#include "src/base/flags.h"
-#include "src/common/globals.h"
-#include "src/compiler/node.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/zone-stats.h"
-#include "src/zone/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// A simple, linear-time scheduler to check whether two nodes are in a same
-// basic block without actually building basic block.
-class V8_EXPORT_PRIVATE LinearScheduler {
- public:
- explicit LinearScheduler(Zone* zone, TFGraph* graph);
- bool SameBasicBlock(Node* node0, Node* node1);
- // Get a node's early schedule position. It is the earliest block (represented
- // by a control node) where a node could be scheduled.
- Node* GetEarlySchedulePosition(Node* node);
-
- private:
- // Compute the level of each control node. The level is defined by the
- // shortest control path from the start node.
- void ComputeControlLevel();
-
- struct NodeState {
- Node* node;
- Node* early_schedule_position;
- int input_index;
- };
-
- int GetControlLevel(Node* control) const {
- auto it = control_level_.find(control);
- DCHECK(it != control_level_.end());
- return it->second;
- }
-
- void SetControlLevel(Node* control, int level) {
- DCHECK(control_level_.find(control) == control_level_.end());
- control_level_[control] = level;
- }
-
- void SetEarlySchedulePosition(Node* node, Node* early_schedule_position) {
- early_schedule_position_[node] = early_schedule_position;
- }
-
- TFGraph* graph_;
- // A map from a control node to the control level of the corresponding basic
- // block.
- ZoneMap<Node*, int> control_level_;
- // A map from a non-control node to its early schedule position.
- ZoneMap<Node*, Node*> early_schedule_position_;
-};
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
-
-#endif // V8_COMPILER_LINEAR_SCHEDULER_H_
diff --git a/deps/v8/src/compiler/pipeline.cc b/deps/v8/src/compiler/pipeline.cc
index 2bb38fa415a..13588d79aaa 100644
--- a/deps/v8/src/compiler/pipeline.cc
+++ b/deps/v8/src/compiler/pipeline.cc
@@ -142,7 +142,6 @@
#endif // V8_ENABLE_WEBASSEMBLY
#if V8_ENABLE_WASM_SIMD256_REVEC
-#include "src/compiler/revectorizer.h"
#include "src/compiler/turboshaft/wasm-revec-phase.h"
#endif // V8_ENABLE_WASM_SIMD256_REVEC
@@ -179,9 +178,6 @@ class PipelineImpl final {
// Substep B.1. Produce a scheduled graph.
V8_WARN_UNUSED_RESULT bool ComputeScheduledGraph();
-#if V8_ENABLE_WASM_SIMD256_REVEC
- V8_WARN_UNUSED_RESULT bool Revectorize();
-#endif // V8_ENABLE_WASM_SIMD256_REVEC
// Substep B.3. Run register allocation on the instruction sequence.
V8_WARN_UNUSED_RESULT bool AllocateRegisters(CallDescriptor* call_descriptor,
@@ -1477,17 +1473,6 @@ struct ComputeSchedulePhase {
}
};
-#if V8_ENABLE_WASM_SIMD256_REVEC
-struct RevectorizePhase {
- DECL_PIPELINE_PHASE_CONSTANTS(Revectorizer)
-
- void Run(TFPipelineData* data, Zone* temp_zone) {
- Revectorizer revec(temp_zone, data->graph(), data->mcgraph(),
- data->source_positions());
- revec.TryRevectorize(data->info()->GetDebugName().get());
- }
-};
-#endif // V8_ENABLE_WASM_SIMD256_REVEC
struct PrintGraphPhase {
DECL_PIPELINE_PHASE_CONSTANTS(PrintGraph)
@@ -3098,6 +3083,11 @@ wasm::WasmCompilationResult Pipeline::GenerateWasmCode(
std::cout << "Finished revec function "
<< data.info()->GetDebugName().get() << std::endl;
}
+ // Report the percentage of this function's SIMD128 operations that were
+ // combined into SIMD256. Recorded via {counter_updates} because
+ // compilation may run on a background thread with no current isolate.
+ counter_updates->AddSample(&Counters::wasm_revec_conversion_percent,
+ turboshaft_data.wasm_revec_percent());
}
}
#endif // V8_ENABLE_WASM_SIMD256_REVEC
@@ -3461,9 +3451,6 @@ bool PipelineImpl::ComputeScheduledGraph() {
return true;
}
-#if V8_ENABLE_WASM_SIMD256_REVEC
-bool PipelineImpl::Revectorize() { return Run<RevectorizePhase>(); }
-#endif // V8_ENABLE_WASM_SIMD256_REVEC
OptimizedCompilationInfo* PipelineImpl::info() const { return data_->info(); }
@@ -3504,6 +3491,9 @@ std::ostream& operator<<(std::ostream& out, const InstructionRangesAsJSON& s) {
return out;
}
+#undef RUN_MAYBE_ABORT
+#undef PIPELINE_RUN_MAYBE_ABORT
+
} // namespace compiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/compiler/processed-feedback.h b/deps/v8/src/compiler/processed-feedback.h
index c1739b35e4a..a4f1a260d25 100644
--- a/deps/v8/src/compiler/processed-feedback.h
+++ b/deps/v8/src/compiler/processed-feedback.h
@@ -192,7 +192,6 @@ class NamedAccessFeedback : public ProcessedFeedback {
bool has_deprecated_map_without_migration_target = false);
NameRef name() const { return name_; }
- NameRef original_name_maybe_thin() const { return original_name_maybe_thin_; }
ZoneVector<MapRef> const& maps() const { return maps_; }
ZoneVector<OptionalObjectRef> const& handlers() const { return handlers_; }
bool has_deprecated_map_without_migration_target() const {
@@ -200,13 +199,9 @@ class NamedAccessFeedback : public ProcessedFeedback {
}
private:
- // The unpacked name of the property. If the original name was a ThinString,
- // this will be the actual underlying string. Used for optimizations that
- // care about the string's content and require IsUniqueName.
+ // The unpacked name of the property. If the name recorded in the feedback
+ // was a ThinString, this is the actual underlying string.
NameRef const name_;
- // The original name of the property, which could be a ThinString. This is
- // crucial for checks that rely on object identity.
- NameRef const original_name_maybe_thin_;
ZoneVector<MapRef> const maps_;
ZoneVector<OptionalObjectRef> const handlers_;
bool has_deprecated_map_without_migration_target_;
diff --git a/deps/v8/src/compiler/representation-change.cc b/deps/v8/src/compiler/representation-change.cc
index 7f13f6765df..b61c77d92a5 100644
--- a/deps/v8/src/compiler/representation-change.cc
+++ b/deps/v8/src/compiler/representation-change.cc
@@ -1280,6 +1280,22 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
case IrOpcode::kNumberConstant: {
if (!TypeCheckIsBigInt(use_info.type_check())) {
double const fv = OpParameter<double>(node->op());
+ if (use_info.type_check() == TypeCheckKind::kUnsigned64) {
+ if (base::IsValueInRangeForNumericType<uint64_t>(fv)) {
+ uint64_t const uv = static_cast<uint64_t>(fv);
+ if (static_cast<double>(uv) == fv) {
+ if (uv == 0 && std::signbit(fv) &&
+ use_info.minus_zero_check() ==
+ CheckForMinusZeroMode::kCheckForMinusZero) {
+ break;
+ }
+ return InsertTypeOverrideForVerifier(
+ NodeProperties::GetType(node), jsgraph()->Uint64Constant(uv));
+ }
+ }
+ break;
+ }
+
if (base::IsValueInRangeForNumericType<int64_t>(fv)) {
int64_t const iv = static_cast<int64_t>(fv);
if (static_cast<double>(iv) == fv) {
@@ -1375,9 +1391,8 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
MachineRepresentation::kWord64);
}
} else if (output_rep == MachineRepresentation::kFloat32) {
+ node = InsertChangeFloat32ToFloat64(node);
if (use_info.type_check() == TypeCheckKind::kAdditiveSafeInteger) {
- // float32 -> float64 -> int64
- node = InsertChangeFloat32ToFloat64(node);
if (output_type.Is(cache_->kAdditiveSafeIntegerFeedback)) {
op = machine()->ChangeFloat64ToInt64();
} else {
@@ -1387,33 +1402,35 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
}
+ } else if (use_info.type_check() == TypeCheckKind::kSigned64 ||
+ use_info.type_check() == TypeCheckKind::kArrayIndex) {
+ if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
+ (output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
+ use_info.truncation().IdentifiesZeroAndMinusZero())) {
+ op = machine()->ChangeFloat64ToInt64();
+ } else {
+ op = simplified()->CheckedFloat64ToInt64(
+ output_type.Maybe(Type::MinusZero())
+ ? use_info.minus_zero_check()
+ : CheckForMinusZeroMode::kDontCheckForMinusZero,
+ use_info.feedback());
+ }
+ } else if (use_info.type_check() == TypeCheckKind::kUnsigned64) {
+ if (output_type.Is(cache_->kDoubleRepresentableUint64)) {
+ op = machine()->ChangeFloat64ToUint64();
+ } else {
+ op = simplified()->CheckedFloat64ToUint64(
+ output_type.Maybe(Type::MinusZero())
+ ? use_info.minus_zero_check()
+ : CheckForMinusZeroMode::kDontCheckForMinusZero,
+ use_info.feedback());
+ }
} else if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
(output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
use_info.truncation().IdentifiesZeroAndMinusZero())) {
- // float32 -> float64 -> int64
- node = InsertChangeFloat32ToFloat64(node);
op = machine()->ChangeFloat64ToInt64();
} else if (output_type.Is(cache_->kDoubleRepresentableUint64)) {
- // float32 -> float64 -> uint64
- node = InsertChangeFloat32ToFloat64(node);
op = machine()->ChangeFloat64ToUint64();
- } else if (use_info.type_check() == TypeCheckKind::kSigned64 ||
- use_info.type_check() == TypeCheckKind::kArrayIndex) {
- // float32 -> float64 -> int64
- node = InsertChangeFloat32ToFloat64(node);
- op = simplified()->CheckedFloat64ToInt64(
- output_type.Maybe(Type::MinusZero())
- ? use_info.minus_zero_check()
- : CheckForMinusZeroMode::kDontCheckForMinusZero,
- use_info.feedback());
- } else if (use_info.type_check() == TypeCheckKind::kUnsigned64) {
- // float32 -> float64 -> uint64
- node = InsertChangeFloat32ToFloat64(node);
- op = simplified()->CheckedFloat64ToUint64(
- output_type.Maybe(Type::MinusZero())
- ? use_info.minus_zero_check()
- : CheckForMinusZeroMode::kDontCheckForMinusZero,
- use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord64);
@@ -1429,25 +1446,35 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
}
+ } else if (use_info.type_check() == TypeCheckKind::kSigned64 ||
+ use_info.type_check() == TypeCheckKind::kArrayIndex) {
+ if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
+ (output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
+ use_info.truncation().IdentifiesZeroAndMinusZero())) {
+ op = machine()->ChangeFloat64ToInt64();
+ } else {
+ op = simplified()->CheckedFloat64ToInt64(
+ output_type.Maybe(Type::MinusZero())
+ ? use_info.minus_zero_check()
+ : CheckForMinusZeroMode::kDontCheckForMinusZero,
+ use_info.feedback());
+ }
+ } else if (use_info.type_check() == TypeCheckKind::kUnsigned64) {
+ if (output_type.Is(cache_->kDoubleRepresentableUint64)) {
+ op = machine()->ChangeFloat64ToUint64();
+ } else {
+ op = simplified()->CheckedFloat64ToUint64(
+ output_type.Maybe(Type::MinusZero())
+ ? use_info.minus_zero_check()
+ : CheckForMinusZeroMode::kDontCheckForMinusZero,
+ use_info.feedback());
+ }
} else if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
(output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
use_info.truncation().IdentifiesZeroAndMinusZero())) {
op = machine()->ChangeFloat64ToInt64();
} else if (output_type.Is(cache_->kDoubleRepresentableUint64)) {
op = machine()->ChangeFloat64ToUint64();
- } else if (use_info.type_check() == TypeCheckKind::kSigned64 ||
- use_info.type_check() == TypeCheckKind::kArrayIndex) {
- op = simplified()->CheckedFloat64ToInt64(
- output_type.Maybe(Type::MinusZero())
- ? use_info.minus_zero_check()
- : CheckForMinusZeroMode::kDontCheckForMinusZero,
- use_info.feedback());
- } else if (use_info.type_check() == TypeCheckKind::kUnsigned64) {
- op = simplified()->CheckedFloat64ToUint64(
- output_type.Maybe(Type::MinusZero())
- ? use_info.minus_zero_check()
- : CheckForMinusZeroMode::kDontCheckForMinusZero,
- use_info.feedback());
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord64);
@@ -1486,16 +1513,18 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
: CheckForMinusZeroMode::kDontCheckForMinusZero,
use_info.feedback());
}
- } else if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
- (output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
- use_info.truncation().IdentifiesZeroAndMinusZero())) {
- op = simplified()->ChangeTaggedToInt64();
} else if (use_info.type_check() == TypeCheckKind::kSigned64) {
- op = simplified()->CheckedTaggedToInt64(
- output_type.Maybe(Type::MinusZero())
- ? use_info.minus_zero_check()
- : CheckForMinusZeroMode::kDontCheckForMinusZero,
- use_info.feedback());
+ if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
+ (output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
+ use_info.truncation().IdentifiesZeroAndMinusZero())) {
+ op = simplified()->ChangeTaggedToInt64();
+ } else {
+ op = simplified()->CheckedTaggedToInt64(
+ output_type.Maybe(Type::MinusZero())
+ ? use_info.minus_zero_check()
+ : CheckForMinusZeroMode::kDontCheckForMinusZero,
+ use_info.feedback());
+ }
} else if (use_info.type_check() == TypeCheckKind::kUnsigned64) {
op = simplified()->CheckedTaggedToUint64(
output_type.Maybe(Type::MinusZero())
@@ -1504,6 +1533,10 @@ Node* RepresentationChanger::GetWord64RepresentationFor(
use_info.feedback());
} else if (use_info.type_check() == TypeCheckKind::kArrayIndex) {
op = simplified()->CheckedTaggedToArrayIndex(use_info.feedback());
+ } else if (output_type.Is(cache_->kDoubleRepresentableInt64) ||
+ (output_type.Is(cache_->kDoubleRepresentableInt64OrMinusZero) &&
+ use_info.truncation().IdentifiesZeroAndMinusZero())) {
+ op = simplified()->ChangeTaggedToInt64();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kWord64);
diff --git a/deps/v8/src/compiler/revectorizer.cc b/deps/v8/src/compiler/revectorizer.cc
deleted file mode 100644
index 0537bd4703b..00000000000
--- a/deps/v8/src/compiler/revectorizer.cc
+++ /dev/null
@@ -1,1462 +0,0 @@
-// Copyright 2022 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/revectorizer.h"
-
-#include "include/v8config.h"
-#include "src/base/cpu/cpu.h"
-#include "src/base/logging.h"
-#include "src/compiler/all-nodes.h"
-#include "src/compiler/backend/simd-shuffle.h"
-#include "src/compiler/compiler-source-position-table.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node-observer.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/verifier.h"
-#include "src/execution/isolate-inl.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-#define TRACE(...) \
- do { \
- if (v8_flags.trace_wasm_revectorize) { \
- PrintF("Revec: "); \
- PrintF(__VA_ARGS__); \
- } \
- } while (false)
-
-namespace {
-
-#define SIMPLE_SIMD_OP(V) \
- V(F64x2Add, F64x4Add) \
- V(F32x4Add, F32x8Add) \
- V(I64x2Add, I64x4Add) \
- V(I32x4Add, I32x8Add) \
- V(I16x8Add, I16x16Add) \
- V(I8x16Add, I8x32Add) \
- V(F64x2Sub, F64x4Sub) \
- V(F32x4Sub, F32x8Sub) \
- V(I64x2Sub, I64x4Sub) \
- V(I32x4Sub, I32x8Sub) \
- V(I16x8Sub, I16x16Sub) \
- V(I8x16Sub, I8x32Sub) \
- V(F64x2Mul, F64x4Mul) \
- V(F32x4Mul, F32x8Mul) \
- V(I64x2Mul, I64x4Mul) \
- V(I32x4Mul, I32x8Mul) \
- V(I16x8Mul, I16x16Mul) \
- V(F64x2Div, F64x4Div) \
- V(F32x4Div, F32x8Div) \
- V(I16x8AddSatS, I16x16AddSatS) \
- V(I16x8SubSatS, I16x16SubSatS) \
- V(I16x8AddSatU, I16x16AddSatU) \
- V(I16x8SubSatU, I16x16SubSatU) \
- V(I8x16AddSatS, I8x32AddSatS) \
- V(I8x16SubSatS, I8x32SubSatS) \
- V(I8x16AddSatU, I8x32AddSatU) \
- V(I8x16SubSatU, I8x32SubSatU) \
- V(F64x2Eq, F64x4Eq) \
- V(F32x4Eq, F32x8Eq) \
- V(I64x2Eq, I64x4Eq) \
- V(I32x4Eq, I32x8Eq) \
- V(I16x8Eq, I16x16Eq) \
- V(I8x16Eq, I8x32Eq) \
- V(F64x2Ne, F64x4Ne) \
- V(F32x4Ne, F32x8Ne) \
- V(I64x2GtS, I64x4GtS) \
- V(I32x4GtS, I32x8GtS) \
- V(I16x8GtS, I16x16GtS) \
- V(I8x16GtS, I8x32GtS) \
- V(F64x2Lt, F64x4Lt) \
- V(F32x4Lt, F32x8Lt) \
- V(F64x2Le, F64x4Le) \
- V(F32x4Le, F32x8Le) \
- V(I32x4MinS, I32x8MinS) \
- V(I16x8MinS, I16x16MinS) \
- V(I8x16MinS, I8x32MinS) \
- V(I32x4MinU, I32x8MinU) \
- V(I16x8MinU, I16x16MinU) \
- V(I8x16MinU, I8x32MinU) \
- V(I32x4MaxS, I32x8MaxS) \
- V(I16x8MaxS, I16x16MaxS) \
- V(I8x16MaxS, I8x32MaxS) \
- V(I32x4MaxU, I32x8MaxU) \
- V(I16x8MaxU, I16x16MaxU) \
- V(I8x16MaxU, I8x32MaxU) \
- V(F32x4Abs, F32x8Abs) \
- V(I32x4Abs, I32x8Abs) \
- V(I16x8Abs, I16x16Abs) \
- V(I8x16Abs, I8x32Abs) \
- V(F32x4Neg, F32x8Neg) \
- V(I32x4Neg, I32x8Neg) \
- V(I16x8Neg, I16x16Neg) \
- V(I8x16Neg, I8x32Neg) \
- V(F64x2Sqrt, F64x4Sqrt) \
- V(F32x4Sqrt, F32x8Sqrt) \
- V(F64x2Min, F64x4Min) \
- V(F32x4Min, F32x8Min) \
- V(F64x2Max, F64x4Max) \
- V(F32x4Max, F32x8Max) \
- V(I64x2Ne, I64x4Ne) \
- V(I32x4Ne, I32x8Ne) \
- V(I16x8Ne, I16x16Ne) \
- V(I8x16Ne, I8x32Ne) \
- V(I32x4GtU, I32x8GtU) \
- V(I16x8GtU, I16x16GtU) \
- V(I8x16GtU, I8x32GtU) \
- V(I64x2GeS, I64x4GeS) \
- V(I32x4GeS, I32x8GeS) \
- V(I16x8GeS, I16x16GeS) \
- V(I8x16GeS, I8x32GeS) \
- V(I32x4GeU, I32x8GeU) \
- V(I16x8GeU, I16x16GeU) \
- V(I8x16GeU, I8x32GeU) \
- V(F32x4Pmin, F32x8Pmin) \
- V(F32x4Pmax, F32x8Pmax) \
- V(F64x2Pmin, F64x4Pmin) \
- V(F64x2Pmax, F64x4Pmax) \
- V(F32x4SConvertI32x4, F32x8SConvertI32x8) \
- V(F32x4UConvertI32x4, F32x8UConvertI32x8) \
- V(I32x4UConvertF32x4, I32x8UConvertF32x8) \
- V(I32x4SConvertF32x4, I32x8SConvertF32x8) \
- V(S128And, S256And) \
- V(S128Or, S256Or) \
- V(S128Xor, S256Xor) \
- V(S128Not, S256Not) \
- V(S128Select, S256Select) \
- V(S128AndNot, S256AndNot)
-
-#define SIMD_SHIFT_OP(V) \
- V(I64x2Shl, I64x4Shl) \
- V(I32x4Shl, I32x8Shl) \
- V(I16x8Shl, I16x16Shl) \
- V(I32x4ShrS, I32x8ShrS) \
- V(I16x8ShrS, I16x16ShrS) \
- V(I64x2ShrU, I64x4ShrU) \
- V(I32x4ShrU, I32x8ShrU) \
- V(I16x8ShrU, I16x16ShrU)
-
-#define SIMD_SIGN_EXTENSION_CONVERT_OP(V) \
- V(I64x2SConvertI32x4Low, I64x2SConvertI32x4High, I64x4SConvertI32x4) \
- V(I64x2UConvertI32x4Low, I64x2UConvertI32x4High, I64x4UConvertI32x4) \
- V(I32x4SConvertI16x8Low, I32x4SConvertI16x8High, I32x8SConvertI16x8) \
- V(I32x4UConvertI16x8Low, I32x4UConvertI16x8High, I32x8UConvertI16x8) \
- V(I16x8SConvertI8x16Low, I16x8SConvertI8x16High, I16x16SConvertI8x16) \
- V(I16x8UConvertI8x16Low, I16x8UConvertI8x16High, I16x16UConvertI8x16)
-
-#define SIMD_SPLAT_OP(V) \
- V(I8x16Splat, I8x32Splat) \
- V(I16x8Splat, I16x16Splat) \
- V(I32x4Splat, I32x8Splat) \
- V(I64x2Splat, I64x4Splat)
-
-// Currently, only Load/TrappingLoad/LoadTransform are supported.
-// TODO(jiepan): add support for UnalignedLoad, LoadLane, LoadTrapOnNull
-bool IsSupportedLoad(const Node* node) {
- if (node->opcode() == IrOpcode::kTrappingLoad ||
- node->opcode() == IrOpcode::kLoad ||
- node->opcode() == IrOpcode::kLoadTransform) {
- return true;
- }
- return false;
-}
-
-#ifdef DEBUG
-bool IsSupportedLoad(const ZoneVector<Node*>& node_group) {
- for (auto node : node_group) {
- if (!IsSupportedLoad(node)) return false;
- }
- return true;
-}
-#endif
-
-int64_t GetConstantValue(const Node* node) {
- int64_t value = -1;
- if (node->opcode() == IrOpcode::kInt64Constant) {
- value = OpParameter<int64_t>(node->op());
- }
- return value;
-}
-
-int64_t GetMemoryOffsetValue(const Node* node) {
- DCHECK(IsSupportedLoad(node) || node->opcode() == IrOpcode::kStore ||
- node->opcode() == IrOpcode::kTrappingStore);
-
- Node* offset = node->InputAt(0);
- if (offset->opcode() == IrOpcode::kLoadFromObject ||
- offset->opcode() == IrOpcode::kLoad) {
- return 0;
- }
-
- int64_t offset_value = -1;
- if (offset->opcode() == IrOpcode::kInt64Add) {
- if (NodeProperties::IsConstant(offset->InputAt(0))) {
- offset_value = GetConstantValue(offset->InputAt(0));
- } else if (NodeProperties::IsConstant(offset->InputAt(1))) {
- offset_value = GetConstantValue(offset->InputAt(1));
- }
- }
- return offset_value;
-}
-
-// We want to combine load/store nodes with continuous memory address,
-// for load/store node, input(0) is memory_start + offset, input(1) is index,
-// we currently use index as the address of the node, nodes with same index and
-// continuous offset can be combined together.
-Node* GetNodeAddress(const Node* node) {
- Node* address = node->InputAt(1);
- // The index is changed to Uint64 for memory32
- if (address->opcode() == IrOpcode::kChangeUint32ToUint64) {
- address = address->InputAt(0);
- }
- return address;
-}
-
-bool IsContinuousAccess(const ZoneVector<Node*>& node_group) {
- DCHECK_GT(node_group.size(), 0);
- int64_t previous_offset = GetMemoryOffsetValue(node_group[0]);
- for (size_t i = 1; i < node_group.size(); ++i) {
- int64_t current_offset = GetMemoryOffsetValue(node_group[i]);
- int64_t diff = current_offset - previous_offset;
- if (diff == 8 && node_group[0]->opcode() == IrOpcode::kLoadTransform) {
- LoadTransformParameters params =
- LoadTransformParametersOf(node_group[0]->op());
- if (params.transformation < LoadTransformation::kFirst128Extend ||
- params.transformation > LoadTransformation::kLast128Extend) {
- TRACE("Non-continuous access!\n");
- return false;
- }
- TRACE("Continuous access with load extend offset!\n");
- } else if (diff != kSimd128Size) {
- TRACE("Non-continuous access!\n");
- return false;
- }
- previous_offset = current_offset;
- }
- return true;
-}
-
-// Returns true if all of the nodes in node_group are constants.
-bool AllConstant(const ZoneVector<Node*>& node_group) {
- for (Node* node : node_group) {
- if (!NodeProperties::IsConstant(node)) {
- return false;
- }
- }
- return true;
-}
-
-// Returns true if all the addresses of the nodes in node_group are identical.
-bool AllSameAddress(const ZoneVector<Node*>& nodes) {
- Node* address = GetNodeAddress(nodes[0]);
- for (size_t i = 1; i < nodes.size(); i++) {
- if (GetNodeAddress(nodes[i]) != address) {
- TRACE("Diff address #%d,#%d!\n", address->id(),
- GetNodeAddress(nodes[i])->id());
- return false;
- }
- }
- return true;
-}
-
-// Returns true if all of the nodes in node_group are identical.
-// Splat opcode in WASM SIMD is used to create vector with identical lanes.
-template <typename T>
-bool IsSplat(const T& node_group) {
- for (typename T::size_type i = 1; i < node_group.size(); ++i) {
- if (node_group[i] != node_group[0]) {
- return false;
- }
- }
- return true;
-}
-
-// Some kinds of node (shuffle, s128const) will have different operator
-// instances even if they have the same properties, we can't simply compare the
-// operator's address. We should compare their opcode and properties.
-V8_INLINE static bool OperatorCanBePacked(const Operator* lhs,
- const Operator* rhs) {
- return lhs->opcode() == rhs->opcode() &&
- lhs->properties() == rhs->properties();
-}
-
-// Returns true if all of the nodes in node_group have the same type.
-bool AllPackableOperator(const ZoneVector<Node*>& node_group) {
- auto op = node_group[0]->op();
- for (ZoneVector<Node*>::size_type i = 1; i < node_group.size(); i++) {
- if (!OperatorCanBePacked(node_group[i]->op(), op)) {
- return false;
- }
- }
- return true;
-}
-
-bool ShiftBySameScalar(const ZoneVector<Node*>& node_group) {
- auto node0 = node_group[0];
- for (ZoneVector<Node*>::size_type i = 1; i < node_group.size(); i++) {
- DCHECK_EQ(node_group[i]->op(), node0->op());
- DCHECK_EQ(node0->InputCount(), 2);
- if (node_group[i]->InputAt(1) != node0->InputAt(1)) {
- return false;
- }
- }
- return true;
-}
-
-bool IsSignExtensionOperation(IrOpcode::Value op) {
-#define CASE(op_low, op_high, not_used) \
- case IrOpcode::k##op_low: \
- case IrOpcode::k##op_high:
- switch (op) {
- SIMD_SIGN_EXTENSION_CONVERT_OP(CASE)
- return true;
- default:
- return false;
- }
-#undef CASE
- UNREACHABLE();
-}
-
-bool MaybePackSignExtensionOp(const ZoneVector<Node*>& node_group) {
-#define CHECK_SIGN_EXTENSION_CASE(op_low, op_high, not_used) \
- case IrOpcode::k##op_low: { \
- if (node_group[1]->opcode() == IrOpcode::k##op_high && \
- node_group[0]->InputAt(0) == node_group[1]->InputAt(0)) { \
- return true; \
- } \
- return false; \
- }
- switch (node_group[0]->opcode()) {
- SIMD_SIGN_EXTENSION_CONVERT_OP(CHECK_SIGN_EXTENSION_CASE)
- default: {
- return false;
- }
- }
-#undef CHECK_SIGN_EXTENSION_CASE
- UNREACHABLE();
-}
-
-class V8_GSL_POINTER EffectChainIterator {
- public:
- explicit EffectChainIterator(Node* node) : node_(node), prev_(nullptr) {}
-
- Node* Advance() {
- prev_ = node_;
- node_ = EffectInputOf(node_);
- return node_;
- }
-
- Node* Prev() {
- DCHECK_NE(prev_, nullptr);
- return prev_;
- }
-
- Node* Next() { return EffectInputOf(node_); }
-
- void Set(Node* node) {
- node_ = node;
- prev_ = nullptr;
- }
-
- Node* operator*() { return node_; }
-
- private:
- Node* EffectInputOf(Node* node) {
- DCHECK(IsSupportedLoad(node));
- return node->InputAt(2);
- }
-
- Node* node_;
- Node* prev_;
-};
-
-void InsertAfter(EffectChainIterator& dest, EffectChainIterator& src) {
- Node* dest_next = dest.Next();
- NodeProperties::ReplaceEffectInput(src.Prev(), src.Next());
- NodeProperties::ReplaceEffectInput(*dest, *src);
- NodeProperties::ReplaceEffectInput(*src, dest_next);
-}
-
-} // anonymous namespace
-
-// Sort load/store node by offset
-bool MemoryOffsetComparer::operator()(const Node* lhs, const Node* rhs) const {
- return GetMemoryOffsetValue(lhs) < GetMemoryOffsetValue(rhs);
-}
-
-void PackNode::Print() const {
- if (revectorized_node_ != nullptr) {
- TRACE("0x%p #%d:%s(%d %d, %s)\n", this, revectorized_node_->id(),
- revectorized_node_->op()->mnemonic(), nodes_[0]->id(),
- nodes_[1]->id(), nodes_[0]->op()->mnemonic());
- } else {
- TRACE("0x%p null(%d %d, %s)\n", this, nodes_[0]->id(), nodes_[1]->id(),
- nodes_[0]->op()->mnemonic());
- }
-}
-
-bool SLPTree::CanBePacked(const ZoneVector<Node*>& node_group) {
- DCHECK_EQ(node_group.size(), 2);
- // Only Support simd128 operators or common operators with simd128
- // MachineRepresentation. The MachineRepresentation of root had been checked,
- // and the leaf node will be checked later. here we omit the check of
- // MachineRepresentation, only check the opcode itself.
- IrOpcode::Value op = node_group[0]->opcode();
- if (!NodeProperties::IsSimd128Operation(node_group[0]) &&
- (op != IrOpcode::kStore) && (op != IrOpcode::kTrappingStore) &&
- (op != IrOpcode::kLoad) && (op != IrOpcode::kTrappingLoad) &&
- (op != IrOpcode::kPhi) && (op != IrOpcode::kLoopExitValue) &&
- (op != IrOpcode::kExtractF128)) {
- return false;
- }
-
- // TODO(jiepan): add support for Constant
- if (AllConstant(node_group)) {
- TRACE("%s(#%d, #%d) are constantant, not supported yet!\n",
- node_group[0]->op()->mnemonic(), node_group[0]->id(),
- node_group[1]->id());
- return false;
- }
- if (IsSignExtensionOperation(op)) {
- if (MaybePackSignExtensionOp(node_group)) {
- return true;
- } else {
- TRACE("%s(#%d, #%d) are not (low, high) sign extension pair\n",
- node_group[0]->op()->mnemonic(), node_group[0]->id(),
- node_group[1]->id());
- return false;
- }
- }
- if (!AllPackableOperator(node_group)) {
- TRACE(
- "%s(#%d, #%d) have different op, and are not sign extension operator\n",
- node_group[0]->op()->mnemonic(), node_group[0]->id(),
- node_group[1]->id());
- return false;
- }
- return true;
-}
-
-PackNode* SLPTree::NewPackNode(const ZoneVector<Node*>& node_group) {
- TRACE("PackNode %s(#%d:, #%d)\n", node_group[0]->op()->mnemonic(),
- node_group[0]->id(), node_group[1]->id());
- PackNode* pnode = zone_->New<PackNode>(zone_, node_group);
- for (Node* node : node_group) {
- node_to_packnode_[node] = pnode;
- }
- return pnode;
-}
-
-PackNode* SLPTree::NewPackNodeAndRecurs(const ZoneVector<Node*>& node_group,
- int start_index, int count,
- unsigned recursion_depth) {
- PackNode* pnode = NewPackNode(node_group);
- for (int i = start_index; i < start_index + count; ++i) {
- ZoneVector<Node*> operands(zone_);
- // Prepare the operand vector.
- for (size_t j = 0; j < node_group.size(); j++) {
- Node* node = node_group[j];
- operands.push_back(NodeProperties::GetValueInput(node, i));
- }
-
- PackNode* child = BuildTreeRec(operands, recursion_depth + 1);
- if (child) {
- pnode->SetOperand(i, child);
- } else {
- return nullptr;
- }
- }
- return pnode;
-}
-
-PackNode* SLPTree::GetPackNode(Node* node) {
- auto I = node_to_packnode_.find(node);
- if (I != node_to_packnode_.end()) {
- return I->second;
- }
- return nullptr;
-}
-
-void SLPTree::PushStack(const ZoneVector<Node*>& node_group) {
- TRACE("Stack Push (%d %s, %d %s)\n", node_group[0]->id(),
- node_group[0]->op()->mnemonic(), node_group[1]->id(),
- node_group[1]->op()->mnemonic());
- on_stack_.insert(node_group.begin(), node_group.end());
- stack_.push({node_group});
-}
-
-void SLPTree::PopStack() {
- const ZoneVector<Node*>& node_group = stack_.top();
- DCHECK_EQ(node_group.size(), 2);
- TRACE("Stack Pop (%d %s, %d %s)\n", node_group[0]->id(),
- node_group[0]->op()->mnemonic(), node_group[1]->id(),
- node_group[1]->op()->mnemonic());
- for (auto node : node_group) {
- on_stack_.erase(node);
- }
- stack_.pop();
-}
-
-bool SLPTree::OnStack(Node* node) {
- return on_stack_.find(node) != on_stack_.end();
-}
-
-bool SLPTree::AllOnStack(const ZoneVector<Node*>& node_group) {
- for (auto node : node_group) {
- if (OnStack(node)) return true;
- }
- return false;
-}
-
-bool SLPTree::StackTopIsPhi() {
- const ZoneVector<Node*>& node_group = stack_.top();
- DCHECK_EQ(node_group.size(), 2);
- return NodeProperties::IsPhi(node_group[0]);
-}
-
-void SLPTree::ClearStack() {
- stack_ = ZoneStack<ZoneVector<Node*>>(zone_);
- on_stack_.clear();
-}
-
-// Try to connect the nodes in |loads| by effect edges. This allows us to build
-// |PackNode| without breaking effect dependency:
-// Before: [Load1]->...->[Load2]->...->[Load3]->...->[Load4]
-// After: [Load1]->[Load2]->[Load3]->[Load4]
-void SLPTree::TryReduceLoadChain(const ZoneVector<Node*>& loads) {
- ZoneSet<Node*> visited(zone());
- for (Node* load : loads) {
- if (visited.find(load) != visited.end()) continue;
- visited.insert(load);
-
- EffectChainIterator dest(load);
- EffectChainIterator it(dest.Next());
- while (SameBasicBlock(*it, load) && IsSupportedLoad(*it)) {
- if (std::find(loads.begin(), loads.end(), *it) != loads.end()) {
- visited.insert(*it);
- if (dest.Next() != *it) {
- Node* prev = it.Prev();
- InsertAfter(dest, it);
- it.Set(prev);
- }
- dest.Advance();
- }
- it.Advance();
- }
- }
-}
-
-bool SLPTree::IsSideEffectFreeLoad(const ZoneVector<Node*>& node_group) {
- DCHECK(IsSupportedLoad(node_group));
- DCHECK_EQ(node_group.size(), 2);
- TRACE("Enter IsSideEffectFreeLoad (%d %s, %d %s)\n", node_group[0]->id(),
- node_group[0]->op()->mnemonic(), node_group[1]->id(),
- node_group[1]->op()->mnemonic());
-
- TryReduceLoadChain(node_group);
- // We only allows Loads that are connected by effect edges.
- if (node_group[0] != node_group[1] &&
- NodeProperties::GetEffectInput(node_group[0]) != node_group[1] &&
- NodeProperties::GetEffectInput(node_group[1]) != node_group[0]) {
- return false;
- }
-
- std::stack<Node*> to_visit;
- std::unordered_set<Node*> visited;
- // Visit all the inputs (except for control inputs) of Loads.
- for (size_t i = 0, e = node_group.size(); i < e; i++) {
- Node* load = node_group[i];
- for (int j = 0; j < NodeProperties::FirstControlIndex(load); ++j) {
- Node* input = load->InputAt(j);
- if (std::find(node_group.begin(), node_group.end(), input) ==
- node_group.end()) {
- to_visit.push(input);
- }
- }
- }
-
- // Check the inputs of Loads and find if they are connected to existing nodes
- // in SLPTree. If there is, then there will be side effect and we can not
- // merge such Loads.
- while (!to_visit.empty()) {
- Node* input = to_visit.top();
- to_visit.pop();
- TRACE("IsSideEffectFreeLoad visit (%d %s)\n", input->id(),
- input->op()->mnemonic());
- if (visited.find(input) == visited.end()) {
- visited.insert(input);
-
- if (OnStack(input)) {
- TRACE("Has internal dependency because (%d %s) on stack\n", input->id(),
- input->op()->mnemonic());
- return false;
- }
-
- // If the input is not in same basic block as Loads, it must not be in
- // SLPTree. Otherwise recursively visit all input's edges and find if they
- // are connected to SLPTree.
- if (SameBasicBlock(input, node_group[0])) {
- for (int i = 0; i < NodeProperties::FirstControlIndex(input); ++i) {
- to_visit.push(input->InputAt(i));
- }
- }
- }
- }
- return true;
-}
-
-PackNode* SLPTree::BuildTree(const ZoneVector<Node*>& roots) {
- TRACE("Enter %s\n", __func__);
-
- DeleteTree();
-
- root_ = BuildTreeRec(roots, 0);
- return root_;
-}
-
-PackNode* SLPTree::BuildTreeRec(const ZoneVector<Node*>& node_group,
- unsigned recursion_depth) {
- TRACE("Enter %s\n", __func__);
- DCHECK_EQ(node_group.size(), 2);
-
- Node* node0 = node_group[0];
- Node* node1 = node_group[1];
-
- if (recursion_depth == RecursionMaxDepth) {
- TRACE("Failed due to max recursion depth!\n");
- return nullptr;
- }
-
- if (AllOnStack(node_group)) {
- if (!StackTopIsPhi()) {
- TRACE("Failed due to (%d %s, %d %s) on stack!\n", node0->id(),
- node0->op()->mnemonic(), node1->id(), node1->op()->mnemonic());
- return nullptr;
- }
- }
- PushStack(node_group);
-
- if (!CanBePacked(node_group)) {
- return nullptr;
- }
-
- DCHECK(AllConstant(node_group) || AllPackableOperator(node_group) ||
- MaybePackSignExtensionOp(node_group));
-
- // Check if this is a duplicate of another entry.
- for (Node* node : node_group) {
- if (PackNode* p = GetPackNode(node)) {
- if (!p->IsSame(node_group)) {
- // TODO(jiepan): Gathering due to partial overlap
- TRACE("Failed due to partial overlap at #%d,%s!\n", node->id(),
- node->op()->mnemonic());
- return nullptr;
- }
-
- PopStack();
- TRACE("Perfect diamond merge at #%d,%s\n", node->id(),
- node->op()->mnemonic());
- return p;
- }
- }
-
- if (node0->opcode() == IrOpcode::kS128Zero) {
- PackNode* p = NewPackNode(node_group);
- PopStack();
- return p;
- }
- if (node0->opcode() == IrOpcode::kS128Const) {
- PackNode* p = NewPackNode(node_group);
- PopStack();
- return p;
- }
- if (node0->opcode() == IrOpcode::kExtractF128) {
- Node* source = node0->InputAt(0);
- TRACE("Extract leaf node from #%d,%s!\n", source->id(),
- source->op()->mnemonic());
- // For 256 only, check whether they are from the same source
- if (node0->InputAt(0) == node1->InputAt(0) &&
- (node0->InputAt(0)->opcode() == IrOpcode::kLoadTransform
- ? node0 == node1
- : OpParameter<int32_t>(node0->op()) + 1 ==
- OpParameter<int32_t>(node1->op()))) {
- TRACE("Added a pair of Extract.\n");
- PackNode* pnode = NewPackNode(node_group);
- PopStack();
- return pnode;
- }
- TRACE("Failed due to ExtractF128!\n");
- return nullptr;
- }
-
- if (IsSupportedLoad(node0)) {
- TRACE("Load leaf node\n");
- if (!AllSameAddress(node_group)) {
- TRACE("Failed due to different load addr!\n");
- PopStack();
- return nullptr;
- }
-
- if (!IsSplat(node_group)) {
- if (node0->opcode() == IrOpcode::kTrappingLoad &&
- LoadRepresentationOf(node0->op()).representation() !=
- MachineRepresentation::kSimd128) {
- PopStack();
- return nullptr;
- }
-
- if (!IsSideEffectFreeLoad(node_group)) {
- TRACE("Failed due to dependency check\n");
- PopStack();
- return nullptr;
- }
-
- // Sort loads by offset
- ZoneVector<Node*> sorted_node_group(node_group.size(), zone_);
- std::partial_sort_copy(node_group.begin(), node_group.end(),
- sorted_node_group.begin(), sorted_node_group.end(),
- MemoryOffsetComparer());
- if (!IsContinuousAccess(sorted_node_group)) {
- TRACE("Failed due to non-continuous load!\n");
- PopStack();
- return nullptr;
- }
- } else if (node0->opcode() == IrOpcode::kLoadTransform) {
- LoadTransformParameters params = LoadTransformParametersOf(node0->op());
- if (params.transformation > LoadTransformation::kLast128Splat) {
- TRACE("LoadTransform failed due to unsupported type #%d!\n",
- node0->id());
- PopStack();
- return nullptr;
- }
- DCHECK_GE(params.transformation, LoadTransformation::kFirst128Splat);
- } else {
- TRACE("Failed due to unsupported splat!\n");
- PopStack();
- return nullptr;
- }
-
- PackNode* p = NewPackNode(node_group);
- PopStack();
- return p;
- }
-
- int value_in_count = node0->op()->ValueInputCount();
-
-#define CASE(op128, op256) case IrOpcode::k##op128:
-#define SIGN_EXTENSION_CASE(op_low, not_used1, not_used2) \
- case IrOpcode::k##op_low:
- switch (node0->opcode()) {
- case IrOpcode::kPhi: {
- TRACE("Added a vector of PHI nodes.\n");
- MachineRepresentation rep = PhiRepresentationOf(node0->op());
- if (rep != MachineRepresentation::kSimd128) {
- return nullptr;
- }
- PackNode* pnode =
- NewPackNodeAndRecurs(node_group, 0, value_in_count, recursion_depth);
- PopStack();
- return pnode;
- }
- case IrOpcode::kLoopExitValue: {
- MachineRepresentation rep = LoopExitValueRepresentationOf(node0->op());
- if (rep != MachineRepresentation::kSimd128) {
- return nullptr;
- }
- PackNode* pnode =
- NewPackNodeAndRecurs(node_group, 0, value_in_count, recursion_depth);
- PopStack();
- return pnode;
- }
- case IrOpcode::kI8x16Shuffle: {
- // Try match 32x8Splat or 64x4Splat.
- if (IsSplat(node_group)) {
- const uint8_t* shuffle = S128ImmediateParameterOf(node0->op()).data();
- int index;
- if ((SimdShuffle::TryMatchSplat<4>(shuffle, &index) &&
- node0->InputAt(index >> 2)->opcode() == IrOpcode::kTrappingLoad) ||
- (SimdShuffle::TryMatchSplat<2>(shuffle, &index) &&
- node0->InputAt(index >> 1)->opcode() == IrOpcode::kTrappingLoad)) {
- PopStack();
- return NewPackNode(node_group);
- }
- TRACE("Failed to match splat\n");
- PopStack();
- return nullptr;
- } else {
- PopStack();
- return NewPackNodeAndRecurs(node_group, 0, value_in_count,
- recursion_depth);
- }
- }
- // clang-format off
- SIMPLE_SIMD_OP(CASE) {
- TRACE("Added a vector of %s.\n", node0->op()->mnemonic());
- PackNode* pnode = NewPackNodeAndRecurs(node_group, 0, value_in_count,
- recursion_depth);
- PopStack();
- return pnode;
- }
- SIMD_SHIFT_OP(CASE) {
- if (ShiftBySameScalar(node_group)) {
- TRACE("Added a vector of %s.\n", node0->op()->mnemonic());
- PackNode* pnode =
- NewPackNodeAndRecurs(node_group, 0, 1, recursion_depth);
- PopStack();
- return pnode;
- }
- TRACE("Failed due to shift with different scalar!\n");
- return nullptr;
- }
- SIMD_SIGN_EXTENSION_CONVERT_OP(SIGN_EXTENSION_CASE) {
- TRACE("add a vector of sign extension op and stop building tree\n");
- PackNode* pnode = NewPackNode(node_group);
- PopStack();
- return pnode;
- }
- SIMD_SPLAT_OP(CASE) {
- TRACE("Added a vector of %s.\n", node0->op()->mnemonic());
- if (node0->InputAt(0) != node1->InputAt(0)) {
- TRACE("Failed due to different splat input");
- return nullptr;
- }
- PackNode* pnode = NewPackNode(node_group);
- PopStack();
- return pnode;
- }
- // clang-format on
-
- // TODO(jiepan): UnalignedStore, StoreTrapOnNull.
- case IrOpcode::kStore:
- case IrOpcode::kTrappingStore: {
- TRACE("Added a vector of stores.\n");
- if (!AllSameAddress(node_group)) {
- TRACE("Failed due to different store addr!\n");
- return nullptr;
- }
- PackNode* pnode = NewPackNodeAndRecurs(node_group, 2, 1, recursion_depth);
- PopStack();
- return pnode;
- }
- default:
- TRACE("Default branch #%d:%s\n", node0->id(), node0->op()->mnemonic());
- break;
- }
-#undef CASE
-#undef SIGN_EXTENSION_CASE
- return nullptr;
-}
-
-void SLPTree::DeleteTree() {
- ClearStack();
- node_to_packnode_.clear();
-}
-
-void SLPTree::Print(const char* info) {
- TRACE("%s, Packed node:\n", info);
- if (!v8_flags.trace_wasm_revectorize) {
- return;
- }
-
- ForEach([](PackNode const* pnode) { pnode->Print(); });
-}
-
-template <typename FunctionType>
-void SLPTree::ForEach(FunctionType callback) {
- std::unordered_set<PackNode const*> visited;
-
- for (auto& entry : node_to_packnode_) {
- PackNode const* pnode = entry.second;
- if (!pnode || visited.find(pnode) != visited.end()) {
- continue;
- }
- visited.insert(pnode);
-
- callback(pnode);
- }
-}
-
-//////////////////////////////////////////////////////
-
-Revectorizer::Revectorizer(Zone* zone, TFGraph* graph, MachineGraph* mcgraph,
- SourcePositionTable* source_positions)
- : zone_(zone),
- graph_(graph),
- mcgraph_(mcgraph),
- group_of_stores_(zone),
- source_positions_(source_positions),
- support_simd256_(false) {
- DetectCPUFeatures();
- slp_tree_ = zone_->New<SLPTree>(zone, graph);
- Isolate* isolate = Isolate::TryGetCurrent();
- node_observer_for_test_ = isolate ? isolate->node_observer() : nullptr;
-}
-
-bool Revectorizer::DecideVectorize() {
- TRACE("Enter %s\n", __func__);
-
- int save = 0, cost = 0;
- slp_tree_->ForEach([&](PackNode const* pnode) {
- const ZoneVector<Node*>& nodes = pnode->Nodes();
- IrOpcode::Value op = nodes[0]->opcode();
-
- // Skip LoopExit as auxiliary nodes are not issued in generated code.
- // Skip Extract128 as we will reuse its revectorized input and no additional
- // extract nodes will be generated.
- if (op == IrOpcode::kLoopExitValue || op == IrOpcode::kExtractF128) {
- return;
- }
- // Splat nodes will not cause a saving as it simply extends itself.
- if (!IsSplat(nodes)) {
- save++;
- }
-
- for (size_t i = 0; i < nodes.size(); i++) {
- if (i > 0 && nodes[i] == nodes[0]) continue;
-
- for (auto edge : nodes[i]->use_edges()) {
- if (!NodeProperties::IsValueEdge(edge)) continue;
- Node* useNode = edge.from();
- if (!GetPackNode(useNode) && !(useNode->uses().empty()) &&
- useNode->opcode() != IrOpcode::kLoopExitValue) {
- TRACE("External use edge: (%d:%s) -> (%d:%s)\n", useNode->id(),
- useNode->op()->mnemonic(), nodes[i]->id(),
- nodes[i]->op()->mnemonic());
- cost++;
-
- // We only need one Extract node and all other uses can share.
- break;
- }
- }
- }
- });
-
- TRACE("Save: %d, cost: %d\n", save, cost);
- return save > cost;
-}
-
-void Revectorizer::SetEffectInput(PackNode* pnode, int index, Node*& input) {
- const ZoneVector<Node*>& nodes = pnode->Nodes();
-
- // We assumed there's no effect edge to the 3rd node inbetween.
- DCHECK(nodes[0] == nodes[1] ||
- NodeProperties::GetEffectInput(nodes[0]) == nodes[1] ||
- NodeProperties::GetEffectInput(nodes[1]) == nodes[0]);
-
- // Scanning till find the other effect outside pnode.
- for (size_t i = 0; i < nodes.size(); i++) {
- Node* node128 = nodes[i];
- PackNode* effect = GetPackNode(node128->InputAt(index));
- if (effect == pnode) continue;
- if (effect) {
- pnode->SetOperand(index, effect);
- } else {
- input = node128->InputAt(index);
- }
- break;
- }
-}
-
-void Revectorizer::SetMemoryOpInputs(base::SmallVector<Node*, 2>& inputs,
- PackNode* pnode, int effect_index) {
- Node* node = pnode->Nodes()[0];
- // Keep the addressing inputs
- inputs[0] = node->InputAt(0);
- inputs[1] = node->InputAt(1);
- // Set the effect input and the value input will be set later
- SetEffectInput(pnode, effect_index, inputs[effect_index]);
- // Set the control input
- inputs[effect_index + 1] = node->InputAt(effect_index + 1);
-}
-
-Node* Revectorizer::VectorizeTree(PackNode* pnode) {
- TRACE("Enter %s with PackNode\n", __func__);
-
- Node* node0 = pnode->Nodes()[0];
- Node* node1 = pnode->Nodes()[1];
- if (pnode->RevectorizedNode()) {
- TRACE("Diamond merged for #%d:%s\n", node0->id(), node0->op()->mnemonic());
- return pnode->RevectorizedNode();
- }
-
- int input_count = node0->InputCount();
- TRACE("Vectorize #%d:%s, input count: %d\n", node0->id(),
- node0->op()->mnemonic(), input_count);
-
- IrOpcode::Value op = node0->opcode();
- const Operator* new_op = nullptr;
- Node* source = nullptr;
- Node* dead = mcgraph()->Dead();
- base::SmallVector<Node*, 2> inputs(input_count);
- for (int i = 0; i < input_count; i++) inputs[i] = dead;
-
- switch (op) {
- case IrOpcode::kPhi: {
- DCHECK_EQ(PhiRepresentationOf(node0->op()),
- MachineRepresentation::kSimd128);
- new_op = mcgraph_->common()->Phi(MachineRepresentation::kSimd256,
- input_count - 1);
- inputs[input_count - 1] = NodeProperties::GetControlInput(node0);
- break;
- }
- case IrOpcode::kLoopExitValue: {
- DCHECK_EQ(LoopExitValueRepresentationOf(node0->op()),
- MachineRepresentation::kSimd128);
- new_op =
- mcgraph_->common()->LoopExitValue(MachineRepresentation::kSimd256);
- inputs[input_count - 1] = NodeProperties::GetControlInput(node0);
- break;
- }
-#define SIMPLE_CASE(from, to) \
- case IrOpcode::k##from: \
- new_op = mcgraph_->machine()->to(); \
- break;
- SIMPLE_SIMD_OP(SIMPLE_CASE)
-#undef SIMPLE_CASE
-#undef SIMPLE_SIMD_OP
-
-#define SHIFT_CASE(from, to) \
- case IrOpcode::k##from: { \
- DCHECK(ShiftBySameScalar(pnode->Nodes())); \
- new_op = mcgraph_->machine()->to(); \
- inputs[1] = node0->InputAt(1); \
- break; \
- }
- SIMD_SHIFT_OP(SHIFT_CASE)
-#undef SHIFT_CASE
-#undef SIMD_SHIFT_OP
-
-#define SIGN_EXTENSION_CONVERT_CASE(from, not_used, to) \
- case IrOpcode::k##from: { \
- DCHECK_EQ(node0->InputAt(0), pnode->Nodes()[1]->InputAt(0)); \
- new_op = mcgraph_->machine()->to(); \
- inputs[0] = node0->InputAt(0); \
- break; \
- }
- SIMD_SIGN_EXTENSION_CONVERT_OP(SIGN_EXTENSION_CONVERT_CASE)
-#undef SIGN_EXTENSION_CONVERT_CASE
-#undef SIMD_SIGN_EXTENSION_CONVERT_OP
-
-#define SPLAT_CASE(from, to) \
- case IrOpcode::k##from: \
- new_op = mcgraph_->machine()->to(); \
- inputs[0] = node0->InputAt(0); \
- break;
- SIMD_SPLAT_OP(SPLAT_CASE)
-#undef SPLAT_CASE
-#undef SIMD_SPLAT_OP
- case IrOpcode::kI8x16Shuffle: {
- // clang-format off
- if (IsSplat(pnode->Nodes())) {
- const uint8_t* shuffle = S128ImmediateParameterOf(node0->op()).data();
- int index, offset;
-
- // Match Splat and Revectorize to LoadSplat as AVX-256 does not support
- // shuffling across 128-bit lane.
- if (SimdShuffle::TryMatchSplat<4>(shuffle, &index)) {
- new_op = mcgraph_->machine()->LoadTransform(
- MemoryAccessKind::kTrapping,
- LoadTransformation::kS256Load32Splat);
- offset = index * 4;
- } else if (SimdShuffle::TryMatchSplat<2>(shuffle, &index)) {
- new_op = mcgraph_->machine()->LoadTransform(
- MemoryAccessKind::kTrapping,
- LoadTransformation::kS256Load64Splat);
- offset = index * 8;
- } else {
- UNREACHABLE();
- }
-
- source = node0->InputAt(offset >> 4);
- DCHECK_EQ(source->opcode(), IrOpcode::kTrappingLoad);
- inputs.resize(4);
- // Update LoadSplat offset.
- if (index) {
- SourcePositionTable::Scope scope(source_positions_, source);
- inputs[0] = graph()->NewNode(mcgraph_->machine()->Int64Add(),
- source->InputAt(0),
- mcgraph_->Int64Constant(offset));
- } else {
- inputs[0] = source->InputAt(0);
- }
- // Keep source index, effect and control inputs.
- inputs[1] = source->InputAt(1);
- inputs[2] = source->InputAt(2);
- inputs[3] = source->InputAt(3);
- input_count = 4;
- } else {
- const uint8_t* shuffle0 = S128ImmediateParameterOf(node0->op()).data();
- const uint8_t* shuffle1 = S128ImmediateParameterOf(node1->op()).data();
- uint8_t new_shuffle[32];
-
- if (node0->InputAt(0) == node0->InputAt(1) &&
- node1->InputAt(0) == node1->InputAt(1)) {
- // Shuffle is Swizzle
- for (int i = 0; i < 16; ++i) {
- new_shuffle[i] = shuffle0[i] % 16;
- new_shuffle[i + 16] = 16 + shuffle1[i] % 16;
- }
- } else {
- for (int i = 0; i < 16; ++i) {
- if (shuffle0[i] < 16) {
- new_shuffle[i] = shuffle0[i];
- } else {
- new_shuffle[i] = 16 + shuffle0[i];
- }
-
- if (shuffle1[i] < 16) {
- new_shuffle[i + 16] = 16 + shuffle1[i];
- } else {
- new_shuffle[i + 16] = 32 + shuffle1[i];
- }
- }
- }
- new_op = mcgraph_->machine()->I8x32Shuffle(new_shuffle);
- }
- break;
- // clang-format on
- }
- case IrOpcode::kS128Zero: {
- new_op = mcgraph_->machine()->S256Zero();
- break;
- }
- case IrOpcode::kS128Const: {
- uint8_t value[32];
- const uint8_t* value0 = S128ImmediateParameterOf(node0->op()).data();
- const uint8_t* value1 = S128ImmediateParameterOf(node1->op()).data();
- for (int i = 0; i < kSimd128Size; ++i) {
- value[i] = value0[i];
- value[i + 16] = value1[i];
- }
- new_op = mcgraph_->machine()->S256Const(value);
- break;
- }
- case IrOpcode::kTrappingLoad: {
- DCHECK_EQ(LoadRepresentationOf(node0->op()).representation(),
- MachineRepresentation::kSimd128);
- new_op = mcgraph_->machine()->TrappingLoad(MachineType::Simd256());
- SetMemoryOpInputs(inputs, pnode, 2);
- break;
- }
- case IrOpcode::kLoad: {
- DCHECK_EQ(LoadRepresentationOf(node0->op()).representation(),
- MachineRepresentation::kSimd128);
- new_op = mcgraph_->machine()->Load(MachineType::Simd256());
- SetMemoryOpInputs(inputs, pnode, 2);
- break;
- }
- case IrOpcode::kTrappingStore: {
- DCHECK_EQ(StoreRepresentationOf(node0->op()).representation(),
- MachineRepresentation::kSimd128);
- new_op =
- mcgraph_->machine()->TrappingStore(MachineRepresentation::kSimd256);
- SetMemoryOpInputs(inputs, pnode, 3);
- break;
- }
- case IrOpcode::kStore: {
- DCHECK_EQ(StoreRepresentationOf(node0->op()).representation(),
- MachineRepresentation::kSimd128);
- WriteBarrierKind write_barrier_kind =
- StoreRepresentationOf(node0->op()).write_barrier_kind();
- new_op = mcgraph_->machine()->Store(StoreRepresentation(
- MachineRepresentation::kSimd256, write_barrier_kind));
- SetMemoryOpInputs(inputs, pnode, 3);
- break;
- }
- case IrOpcode::kLoadTransform: {
- LoadTransformParameters params = LoadTransformParametersOf(node0->op());
- LoadTransformation new_transformation;
-
- // clang-format off
- switch (params.transformation) {
- case LoadTransformation::kS128Load8Splat:
- new_transformation = LoadTransformation::kS256Load8Splat;
- break;
- case LoadTransformation::kS128Load16Splat:
- new_transformation = LoadTransformation::kS256Load16Splat;
- break;
- case LoadTransformation::kS128Load32Splat:
- new_transformation = LoadTransformation::kS256Load32Splat;
- break;
- case LoadTransformation::kS128Load64Splat:
- new_transformation = LoadTransformation::kS256Load64Splat;
- break;
- case LoadTransformation::kS128Load8x8S:
- new_transformation = LoadTransformation::kS256Load8x16S;
- break;
- case LoadTransformation::kS128Load8x8U:
- new_transformation = LoadTransformation::kS256Load8x16U;
- break;
- case LoadTransformation::kS128Load16x4S:
- new_transformation = LoadTransformation::kS256Load16x8S;
- break;
- case LoadTransformation::kS128Load16x4U:
- new_transformation = LoadTransformation::kS256Load16x8U;
- break;
- case LoadTransformation::kS128Load32x2S:
- new_transformation = LoadTransformation::kS256Load32x4S;
- break;
- case LoadTransformation::kS128Load32x2U:
- new_transformation = LoadTransformation::kS256Load32x4U;
- break;
- default:
- UNREACHABLE();
- }
- // clang-format on
-
- new_op =
- mcgraph_->machine()->LoadTransform(params.kind, new_transformation);
- SetMemoryOpInputs(inputs, pnode, 2);
- break;
- }
- case IrOpcode::kExtractF128: {
- pnode->SetRevectorizedNode(node0->InputAt(0));
- // The extract uses other than its parent don't need to change.
- break;
- }
- default:
- UNREACHABLE();
- }
-
- DCHECK(pnode->RevectorizedNode() || new_op);
- if (new_op != nullptr) {
- SourcePositionTable::Scope scope(source_positions_, node0);
- Node* new_node =
- graph()->NewNode(new_op, input_count, inputs.begin(), true);
- pnode->SetRevectorizedNode(new_node);
- for (int i = 0; i < input_count; i++) {
- if (inputs[i] == dead) {
- new_node->ReplaceInput(i, VectorizeTree(pnode->GetOperand(i)));
- }
- }
- // Extract Uses
- const ZoneVector<Node*>& nodes = pnode->Nodes();
- for (size_t i = 0; i < nodes.size(); i++) {
- if (i > 0 && nodes[i] == nodes[i - 1]) continue;
- Node* input_128 = nullptr;
- for (auto edge : nodes[i]->use_edges()) {
- Node* useNode = edge.from();
- if (!GetPackNode(useNode)) {
- if (NodeProperties::IsValueEdge(edge)) {
- // Extract use
- TRACE("Replace Value Edge from %d:%s, to %d:%s\n", useNode->id(),
- useNode->op()->mnemonic(), edge.to()->id(),
- edge.to()->op()->mnemonic());
-
- if (!input_128) {
- TRACE("Create ExtractF128(%lu) node from #%d\n", i,
- new_node->id());
- input_128 = graph()->NewNode(
- mcgraph()->machine()->ExtractF128(static_cast<int32_t>(i)),
- new_node);
- }
- edge.UpdateTo(input_128);
- } else if (NodeProperties::IsEffectEdge(edge)) {
- TRACE("Replace Effect Edge from %d:%s, to %d:%s\n", useNode->id(),
- useNode->op()->mnemonic(), edge.to()->id(),
- edge.to()->op()->mnemonic());
-
- edge.UpdateTo(new_node);
- }
- }
- }
- if (nodes[i]->uses().empty()) nodes[i]->Kill();
- }
-
- // Update effect use of NewNode from the dependent source.
- if (op == IrOpcode::kI8x16Shuffle && IsSplat(nodes)) {
- DCHECK(source);
- NodeProperties::ReplaceEffectInput(source, new_node, 0);
- TRACE("Replace Effect Edge from %d:%s, to %d:%s\n", source->id(),
- source->op()->mnemonic(), new_node->id(),
- new_node->op()->mnemonic());
- // Remove unused value use, so that we can safely elimite the node later.
- NodeProperties::ReplaceValueInput(node0, dead, 0);
- NodeProperties::ReplaceValueInput(node0, dead, 1);
- TRACE("Remove Value Input of %d:%s\n", node0->id(),
- node0->op()->mnemonic());
-
- // We will try cleanup source nodes later
- sources_.insert(source);
- }
- }
-
- return pnode->RevectorizedNode();
-}
-
-void Revectorizer::DetectCPUFeatures() {
- base::CPU cpu;
- if (v8_flags.enable_avx && v8_flags.enable_avx2 && cpu.has_avx2()) {
- support_simd256_ = true;
- }
-}
-
-bool Revectorizer::TryRevectorize(const char* function) {
- source_positions_->AddDecorator();
-
- bool success = false;
- if (support_simd256_ && graph_->GetSimdStoreNodes().size()) {
- TRACE("TryRevectorize %s\n", function);
- CollectSeeds();
- for (auto entry : group_of_stores_) {
- ZoneMap<Node*, StoreNodeSet>* store_chains = entry.second;
- if (store_chains != nullptr) {
- PrintStores(store_chains);
- if (ReduceStoreChains(store_chains)) {
- TRACE("Successful revectorize %s\n", function);
- success = true;
- }
- }
- }
- TRACE("Finish revectorize %s\n", function);
- }
- source_positions_->RemoveDecorator();
- return success;
-}
-
-void Revectorizer::UpdateSources() {
- for (auto* src : sources_) {
- std::vector<Node*> effect_uses;
- bool hasExternalValueUse = false;
- for (auto edge : src->use_edges()) {
- Node* use = edge.from();
- if (!GetPackNode(use)) {
- if (NodeProperties::IsValueEdge(edge)) {
- TRACE("Source node has external value dependence %d:%s\n",
- edge.from()->id(), edge.from()->op()->mnemonic());
- hasExternalValueUse = true;
- break;
- } else if (NodeProperties::IsEffectEdge(edge)) {
- effect_uses.push_back(use);
- }
- }
- }
-
- if (!hasExternalValueUse) {
- // Remove unused source and linearize effect chain.
- Node* effect = NodeProperties::GetEffectInput(src);
- for (auto use : effect_uses) {
- TRACE("Replace Effect Edge for source node from %d:%s, to %d:%s\n",
- use->id(), use->op()->mnemonic(), effect->id(),
- effect->op()->mnemonic());
- NodeProperties::ReplaceEffectInput(use, effect, 0);
- }
- }
- }
-
- sources_.clear();
-}
-
-void Revectorizer::CollectSeeds() {
- for (auto it = graph_->GetSimdStoreNodes().begin();
- it != graph_->GetSimdStoreNodes().end(); ++it) {
- Node* node = *it;
- Node* dominator = slp_tree_->GetEarlySchedulePosition(node);
-
- if ((GetMemoryOffsetValue(node) % kSimd128Size) != 0) {
- continue;
- }
- Node* address = GetNodeAddress(node);
- ZoneMap<Node*, StoreNodeSet>* store_nodes;
- auto first_level_iter = group_of_stores_.find(dominator);
- if (first_level_iter == group_of_stores_.end()) {
- store_nodes = zone_->New<ZoneMap<Node*, StoreNodeSet>>(zone_);
- group_of_stores_[dominator] = store_nodes;
- } else {
- store_nodes = first_level_iter->second;
- }
- auto second_level_iter = store_nodes->find(address);
- if (second_level_iter == store_nodes->end()) {
- second_level_iter =
- store_nodes->insert({address, StoreNodeSet(zone())}).first;
- }
- second_level_iter->second.insert(node);
- }
-}
-
-bool Revectorizer::ReduceStoreChains(
- ZoneMap<Node*, StoreNodeSet>* store_chains) {
- TRACE("Enter %s\n", __func__);
- bool changed = false;
- for (auto chain_iter = store_chains->cbegin();
- chain_iter != store_chains->cend(); ++chain_iter) {
- if (chain_iter->second.size() >= 2 && chain_iter->second.size() % 2 == 0) {
- ZoneVector<Node*> store_chain(chain_iter->second.begin(),
- chain_iter->second.end(), zone_);
- for (auto it = store_chain.begin(); it < store_chain.end(); it = it + 2) {
- ZoneVector<Node*> stores_unit(it, it + 2, zone_);
- if ((NodeProperties::GetEffectInput(stores_unit[0]) == stores_unit[1] ||
- NodeProperties::GetEffectInput(stores_unit[1]) ==
- stores_unit[0]) &&
- ReduceStoreChain(stores_unit)) {
- changed = true;
- }
- }
- }
- }
-
- return changed;
-}
-
-bool Revectorizer::ReduceStoreChain(const ZoneVector<Node*>& Stores) {
- TRACE("Enter %s, root@ (#%d,#%d)\n", __func__, Stores[0]->id(),
- Stores[1]->id());
- if (!IsContinuousAccess(Stores)) {
- return false;
- }
-
- PackNode* root = slp_tree_->BuildTree(Stores);
- if (!root) {
- TRACE("Build tree failed!\n");
- return false;
- }
-
- slp_tree_->Print("After build tree");
-
- if (DecideVectorize()) {
- VectorizeTree(root);
- UpdateSources();
- slp_tree_->Print("After vectorize tree");
-
- if (node_observer_for_test_) {
- slp_tree_->ForEach([&](const PackNode* pnode) {
- Node* node = pnode->RevectorizedNode();
- if (node) {
- node_observer_for_test_->OnNodeCreated(node);
- }
- });
- }
- }
-
- TRACE("\n");
- return true;
-}
-
-void Revectorizer::PrintStores(ZoneMap<Node*, StoreNodeSet>* store_chains) {
- if (!v8_flags.trace_wasm_revectorize) {
- return;
- }
- TRACE("Enter %s\n", __func__);
- for (auto it = store_chains->cbegin(); it != store_chains->cend(); ++it) {
- if (it->second.size() > 0) {
- TRACE("address = #%d:%s \n", it->first->id(),
- it->first->op()->mnemonic());
-
- for (auto node : it->second) {
- TRACE("#%d:%s, ", node->id(), node->op()->mnemonic());
- }
-
- TRACE("\n");
- }
- }
-}
-
-#undef TRACE
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/src/compiler/revectorizer.h b/deps/v8/src/compiler/revectorizer.h
deleted file mode 100644
index 44dc61998bc..00000000000
--- a/deps/v8/src/compiler/revectorizer.h
+++ /dev/null
@@ -1,211 +0,0 @@
-// Copyright 2022 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_COMPILER_REVECTORIZER_H_
-#define V8_COMPILER_REVECTORIZER_H_
-
-// Revectorizer is an optimization to promote pairs of simd128 nodes to new
-// simd256 nodes accelerated by wider vector available from hardware e.g. the
-// YMM registers from AVX2 instruction set when possible and beneficial. The
-// main algorithm is based on the Superword Level Parallel (SLP) vectorization
-// technique.
-
-#include <vector>
-
-#include "src/base/small-vector.h"
-#include "src/compiler/linear-scheduler.h"
-#include "src/compiler/machine-graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node-marker.h"
-#include "src/compiler/node-properties.h"
-#include "src/compiler/node.h"
-#include "src/compiler/schedule.h"
-#include "src/compiler/turbofan-graph.h"
-#include "src/zone/zone-containers.h"
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class SourcePositionTable;
-
-struct V8_EXPORT_PRIVATE MemoryOffsetComparer {
- bool operator()(const Node* lhs, const Node* rhs) const;
-};
-
-using StoreNodeSet = ZoneSet<Node*, MemoryOffsetComparer>;
-
-// A PackNode consists of a fixed number of isomorphic simd128 nodes which can
-// execute in parallel and convert to a 256-bit simd node later. The nodes in a
-// PackNode must satisfy that they can be scheduled in the same basic block and
-// are mutually independent.
-class PackNode final : public NON_EXPORTED_BASE(ZoneObject) {
- public:
- explicit PackNode(Zone* zone, const ZoneVector<Node*>& node_group)
- : nodes_(node_group.cbegin(), node_group.cend(), zone),
- operands_(zone),
- revectorized_node_(nullptr) {}
- const ZoneVector<Node*>& Nodes() const { return nodes_; }
- bool IsSame(const ZoneVector<Node*>& node_group) const {
- return nodes_ == node_group;
- }
- Node* RevectorizedNode() const { return revectorized_node_; }
- void SetRevectorizedNode(Node* node) { revectorized_node_ = node; }
- // returns the index operand of this PackNode.
- PackNode* GetOperand(size_t index) {
- DCHECK_LT(index, operands_.size());
- return operands_[index];
- }
-
- ZoneVector<PackNode*>::size_type GetOperandsSize() const {
- return operands_.size();
- }
-
- void SetOperand(size_t index, PackNode* pnode) {
- if (operands_.size() < index + 1) operands_.resize(index + 1);
- operands_[index] = pnode;
- }
-
- void Print() const;
-
- private:
- ZoneVector<Node*> nodes_;
- ZoneVector<PackNode*> operands_;
- Node* revectorized_node_;
-};
-
-// An auxillary tree structure with a set of PackNodes based on the Superword
-// Level Parallelism (SLP) vectorization technique. The BuildTree method will
-// start from a selected root, e.g. a group of consecutive stores, and extend
-// through value inputs to create new PackNodes if the inputs are valid, or
-// conclude that the current PackNode is a leaf and terminate the tree.
-// Below is an example of SLPTree where loads and stores in each PackNode are
-// all consecutive.
-// [Load0, Load1] [Load2, Load3]
-// \ /
-// [Add0, Add1]
-// |
-// [Store0, Store1]
-class SLPTree : public NON_EXPORTED_BASE(ZoneObject) {
- public:
- explicit SLPTree(Zone* zone, TFGraph* graph)
- : zone_(zone),
- graph_(graph),
- root_(nullptr),
- on_stack_(zone),
- stack_(zone),
- node_to_packnode_(zone) {
- scheduler_ = zone->New<LinearScheduler>(zone, graph);
- }
-
- PackNode* BuildTree(const ZoneVector<Node*>& roots);
- void DeleteTree();
-
- PackNode* GetPackNode(Node* node);
-
- void Print(const char* info);
-
- template <typename FunctionType>
- void ForEach(FunctionType callback);
-
- Node* GetEarlySchedulePosition(Node* node) {
- return scheduler_->GetEarlySchedulePosition(node);
- }
-
- private:
- friend class LinearScheduler;
-
- // This is the recursive part of BuildTree.
- PackNode* BuildTreeRec(const ZoneVector<Node*>& node_group, unsigned depth);
-
- // Baseline: create a new PackNode, and return.
- PackNode* NewPackNode(const ZoneVector<Node*>& node_group);
-
- // Recursion: create a new PackNode and call BuildTreeRec recursively
- PackNode* NewPackNodeAndRecurs(const ZoneVector<Node*>& node_group,
- int start_index, int count, unsigned depth);
-
- bool CanBePacked(const ZoneVector<Node*>& node_group);
-
- TFGraph* graph() const { return graph_; }
- Zone* zone() const { return zone_; }
-
- // Node stack operations.
- void PopStack();
- void PushStack(const ZoneVector<Node*>& node_group);
- void ClearStack();
- bool OnStack(Node* node);
- bool AllOnStack(const ZoneVector<Node*>& node_group);
- bool StackTopIsPhi();
-
- void TryReduceLoadChain(const ZoneVector<Node*>& loads);
- bool IsSideEffectFreeLoad(const ZoneVector<Node*>& node_group);
- bool SameBasicBlock(Node* node0, Node* node1) {
- return scheduler_->SameBasicBlock(node0, node1);
- }
-
- Zone* const zone_;
- TFGraph* const graph_;
- PackNode* root_;
- LinearScheduler* scheduler_;
- ZoneSet<Node*> on_stack_;
- ZoneStack<ZoneVector<Node*>> stack_;
- // Maps a specific node to PackNode.
- ZoneUnorderedMap<Node*, PackNode*> node_to_packnode_;
- static constexpr size_t RecursionMaxDepth = 1000;
-};
-
-// The Revectorizer pass will firstly collect seeds with valid group of
-// consecutive stores as the root to build the SLPTree. If the SLPTree is built
-// successfully, it will estimate the cost of the 256-bit transformation for
-// each PackNode and conduct the final revectorization if benefitial.
-class V8_EXPORT_PRIVATE Revectorizer final
- : public NON_EXPORTED_BASE(ZoneObject) {
- public:
- Revectorizer(Zone* zone, TFGraph* graph, MachineGraph* mcgraph,
- SourcePositionTable* source_positions);
- void DetectCPUFeatures();
- bool TryRevectorize(const char* name);
-
- private:
- void CollectSeeds();
-
- bool ReduceStoreChains(ZoneMap<Node*, StoreNodeSet>* store_chains);
- bool ReduceStoreChain(const ZoneVector<Node*>& Stores);
-
- void PrintStores(ZoneMap<Node*, StoreNodeSet>* store_chains);
- Zone* zone() const { return zone_; }
- TFGraph* graph() const { return graph_; }
- MachineGraph* mcgraph() const { return mcgraph_; }
-
- PackNode* GetPackNode(Node* node) const {
- return slp_tree_->GetPackNode(node);
- }
-
- bool DecideVectorize();
-
- void SetEffectInput(PackNode* pnode, int index, Node*& nput);
- void SetMemoryOpInputs(base::SmallVector<Node*, 2>& inputs, PackNode* pnode,
- int index);
- Node* VectorizeTree(PackNode* pnode);
- void UpdateSources();
-
- Zone* const zone_;
- TFGraph* const graph_;
- MachineGraph* const mcgraph_;
- ZoneMap<Node*, ZoneMap<Node*, StoreNodeSet>*> group_of_stores_;
- std::unordered_set<Node*> sources_;
- SLPTree* slp_tree_;
- SourcePositionTable* source_positions_;
-
- bool support_simd256_;
-
- compiler::NodeObserver* node_observer_for_test_;
-};
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
-
-#endif // V8_COMPILER_REVECTORIZER_H_
diff --git a/deps/v8/src/compiler/simplified-lowering.cc b/deps/v8/src/compiler/simplified-lowering.cc
index 84576026600..d87dbb59d66 100644
--- a/deps/v8/src/compiler/simplified-lowering.cc
+++ b/deps/v8/src/compiler/simplified-lowering.cc
@@ -1839,7 +1839,7 @@ class RepresentationSelector {
}
bool CanSpeculateAdditiveSafeInteger(Node* node) {
- if (!v8_flags.additive_safe_int_feedback) return false;
+ if (!v8_flags.turbofan_additive_safe_int_feedback) return false;
return NumberOperationHintOf(node->op()) ==
NumberOperationHint::kAdditiveSafeInteger;
}
@@ -5019,6 +5019,8 @@ class RepresentationSelector {
case IrOpcode::kDeadValue:
ProcessInput<T>(node, 0, UseInfo::Any());
return SetOutput<T>(node, MachineRepresentation::kNone);
+ case IrOpcode::kMemoryBarrier:
+ return SetOutput<T>(node, MachineRepresentation::kNone);
case IrOpcode::kMajorGCForCompilerTesting:
ProcessRemainingInputs<T>(node, 0);
return SetOutput<T>(node, MachineRepresentation::kTagged);
diff --git a/deps/v8/src/compiler/turbofan-types.cc b/deps/v8/src/compiler/turbofan-types.cc
index e72241a9099..11de500c464 100644
--- a/deps/v8/src/compiler/turbofan-types.cc
+++ b/deps/v8/src/compiler/turbofan-types.cc
@@ -197,6 +197,7 @@ Type::bitset BitsetType::Lub(MapRefLike map, JSHeapBroker* broker) {
case HEAP_NUMBER_TYPE:
return kNumber;
case CPP_HEAP_EXTERNAL_OBJECT_TYPE:
+ case CPP_GCMANAGED_BASE_TYPE:
case JS_ARRAY_ITERATOR_PROTOTYPE_TYPE:
case JS_ITERATOR_PROTOTYPE_TYPE:
case JS_MAP_ITERATOR_PROTOTYPE_TYPE:
@@ -311,6 +312,8 @@ Type::bitset BitsetType::Lub(MapRefLike map, JSHeapBroker* broker) {
#endif // V8_TEMPORAL_SUPPORT
case JS_RAW_JSON_TYPE:
#if V8_ENABLE_WEBASSEMBLY
+ case WASM_CUSTOM_MAP_TYPE:
+ case WASM_CUSTOM_MAP_WRAPPER_TYPE:
case WASM_GLOBAL_OBJECT_TYPE:
case WASM_INSTANCE_OBJECT_TYPE:
case WASM_MEMORY_OBJECT_TYPE:
diff --git a/deps/v8/src/compiler/turboshaft/assembler.h b/deps/v8/src/compiler/turboshaft/assembler.h
index e77b4e2efb3..548f6e5b902 100644
--- a/deps/v8/src/compiler/turboshaft/assembler.h
+++ b/deps/v8/src/compiler/turboshaft/assembler.h
@@ -3498,10 +3498,15 @@ class AssemblerOpInterface : public Next {
void JSStackCheck(V<Context> context, OptionalV<LazyFrameState> frame_state,
JSStackCheckOp::Kind kind) {
+ if (V8_UNLIKELY(v8_flags.disable_loop_stack_checks &&
+ kind == JSStackCheckOp::Kind::kLoop)) {
+ return;
+ }
ReduceIfReachableJSStackCheck(context, frame_state, kind);
}
void JSLoopStackCheck(V<Context> context, V<LazyFrameState> frame_state) {
+ if (V8_UNLIKELY(v8_flags.disable_loop_stack_checks)) return;
JSStackCheck(context, frame_state, JSStackCheckOp::Kind::kLoop);
}
void JSFunctionEntryStackCheck(V<Context> context,
@@ -4029,7 +4034,7 @@ class AssemblerOpInterface : public Next {
lazy_deopt_on_throw, !compiling_builtins);
return returns_t::CastIfNeeded(
Call(CEntryStubConstant(isolate, result_size), frame_state,
- base::VectorOf(arguments), desc));
+ base::VectorOf(arguments), desc, Desc::kEffects));
}
template <typename Desc>
@@ -4818,6 +4823,10 @@ class AssemblerOpInterface : public Next {
Word64AddSub128BinopOp::Kind::kSub);
}
+ V<Word64Pair> Word64Add3(V<Word64> a, V<Word64> b, V<Word64> c) {
+ return ReduceIfReachableWord64Add3(a, b, c);
+ }
+
V<Word64Pair> Word64MulWide(V<Word64> left, V<Word64> right,
Word64MulWideOp::Kind kind) {
return ReduceIfReachableWord64MulWide(left, right, kind);
@@ -5404,6 +5413,11 @@ class AssemblerOpInterface : public Next {
return ReduceIfReachableStringPrepareForGetCodeUnit(string);
}
+ V<Object> LoadWasmTypeInfo(V<Map> map) {
+ int offset = offsetof(Map, constructor_or_back_pointer_or_native_context_);
+ return Load(map, LoadOp::Kind::TaggedBase().Immutable(),
+ MemoryRepresentation::TaggedPointer(), offset);
+ }
#endif // V8_ENABLE_WEBASSEMBLY
#ifdef V8_ENABLE_SIMD128
diff --git a/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h b/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h
index c73e1d66cc7..e1eeb5aa42b 100644
--- a/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h
+++ b/deps/v8/src/compiler/turboshaft/builtin-call-descriptors.h
@@ -1074,8 +1074,9 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsContext = true;
static constexpr Operator::Properties kProperties =
Operator::kNoDeopt | Operator::kNoWrite;
- static constexpr OpEffects kEffects =
- base_effects.CanReadMemory().CanAllocateWithoutIdentity();
+ static constexpr OpEffects kEffects = base_effects.CanReadMemory()
+ .CanAllocateWithoutIdentity()
+ .CanThrowOrTrap();
};
#endif
@@ -1180,8 +1181,7 @@ struct BuiltinCallDescriptor {
struct WasmStringNewWtf8Array : public Descriptor<WasmStringNewWtf8Array> {
static constexpr auto kFunction = Builtin::kWasmStringNewWtf8Array;
- using arguments_t =
- std::tuple<V<Word32>, V<Word32>, V<WasmArray>, V<Smi>, V<Smi>>;
+ using arguments_t = std::tuple<V<Word32>, V<Word32>, V<WasmArray>, V<Smi>>;
using results_t = std::tuple<V<WasmStringRefNullable>>;
static constexpr bool kNeedsFrameState = false;
@@ -1195,22 +1195,7 @@ struct BuiltinCallDescriptor {
struct WasmStringNewWtf16Array : public Descriptor<WasmStringNewWtf16Array> {
static constexpr auto kFunction = Builtin::kWasmStringNewWtf16Array;
- using arguments_t = std::tuple<V<WasmArray>, V<Word32>, V<Word32>>;
- using results_t = std::tuple<V<String>>;
-
- static constexpr bool kNeedsFrameState = false;
- static constexpr bool kNeedsContext = false;
- static constexpr Operator::Properties kProperties =
- Operator::kNoDeopt | Operator::kNoThrow;
- static constexpr OpEffects kEffects = base_effects.CanReadHeapMemory()
- .CanAllocateWithoutIdentity()
- .CanThrowOrTrap();
- };
-
- struct WasmStringNewWtf16ArrayShared
- : public Descriptor<WasmStringNewWtf16ArrayShared> {
- static constexpr auto kFunction = Builtin::kWasmStringNewWtf16ArrayShared;
- using arguments_t = std::tuple<V<WasmArray>, V<Word32>, V<Word32>>;
+ using arguments_t = std::tuple<V<WasmArray>, V<Word32>, V<Word32>, V<Smi>>;
using results_t = std::tuple<V<String>>;
static constexpr bool kNeedsFrameState = false;
@@ -1281,10 +1266,9 @@ struct BuiltinCallDescriptor {
using results_t = std::tuple<V<WasmArray>>;
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().CanAllocate();
+ base_effects.CanReadMemory().CanAllocate().CanThrowOrTrap();
};
struct WasmStringEncodeWtf16Array
@@ -1324,7 +1308,7 @@ struct BuiltinCallDescriptor {
static constexpr bool kNeedsContext = false;
static constexpr Operator::Properties kProperties = Operator::kNoDeopt;
static constexpr OpEffects kEffects =
- base_effects.CanAllocateWithoutIdentity();
+ base_effects.CanAllocateWithoutIdentity().CanThrowOrTrap();
};
struct WasmStringToDouble : public Descriptor<WasmStringToDouble> {
@@ -1541,14 +1525,14 @@ struct BuiltinCallDescriptor {
struct WasmStringNewWtf16 : public Descriptor<WasmStringNewWtf16> {
static constexpr auto kFunction = Builtin::kWasmStringNewWtf16;
- using arguments_t = std::tuple<V<Word32>, V<WordPtr>, V<Word32>>;
+ using arguments_t = std::tuple<V<Word32>, V<WordPtr>, V<Word32>, V<Smi>>;
using results_t = std::tuple<V<String>>;
static constexpr bool kNeedsFrameState = false;
static constexpr bool kNeedsContext = false;
static constexpr Operator::Properties kProperties =
Operator::kNoDeopt | Operator::kNoThrow;
- static constexpr OpEffects kEffects = base_effects.CanReadHeapMemory()
+ static constexpr OpEffects kEffects = base_effects.CanReadMemory()
.CanAllocateWithoutIdentity()
.CanThrowOrTrap();
};
diff --git a/deps/v8/src/compiler/turboshaft/graph-builder.cc b/deps/v8/src/compiler/turboshaft/graph-builder.cc
index 7547de2ae7f..4864bf773c5 100644
--- a/deps/v8/src/compiler/turboshaft/graph-builder.cc
+++ b/deps/v8/src/compiler/turboshaft/graph-builder.cc
@@ -2758,6 +2758,8 @@ OpIndex GraphBuilder::Process(
Map(node->InputAt(0)), Map(node->InputAt(1)), Map(node->InputAt(4)),
Map(node->InputAt(5)), Map(node->InputAt(2)), Map(node->InputAt(3)),
0);
+ case IrOpcode::kMemoryBarrier:
+ return __ MemoryBarrier(OpParameter<AtomicMemoryOrder>(node->op()));
#ifdef V8_ENABLE_WEBASSEMBLY
#define SIMD128_BINOP(name) \
diff --git a/deps/v8/src/compiler/turboshaft/int64-lowering-reducer.h b/deps/v8/src/compiler/turboshaft/int64-lowering-reducer.h
index 55c1f012124..31a2575d79b 100644
--- a/deps/v8/src/compiler/turboshaft/int64-lowering-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/int64-lowering-reducer.h
@@ -9,6 +9,7 @@
#error This header should only be included if WebAssembly is enabled.
#endif // !V8_ENABLE_WEBASSEMBLY
+#include "src/base/bits.h"
#include "src/codegen/machine-type.h"
#include "src/compiler/turboshaft/assembler.h"
#include "src/compiler/turboshaft/operations.h"
@@ -387,35 +388,6 @@ class Int64LoweringReducer : public Next {
FATAL("%s", str.str().c_str());
}
- std::pair<OptionalV<Word32>, int32_t> IncreaseOffset(
- OptionalV<Word32> index, int32_t offset, int32_t add_offset,
- uint8_t element_size_log2, bool tagged_base) {
- uint32_t element_size = 1 << element_size_log2;
- // Note that the offset will just wrap around. Still, we need to always
- // use an offset that is not std::numeric_limits<int32_t>::min() on tagged
- // loads.
- // TODO(dmercadier): Replace LoadOp::OffsetIsValid by taking care of this
- // special case in the LoadStoreSimplificationReducer instead.
- int32_t new_offset =
- static_cast<uint32_t>(offset) + static_cast<uint32_t>(add_offset);
- OptionalV<Word32> new_index = index;
- if (!LoadOp::OffsetIsValid(new_offset, tagged_base)) {
- // We cannot encode the new offset because it has the one invalid value.
- // We can choose any other value and the only requirement is that we end
- // up at the same final location after calculating
- // | index * element_size + offset
- // So we'll just subtract "one element" and increase the index by one.
- // We could do this for almost any arbitrary value larger than 0.
- new_offset -= element_size;
- if (index.has_value()) {
- new_index = __ Word32Add(new_index.value(), 1);
- } else {
- new_index = __ Word32Constant(1);
- }
- }
- return {new_index, new_offset};
- }
-
OpIndex REDUCE(Load)(OpIndex base, OptionalOpIndex index, LoadOp::Kind kind,
MemoryRepresentation loaded_rep,
RegisterRepresentation result_rep, int32_t offset,
@@ -443,15 +415,15 @@ class Int64LoweringReducer : public Next {
}
if (loaded_rep == MemoryRepresentation::Int64() ||
loaded_rep == MemoryRepresentation::Uint64()) {
- auto [high_index, high_offset] = IncreaseOffset(
- index, offset, sizeof(int32_t), element_scale, kind.tagged_base);
+ int32_t high_offset =
+ base::bits::WraparoundAdd32(offset, sizeof(int32_t));
return __ MakeTuple(
Next::ReduceLoad(base, index, kind, MemoryRepresentation::Int32(),
RegisterRepresentation::Word32(), offset,
element_scale),
- Next::ReduceLoad(
- base, high_index, kind, MemoryRepresentation::Int32(),
- RegisterRepresentation::Word32(), high_offset, element_scale));
+ Next::ReduceLoad(base, index, kind, MemoryRepresentation::Int32(),
+ RegisterRepresentation::Word32(), high_offset,
+ element_scale));
}
return Next::ReduceLoad(base, index, kind, loaded_rep, result_rep, offset,
element_scale);
@@ -488,12 +460,12 @@ class Int64LoweringReducer : public Next {
maybe_initializing_or_transitioning,
maybe_indirect_pointer_tag);
// high store
- auto [high_index, high_offset] = IncreaseOffset(
- index, offset, sizeof(int32_t), element_size_log2, kind.tagged_base);
- Next::ReduceStore(
- base, high_index, high, kind, MemoryRepresentation::Int32(),
- write_barrier, memory_order, high_offset, element_size_log2,
- maybe_initializing_or_transitioning, maybe_indirect_pointer_tag);
+ int32_t high_offset =
+ base::bits::WraparoundAdd32(offset, sizeof(int32_t));
+ Next::ReduceStore(base, index, high, kind, MemoryRepresentation::Int32(),
+ write_barrier, memory_order, high_offset,
+ element_size_log2, maybe_initializing_or_transitioning,
+ maybe_indirect_pointer_tag);
return V<None>::Invalid();
}
return Next::ReduceStore(
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 b1aff4ea7d7..fe618692f15 100644
--- a/deps/v8/src/compiler/turboshaft/late-load-elimination-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/late-load-elimination-reducer.h
@@ -1076,7 +1076,6 @@ class V8_EXPORT_PRIVATE LateLoadEliminationReducer : public Next {
V<Object> REDUCE_INPUT_GRAPH(LoadTrustedPointer)(
V<Object> ig_index, const LoadTrustedPointerOp& load) {
if (v8_flags.turboshaft_trusted_load_elimination) {
- CHECK(v8_flags.turboshaft_load_elimination);
Replacement replacement = analyzer_.GetReplacement(ig_index);
if (replacement.IsLoadElimination()) {
OpIndex replacement_ig_index = replacement.replacement();
diff --git a/deps/v8/src/compiler/turboshaft/load-store-simplification-reducer.h b/deps/v8/src/compiler/turboshaft/load-store-simplification-reducer.h
index 97811c7f80e..c05d12d960f 100644
--- a/deps/v8/src/compiler/turboshaft/load-store-simplification-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/load-store-simplification-reducer.h
@@ -29,9 +29,6 @@ struct LoadStoreSimplificationConfiguration {
// TODO(12783): This needs to be extended for all architectures that don't
// have loads with the base + index * element_size + offset pattern.
#if V8_TARGET_ARCH_RESTRICTIVE_LOAD_STORE
- // As tagged loads result in modfiying the offset by -1, those loads are
- // converted into raw loads.
- static constexpr bool kNeedsUntaggedBase = true;
// By setting {kMinOffset} > {kMaxOffset}, we ensure that all offsets
// (including 0) are merged into the computed index.
static constexpr int32_t kMinOffset = 1;
@@ -41,7 +38,6 @@ struct LoadStoreSimplificationConfiguration {
// typically support only a limited `element_size_log2`.
static constexpr int kMaxElementSizeLog2 = 0;
#elif V8_TARGET_ARCH_S390X
- static constexpr bool kNeedsUntaggedBase = false;
// s390x supports *(base + index + displacement), element_size isn't
// supported.
static constexpr int32_t kDisplacementBits = 20; // 20 bit signed integer.
@@ -51,8 +47,7 @@ struct LoadStoreSimplificationConfiguration {
(static_cast<int32_t>(1) << (kDisplacementBits - 1)) - 1;
static constexpr int kMaxElementSizeLog2 = 0;
#else
- static constexpr bool kNeedsUntaggedBase = false;
- // We don't want to encode INT32_MIN in the offset becauce instruction
+ // We don't want to encode INT32_MIN in the offset because instruction
// selection might not be able to put this into an immediate operand.
static constexpr int32_t kMinOffset = std::numeric_limits<int32_t>::min() + 1;
static constexpr int32_t kMaxOffset = std::numeric_limits<int32_t>::max();
@@ -138,11 +133,7 @@ class LoadStoreSimplificationReducer : public Next,
// If the base is tagged we also need to subtract the kHeapObjectTag
// eventually.
const int32_t min = kMinOffset + (tagged_base ? kHeapObjectTag : 0);
- if (min <= offset && offset <= kMaxOffset) {
- DCHECK(LoadOp::OffsetIsValid(offset, tagged_base));
- return true;
- }
- return false;
+ return min <= offset && offset <= kMaxOffset;
}
bool CanEncodeAtomic(OptionalOpIndex index, uint8_t element_size_log2,
@@ -161,26 +152,19 @@ class LoadStoreSimplificationReducer : public Next,
element_size_log2 = 0;
}
- if (kNeedsUntaggedBase) {
- if (kind.tagged_base) {
- kind.tagged_base = false;
- DCHECK_LE(std::numeric_limits<int32_t>::min() + kHeapObjectTag, offset);
- offset -= kHeapObjectTag;
- base = __ BitcastHeapObjectToWordPtr(base);
- }
- }
-
// TODO(nicohartmann@): Remove the case for atomics once crrev.com/c/5237267
// is ported to x64.
if (!CanEncodeOffset(offset, kind.tagged_base) ||
(kind.is_atomic &&
!CanEncodeAtomic(index, element_size_log2, offset))) {
+ intptr_t displacement = offset;
if (kind.tagged_base) {
kind.tagged_base = false;
- DCHECK_LE(std::numeric_limits<int32_t>::min() + kHeapObjectTag, offset);
- offset -= kHeapObjectTag;
+ displacement = static_cast<intptr_t>(
+ static_cast<uintptr_t>(displacement) - kHeapObjectTag);
base = __ BitcastHeapObjectToWordPtr(base);
}
+ offset = 0;
// If an index is present, the element_size_log2 is changed to zero.
// So any load follows the form *(base + offset). To simplify
// instruction selection, both static and dynamic offsets are stored in
@@ -188,30 +172,30 @@ class LoadStoreSimplificationReducer : public Next,
// As tagged loads result in modifying the offset by -1, those loads are
// converted into raw loads (above).
if (!index.has_value() || matcher_.MatchIntegralZero(index.value())) {
- index = __ IntPtrConstant(offset);
+ index = __ IntPtrConstant(displacement);
element_size_log2 = 0;
- offset = 0;
- } else if (element_size_log2 != 0) {
- index = __ WordPtrShiftLeft(index.value(), element_size_log2);
- element_size_log2 = 0;
- }
- if (offset != 0) {
-#if V8_TARGET_ARCH_RESTRICTIVE_LOAD_STORE
- if (allow_base_index_hoisting) {
- // Hoist the *(base + index) out to a new base if possible to reduce
- // number of add ops from one per memory access to one per block of
- // memory accesses. Common subexpression elimination will get rid of
- // the redundant adds.
- DCHECK(!kind.tagged_base);
- base = __ WordPtrAdd(base, index.value());
- index = __ IntPtrConstant(offset);
- } else {
- index = __ WordPtrAdd(index.value(), offset);
+ } else {
+ if (element_size_log2 != 0) {
+ index = __ WordPtrShiftLeft(index.value(), element_size_log2);
+ element_size_log2 = 0;
}
+ if (displacement != 0) {
+#if V8_TARGET_ARCH_RESTRICTIVE_LOAD_STORE
+ if (allow_base_index_hoisting) {
+ // Hoist the *(base + index) out to a new base if possible to reduce
+ // number of add ops from one per memory access to one per block of
+ // memory accesses. Common subexpression elimination will get rid of
+ // the redundant adds.
+ DCHECK(!kind.tagged_base);
+ base = __ WordPtrAdd(base, index.value());
+ index = __ IntPtrConstant(displacement);
+ } else {
+ index = __ WordPtrAdd(index.value(), displacement);
+ }
#else
- index = __ WordPtrAdd(index.value(), offset);
+ index = __ WordPtrAdd(index.value(), displacement);
#endif
- offset = 0;
+ }
}
DCHECK_EQ(offset, 0);
DCHECK_EQ(element_size_log2, 0);
diff --git a/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.cc b/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.cc
index 80d377ed9f0..2eb3dac1565 100644
--- a/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.cc
+++ b/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.cc
@@ -29,7 +29,9 @@ void LoopUnrollingAnalyzer::DetectUnrollableLoops() {
for (const auto& [start, info] : loop_finder_.LoopHeaders()) {
IterationCount iter_count = GetLoopIterationCount(info);
TRACE("LoopUnrollingAnalyzer: loop at "
- << start->index() << " ==> iter_count=" << iter_count);
+ << start->index() << " ==> iter_count=" << iter_count
+ << " op_count=" << loop_finder_.GetLoopInfo(start).op_count
+ << " has_any_call=" << loop_finder_.GetLoopInfo(start).has_any_call);
loop_iteration_count_.insert({start, iter_count});
if (ShouldFullyUnrollLoop(start) || ShouldPartiallyUnrollLoop(start)) {
diff --git a/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.h b/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.h
index b42851b5d86..3f4d343d214 100644
--- a/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/loop-unrolling-reducer.h
@@ -276,7 +276,7 @@ class V8_EXPORT_PRIVATE LoopUnrollingAnalyzer {
// count we have seen in some huge Wasm functions in the past, e.g., function
// #21937 of https://crbug.com/383661627 (1.7M operations, 2.7MB wire bytes).
static constexpr size_t kMaxFunctionSizeForPartialUnrolling = 1'000'000;
- static constexpr size_t kJSMaxLoopSizeForPartialUnrolling = 50;
+ static constexpr size_t kJSMaxLoopSizeForPartialUnrolling = 64;
static constexpr size_t kWasmMaxLoopSizeForPartialUnrolling = 80;
static constexpr size_t kWasmMaxUnrolledLoopSize = 240;
static constexpr size_t kMaxLoopIterationsForFullUnrolling = 4;
diff --git a/deps/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h b/deps/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h
index 792d25eaf93..46c384b0160 100644
--- a/deps/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h
+++ b/deps/v8/src/compiler/turboshaft/machine-lowering-reducer-inl.h
@@ -2607,11 +2607,12 @@ class MachineLoweringReducer : public Next {
HeapObjectRef ref = MakeRef(broker_, cst->handle());
if (ref.IsString()) {
StringRef str = ref.AsString();
- if (str.IsSeqString()) {
+ MapRef map = str.map(broker_);
+ if (map.IsSeqStringMap()) {
V<Map> dynamic_map = __ LoadMapField(string);
- Handle<Map> expected_map = str.map(broker_).object();
+ Handle<Map> expected_map = map.object();
IF (__ TaggedEqual(dynamic_map, __ HeapConstant(expected_map))) {
- bool one_byte = str.IsOneByteRepresentation();
+ bool one_byte = map.IsOneByteStringMap();
GOTO(done,
LoadFromSeqString(string, pos, __ Word32Constant(one_byte)));
}
@@ -3068,38 +3069,21 @@ class MachineLoweringReducer : public Next {
V<LazyFrameState> frame_state,
V<Context> context,
LazyDeoptOnThrow lazy_deopt_on_throw) {
- // Static classification by output-graph ConstantOp: lets us skip the type
- // guard on inputs that we already know are SeqOneByteString.
- enum class StaticShape : uint8_t {
- kUnknown, // Runtime check needed.
- kIsSeqOneByte, // Constant SeqOneByteString; type guard can be elided.
- kCantBe, // Constant of any other shape; inline can never succeed.
- };
- auto classify = [&](V<Object> value) {
+ // A constant operand whose map is outside the SeqOneByteString map set can
+ // never reach the fast path: no string transition enters that set, so the
+ // check below is statically false and the whole inline is dead.
+ auto can_be_seq_one_byte = [&](V<Object> value) {
const ConstantOp* c =
__ Get(value).template TryCast<Opmask::kHeapConstant>();
- if (!c) return StaticShape::kUnknown;
- JSHeapBroker* broker = __ data() -> broker();
- if (broker == nullptr) return StaticShape::kUnknown;
- UnparkedScopeIfNeeded scope(broker);
+ if (!c) return true;
+ UnparkedScopeIfNeeded scope(broker_);
AllowHandleDereference allow_handle_dereference;
- HeapObjectRef ref = MakeRef(broker, c->handle());
- if (!ref.IsString()) return StaticShape::kCantBe;
- StringRef sref = ref.AsString();
- if (!sref.IsSeqString() || !sref.IsOneByteRepresentation()) {
- return StaticShape::kCantBe;
- }
- // A SeqOneByteString can still be internalized in place after this code
- // is compiled.
- if (sref.IsInternalizedString()) return StaticShape::kIsSeqOneByte;
- return StaticShape::kUnknown;
+ OptionalMapRef map =
+ MakeRef(broker_, c->handle()).map_direct_read(broker_);
+ return !map.has_value() || map->IsSeqOneByteStringMap();
};
- StaticShape recv_shape = classify(receiver);
- StaticShape arg_shape = classify(compare_str);
- const bool skip_recv_check = recv_shape == StaticShape::kIsSeqOneByte;
- const bool skip_arg_check = arg_shape == StaticShape::kIsSeqOneByte;
const bool always_bail =
- recv_shape == StaticShape::kCantBe || arg_shape == StaticShape::kCantBe;
+ !can_be_seq_one_byte(receiver) || !can_be_seq_one_byte(compare_str);
Label<Smi> done(this);
Label<> bailout(this);
@@ -3117,25 +3101,16 @@ class MachineLoweringReducer : public Next {
if (always_bail) return emit_bailout();
- // Both inputs must be SeqOneByteString. The mask covers the
- // string/non-string bit and the representation+encoding bits, both of
- // which fit in the 16-bit Map::instance_type.
- static constexpr uint32_t kSeqOneByteCheckMask =
- kIsNotStringMask | kStringRepresentationAndEncodingMask;
- static_assert(
- kSeqOneByteStringTag == (kSeqOneByteCheckMask & kSeqOneByteStringTag),
- "kSeqOneByteStringTag must be representable in the check mask");
-
+ // Both inputs must be SeqOneByteString. This has to be re-checked at
+ // runtime even for constants: a string can be thinned, externalized,
+ // internalized or shared in place after this code is compiled, and the
+ // first two shrink the object while String::length keeps its old value.
auto check_seq_1byte = [&](V<Object> value) {
GOTO_IF(__ ObjectIsSmi(value), bailout);
- V<Map> map = __ LoadMapField(value);
- V<Word32> instance_type = __ LoadInstanceTypeField(map);
- V<Word32> masked =
- __ Word32BitwiseAnd(instance_type, kSeqOneByteCheckMask);
- GOTO_IF_NOT(__ Word32Equal(masked, kSeqOneByteStringTag), bailout);
+ GOTO_IF_NOT(IsSeqOneByteStringMap(__ LoadMapField(value)), bailout);
};
- if (!skip_recv_check) check_seq_1byte(receiver);
- if (!skip_arg_check) check_seq_1byte(compare_str);
+ check_seq_1byte(receiver);
+ check_seq_1byte(compare_str);
// Pointer-eq receiver/arg -> 0. Done after the type guards so a
// non-string receiver passed via .call falls through to the bailout
@@ -3646,6 +3621,13 @@ class MachineLoweringReducer : public Next {
FixedArray::OffsetOfElementAt(0), kTaggedSizeLog2);
IF_NOT (__ WordPtrEqual(__ BitcastTaggedToWordPtr(array_entry), weak_map)) {
+ // 0. Special receivers must deopt. Access checks and named interceptors
+ // imply special receiver.
+ V<Word32> instance_type = __ LoadInstanceTypeField(map);
+ __ DeoptimizeIf(
+ __ Uint32LessThanOrEqual(instance_type, LAST_SPECIAL_RECEIVER_TYPE),
+ frame_state, DeoptimizeReason::kWrongMap, feedback);
+
// 1. Check descriptor count.
V<Word32> bitfield3 =
__ template LoadField<Word32>(map, AccessBuilder::ForMapBitField3());
@@ -4644,6 +4626,32 @@ class MachineLoweringReducer : public Next {
heap_object, AccessBuilder::ForHeapNumberOrOddballValue());
}
+ // Accepts the sequential, internalized and shared one-byte string maps
+ // alike, matching InstanceTypeChecker::IsSeqOneByteString(Tagged<Map>).
+ // Guards on a string constant's map need the whole set: the string can be
+ // internalized or shared in place afterwards, which stores one of the other
+ // maps without changing the layout the guarded code reads.
+ V<Word32> IsSeqOneByteStringMap(V<Map> map) {
+#if V8_STATIC_ROOTS_BOOL
+ using StringTypeRange = InstanceTypeChecker::kUniqueMapRangeOfStringType;
+ static_assert(StringTypeRange::kSeqString.first == 0);
+ V<Word32> map_bits =
+ __ TruncateWordPtrToWord32(__ BitcastTaggedToWordPtr(map));
+ return __ Word32BitwiseAnd(
+ __ Uint32LessThanOrEqual(map_bits, StringTypeRange::kSeqString.second),
+ __ Word32Equal(
+ __ Word32BitwiseAnd(map_bits,
+ InstanceTypeChecker::kStringMapEncodingMask),
+ InstanceTypeChecker::kOneByteStringMapBit));
+#else
+ return __ Word32Equal(
+ __ Word32BitwiseAnd(
+ __ LoadInstanceTypeField(map),
+ kIsNotStringMask | kStringRepresentationAndEncodingMask),
+ kStringTag | kSeqOneByteStringTag);
+#endif // V8_STATIC_ROOTS_BOOL
+ }
+
V<Word32> LoadFromSeqOneByteString(V<Object> receiver, V<WordPtr> position) {
return __ template LoadNonArrayBufferElement<Word32>(
receiver, AccessBuilder::ForSeqOneByteStringCharacter(), position);
diff --git a/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h b/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h
index 10743cdfd2c..3e2b973e078 100644
--- a/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/machine-optimization-reducer.h
@@ -1603,6 +1603,61 @@ class MachineOptimizationReducer : public Next {
return Next::ReduceOverflowCheckedBinop(left, right, kind, rep);
}
+ // Checks if {al, ah} is the result of an add128(x, 0, y, 0) and {bh} is
+ // another constant 0 high half, and returns the nested add128 if so.
+ // Returns nullptr if it fails to match the pattern.
+ const Word64AddSub128BinopOp* TryMatchAdd3(V<Word64> al, V<Word64> ah,
+ V<Word64> bh) {
+ const ProjectionOp* p0 = matcher_.TryCast<ProjectionOp>(al);
+ if (!p0 || p0->index != 0) return nullptr;
+ const ProjectionOp* p1 = matcher_.TryCast<ProjectionOp>(ah);
+ if (!p1 || p1->index != 1) return nullptr;
+ if (p0->input() != p1->input()) return nullptr;
+ if (!matcher_.Get(al).saturated_use_count.Is(0) ||
+ !matcher_.Get(ah).saturated_use_count.Is(0)) {
+ return nullptr;
+ }
+ const Word64AddSub128BinopOp* nested =
+ 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)) {
+ return nullptr;
+ }
+ if (cx != 0 || cy != 0 || cz != 0) return nullptr;
+ return nested;
+ }
+
+ V<Word64Pair> REDUCE(Word64AddSub128Binop)(
+ V<Word64> al, V<Word64> ah, V<Word64> bl, V<Word64> bh,
+ Word64AddSub128BinopOp::Kind kind) {
+ if (ShouldSkipOptimizationStep()) {
+ return Next::ReduceWord64AddSub128Binop(al, ah, bl, bh, kind);
+ }
+
+ // TODO(ryandiaz): implement on arm64
+#ifdef V8_TARGET_ARCH_X64
+ 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)) {
+ return __ Word64Add3(nested->left_low(), nested->right_low(), bl);
+ }
+
+ // add128(x, 0, add128(y, 0, z, 0)) -> add3(x, y, z)
+ 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
+ return Next::ReduceWord64AddSub128Binop(al, ah, bl, bh, kind);
+ }
+
V<Word32> REDUCE(Comparison)(V<Any> left, V<Any> right,
ComparisonOp::Kind kind,
RegisterRepresentation rep) {
@@ -2202,8 +2257,8 @@ class MachineOptimizationReducer : public Next {
if (stored_rep.SizeInBytes() <= 4) {
value = TryRemoveWord32ToWord64Conversion(value);
}
- index = ReduceMemoryIndex(index.value_or_invalid(), &offset, &element_scale,
- kind.tagged_base);
+ index =
+ ReduceMemoryIndex(index.value_or_invalid(), &offset, &element_scale);
switch (stored_rep) {
case MemoryRepresentation::Uint8():
case MemoryRepresentation::Int8():
@@ -2267,14 +2322,13 @@ class MachineOptimizationReducer : public Next {
#endif
while (true) {
- index = ReduceMemoryIndex(index.value_or_invalid(), &offset,
- &element_scale, kind.tagged_base);
+ index =
+ ReduceMemoryIndex(index.value_or_invalid(), &offset, &element_scale);
if (!kind.tagged_base && !index.valid()) {
if (V<WordPtr> left, right;
matcher_.MatchWordAdd(base_idx, &left, &right,
WordRepresentation::WordPtr()) &&
- TryAdjustOffset(&offset, matcher_.Get(right), element_scale,
- kind.tagged_base)) {
+ TryAdjustOffset(&offset, matcher_.Get(right), element_scale)) {
base_idx = left;
continue;
}
@@ -2886,7 +2940,7 @@ class MachineOptimizationReducer : public Next {
// Try to match a constant and add it to `offset`. Return `true` if
// successful.
bool TryAdjustOffset(int32_t* offset, const Operation& maybe_constant,
- uint8_t element_scale, bool tagged_base) {
+ uint8_t element_scale) {
if (!maybe_constant.Is<ConstantOp>()) return false;
const ConstantOp& constant = maybe_constant.Cast<ConstantOp>();
if (constant.rep != WordRepresentation::WordPtr() ||
@@ -2904,8 +2958,7 @@ class MachineOptimizationReducer : public Next {
!base::bits::SignedAddOverflow32(
*offset,
static_cast<int32_t>(base::bits::Unsigned(diff) << element_scale),
- &new_offset) &&
- LoadOp::OffsetIsValid(new_offset, tagged_base)) {
+ &new_offset)) {
*offset = new_offset;
return true;
}
@@ -2953,10 +3006,10 @@ class MachineOptimizationReducer : public Next {
// `element_scale` and returning the updated `index`.
// Return `OpIndex::Invalid()` if the resulting index is zero.
OpIndex ReduceMemoryIndex(OpIndex index, int32_t* offset,
- uint8_t* element_scale, bool tagged_base) {
+ uint8_t* element_scale) {
while (index.valid()) {
const Operation& index_op = matcher_.Get(index);
- if (TryAdjustOffset(offset, index_op, *element_scale, tagged_base)) {
+ if (TryAdjustOffset(offset, index_op, *element_scale)) {
index = OpIndex::Invalid();
*element_scale = 0;
} else if (TryAdjustIndex(*offset, &index, index_op, *element_scale)) {
@@ -2980,7 +3033,7 @@ class MachineOptimizationReducer : public Next {
// instruction selector to support xchg with index *and* offset.
if (binary_op->kind == WordBinopOp::Kind::kAdd &&
TryAdjustOffset(offset, matcher_.Get(binary_op->right()),
- *element_scale, tagged_base)) {
+ *element_scale)) {
index = binary_op->left();
continue;
}
@@ -3383,13 +3436,17 @@ class MachineOptimizationReducer : public Next {
JSHeapBroker* broker = __ data() -> broker();
const OperationMatcher& matcher_ = __ matcher();
+ // TODO(victorgomes): This also applies to JS. The bit patterns for `the_hole`
+ // and `undefined` are signalling NaNs. Optimizing away an arithmetic
+ // operation skips NaN quieting, allowing these sentinel bit patterns to
+ // survive and be misinterpreted when stored in a FixedDoubleArray. This
+ // could be re-enabled if we prove that the node does not flow into a
+ // FixedDoubleArray store, or if we emit a silencing instead.
+ static constexpr bool signalling_nan_possible = true;
#if V8_ENABLE_WEBASSEMBLY
- // Note: `signalling_nan_possible` and `ensure_deterministic_nan` are always
- // the same value; we introduce both to better express intent at use sites.
- const bool signalling_nan_possible = __ data() -> is_wasm();
- const bool ensure_deterministic_nan = signalling_nan_possible;
+ // Only wasm needs NaNs to be deterministic.
+ const bool ensure_deterministic_nan = __ data() -> is_wasm();
#else
- static constexpr bool signalling_nan_possible = false;
static constexpr bool ensure_deterministic_nan = false;
#endif // V8_ENABLE_WEBASSEMBLY
};
diff --git a/deps/v8/src/compiler/turboshaft/operations.h b/deps/v8/src/compiler/turboshaft/operations.h
index ab3b571a750..e1ea2f66a84 100644
--- a/deps/v8/src/compiler/turboshaft/operations.h
+++ b/deps/v8/src/compiler/turboshaft/operations.h
@@ -301,6 +301,7 @@ using Variable = SnapshotTable<OpIndex, VariableData>::Key;
V(FloatBinop) \
V(Word32PairBinop) \
V(Word64AddSub128Binop) \
+ V(Word64Add3) \
V(Word64MulWide) \
V(OverflowCheckedBinop) \
V(WordUnary) \
@@ -1826,6 +1827,30 @@ struct Word64MulWideOp : FixedArityOperationT<2, Word64MulWideOp> {
void PrintOptions(std::ostream& os) const;
};
+struct Word64Add3Op : FixedArityOperationT<3, Word64Add3Op> {
+ static constexpr OpEffects effects = OpEffects();
+
+ base::Vector<const RegisterRepresentation> outputs_rep() const {
+ return RepVector<RegisterRepresentation::Word64(),
+ RegisterRepresentation::Word64()>();
+ }
+
+ base::Vector<const MaybeRegisterRepresentation> inputs_rep(
+ const ZoneVector<MaybeRegisterRepresentation>& storage) const {
+ return MaybeRepVector<MaybeRegisterRepresentation::Word64(),
+ MaybeRegisterRepresentation::Word64(),
+ MaybeRegisterRepresentation::Word64()>();
+ }
+
+ Word64Add3Op(V<Word64> a, V<Word64> b, V<Word64> c) : Base(a, b, c) {}
+
+ V<Word64> first() const { return input<Word64>(0); }
+ V<Word64> second() const { return input<Word64>(1); }
+ V<Word64> third() const { return input<Word64>(2); }
+
+ auto options() const { return std::tuple{}; }
+};
+
struct Word64AddSub128BinopOp
: FixedArityOperationT<4, Word64AddSub128BinopOp> {
enum class Kind : uint8_t { kAdd, kSub };
@@ -3186,16 +3211,6 @@ struct LoadOp : OperationT<LoadOp> {
return input_count == 2 ? input(1) : OpIndex::Invalid();
}
- static constexpr bool OffsetIsValid(int32_t offset, bool tagged_base) {
- if (tagged_base) {
- // When a Load has the tagged_base Kind, it means that {offset} will
- // eventually need a "-kHeapObjectTag". If the {offset} is
- // min_int, then subtracting kHeapObjectTag will underflow.
- return offset >= std::numeric_limits<int32_t>::min() + kHeapObjectTag;
- }
- return true;
- }
-
LoadOp(OpIndex base, OptionalOpIndex index, Kind kind,
MemoryRepresentation loaded_rep, RegisterRepresentation result_rep,
int32_t offset, uint8_t element_size_log2)
@@ -3225,7 +3240,6 @@ struct LoadOp : OperationT<LoadOp> {
DCHECK_IMPLIES(element_size_log2 > 0, index().valid());
DCHECK_IMPLIES(kind.maybe_unaligned,
!SupportedOperations::IsUnalignedLoadSupported(loaded_rep));
- DCHECK(OffsetIsValid(offset, kind.tagged_base));
}
static LoadOp& New(Graph* graph, OpIndex base, OptionalOpIndex index,
Kind kind, MemoryRepresentation loaded_rep,
@@ -3733,7 +3747,6 @@ struct StoreOp : OperationT<StoreOp> {
DCHECK_IMPLIES(element_size_log2 > 0, index().valid());
DCHECK_IMPLIES(kind.maybe_unaligned,
!SupportedOperations::IsUnalignedLoadSupported(stored_rep));
- DCHECK(LoadOp::OffsetIsValid(offset, kind.tagged_base));
DCHECK_EQ(kind.is_atomic, memory_order().has_value());
}
static StoreOp& New(
@@ -8670,6 +8683,15 @@ struct Simd128ConstantOp : FixedArityOperationT<0, Simd128ConstantOp> {
bool IsZero() const { return std::memcmp(kZero, value, 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;
};
@@ -9693,6 +9715,16 @@ 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;
};
@@ -9788,6 +9820,15 @@ struct Simd256ConstantOp : FixedArityOperationT<0, Simd256ConstantOp> {
bool IsZero() const { return std::memcmp(kZero, value, 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/phase.h b/deps/v8/src/compiler/turboshaft/phase.h
index c56d213f2e0..fc75bebd082 100644
--- a/deps/v8/src/compiler/turboshaft/phase.h
+++ b/deps/v8/src/compiler/turboshaft/phase.h
@@ -490,6 +490,12 @@ class V8_EXPORT_PRIVATE PipelineData {
}
void clear_wasm_revec_analyzer() { wasm_revec_analyzer_ = nullptr; }
+
+ // Percentage (0-100) of this function's SIMD128 operations combined into
+ // SIMD256. 0 means revec was not performed. Recorded to the
+ // V8.WasmRevecConversionPercent histogram after code generation.
+ int wasm_revec_percent() const { return wasm_revec_percent_; }
+ void set_wasm_revec_percent(int percent) { wasm_revec_percent_ = percent; }
#endif // V8_ENABLE_WASM_SIMD256_REVEC
WasmShuffleAnalyzer* wasm_shuffle_analyzer() const {
@@ -497,6 +503,10 @@ class V8_EXPORT_PRIVATE PipelineData {
return wasm_shuffle_analyzer_;
}
+ bool has_wasm_shuffle_analyzer() const {
+ return wasm_shuffle_analyzer_ != nullptr;
+ }
+
void set_wasm_shuffle_analyzer(WasmShuffleAnalyzer* wasm_shuffle_analyzer) {
DCHECK_NULL(wasm_shuffle_analyzer_);
wasm_shuffle_analyzer_ = wasm_shuffle_analyzer;
@@ -614,6 +624,7 @@ class V8_EXPORT_PRIVATE PipelineData {
#ifdef V8_ENABLE_WASM_SIMD256_REVEC
WasmRevecAnalyzer* wasm_revec_analyzer_ = nullptr;
+ int wasm_revec_percent_ = 0;
#endif // V8_ENABLE_WASM_SIMD256_REVEC
#endif // V8_ENABLE_WEBASSEMBLY
};
diff --git a/deps/v8/src/compiler/turboshaft/pipelines.cc b/deps/v8/src/compiler/turboshaft/pipelines.cc
index 9814eb663cc..3c773aeac12 100644
--- a/deps/v8/src/compiler/turboshaft/pipelines.cc
+++ b/deps/v8/src/compiler/turboshaft/pipelines.cc
@@ -207,4 +207,6 @@ bool Pipeline::CreateGraphFromTurbofan(compiler::TFPipelineData* turbofan_data,
return true;
}
+#undef RUN_MAYBE_ABORT
+
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/src/compiler/turboshaft/random-rescheduling-phase.cc b/deps/v8/src/compiler/turboshaft/random-rescheduling-phase.cc
index 09514e12244..c4ccc09c97e 100644
--- a/deps/v8/src/compiler/turboshaft/random-rescheduling-phase.cc
+++ b/deps/v8/src/compiler/turboshaft/random-rescheduling-phase.cc
@@ -288,9 +288,7 @@ class RandomRescheduler : public Assembler<ReschedulingReducer, GraphVisitor> {
if (ready_op_count == 0) return OpIndex::Invalid();
size_t pick = static_cast<size_t>(rng_.NextInt64()) % ready_op_count;
- auto it = ready_ops_.begin();
- std::advance(it, pick);
- return *it;
+ return ready_ops_[pick];
}
bool AllInputsScheduled(OpIndex index) {
@@ -342,7 +340,7 @@ class RandomRescheduler : public Assembler<ReschedulingReducer, GraphVisitor> {
case OpState::kReady:
// If this was ready before, it should still be.
CHECK(IsReady(index, op, produced_effects));
- ready_ops_.insert(index);
+ ready_ops_.push_back(index);
if (!has_advanced) {
has_advanced = true;
first_unscheduled_iter = iter;
@@ -365,7 +363,7 @@ class RandomRescheduler : public Assembler<ReschedulingReducer, GraphVisitor> {
}
private:
- ZoneAbslFlatHashSet<OpIndex> ready_ops_;
+ ZoneVector<OpIndex> ready_ops_;
base::RandomNumberGenerator rng_;
};
diff --git a/deps/v8/src/compiler/turboshaft/runtime-call-descriptors.h b/deps/v8/src/compiler/turboshaft/runtime-call-descriptors.h
index 369d82638ee..735ee63e52e 100644
--- a/deps/v8/src/compiler/turboshaft/runtime-call-descriptors.h
+++ b/deps/v8/src/compiler/turboshaft/runtime-call-descriptors.h
@@ -27,6 +27,11 @@ struct runtime : CallDescriptorBuilder {
template <typename Derived>
struct Descriptor {
+ // Default effects are CanCallAnything to be as safe as possible. Individual
+ // RuntimeCallDescriptor can declare their own kEffects fields with narrower
+ // effects if desired.
+ static constexpr OpEffects kEffects = OpEffects().CanCallAnything();
+
static const TSCallDescriptor* Create(size_t actual_argument_count,
Zone* zone,
LazyDeoptOnThrow lazy_deopt_on_throw,
@@ -439,6 +444,8 @@ struct runtime : CallDescriptorBuilder {
// frame.
static constexpr bool kCanTriggerLazyDeopt = false;
static constexpr Operator::Properties kProperties = Operator::kFoldable;
+ static constexpr OpEffects kEffects =
+ OpEffects().CanAllocate().RequiredWhenUnused();
};
struct ArrayIsArray : public Descriptor<ArrayIsArray> {
diff --git a/deps/v8/src/compiler/turboshaft/stack-check-lowering-reducer.h b/deps/v8/src/compiler/turboshaft/stack-check-lowering-reducer.h
index 65fb05dd1c8..1d600186da4 100644
--- a/deps/v8/src/compiler/turboshaft/stack-check-lowering-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/stack-check-lowering-reducer.h
@@ -133,10 +133,10 @@ class StackCheckLoweringReducer : public Next {
V<WordPtr> limit = __ Load(
__ LoadRootRegister(), LoadOp::Kind::RawAligned().NotLoadEliminable(),
MemoryRepresentation::UintPtr(), IsolateData::jslimit_offset());
- V<WordPtr> gap =
- __ ChangeInt32ToIntPtr(__ UntagSmi(__ StackCheckOffset()));
IF_NOT (LIKELY(
__ StackPointerGreaterThan(limit, StackCheckKind::kWasm))) {
+ V<WordPtr> gap =
+ __ ChangeInt32ToIntPtr(__ UntagSmi(__ StackCheckOffset()));
V<WordPtr> target =
__ RelocatableWasmBuiltinCallTarget(Builtin::kWasmStackGuard);
__ Call(target, {gap}, entry_ts_call_descriptor);
diff --git a/deps/v8/src/compiler/turboshaft/turbolev-frontend-pipeline.cc b/deps/v8/src/compiler/turboshaft/turbolev-frontend-pipeline.cc
index bd5e7ad7c12..e79cbab4e43 100644
--- a/deps/v8/src/compiler/turboshaft/turbolev-frontend-pipeline.cc
+++ b/deps/v8/src/compiler/turboshaft/turbolev-frontend-pipeline.cc
@@ -244,7 +244,7 @@ struct TruncationPhase {
PhaseResult Run(maglev::Graph* graph) {
maglev::GraphBackwardProcessor<maglev::PropagateTruncationProcessor>
- propagate;
+ propagate(graph);
propagate.ProcessGraph(graph);
// TODO(victorgomes): Support identities to flow to next passes?
maglev::GraphProcessor<maglev::TruncationProcessor> truncate(graph);
@@ -257,9 +257,17 @@ struct PhiUntaggingPhase {
DECL_TURBOLEV_PHASE_CONSTANTS(PhiUntagging)
PhaseResult Run(maglev::Graph* graph) {
- maglev::GraphProcessor<maglev::MaglevPhiRepresentationSelector> processor(
- graph);
+ maglev::ReachableExceptionHandlerTracker tracker(graph);
+ maglev::MaglevPhiRepresentationSelector representation_selector(graph);
+ maglev::GraphMultiProcessor<maglev::ReachableExceptionHandlerTracker&,
+ maglev::MaglevPhiRepresentationSelector&>
+ processor(tracker, representation_selector);
processor.ProcessGraph(graph);
+
+ if (graph->may_have_unreachable_blocks()) {
+ graph->RemoveUnreachableBlocks();
+ }
+
return PhaseResult::kContinue;
}
};
@@ -393,20 +401,20 @@ auto TurbolevFrontendPipeline::Run(Args&&... args) {
Phase phase;
SYNCHRONIZATION_POINT(Phase::synchronization_point_name());
PhaseResult result = phase.Run(graph_, std::forward<Args>(args)...);
- if (V8_UNLIKELY(ShouldPrintMaglevGraph(Phase::phase))) {
- PrintMaglevGraph(Phase::phase);
- }
- if (compilation_info_->trace_json_enabled()) {
- maglev::PrintMaglevGraphAsJSON(compilation_info_.get(), graph_,
- Phase::phase);
- }
-#ifdef DEBUG
if (result == PhaseResult::kContinue) {
+ if (V8_UNLIKELY(ShouldPrintMaglevGraph(Phase::phase))) {
+ PrintMaglevGraph(Phase::phase);
+ }
+ if (compilation_info_->trace_json_enabled()) {
+ maglev::PrintMaglevGraphAsJSON(compilation_info_.get(), graph_,
+ Phase::phase);
+ }
+#ifdef DEBUG
maglev::GraphProcessor<maglev::MaglevGraphVerifier> verifier(
compilation_info_.get(), Phase::phase);
verifier.ProcessGraph(graph_);
- }
#endif
+ }
return result;
}
diff --git a/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc b/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc
index b811f927091..8ef949f7a30 100644
--- a/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc
+++ b/deps/v8/src/compiler/turboshaft/turbolev-graph-builder.cc
@@ -738,8 +738,7 @@ class GraphBuildingNodeProcessor {
#endif
if (maglev_block->is_loop() &&
- (loop_single_edge_predecessors_.contains(maglev_block) ||
- pre_loop_generator_blocks_.contains(maglev_block))) {
+ generator_analyzer_.HeaderIsBypassed(maglev_block)) {
EmitLoopSinglePredecessorBlock(maglev_block);
}
@@ -783,33 +782,29 @@ class GraphBuildingNodeProcessor {
// their inputs (and also, Maglev exception blocks have no
// predecessors).
!maglev_block->is_exception_handler_block()) {
- ComputePredecessorPermutations(maglev_block, turboshaft_block, false,
- false);
+ ComputePredecessorPermutations(maglev_block, turboshaft_block);
}
return maglev::BlockProcessResult::kContinue;
}
void ComputePredecessorPermutations(maglev::BasicBlock* maglev_block,
- Block* turboshaft_block,
- bool skip_backedge,
- bool ignore_last_predecessor) {
- // This function is only called for loops that need a "single block
- // predecessor" (from EmitLoopSinglePredecessorBlock). The backedge should
- // always be skipped in thus cases. Additionally, this means that when
- // even when {maglev_block} is a loop, {turboshaft_block} shouldn't and
- // should instead be the new single forward predecessor of the loop.
- DCHECK_EQ(skip_backedge, maglev_block->is_loop());
+ Block* turboshaft_block) {
+ // When {maglev_block} is a loop, it is one whose header is bypassed by
+ // generator resumes, and {turboshaft_block} is the single forward
+ // predecessor that EmitLoopSinglePredecessorBlock created for it: the
+ // backedge is not one of its predecessors, and its last predecessor is the
+ // block gathering the resume edges, which has no Maglev origin.
+ const bool is_loop = maglev_block->is_loop();
DCHECK(!turboshaft_block->IsLoop());
DCHECK(maglev_block->has_phi());
DCHECK(turboshaft_block->IsBound());
DCHECK_EQ(__ current_block(), turboshaft_block);
- // Collecting the Maglev predecessors.
+ // Collecting the Maglev predecessors, skipping the backedge for a loop.
base::SmallVector<const maglev::BasicBlock*, 16> maglev_predecessors;
maglev_predecessors.resize(maglev_block->predecessor_count());
- for (int i = 0; i < maglev_block->predecessor_count() - skip_backedge;
- ++i) {
+ for (int i = 0; i < maglev_block->predecessor_count() - is_loop; ++i) {
maglev_predecessors[i] = maglev_block->predecessor_at(i);
}
@@ -820,8 +815,7 @@ class GraphBuildingNodeProcessor {
// Iterating predecessors from the end (because it's simpler and more
// efficient in Turboshaft).
for (const Block* pred : turboshaft_block->PredecessorsIterable()) {
- if (ignore_last_predecessor &&
- index == turboshaft_block->PredecessorCount() - 1) {
+ if (is_loop && index == turboshaft_block->PredecessorCount() - 1) {
// When generator resumes bypass loop headers, we add an additional
// predecessor to the header's predecessor (called {pred_for_generator}
// in EmitLoopSinglePredecessorBlock). This block doesn't have Maglev
@@ -1000,43 +994,39 @@ class GraphBuildingNodeProcessor {
void EmitLoopSinglePredecessorBlock(maglev::BasicBlock* maglev_loop_header) {
DCHECK(maglev_loop_header->is_loop());
- bool has_special_generator_handling = false;
- V<Word32> switch_var_first_input;
- if (pre_loop_generator_blocks_.contains(maglev_loop_header)) {
- // This loop header used to be bypassed by generator resume edges. It will
- // now act as a secondary switch for the generator resumes.
- std::vector<GeneratorSplitEdge>& generator_preds =
- pre_loop_generator_blocks_[maglev_loop_header];
- // {generator_preds} contains all of the edges that were bypassing this
- // loop header. Rather than adding that many predecessors to the loop
- // header, will create a single predecessor, {pred_for_generator}, to
- // which all of the edges of {generator_preds} will go.
- Block* pred_for_generator = __ NewBlock();
-
- for (GeneratorSplitEdge pred : generator_preds) {
- __ Bind(pred.pre_loop_dst);
- __ SetVariable(header_switch_input_,
- __ Word32Constant(pred.switch_value));
- __ Goto(pred_for_generator);
- }
-
- __ Bind(pred_for_generator);
- switch_var_first_input = __ GetVariable(header_switch_input_);
- DCHECK(switch_var_first_input.valid());
+ DCHECK(pre_loop_generator_blocks_.contains(maglev_loop_header));
- BuildJump(maglev_loop_header);
+ // This loop header used to be bypassed by generator resume edges. It will
+ // now act as a secondary switch for the generator resumes.
+ std::vector<GeneratorSplitEdge>& generator_preds =
+ pre_loop_generator_blocks_[maglev_loop_header];
+ // {generator_preds} contains all of the edges that were bypassing this
+ // loop header. Rather than adding that many predecessors to the loop
+ // header, will create a single predecessor, {pred_for_generator}, to
+ // which all of the edges of {generator_preds} will go.
+ Block* pred_for_generator = __ NewBlock();
- has_special_generator_handling = true;
- on_generator_switch_loop_ = true;
+ for (GeneratorSplitEdge pred : generator_preds) {
+ __ Bind(pred.pre_loop_dst);
+ __ SetVariable(header_switch_input_,
+ __ Word32Constant(pred.switch_value));
+ __ Goto(pred_for_generator);
}
+ __ Bind(pred_for_generator);
+ V<Word32> switch_var_first_input = __ GetVariable(header_switch_input_);
+ DCHECK(switch_var_first_input.valid());
+
+ BuildJump(maglev_loop_header);
+
+ on_generator_switch_loop_ = true;
+
DCHECK(loop_single_edge_predecessors_.contains(maglev_loop_header));
Block* loop_pred = loop_single_edge_predecessors_[maglev_loop_header];
__ Bind(loop_pred);
if (maglev_loop_header->has_phi()) {
- ComputePredecessorPermutations(maglev_loop_header, loop_pred, true,
- has_special_generator_handling);
+ ComputePredecessorPermutations(maglev_loop_header, loop_pred);
// Now we need to emit Phis (one per loop phi in {block}, which should
// contain the same input except for the backedge).
@@ -1046,58 +1036,51 @@ class GraphBuildingNodeProcessor {
constexpr int kSkipBackedge = 1;
int input_count = phi->input_count() - kSkipBackedge;
- if (has_special_generator_handling) {
- // Adding an input to the Phis to account for the additional
- // generator-related predecessor.
- V<Any> additional_input;
- switch (phi->value_representation()) {
- case maglev::ValueRepresentation::kTagged:
- additional_input = dummy_object_input_;
- break;
- case maglev::ValueRepresentation::kInt32:
- case maglev::ValueRepresentation::kUint32:
- additional_input = dummy_word32_input_;
- break;
- case maglev::ValueRepresentation::kFloat64:
- case maglev::ValueRepresentation::kHoleyFloat64:
- additional_input = dummy_float64_input_;
- break;
- case maglev::ValueRepresentation::kIntPtr:
- case maglev::ValueRepresentation::kRawPtr:
- case maglev::ValueRepresentation::kNone:
- // Maglev doesn't have IntPtr / RawPtr Phis.
- UNREACHABLE();
- }
- loop_phis_first_input_.push_back(
- MakePhiMaybePermuteInputs(phi, input_count, additional_input));
- } else {
- loop_phis_first_input_.push_back(
- MakePhiMaybePermuteInputs(phi, input_count));
+ // Adding an input to the Phis to account for the additional
+ // generator-related predecessor.
+ V<Any> additional_input;
+ switch (phi->value_representation()) {
+ case maglev::ValueRepresentation::kTagged:
+ additional_input = dummy_object_input_;
+ break;
+ case maglev::ValueRepresentation::kInt32:
+ case maglev::ValueRepresentation::kUint32:
+ additional_input = dummy_word32_input_;
+ break;
+ case maglev::ValueRepresentation::kFloat64:
+ case maglev::ValueRepresentation::kHoleyFloat64:
+ additional_input = dummy_float64_input_;
+ break;
+ case maglev::ValueRepresentation::kIntPtr:
+ case maglev::ValueRepresentation::kRawPtr:
+ case maglev::ValueRepresentation::kNone:
+ // Maglev doesn't have IntPtr / RawPtr Phis.
+ UNREACHABLE();
}
+ loop_phis_first_input_.push_back(
+ MakePhiMaybePermuteInputs(phi, input_count, additional_input));
}
}
- if (has_special_generator_handling) {
- // We now emit the Phi that will be used in the loop's main switch.
- base::SmallVector<OpIndex, 16> inputs;
- constexpr int kSkipGeneratorPredecessor = 1;
+ // We now emit the Phi that will be used in the loop's main switch.
+ base::SmallVector<OpIndex, 16> inputs;
+ constexpr int kSkipGeneratorPredecessor = 1;
- // We insert a default input for all of the non-generator predecessor.
- int input_count_without_generator =
- loop_pred->PredecessorCount() - kSkipGeneratorPredecessor;
- DCHECK(loop_default_generator_value_.valid());
- inputs.insert(inputs.begin(), input_count_without_generator,
- loop_default_generator_value_);
+ // We insert a default input for all of the non-generator predecessor.
+ int input_count_without_generator =
+ loop_pred->PredecessorCount() - kSkipGeneratorPredecessor;
+ DCHECK(loop_default_generator_value_.valid());
+ inputs.insert(inputs.begin(), input_count_without_generator,
+ loop_default_generator_value_);
- // And we insert the "true" input for the generator predecessor (which is
- // {pred_for_generator} above).
- DCHECK(switch_var_first_input.valid());
- inputs.push_back(switch_var_first_input);
+ // And we insert the "true" input for the generator predecessor (which is
+ // {pred_for_generator} above).
+ DCHECK(switch_var_first_input.valid());
+ inputs.push_back(switch_var_first_input);
- __ SetVariable(
- header_switch_input_,
- __ Phi(base::VectorOf(inputs), RegisterRepresentation::Word32()));
- }
+ __ SetVariable(
+ header_switch_input_,
+ __ Phi(base::VectorOf(inputs), RegisterRepresentation::Word32()));
// Actually jumping to the loop.
__ Goto(Map(maglev_loop_header));
@@ -1339,12 +1322,11 @@ class GraphBuildingNodeProcessor {
if (__ current_block()->IsLoop()) {
DCHECK(state.block()->is_loop());
OpIndex first_phi_input;
- if (state.block()->predecessor_count() > 2 ||
- generator_analyzer_.HeaderIsBypassed(state.block())) {
- // This loop has multiple forward edges in Maglev, so we should have
- // created an intermediate block in Turboshaft, which will be the only
- // predecessor of the Turboshaft loop, and from which we'll find the
- // first input for this loop phi.
+ if (generator_analyzer_.HeaderIsBypassed(state.block())) {
+ // Resume jumps enter this loop without going through its header, so we
+ // should have created an intermediate block in Turboshaft, which will
+ // be the only predecessor of the Turboshaft loop, and from which we'll
+ // find the first input for this loop phi.
DCHECK_EQ(loop_phis_first_input_.size(),
static_cast<size_t>(state.block()->phis()->LengthForTest()));
DCHECK_GE(loop_phis_first_input_index_, 0);
@@ -2742,8 +2724,8 @@ class GraphBuildingNodeProcessor {
const maglev::ProcessingState& state) {
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info());
__ DeoptimizeIfNot(
- __ Uint32LessThan(Map(node->ValueInput()), Smi::kMaxValue), frame_state,
- DeoptimizeReason::kNotASmi,
+ __ Uint32LessThanOrEqual(Map(node->ValueInput()), Smi::kMaxValue),
+ frame_state, DeoptimizeReason::kNotASmi,
node->eager_deopt_info()->feedback_to_update());
return maglev::ProcessResult::kContinue;
}
@@ -3549,35 +3531,6 @@ class GraphBuildingNodeProcessor {
__ ChangeInt32ToIntPtr(Map(node->IndexInput()))));
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(
- maglev::LoadHoleyFixedDoubleArrayElementCheckedNotHole* node,
- const maglev::ProcessingState& state) {
- GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info());
- V<Float64> result = __ LoadFixedDoubleArrayElement(
- Map(node->ElementsInput()),
- __ ChangeInt32ToIntPtr(Map(node->IndexInput())));
- __ DeoptimizeIf(__ Float64IsHole(result), frame_state,
- DeoptimizeReason::kHole,
- node->eager_deopt_info()->feedback_to_update());
- SetMap(node, result);
- return maglev::ProcessResult::kContinue;
- }
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- maglev::ProcessResult Process(
- maglev::LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole* node,
- const maglev::ProcessingState& state) {
- GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info());
- V<Float64> result = __ LoadFixedDoubleArrayElement(
- Map(node->ElementsInput()),
- __ ChangeInt32ToIntPtr(Map(node->IndexInput())));
- __ DeoptimizeIf(__ Float64IsUndefinedOrHole(result), frame_state,
- DeoptimizeReason::kHole,
- node->eager_deopt_info()->feedback_to_update());
- SetMap(node, result);
- return maglev::ProcessResult::kContinue;
- }
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
// Maps a maglev static type to the memory representation of a tagged
// field access.
MemoryRepresentation TaggedMemoryRepresentation(maglev::NodeType type) {
@@ -3695,16 +3648,37 @@ class GraphBuildingNodeProcessor {
WriteBarrierKind::kFullWriteBarrier);
return maglev::ProcessResult::kContinue;
}
- template <Either<maglev::StoreFixedDoubleArrayElement,
- maglev::StoreFixedHoleyDoubleArrayElement>
- T>
- maglev::ProcessResult Process(T* node, const maglev::ProcessingState& state) {
+ maglev::ProcessResult Process(maglev::StoreFixedDoubleArrayElement* node,
+ const maglev::ProcessingState& state) {
__ StoreFixedDoubleArrayElement(
Map(node->ElementsInput()),
__ ChangeInt32ToIntPtr(Map(node->IndexInput())),
Map(node->ValueInput()));
return maglev::ProcessResult::kContinue;
}
+ maglev::ProcessResult Process(maglev::StoreFixedDoubleArrayHole* node,
+ const maglev::ProcessingState& state) {
+ __ StoreFixedDoubleArrayElement(
+ Map(node->ElementsInput()),
+ __ ChangeInt32ToIntPtr(Map(node->IndexInput())),
+ __ Float64Constant(internal::Float64::hole_nan()));
+ return maglev::ProcessResult::kContinue;
+ }
+ maglev::ProcessResult Process(maglev::StoreFixedHoleyDoubleArrayElement* node,
+ const maglev::ProcessingState& state) {
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ ScopedVar<Float64, AssemblerT> value(this, Map(node->ValueInput()));
+ IF (__ Float64IsHole(value)) {
+ value = __ Float64Constant(internal::Float64::undefined_nan());
+ }
+#else
+ V<Float64> value = Map(node->ValueInput());
+#endif // V8_ENABLE_UNDEFINED_DOUBLE
+ __ StoreFixedDoubleArrayElement(
+ Map(node->ElementsInput()),
+ __ ChangeInt32ToIntPtr(Map(node->IndexInput())), value);
+ return maglev::ProcessResult::kContinue;
+ }
maglev::ProcessResult Process(maglev::StoreMap* node,
const maglev::ProcessingState& state) {
__ Store(Map(node->ValueInput()), __ HeapConstant(node->map().object()),
@@ -3929,15 +3903,15 @@ class GraphBuildingNodeProcessor {
DeoptimizeReason::kOutOfBounds,
node->eager_deopt_info()->feedback_to_update());
}
- __ DeoptimizeIfNot(
- __ Uint32LessThan(Map<Word32>(node->IndexInput()),
- __ TruncateWordPtrToWord32(byte_length)),
- frame_state, DeoptimizeReason::kOutOfBounds,
- node->eager_deopt_info()->feedback_to_update());
+ __ DeoptimizeIfNot(__ UintPtrLessThan(__ ChangeInt32ToIntPtr(
+ Map<Word32>(node->IndexInput())),
+ byte_length),
+ frame_state, DeoptimizeReason::kOutOfBounds,
+ node->eager_deopt_info()->feedback_to_update());
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::LoadSignedIntDataViewElement* node,
+ maglev::ProcessResult Process(maglev::LoadInt32DataViewElement* node,
const maglev::ProcessingState& state) {
V<WordPtr> storage = Map<WordPtr>(node->DataPointerInput());
// TODO(dmercadier): Peephole optimize TruncateJSPrimitiveToUntagged(Boolean
@@ -3949,11 +3923,11 @@ class GraphBuildingNodeProcessor {
TruncateJSPrimitiveToUntaggedOp::InputAssumptions::kObject);
SetMap(node, __ LoadDataViewElement(
Map(node->ObjectInput()), storage,
- __ ChangeUint32ToUintPtr(Map<Word32>(node->IndexInput())),
+ __ ChangeInt32ToIntPtr(Map<Word32>(node->IndexInput())),
is_little_endian, node->external_array_type()));
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::LoadDoubleDataViewElement* node,
+ maglev::ProcessResult Process(maglev::LoadUint32DataViewElement* node,
const maglev::ProcessingState& state) {
V<WordPtr> storage = Map<WordPtr>(node->DataPointerInput());
// TODO(dmercadier): Peephole optimize TruncateJSPrimitiveToUntagged(Boolean
@@ -3966,12 +3940,33 @@ class GraphBuildingNodeProcessor {
SetMap(node,
__ LoadDataViewElement(
Map(node->ObjectInput()), storage,
- __ ChangeUint32ToUintPtr(Map<Word32>(node->IndexInput())),
- is_little_endian, ExternalArrayType::kExternalFloat64Array));
+ __ ChangeInt32ToIntPtr(Map<Word32>(node->IndexInput())),
+ is_little_endian, ExternalArrayType::kExternalUint32Array));
+ return maglev::ProcessResult::kContinue;
+ }
+ maglev::ProcessResult Process(maglev::LoadDoubleDataViewElement* node,
+ const maglev::ProcessingState& state) {
+ V<WordPtr> storage = Map<WordPtr>(node->DataPointerInput());
+ // TODO(dmercadier): Peephole optimize TruncateJSPrimitiveToUntagged(Boolean
+ // -> Bit) in SimplifiedOptimizationReducer, since the
+ // is_little_endian_input will often be a constant True/False boolean in
+ // practice.
+ V<Word32> is_little_endian =
+ ToBit(node->IsLittleEndianInput(),
+ TruncateJSPrimitiveToUntaggedOp::InputAssumptions::kObject);
+ V<Float> value = V<Float>::Cast(__ LoadDataViewElement(
+ Map(node->ObjectInput()), storage,
+ __ ChangeInt32ToIntPtr(Map<Word32>(node->IndexInput())),
+ is_little_endian, node->external_array_type()));
+ if (node->external_array_type() ==
+ ExternalArrayType::kExternalFloat32Array) {
+ value = __ ChangeFloat32ToFloat64(V<Float32>::Cast(value));
+ }
+ SetMap(node, value);
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::StoreSignedIntDataViewElement* node,
+ maglev::ProcessResult Process(maglev::StoreInt32DataViewElement* node,
const maglev::ProcessingState& state) {
V<WordPtr> storage = Map<WordPtr>(node->DataPointerInput());
// TODO(dmercadier): Peephole optimize TruncateJSPrimitiveToUntagged(Boolean
@@ -3983,11 +3978,12 @@ class GraphBuildingNodeProcessor {
TruncateJSPrimitiveToUntaggedOp::InputAssumptions::kObject);
__ StoreDataViewElement(
Map(node->ObjectInput()), storage,
- __ ChangeUint32ToUintPtr(Map<Word32>(node->IndexInput())),
+ __ ChangeInt32ToIntPtr(Map<Word32>(node->IndexInput())),
Map<Word32>(node->ValueInput()), is_little_endian,
node->external_array_type());
return maglev::ProcessResult::kContinue;
}
+
maglev::ProcessResult Process(maglev::StoreDoubleDataViewElement* node,
const maglev::ProcessingState& state) {
V<WordPtr> storage = Map<WordPtr>(node->DataPointerInput());
@@ -3998,11 +3994,15 @@ class GraphBuildingNodeProcessor {
V<Word32> is_little_endian =
ToBit(node->IsLittleEndianInput(),
TruncateJSPrimitiveToUntaggedOp::InputAssumptions::kObject);
+ OpIndex value = Map<Float64>(node->ValueInput());
+ if (node->external_array_type() ==
+ ExternalArrayType::kExternalFloat32Array) {
+ value = __ TruncateFloat64ToFloat32(value);
+ }
__ StoreDataViewElement(
Map(node->ObjectInput()), storage,
- __ ChangeUint32ToUintPtr(Map<Word32>(node->IndexInput())),
- Map<Float64>(node->ValueInput()), is_little_endian,
- ExternalArrayType::kExternalFloat64Array);
+ __ ChangeInt32ToIntPtr(Map<Word32>(node->IndexInput())), value,
+ is_little_endian, node->external_array_type());
return maglev::ProcessResult::kContinue;
}
@@ -4020,10 +4020,11 @@ class GraphBuildingNodeProcessor {
void BuildJump(maglev::BasicBlock* target) {
Block* destination = Map(target);
- if (target->is_loop() && (target->predecessor_count() > 2 ||
- generator_analyzer_.HeaderIsBypassed(target))) {
- // This loop has multiple forward edges in Maglev, so we'll create an
- // extra block in Turboshaft that will be the only predecessor.
+ DCHECK_IMPLIES(target->is_loop(), target->predecessor_count() <= 2);
+ if (target->is_loop() && generator_analyzer_.HeaderIsBypassed(target)) {
+ // Resume jumps enter this loop without going through its header, so
+ // we'll create an extra block in Turboshaft that will be the only
+ // predecessor.
auto it = loop_single_edge_predecessors_.find(target);
if (it != loop_single_edge_predecessors_.end()) {
destination = it->second;
@@ -5138,27 +5139,34 @@ class GraphBuildingNodeProcessor {
node->eager_deopt_info()->feedback_to_update()));
return maglev::ProcessResult::kContinue;
}
+ // The narrowest kind that still admits everything the conversion is allowed
+ // to assume about its input.
+ static ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind
+ JSPrimitiveKindFor(maglev::NodeType assumed_input_type) {
+ if (maglev::NodeTypeIs(assumed_input_type, maglev::NodeType::kNumber)) {
+ return ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::kNumber;
+ }
+ if (maglev::NodeTypeIs(assumed_input_type,
+ maglev::NodeType::kNumberOrBoolean)) {
+ return ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
+ kNumberOrBoolean;
+ }
+ if (maglev::NodeTypeIs(assumed_input_type,
+ maglev::NodeType::kNumberOrUndefined)) {
+ return ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
+ kNumberOrUndefined;
+ }
+ DCHECK(maglev::NodeTypeIs(assumed_input_type,
+ maglev::NodeType::kNumberOrOddball));
+ return ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
+ kNumberOrOddball;
+ }
+
maglev::ProcessResult Process(maglev::CheckedNumberOrOddballToFloat64* node,
const maglev::ProcessingState& state) {
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info());
- ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind kind;
- switch (node->conversion_type()) {
- case maglev::TaggedToFloat64ConversionType::kOnlyNumber:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::kNumber;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrUndefined:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
- kNumberOrUndefined;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrBoolean:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
- kNumberOrBoolean;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrOddball:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
- kNumberOrOddball;
- break;
- }
+ ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind kind =
+ JSPrimitiveKindFor(node->assumed_input_type());
SetMap(node,
__ ConvertJSPrimitiveToUntaggedOrDeopt(
Map(node->ValueInput()), frame_state, kind,
@@ -5171,24 +5179,8 @@ class GraphBuildingNodeProcessor {
maglev::CheckedNumberOrOddballToHoleyFloat64* node,
const maglev::ProcessingState& state) {
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info());
- ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind kind;
- switch (node->conversion_type()) {
- case maglev::TaggedToFloat64ConversionType::kOnlyNumber:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::kNumber;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrUndefined:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
- kNumberOrUndefined;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrBoolean:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
- kNumberOrBoolean;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrOddball:
- kind = ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind::
- kNumberOrOddball;
- break;
- }
+ ConvertJSPrimitiveToUntaggedOrDeoptOp::JSPrimitiveKind kind =
+ JSPrimitiveKindFor(node->assumed_input_type());
SetMap(
node,
__ ConvertJSPrimitiveToUntaggedOrDeopt(
@@ -5204,9 +5196,9 @@ class GraphBuildingNodeProcessor {
}
maglev::ProcessResult Process(maglev::UnsafeNumberToFloat64* node,
const maglev::ProcessingState& state) {
- // `node->conversion_type()` doesn't matter here, since for both HeapNumbers
- // and Oddballs, the Float64 value is at the same index (and this node never
- // deopts, regardless of its input).
+ // `node->assumed_input_type()` doesn't matter here, since for both
+ // HeapNumbers and Oddballs, the Float64 value is at the same index (and
+ // this node never deopts, regardless of its input).
SetMap(node, __ ConvertJSPrimitiveToUntagged(
Map(node->ValueInput()),
ConvertJSPrimitiveToUntaggedOp::UntaggedKind::kFloat64,
@@ -5216,9 +5208,9 @@ class GraphBuildingNodeProcessor {
}
maglev::ProcessResult Process(maglev::UnsafeNumberOrOddballToFloat64* node,
const maglev::ProcessingState& state) {
- // `node->conversion_type()` doesn't matter here, since for both HeapNumbers
- // and Oddballs, the Float64 value is at the same index (and this node never
- // deopts, regardless of its input).
+ // `node->assumed_input_type()` doesn't matter here, since for both
+ // HeapNumbers and Oddballs, the Float64 value is at the same index (and
+ // this node never deopts, regardless of its input).
SetMap(node, __ ConvertJSPrimitiveToUntagged(
Map(node->ValueInput()),
ConvertJSPrimitiveToUntaggedOp::UntaggedKind::kFloat64,
@@ -5229,9 +5221,9 @@ class GraphBuildingNodeProcessor {
maglev::ProcessResult Process(
maglev::UnsafeNumberOrOddballToHoleyFloat64* node,
const maglev::ProcessingState& state) {
- // `node->conversion_type()` doesn't matter here, since for both HeapNumbers
- // and Oddballs, the Float64 value is at the same index (and this node never
- // deopts, regardless of its input).
+ // `node->assumed_input_type()` doesn't matter here, since for both
+ // HeapNumbers and Oddballs, the Float64 value is at the same index (and
+ // this node never deopts, regardless of its input).
SetMap(node,
__ ConvertJSPrimitiveToUntagged(
Map(node->ValueInput()),
@@ -5310,15 +5302,18 @@ class GraphBuildingNodeProcessor {
ConvertJSPrimitiveToUntaggedOrDeoptOp::UntaggedKind::kArrayIndex,
CheckForMinusZeroMode::kCheckForMinusZero, feedback);
if constexpr (Is64()) {
- // ArrayIndex is 32-bit in Maglev, but 64 in Turboshaft. This means that
- // we have to convert it to 32-bit before the following `SetMap`, and we
- // thus have to check that it actually fits in a Uint32.
- __ DeoptimizeIfNot(__ Uint64LessThanOrEqual(
- result, std::numeric_limits<uint32_t>::max()),
+ // UntaggedKind::kArrayIndex produces signed Word64 in Turboshaft, but
+ // Maglev's CheckedObjectToIndex produces signed Int32. Ensure the value
+ // fits in a signed Int32 before mapping it (negative indices are valid
+ // and handled downstream by bounds checks).
+ V<Word32> i32 = __ TruncateWord64ToWord32(result);
+ __ DeoptimizeIfNot(__ Word64Equal(__ ChangeInt32ToInt64(i32), result),
frame_state, DeoptimizeReason::kNotInt32, feedback);
RETURN_IF_UNREACHABLE();
+ SetMap(node, i32);
+ } else {
+ SetMap(node, result);
}
- SetMap(node, Is64() ? __ TruncateWord64ToWord32(result) : result);
return maglev::ProcessResult::kContinue;
}
template <
@@ -5438,21 +5433,21 @@ class GraphBuildingNodeProcessor {
maglev::TruncateCheckedNumberOrOddballToInt32* node,
const maglev::ProcessingState& state) {
TruncateJSPrimitiveToWord32OrDeoptOp::InputRequirement input_requirement;
- switch (node->conversion_type()) {
- case maglev::TaggedToFloat64ConversionType::kOnlyNumber:
- input_requirement =
- TruncateJSPrimitiveToWord32OrDeoptOp::InputRequirement::kNumber;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrUndefined:
- UNREACHABLE();
- case maglev::TaggedToFloat64ConversionType::kNumberOrBoolean:
- input_requirement = TruncateJSPrimitiveToWord32OrDeoptOp::
- InputRequirement::kNumberOrBoolean;
- break;
- case maglev::TaggedToFloat64ConversionType::kNumberOrOddball:
- input_requirement = TruncateJSPrimitiveToWord32OrDeoptOp::
- InputRequirement::kNumberOrOddball;
- break;
+ if (maglev::NodeTypeIs(node->assumed_input_type(),
+ maglev::NodeType::kNumber)) {
+ input_requirement =
+ TruncateJSPrimitiveToWord32OrDeoptOp::InputRequirement::kNumber;
+ } else if (maglev::NodeTypeIs(node->assumed_input_type(),
+ maglev::NodeType::kNumberOrBoolean)) {
+ input_requirement = TruncateJSPrimitiveToWord32OrDeoptOp::
+ InputRequirement::kNumberOrBoolean;
+ } else {
+ DCHECK(maglev::NodeTypeIs(node->assumed_input_type(),
+ maglev::NodeType::kNumberOrOddball));
+ DCHECK_NE(node->assumed_input_type(),
+ maglev::NodeType::kNumberOrUndefined);
+ input_requirement = TruncateJSPrimitiveToWord32OrDeoptOp::
+ InputRequirement::kNumberOrOddball;
}
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->eager_deopt_info());
SetMap(node, __ TruncateJSPrimitiveToWord32OrDeopt(
@@ -5485,10 +5480,8 @@ class GraphBuildingNodeProcessor {
return maglev::ProcessResult::kContinue;
}
- template <Either<maglev::Float64ToSilencedFloat64,
- maglev::HoleyFloat64ToSilencedFloat64>
- T>
- maglev::ProcessResult Process(T* node, const maglev::ProcessingState& state) {
+ maglev::ProcessResult Process(maglev::Float64ToSilencedFloat64* node,
+ const maglev::ProcessingState& state) {
SetMap(node, __ Float64SilenceNaN(Map(node->ValueInput())));
return maglev::ProcessResult::kContinue;
}
@@ -5498,21 +5491,6 @@ class GraphBuildingNodeProcessor {
SetMap(node, __ Float64SilenceNaN(Map(node->ValueInput())));
return maglev::ProcessResult::kContinue;
}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- maglev::ProcessResult Process(
- maglev::HoleyFloat64ConvertHoleToUndefined* node,
- const maglev::ProcessingState& state) {
- V<Float64> input = Map(node->ValueInput());
-
- ScopedVar<Float64, AssemblerT> result(this, input);
- IF (__ Float64IsHole(input)) {
- result = __ Float64Constant(internal::Float64::undefined_nan());
- }
-
- SetMap(node, result);
- return maglev::ProcessResult::kContinue;
- }
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
maglev::ProcessResult Process(maglev::CheckedHoleyFloat64ToFloat64* node,
const maglev::ProcessingState& state) {
V<Float64> input = Map(node->ValueInput());
@@ -5857,11 +5835,6 @@ class GraphBuildingNodeProcessor {
return maglev::ProcessResult::kContinue;
}
- maglev::ProcessResult Process(maglev::TryOnStackReplacement*,
- const maglev::ProcessingState&) {
- // Turboshaft is the top tier compiler, so we never need to OSR from it.
- return maglev::ProcessResult::kContinue;
- }
maglev::ProcessResult Process(maglev::ReduceInterruptBudgetForReturn*,
const maglev::ProcessingState&) {
// No need to update the interrupt budget once we reach Turboshaft.
@@ -5875,6 +5848,7 @@ class GraphBuildingNodeProcessor {
}
maglev::ProcessResult Process(maglev::HandleNoHeapWritesInterrupt* node,
const maglev::ProcessingState&) {
+ DCHECK(!v8_flags.disable_loop_stack_checks);
GET_FRAME_STATE_MAYBE_ABORT(frame_state, node->lazy_deopt_info());
__ JSLoopStackCheck(native_context(), frame_state);
return maglev::ProcessResult::kContinue;
@@ -6402,9 +6376,12 @@ class GraphBuildingNodeProcessor {
value->Cast<maglev::HeapConstant>()->ref().object()));
break;
- case maglev::Opcode::kFloat64Constant: {
+ case maglev::Opcode::kFloat64Constant:
+ case maglev::Opcode::kHoleyFloat64Constant: {
i::Float64 value_as_float =
- value->Cast<maglev::Float64Constant>()->value();
+ value->opcode() == maglev::Opcode::kFloat64Constant
+ ? value->Cast<maglev::Float64Constant>()->value()
+ : value->Cast<maglev::HoleyFloat64Constant>()->value();
DCHECK(vobj->has_static_map());
const bool is_fixed_double_array =
vobj->map()->IsFixedDoubleArrayMap();
@@ -6888,9 +6865,8 @@ class GraphBuildingNodeProcessor {
__ output_graph().Get(phi_index).Cast<PendingLoopPhiOp>();
__ output_graph().Replace<PhiOp>(
phi_index,
- base::VectorOf(
- {pending_phi.first(),
- Map(maglev_phi -> backedge_input(), kIndexCanBeInvalid)}),
+ base::VectorOf({pending_phi.first(),
+ Map(maglev_phi -> backedge(), kIndexCanBeInvalid)}),
pending_phi.rep);
}
}
@@ -7217,20 +7193,20 @@ class GraphBuildingNodeProcessor {
// to map the exception phi corresponding to the accumulator.
V<Object> catch_block_begin_ = V<Object>::Invalid();
- // Maglev loops can have multiple forward edges, while Turboshaft should only
- // have a single one. When a Maglev loop has multiple forward edges, we create
- // an additional Turboshaft block before (which we record in
- // {loop_single_edge_predecessors_}), and jumps to the loop will instead go to
- // this additional block, which will become the only forward predecessor of
- // the loop.
+ // Maglev generator loops can be entered through resume jumps that bypass
+ // their header, while a Turboshaft loop should only have a single forward
+ // edge. For those loops we create an additional Turboshaft block before
+ // (which we record in {loop_single_edge_predecessors_}), and jumps to the
+ // loop will instead go to this additional block, which will become the only
+ // forward predecessor of the loop.
ZoneUnorderedMap<const maglev::BasicBlock*, Block*>
loop_single_edge_predecessors_;
- // When we create an additional loop predecessor for loops that have multiple
- // forward predecessors, we store the newly created phis in
- // {loop_phis_first_input_}, so that we can then use them as the first input
- // of the original loop phis. {loop_phis_first_input_index_} is used as an
- // index in {loop_phis_first_input_} in VisitPhi so that we know where to find
- // the first input for the current loop phi.
+ // When we create an additional loop predecessor for such loops, we store the
+ // newly created phis in {loop_phis_first_input_}, so that we can then use
+ // them as the first input of the original loop phis.
+ // {loop_phis_first_input_index_} is used as an index in
+ // {loop_phis_first_input_} in VisitPhi so that we know where to find the
+ // first input for the current loop phi.
base::SmallVector<OpIndex, 16> loop_phis_first_input_;
int loop_phis_first_input_index_ = -1;
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 a7c9b97016a..6ec07fc6220 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
@@ -866,6 +866,7 @@ class WasmInJsInliningInterface {
BAILOUT_WASM_OP(AtomicWait)
BAILOUT_WASM_OP(AtomicOp)
BAILOUT_WASM_OP(AtomicFence)
+ BAILOUT_WASM_OP(Publish)
BAILOUT_WASM_OP(Pause)
BAILOUT_WASM_OP(StructAtomicRMW)
diff --git a/deps/v8/src/compiler/turboshaft/wasm-lowering-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-lowering-reducer.h
index 60c6868ee2b..2f99fa97ede 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-lowering-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-lowering-reducer.h
@@ -73,38 +73,27 @@ class WasmLoweringReducer : public Next {
OptionalV<EagerFrameState> frame_state,
wasm::ValueType type, TrapId trap_id) {
if (trap_id == TrapId::kTrapNullDereference) {
- // Skip the check altogether if null checks are turned off.
- if (!v8_flags.wasm_skip_null_checks) {
- if (null_check_strategy_ == NullCheckStrategy::kTrapHandler) {
- // To make sure load elimination sees consistent representations, we
- // load known fields of objects.
- if (wasm::IsSubtypeOf(type.AsNonShared(), wasm::kWasmStructRef,
- module_) ||
- wasm::IsSubtypeOf(type.AsNonShared(), wasm::kWasmArrayRef,
- module_)) {
- __ Load(object, LoadOp::Kind::TrapOnNull().Immutable(),
- MemoryRepresentation::AnyTagged(),
- offsetof(WasmObject, properties_or_hash_));
- } else if (wasm::IsSubtypeOf(type, wasm::kWasmWaitqueueRef,
- module_)) {
- __ Load(object, LoadOp::Kind::TrapOnNull().Immutable(),
- MemoryRepresentation::Uint32(),
- offsetof(Foreign, foreign_address_));
- } else if (wasm::IsSubtypeOf(type.AsNonShared(), wasm::kWasmFuncRef,
- module_)) {
- __ Load(object, LoadOp::Kind::TrapOnNull().Immutable(),
- MemoryRepresentation::AnyTagged(),
- offsetof(WasmFuncRef, trusted_internal_));
- } else {
- __ TrapIf(__ IsNull(object, type), frame_state, trap_id);
- }
- } else {
- __ TrapIf(__ IsNull(object, type), frame_state, trap_id);
- }
+ if (v8_flags.wasm_skip_null_checks) return object;
+
+ // Use an explicit null check if
+ // (1) we cannot use trap handler or
+ // (2) the object might be a Smi (anyref, externref, exnref) or
+ // (3) null checks for the object's type must check for JS null.
+ bool use_explicit_check =
+ null_check_strategy_ == NullCheckStrategy::kExplicit ||
+ wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(), type.AsNonShared(),
+ module_) ||
+ wasm::IsSubtypeOf(wasm::kWasmExnRef.AsNonNull(), type.AsNonShared(),
+ module_) ||
+ !type.use_wasm_null();
+ if (!use_explicit_check) {
+ __ Load(object, LoadOp::Kind::TrapOnNull().Immutable(),
+ MemoryRepresentation::TaggedPointer(),
+ offsetof(HeapObject, map_));
+ return object;
}
- } else {
- __ TrapIf(__ IsNull(object, type), frame_state, trap_id);
}
+ __ TrapIf(__ IsNull(object, type), frame_state, trap_id);
return object;
}
@@ -143,9 +132,6 @@ class WasmLoweringReducer : public Next {
Label<> int_to_smi_label(&Asm());
Label<> heap_number_label(&Asm());
- constexpr int32_t kInt31MaxValue = 0x3fffffff;
- constexpr int32_t kInt31MinValue = -kInt31MaxValue - 1;
-
if (is_nullable) {
GOTO_IF(__ IsNull(object, wasm::kWasmExternRef), null_label);
}
@@ -168,9 +154,9 @@ class WasmLoweringReducer : public Next {
V<Word32> int_value = __ UntagSmi(V<Smi>::Cast(object));
// Convert to heap number if the int32 does not fit into an i31ref.
- GOTO_IF(__ Int32LessThan(kInt31MaxValue, int_value),
+ GOTO_IF(__ Int32LessThan(wasm::kInt31MaxValue, int_value),
convert_to_heap_number_label);
- GOTO_IF(__ Int32LessThan(int_value, kInt31MinValue),
+ GOTO_IF(__ Int32LessThan(int_value, wasm::kInt31MinValue),
convert_to_heap_number_label);
GOTO(end_label, object);
@@ -189,9 +175,11 @@ class WasmLoweringReducer : public Next {
V<Float64> float_value =
__ LoadHeapNumberValue(V<HeapNumber>::Cast(object));
// Check range of float value.
- GOTO_IF(__ Float64LessThan(float_value, __ Float64Constant(kInt31MinValue)),
+ GOTO_IF(__ Float64LessThan(float_value,
+ __ Float64Constant(wasm::kInt31MinValue)),
end_label, object);
- GOTO_IF(__ Float64LessThan(__ Float64Constant(kInt31MaxValue), float_value),
+ GOTO_IF(__ Float64LessThan(__ Float64Constant(wasm::kInt31MaxValue),
+ float_value),
end_label, object);
// Check if value is -0.
V<Word32> is_minus_zero;
@@ -245,23 +233,8 @@ class WasmLoweringReducer : public Next {
wasm::ModuleTypeIndex type_index, int field_index,
bool is_signed, CheckForNull null_check,
std::optional<AtomicMemoryOrder> memory_order) {
- if (field_index == StructGetOp::kDescFieldIndex) {
- if (null_check == kWithNullCheck) {
- __ TrapIf(__ IsNull(object, wasm::kWasmAnyRef), frame_state,
- TrapId::kTrapNullDereference);
- }
- V<Map> map = __ LoadMapField(object);
- return __ Load(map, LoadOp::Kind::TaggedBase().Immutable(),
- MemoryRepresentation::TaggedPointer(),
- offsetof(Map, instance_descriptors_));
- }
-
- // TODO(mliedtke): Get rid of the requires_aligned_access by aligning
- // WasmNull to 8 bytes.
- bool requires_aligned_access =
- memory_order.has_value() && type->field(field_index) == wasm::kWasmI64;
- auto [explicit_null_check, implicit_null_check] = null_checks_for_struct_op(
- null_check, field_index, requires_aligned_access);
+ auto [explicit_null_check, implicit_null_check] =
+ null_checks_for_struct_op(null_check, field_index);
if (explicit_null_check) {
__ TrapIf(__ IsNull(object, wasm::kWasmAnyRef), frame_state,
@@ -270,6 +243,20 @@ class WasmLoweringReducer : public Next {
LoadOp::Kind load_kind = implicit_null_check ? LoadOp::Kind::TrapOnNull()
: LoadOp::Kind::TaggedBase();
+ if (field_index == StructGetOp::kDescFieldIndex) {
+ // Can't use {LoadMapField} because that doesn't support specifying
+ // {LoadOp::Kind::TrapOnNull}.
+ V<Map> map = __ Load(object, load_kind.Immutable(),
+ MemoryRepresentation::TaggedPointer(),
+ offsetof(HeapObject, map_));
+#if V8_MAP_PACKING
+ UNIMPLEMENTED();
+#endif
+ return __ Load(map, LoadOp::Kind::TaggedBase().Immutable(),
+ MemoryRepresentation::TaggedPointer(),
+ offsetof(Map, instance_descriptors_));
+ }
+
if (!type->mutability(field_index)) {
load_kind = load_kind.Immutable();
}
@@ -297,12 +284,8 @@ class WasmLoweringReducer : public Next {
if (memory_order == AtomicMemoryOrder::kAcqRel) {
memory_order = AtomicMemoryOrder::kSeqCst;
}
- // TODO(mliedtke): Get rid of the requires_aligned_access by aligning
- // WasmNull to 8 bytes.
- bool requires_aligned_access =
- memory_order.has_value() && type->field(field_index) == wasm::kWasmI64;
- auto [explicit_null_check, implicit_null_check] = null_checks_for_struct_op(
- null_check, field_index, requires_aligned_access);
+ auto [explicit_null_check, implicit_null_check] =
+ null_checks_for_struct_op(null_check, field_index);
if (explicit_null_check) {
__ TrapIf(__ IsNull(object, wasm::kWasmAnyRef), frame_state,
@@ -338,11 +321,8 @@ class WasmLoweringReducer : public Next {
wasm::ModuleTypeIndex type_index,
int field_index, CheckForNull null_check,
AtomicMemoryOrder memory_order) {
- // TODO(mliedtke): Get rid of the requires_aligned_access by aligning
- // WasmNull to 8 bytes.
- bool requires_aligned_access = type->field(field_index) == wasm::kWasmI64;
- auto [explicit_null_check, implicit_null_check] = null_checks_for_struct_op(
- null_check, field_index, requires_aligned_access);
+ auto [explicit_null_check, implicit_null_check] =
+ null_checks_for_struct_op(null_check, field_index);
if (explicit_null_check) {
__ TrapIf(__ IsNull(object, wasm::kWasmAnyRef),
@@ -718,8 +698,6 @@ class WasmLoweringReducer : public Next {
V<Word32> ReduceWasmTypeCheckAbstract(V<Object> object,
WasmTypeCheckConfig config) {
- const bool object_can_be_null = config.from.is_nullable();
- const bool null_succeeds = config.to.is_nullable();
const bool object_can_be_i31 =
wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(),
config.from.AsNonShared(), module_) ||
@@ -737,10 +715,9 @@ class WasmLoweringReducer : public Next {
break;
}
// Null checks performed by any other type check need control flow. We can
- // skip the null check if null fails, because it's covered by the Smi
- // check or instance type check we'll do later.
- if (object_can_be_null && null_succeeds) {
- const int kResult = 1;
+ // skip the null check if success is determined by a Smi check.
+ if (config.from.is_nullable() && config.to != wasm::kWasmRefI31) {
+ const int kResult = config.to.is_nullable() ? 1 : 0;
GOTO_IF(UNLIKELY(__ IsNull(object, config.from)), end_label,
__ Word32Constant(kResult));
}
@@ -806,8 +783,6 @@ class WasmLoweringReducer : public Next {
V<Object> ReduceWasmTypeCastAbstract(V<Object> object,
OptionalV<EagerFrameState> frame_state,
WasmTypeCheckConfig config) {
- const bool object_can_be_null = config.from.is_nullable();
- const bool null_succeeds = config.to.is_nullable();
const bool object_can_be_i31 =
wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(),
config.from.AsNonShared(), module_) ||
@@ -825,12 +800,18 @@ class WasmLoweringReducer : public Next {
TrapId::kTrapIllegalCast);
break;
}
- // Null checks performed by any other type cast can be skipped if null
- // fails, because it's covered by the Smi check
- // or instance type check we'll do later.
- if (object_can_be_null && null_succeeds &&
- !v8_flags.wasm_skip_null_checks) {
- GOTO_IF(UNLIKELY(__ IsNull(object, config.from)), end_label);
+ // Null checks performed by any other type cast can only be skipped if
+ // a Smi check is the only operation we'll need (i.e. the target type
+ // is non-nullable (ref i31).
+ if (config.from.is_nullable() && config.to != wasm::kWasmRefI31) {
+ V<Word32> is_null = __ IsNull(object, config.from);
+ if (config.to.is_nullable()) {
+ GOTO_IF(UNLIKELY(is_null), end_label);
+ } else if (!v8_flags.wasm_skip_null_checks) {
+ // TODO(jkummerow): Consider using a trapping map load instead, and
+ // adjusting its message to be "illegal cast" instead of "null deref".
+ __ TrapIf(is_null, frame_state, TrapId::kTrapIllegalCast);
+ }
}
if (to_kind == wasm::GenericKind::kI31) {
// If earlier optimization passes reached the limit of possible graph
@@ -895,7 +876,6 @@ class WasmLoweringReducer : public Next {
WasmTypeCheckConfig config) {
DCHECK(rtt.has_value());
int rtt_depth = wasm::GetSubtypingDepth(module_, config.to.ref_index());
- bool object_can_be_null = config.from.is_nullable();
bool object_can_be_i31 = wasm::IsSubtypeOf(
wasm::kWasmI31Ref.AsNonNull(), config.from.AsNonShared(), module_);
@@ -903,14 +883,13 @@ class WasmLoweringReducer : public Next {
bool is_cast_from_any =
config.from.is_reference_to(wasm::GenericKind::kAny);
- // If we are casting from any and null results in check failure, then the
- // {IsDataRefMap} check below subsumes the null check. Otherwise, perform
- // an explicit null check now.
- if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
+ if (config.from.is_nullable()) {
V<Word32> is_null = __ IsNull(object, wasm::kWasmAnyRef);
if (config.to.is_nullable()) {
GOTO_IF(UNLIKELY(is_null), end_label);
} else if (!v8_flags.wasm_skip_null_checks) {
+ // TODO(jkummerow): Consider using a trapping map load instead, and
+ // adjusting its message to be "illegal cast" instead of "null deref".
__ TrapIf(is_null, frame_state, TrapId::kTrapIllegalCast);
}
}
@@ -952,7 +931,7 @@ class WasmLoweringReducer : public Next {
__ TrapIfNot(is_wasm_obj, frame_state, TrapId::kTrapIllegalCast);
}
- V<Object> type_info = LoadWasmTypeInfo(map);
+ V<Object> type_info = __ LoadWasmTypeInfo(map);
DCHECK_GE(rtt_depth, 0);
// If the depth of the rtt is known to be less that the minimum supertype
// array length, we can access the supertype without bounds-checking the
@@ -985,7 +964,6 @@ class WasmLoweringReducer : public Next {
WasmTypeCheckConfig config) {
DCHECK(rtt.has_value());
int rtt_depth = wasm::GetSubtypingDepth(module_, config.to.ref_index());
- bool object_can_be_null = config.from.is_nullable();
bool object_can_be_i31 = wasm::IsSubtypeOf(
wasm::kWasmI31Ref.AsNonNull(), config.from.AsNonShared(), module_);
bool is_cast_from_any =
@@ -993,10 +971,7 @@ class WasmLoweringReducer : public Next {
Label<Word32> end_label(&Asm());
- // If we are casting from any and null results in check failure, then the
- // {IsDataRefMap} check below subsumes the null check. Otherwise, perform
- // an explicit null check now.
- if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
+ if (config.from.is_nullable()) {
const int kResult = config.to.is_nullable() ? 1 : 0;
GOTO_IF(UNLIKELY(__ IsNull(object, wasm::kWasmAnyRef)), end_label,
kResult);
@@ -1035,7 +1010,7 @@ class WasmLoweringReducer : public Next {
GOTO_IF_NOT(LIKELY(is_wasm_obj), end_label, 0);
}
- V<Object> type_info = LoadWasmTypeInfo(map);
+ V<Object> type_info = __ LoadWasmTypeInfo(map);
DCHECK_GE(rtt_depth, 0);
// If the depth of the rtt is known to be less that the minimum supertype
// array length, we can access the supertype without bounds-checking the
@@ -1145,20 +1120,12 @@ class WasmLoweringReducer : public Next {
comparison_value, LAST_WASM_OBJECT_TYPE - FIRST_WASM_OBJECT_TYPE);
}
- V<Object> LoadWasmTypeInfo(V<Map> map) {
- int offset = offsetof(Map, constructor_or_back_pointer_or_native_context_);
- return __ Load(map, LoadOp::Kind::TaggedBase().Immutable(),
- MemoryRepresentation::TaggedPointer(), offset);
- }
-
std::pair<bool, bool> null_checks_for_struct_op(CheckForNull null_check,
- int field_index,
- bool requires_alignment) {
+ int field_index) {
bool explicit_null_check =
null_check == kWithNullCheck &&
(null_check_strategy_ == NullCheckStrategy::kExplicit ||
- field_index > wasm::kMaxStructFieldIndexForImplicitNullCheck ||
- requires_alignment);
+ field_index > wasm::kMaxStructFieldIndexForImplicitNullCheck);
bool implicit_null_check =
null_check == kWithNullCheck && !explicit_null_check;
return {explicit_null_check, implicit_null_check};
diff --git a/deps/v8/src/compiler/turboshaft/wasm-revec-phase.cc b/deps/v8/src/compiler/turboshaft/wasm-revec-phase.cc
index 9483b46153f..019c6ee2a65 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-revec-phase.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-revec-phase.cc
@@ -15,6 +15,7 @@ void WasmRevecPhase::Run(PipelineData* data, Zone* temp_zone) {
WasmRevecAnalyzer analyzer(data, temp_zone, data->graph());
if (analyzer.ShouldReduce()) {
+ data->set_wasm_revec_percent(analyzer.revectorized_percent());
data->set_wasm_revec_analyzer(&analyzer);
UnparkedScopeIfNeeded scope(data->broker(),
v8_flags.turboshaft_trace_reduction);
diff --git a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc
index 5ad129cc154..26b861af332 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.cc
@@ -91,6 +91,20 @@ bool IsCompatibleOpAndKind(const Operation& op0, const Operation& op1) {
return IsSupportedSameSimd128OpKind(op0, op1);
}
+// Returns true if {op} is a SIMD128 operation, i.e. it produces a SIMD128
+// value or stores one. Used to compute the denominator for the SIMD256
+// conversion percentage.
+bool IsSimd128Operation(const Operation& op) {
+ for (RegisterRepresentation rep : op.outputs_rep()) {
+ if (rep == RegisterRepresentation::Simd128()) return true;
+ }
+ if (const StoreOp* store_op = op.TryCast<StoreOp>()) {
+ return store_op->stored_rep == MemoryRepresentation::Simd128();
+ }
+ // Store-lane has no output and is not a StoreOp, but is a SIMD128 operation.
+ return op.Is<Simd128LaneMemoryOp>();
+}
+
// Save the result of a uint64_t subtraction.
class OffsetDiff {
public:
@@ -214,11 +228,25 @@ class StoreLoadInfo {
bool is_valid() const { return op_ != nullptr; }
+ const Operation* base() const { return base_; }
const Operation* index() const { return index_; }
- uint64_t indexc_ = 0;
+ uint64_t indexc() const { return indexc_; }
uint64_t offset() const { return offset_; }
const Op* op() const { return op_; }
+ // Comparison for ordering in StoreInfoSet. Must match operator-()
+ // compatibility check to ensure only compatible stores are grouped. ZoneSet
+ // discards entries that compare equal (neither < the other per strict weak
+ // ordering), so all distinguishing fields must be compared. E.g., without
+ // indexc comparison, stores with offset=0,indexc=0 and offset=0,indexc=64
+ // would compare equal and the second would be discarded from the set.
+ bool operator<(const StoreLoadInfo<Op>& other) const {
+ if (base_ != other.base_) return base_ < other.base_;
+ if (index_ != other.index_) return index_ < other.index_;
+ if (indexc_ != other.indexc_) return indexc_ < other.indexc_;
+ return offset_ < other.offset_;
+ }
+
private:
void set_invalid() { op_ = nullptr; }
@@ -226,15 +254,13 @@ class StoreLoadInfo {
const Operation* base_;
const Operation* index_;
uint64_t offset_;
+ uint64_t indexc_ = 0;
};
struct StoreInfoCompare {
bool operator()(const StoreLoadInfo<StoreOp>& lhs,
const StoreLoadInfo<StoreOp>& rhs) const {
- if (lhs.index() != rhs.index()) {
- return lhs.index() < rhs.index();
- }
- return lhs.offset() < rhs.offset();
+ return lhs < rhs;
}
};
@@ -489,6 +515,18 @@ PackNode* SLPTree::NewIntersectPackNode(const NodeGroup& node_group) {
return intersect_pnode;
}
+void SLPTree::AddLoadToShufflePackNode(OpIndex load_idx,
+ ShufflePackNode* pnode) {
+ auto it = load_to_shuffle_packnodes_.find(load_idx);
+ if (it == load_to_shuffle_packnodes_.end()) {
+ bool result;
+ std::tie(it, result) = load_to_shuffle_packnodes_.emplace(
+ load_idx, ZoneVector<ShufflePackNode*>(phase_zone_));
+ DCHECK(result);
+ }
+ it->second.push_back(pnode);
+}
+
PackNode* SLPTree::NewCommutativePackNodeAndRecurse(const NodeGroup& node_group,
unsigned depth) {
PackNode* pnode = NewPackNode(node_group);
@@ -635,9 +673,24 @@ ShufflePackNode* SLPTree::Try256ShuffleMatchLoad8x8U(
return nullptr;
}
}
+ // The vector load-transform is emitted when the reducer visits the
+ // shared load transform itself (see WasmRevecReducer::REDUCE_INPUT_GRAPH
+ // (Simd128LoadTransform)), not when it visits the shuffles, so it can
+ // never be reordered past an intervening store. This is only sound if
+ // the load and the shuffles are reduced in the same relative order as
+ // they appear here, which requires them to be in the same block.
+ if (graph_.BlockIndexOf(shuffle0_left_idx) !=
+ graph_.BlockIndexOf(op_idx0)) {
+ TRACE(
+ "Load transform and shuffle are not in the same block for "
+ "k8x8U\n");
+ return nullptr;
+ }
TRACE("match load extend 8x8->32x8\n");
- return NewShufflePackNode(
+ ShufflePackNode* pnode = NewShufflePackNode(
node_group, ShufflePackNode::SpecificInfo::Kind::kS256Load8x8U);
+ AddLoadToShufflePackNode(shuffle0_left_idx, pnode);
+ return pnode;
}
TRACE("Shuffle's left input is not k64Zero load transform.\n");
return nullptr;
@@ -780,7 +833,7 @@ SLPTree::TryGetExtendIntToF32x4Info(OpIndex index) {
// Get information for lane 0 (splat).
const Simd128SplatOp* splat = graph_.Get(current).TryCast<Simd128SplatOp>();
- if (!splat) {
+ if (!splat || splat->kind != Simd128SplatOp::Kind::kF32x4) {
TRACE("Mismatch in splat\n");
return {};
}
@@ -859,29 +912,27 @@ bool SLPTree::TryMatchExtendIntToF32x4(const NodeGroup& node_group,
return false;
}
- // Use uint8_t to match start_lane type and avoid type mismatch.
- uint8_t min_lane_index =
- std::min(info0.value().start_lane, info1.value().start_lane);
- uint8_t max_lane_index =
- std::max(info0.value().start_lane, info1.value().start_lane);
-
- // Check lane difference without std::abs on unsigned types.
- if (max_lane_index - min_lane_index != 4) {
+ // The group is revectorized into a single 256-bit conversion of the eight
+ // lanes starting at {start_lane}, whose lower half feeds node_group[0] and
+ // whose upper half feeds node_group[1] (see GetExtractOpIfNeeded). So node0
+ // has to extend from the lower four lanes and node1 from the upper four.
+ // The reversed order would need an extra shuffle and is not supported.
+ const uint8_t start_lane = info0.value().start_lane;
+ if (info1.value().start_lane != start_lane + 4) {
return false;
}
if (info0.value().lane_size == 1) {
- if (min_lane_index != 0 && min_lane_index != 8) {
+ if (start_lane != 0 && start_lane != 8) {
return false;
}
} else {
DCHECK_EQ(info0.value().lane_size, 2);
- if (min_lane_index != 0) {
+ if (start_lane != 0) {
return false;
}
}
*info = info0.value();
- info->start_lane = min_lane_index;
return true;
}
@@ -1338,6 +1389,9 @@ PackNode* SLPTree::BuildTreeRec(const NodeGroup& node_group,
TRACE("Failed due to unsupported Simd128Shuffle op kind!\n");
return nullptr;
}
+ // Simd128Shuffle has no side effects, so emitting the vector
+ // load-transform at the load's position (earlier in the program) is safe.
+ 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;
@@ -1367,18 +1421,50 @@ PackNode* SLPTree::BuildTreeRec(const NodeGroup& node_group,
int index;
if (SimdShuffle::TryMatchSplat<4>(shuffle0, &index) &&
graph_.Get(op0.input(index >> 2)).opcode == Opcode::kLoad) {
+ OpIndex load_index = op0.input(index >> 2);
+ // The vector load-transform is emitted when the reducer visits
+ // the load itself (see WasmRevecReducer::REDUCE_INPUT_GRAPH
+ // (Load)), not when it visits the shuffle, so it can never be
+ // reordered past an intervening store. This is only sound if
+ // the load and the shuffle are reduced in the same relative
+ // order as they appear here, which requires them to be in the
+ // same block.
+ if (V8_UNLIKELY(graph_.BlockIndexOf(load_index) !=
+ graph_.BlockIndexOf(node0))) {
+ TRACE(
+ "Load and shuffle are not in the same block for "
+ "k32Splat\n");
+ return nullptr;
+ }
ShufflePackNode* pnode = NewShufflePackNode(
node_group,
ShufflePackNode::SpecificInfo::Kind::kS256Load32Transform);
pnode->info().set_splat_index(index);
+ AddLoadToShufflePackNode(load_index, pnode);
return pnode;
} else if (SimdShuffle::TryMatchSplat<2>(shuffle0, &index) &&
graph_.Get(op0.input(index >> 1)).opcode ==
Opcode::kLoad) {
+ OpIndex load_index = op0.input(index >> 1);
+ // The vector load-transform is emitted when the reducer visits
+ // the load itself (see WasmRevecReducer::REDUCE_INPUT_GRAPH
+ // (Load)), not when it visits the shuffle, so it can never be
+ // reordered past an intervening store. This is only sound if
+ // the load and the shuffle are reduced in the same relative
+ // order as they appear here, which requires them to be in the
+ // same block.
+ if (V8_UNLIKELY(graph_.BlockIndexOf(load_index) !=
+ graph_.BlockIndexOf(node0))) {
+ TRACE(
+ "Load and shuffle are not in the same block for "
+ "k64Splat\n");
+ return nullptr;
+ }
ShufflePackNode* pnode = NewShufflePackNode(
node_group,
ShufflePackNode::SpecificInfo::Kind::kS256Load64Transform);
pnode->info().set_splat_index(index);
+ AddLoadToShufflePackNode(load_index, pnode);
return pnode;
}
}
@@ -1443,6 +1529,23 @@ void WasmRevecAnalyzer::MergeSLPTree(SLPTree& slp_tree) {
intersect_pnodes.end());
}
+ // Different SLPTrees (rooted at different store seeds) can independently
+ // match distinct shuffle patterns that share the same underlying load, so
+ // accumulate into the existing vector rather than dropping on key
+ // collision (as a plain unordered_map::merge would).
+ for (const auto& entry : slp_tree.GetLoadToShufflePackNodesMapping()) {
+ auto it = revectorizable_load_shuffle_node_.find(entry.first);
+ if (it == revectorizable_load_shuffle_node_.end()) {
+ bool result;
+ std::tie(it, result) = revectorizable_load_shuffle_node_.emplace(
+ entry.first, ZoneVector<ShufflePackNode*>(phase_zone_));
+ DCHECK(result);
+ }
+ ZoneVector<ShufflePackNode*>& shuffle_pnodes = it->second;
+ shuffle_pnodes.insert(shuffle_pnodes.end(), entry.second.begin(),
+ entry.second.end());
+ }
+
revectorizable_node_.merge(slp_tree.GetNodeMapping());
reorder_inputs_.merge(slp_tree.GetReorderInputs());
}
@@ -1463,6 +1566,9 @@ bool WasmRevecAnalyzer::IsSupportedReduceSeed(const Operation& op) {
void WasmRevecAnalyzer::ProcessBlock(const Block& block) {
StoreInfoSet simd128_stores(phase_zone_);
for (const Operation& op : base::Reversed(graph_.operations(block))) {
+ if (IsSimd128Operation(op)) {
+ ++simd128_op_count_;
+ }
if (const StoreOp* store_op = op.TryCast<StoreOp>()) {
if (store_op->stored_rep == MemoryRepresentation::Simd128()) {
StoreLoadInfo<StoreOp> info(&graph_, store_op);
@@ -1564,6 +1670,12 @@ void WasmRevecAnalyzer::Run() {
use_map_ = phase_zone_->New<Simd128UseMap>(graph_, phase_zone_);
if (DecideVectorize()) {
should_reduce_ = true;
+ for (const auto& entry : revectorizable_node_) {
+ // Force-packed and intersect nodes still execute as two SIMD128
+ // operations plus a SimdPack128To256, so they are not combined into a
+ // SIMD256 operation and must not count towards the conversion ratio.
+ if (!entry.second->is_force_packing()) ++revectorized_simd128_count_;
+ }
Print("Decided to vectorize");
}
}
diff --git a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h
index 951a31e3719..dbe9a0b0ae7 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-revec-reducer.h
@@ -479,7 +479,8 @@ class SLPTree : public NON_EXPORTED_BASE(ZoneObject) {
phase_zone_(zone),
root_(nullptr),
node_to_packnode_(zone),
- node_to_intersect_packnodes_(zone) {}
+ node_to_intersect_packnodes_(zone),
+ load_to_shuffle_packnodes_(zone) {}
// Information for extending i8x16/i16x8 to f32x4.
struct ExtendIntToF32x4Info {
@@ -510,6 +511,14 @@ class SLPTree : public NON_EXPORTED_BASE(ZoneObject) {
ZoneUnorderedMap<OpIndex, ZoneVector<PackNode*>>& GetIntersectNodeMapping() {
return node_to_intersect_packnodes_;
}
+ // Maps the shared Load/Simd128LoadTransform feeding matched shuffle-splat
+ // or Load8x8U patterns to the ShufflePackNodes that consume it, so the
+ // reducer can emit the vector load-transform when it visits the load
+ // itself, rather than re-deriving it when visiting each shuffle.
+ ZoneUnorderedMap<OpIndex, ZoneVector<ShufflePackNode*>>&
+ GetLoadToShufflePackNodesMapping() {
+ return load_to_shuffle_packnodes_;
+ }
ZoneUnorderedSet<OpIndex>& GetReorderInputs() { return reorder_inputs_; }
void Print(const char* info);
@@ -543,6 +552,12 @@ class SLPTree : public NON_EXPORTED_BASE(ZoneObject) {
ShufflePackNode* NewShufflePackNode(const NodeGroup& node_group,
ShufflePackNode::SpecificInfo::Kind kind);
+ // Registers {pnode} as one of the (possibly several) ShufflePackNodes
+ // that consume {load_idx} (a Load or Simd128LoadTransform) as their shared
+ // input, so the reducer can later emit the vector load-transform(s) when
+ // it visits {load_idx} itself.
+ void AddLoadToShufflePackNode(OpIndex load_idx, ShufflePackNode* pnode);
+
// Try match the following pattern:
// 1. simd128_load64zero(memargs)
// 2. simd128_const[0,0,0,0]
@@ -577,7 +592,10 @@ class SLPTree : public NON_EXPORTED_BASE(ZoneObject) {
ExtendIntToF32x4Info* info);
std::optional<ExtendIntToF32x4Info> TryGetExtendIntToF32x4Info(OpIndex index);
- bool IsSideEffectFreeRange(OpIndex first, OpIndex second);
+ // Checks that no operation strictly between {from} and {to} has an effect
+ // that conflicts with {to}'s effects, so that {to} can safely be hoisted
+ // earlier, next to {from} (e.g. merging two isomorphic ops for packing).
+ bool IsSideEffectFreeRange(OpIndex from, OpIndex to);
bool IsEqual(const OpIndex node0, const OpIndex node1);
// Check if the nodes in the node_group depend on the result of each other.
bool HasInputDependencies(const NodeGroup& node_group);
@@ -595,6 +613,10 @@ class SLPTree : public NON_EXPORTED_BASE(ZoneObject) {
ZoneUnorderedMap<OpIndex, PackNode*> node_to_packnode_;
// Maps a node to multiple IntersectPackNodes.
ZoneUnorderedMap<OpIndex, ZoneVector<PackNode*>> node_to_intersect_packnodes_;
+ // Maps the shared Load/Simd128LoadTransform of matched shuffle-splat or
+ // Load8x8U patterns to the ShufflePackNodes that consume it.
+ ZoneUnorderedMap<OpIndex, ZoneVector<ShufflePackNode*>>
+ load_to_shuffle_packnodes_;
ZoneUnorderedSet<OpIndex> reorder_inputs_{phase_zone_};
};
@@ -610,6 +632,16 @@ class WasmRevecAnalyzer {
void MergeSLPTree(SLPTree& slp_tree);
bool ShouldReduce() const { return should_reduce_; }
+ // Percentage (0-100) of this function's SIMD128 operations that were
+ // combined into SIMD256 operations. Only meaningful once the analysis has
+ // decided to vectorize (i.e. when ShouldReduce() is true).
+ int revectorized_percent() const {
+ if (simd128_op_count_ == 0) return 0;
+ DCHECK_LE(revectorized_simd128_count_, simd128_op_count_);
+ return static_cast<int>(revectorized_simd128_count_ * 100 /
+ simd128_op_count_);
+ }
+
PackNode* GetPackNode(const OpIndex ig_index) {
auto it = revectorizable_node_.find(ig_index);
if (it != revectorizable_node_.end()) {
@@ -626,6 +658,18 @@ class WasmRevecAnalyzer {
return nullptr;
}
+ // Returns the ShufflePackNodes that {node} (a Load or Simd128LoadTransform)
+ // feeds as the shared input of matched shuffle-splat or Load8x8U
+ // pattern(s), if any. A single load can feed multiple distinct shuffle
+ // patterns (e.g. two different splats of the same 128-bit load).
+ ZoneVector<ShufflePackNode*>* GetLoadShufflePackNodes(const OpIndex node) {
+ auto it = revectorizable_load_shuffle_node_.find(node);
+ if (it != revectorizable_load_shuffle_node_.end()) {
+ return &(it->second);
+ }
+ return nullptr;
+ }
+
const OpIndex GetReducedInput(const PackNode* pnode, size_t index = 0) {
if (index >= pnode->GetOperandsSize()) {
return OpIndex::Invalid();
@@ -664,7 +708,15 @@ class WasmRevecAnalyzer {
ZoneUnorderedMap<OpIndex, PackNode*> revectorizable_node_{phase_zone_};
ZoneUnorderedMap<OpIndex, ZoneVector<PackNode*>>
revectorizable_intersect_node_{phase_zone_};
+ ZoneUnorderedMap<OpIndex, ZoneVector<ShufflePackNode*>>
+ revectorizable_load_shuffle_node_{phase_zone_};
bool should_reduce_{false};
+ // Numerator/denominator for revectorized_percent(): number of SIMD128
+ // operations combined into SIMD256, and the total number of SIMD128
+ // operations in the function. Force-packed and intersect nodes are excluded
+ // from the numerator.
+ size_t revectorized_simd128_count_{0};
+ size_t simd128_op_count_{0};
Simd128UseMap* use_map_{nullptr};
ZoneUnorderedSet<OpIndex> reorder_inputs_{phase_zone_};
// Used as a local hash-set, always clear after use.
@@ -748,6 +800,28 @@ class WasmRevecReducer : public UniformReducerAdapter<WasmRevecReducer, Next> {
V<Simd128> REDUCE_INPUT_GRAPH(Simd128LoadTransform)(
V<Simd128> ig_index, const Simd128LoadTransformOp& load_transform) {
+ // If this load transform is the shared k64Zero input of one or more
+ // matched Load8x8U shuffle patterns, emit the vector load-transform(s)
+ // here, at the load transform's own position, so they can't be
+ // reordered past a store that may follow before the shuffles are
+ // reached. A single load transform can feed multiple distinct shuffle
+ // patterns.
+ if (ZoneVector<ShufflePackNode*>* shuffle_pnodes =
+ analyzer_.GetLoadShufflePackNodes(ig_index)) {
+ for (ShufflePackNode* shuffle_pnode : *shuffle_pnodes) {
+ if (shuffle_pnode->RevectorizedNode().valid()) continue;
+ DCHECK_EQ(load_transform.transform_kind,
+ Simd128LoadTransformOp::TransformKind::k64Zero);
+ V<WordPtr> base = __ MapToNewGraph(load_transform.base());
+ V<WordPtr> index = __ MapToNewGraph(load_transform.index());
+ V<Simd256> shuffle_og_index = __ Simd256LoadTransform(
+ base, index, load_transform.load_kind,
+ Simd256LoadTransformOp::TransformKind::k8x8U,
+ load_transform.offset);
+ shuffle_pnode->SetRevectorizedNode(shuffle_og_index);
+ }
+ }
+
PackNode* pnode = analyzer_.GetPackNode(ig_index);
if (!pnode || !pnode->IsDefaultPackNode()) {
return Adapter::ReduceInputGraphSimd128LoadTransform(ig_index,
@@ -799,6 +873,47 @@ class WasmRevecReducer : public UniformReducerAdapter<WasmRevecReducer, Next> {
}
OpIndex REDUCE_INPUT_GRAPH(Load)(OpIndex ig_index, const LoadOp& load) {
+ // If this load is the shared input of one or more matched shuffle-splat
+ // patterns (k32Splat/k64Splat), emit the vector load-transform(s) here,
+ // at the load's own position, so they can't be reordered past a store
+ // that may follow before the shuffle(s) are reached. A single load can
+ // feed multiple distinct splat patterns (e.g. splatting two different
+ // lanes of the same 128-bit load). The scalar load below is still
+ // emitted normally afterward, since it may have other, non-packed uses.
+ if (ZoneVector<ShufflePackNode*>* shuffle_pnodes =
+ analyzer_.GetLoadShufflePackNodes(ig_index)) {
+ for (ShufflePackNode* shuffle_pnode : *shuffle_pnodes) {
+ if (shuffle_pnode->RevectorizedNode().valid()) continue;
+ const bool is_32 =
+ shuffle_pnode->info().kind() ==
+ ShufflePackNode::SpecificInfo::Kind::kS256Load32Transform;
+ const int bytes_per_lane = is_32 ? 4 : 8;
+ // Mask splat_index to get the lane offset within the 128-bit vector.
+ // For 32-bit lanes: mask is 3 (bits 0-1), for 64-bit lanes: mask is 1
+ // (bit 0).
+ const int lane_mask = is_32 ? 3 : 1;
+ // splat_index*bytes_per_lane is at most 12 (for 32-bit) or 8 (for
+ // 64-bit); load.offset is the WASM memarg immediate (up to
+ // INT32_MAX). Compute in int64 to avoid signed-int32 overflow that
+ // would sign-extend to a negative base.
+ const int64_t splat_offset =
+ (shuffle_pnode->info().splat_index() & lane_mask) * bytes_per_lane;
+ const int64_t offset = splat_offset + load.offset;
+
+ V<WordPtr> base = __ WordPtrAdd(__ MapToNewGraph(load.base()),
+ __ IntPtrConstant(offset));
+ V<WordPtr> index = load.index().has_value()
+ ? __ MapToNewGraph(load.index().value())
+ : __ IntPtrConstant(0);
+ const Simd256LoadTransformOp::TransformKind transform_kind =
+ is_32 ? Simd256LoadTransformOp::TransformKind::k32Splat
+ : Simd256LoadTransformOp::TransformKind::k64Splat;
+ V<Simd256> shuffle_og_index =
+ __ Simd256LoadTransform(base, index, load.kind, transform_kind, 0);
+ shuffle_pnode->SetRevectorizedNode(shuffle_og_index);
+ }
+ }
+
PackNode* pnode = analyzer_.GetPackNode(ig_index);
if (!pnode || !pnode->IsDefaultPackNode()) {
return Adapter::ReduceInputGraphLoad(ig_index, load);
@@ -1046,65 +1161,17 @@ class WasmRevecReducer : public UniformReducerAdapter<WasmRevecReducer, Next> {
if (!og_index.valid()) {
const ShufflePackNode::SpecificInfo::Kind kind = pnode->info().kind();
switch (kind) {
+ // The vector load-transform for these two kinds is emitted when the
+ // reducer visits the shared Load/Simd128LoadTransform itself (see
+ // REDUCE_INPUT_GRAPH(Load) and REDUCE_INPUT_GRAPH
+ // (Simd128LoadTransform)), which always happens before this shuffle
+ // is visited. So RevectorizedNode() is already valid by the time we
+ // get here, and the `!og_index.valid()` check above already skipped
+ // this switch entirely.
case ShufflePackNode::SpecificInfo::Kind::kS256Load32Transform:
- case ShufflePackNode::SpecificInfo::Kind::kS256Load64Transform: {
- const bool is_32 =
- kind == ShufflePackNode::SpecificInfo::Kind::kS256Load32Transform;
-
- const OpIndex load_index =
- op.input(pnode->info().splat_index() >> (is_32 ? 2 : 1));
- const LoadOp& load =
- __ input_graph().Get(load_index).template Cast<LoadOp>();
-
- const int bytes_per_lane = is_32 ? 4 : 8;
- // splat_index*bytes_per_lane is at most 28; load.offset is the WASM
- // memarg immediate (up to INT32_MAX). Compute in int64 to avoid
- // signed-int32 overflow that would sign-extend to a negative base.
- const int64_t splat_index =
- pnode->info().splat_index() * bytes_per_lane;
- const int64_t offset = splat_index + load.offset;
-
- V<WordPtr> base = __ WordPtrAdd(__ MapToNewGraph(load.base()),
- __ IntPtrConstant(offset));
-
- V<WordPtr> index = load.index().has_value()
- ? __ MapToNewGraph(load.index().value())
- : __ IntPtrConstant(0);
-
- const Simd256LoadTransformOp::TransformKind transform_kind =
- is_32 ? Simd256LoadTransformOp::TransformKind::k32Splat
- : Simd256LoadTransformOp::TransformKind::k64Splat;
- og_index = __ Simd256LoadTransform(base, index, load.kind,
- transform_kind, 0);
- pnode->SetRevectorizedNode(og_index);
- break;
- }
- case ShufflePackNode::SpecificInfo::Kind::kS256Load8x8U: {
- const Simd128ShuffleOp& op0 = __ input_graph()
- .Get(pnode -> nodes()[0])
- .template Cast<Simd128ShuffleOp>();
-
- V<Simd128> load_transform_idx =
- __ input_graph()
- .Get(op0.left())
- .template Is<Simd128LoadTransformOp>()
- ? op0.left()
- : op0.right();
- const Simd128LoadTransformOp& load_transform =
- __ input_graph()
- .Get(load_transform_idx)
- .template Cast<Simd128LoadTransformOp>();
- DCHECK_EQ(load_transform.transform_kind,
- Simd128LoadTransformOp::TransformKind::k64Zero);
- V<WordPtr> base = __ MapToNewGraph(load_transform.base());
- V<WordPtr> index = __ MapToNewGraph(load_transform.index());
- og_index = __ Simd256LoadTransform(
- base, index, load_transform.load_kind,
- Simd256LoadTransformOp::TransformKind::k8x8U,
- load_transform.offset);
- pnode->SetRevectorizedNode(og_index);
- break;
- }
+ case ShufflePackNode::SpecificInfo::Kind::kS256Load64Transform:
+ case ShufflePackNode::SpecificInfo::Kind::kS256Load8x8U:
+ UNREACHABLE();
#ifdef V8_TARGET_ARCH_X64
case ShufflePackNode::SpecificInfo::Kind::kShufd: {
V<Simd256> og_left = analyzer_.GetReducedInput(pnode, 0);
@@ -1211,11 +1278,11 @@ class WasmRevecReducer : public UniformReducerAdapter<WasmRevecReducer, Next> {
while (!inputs.empty()) {
OpIndex idx = inputs.front();
inputs.pop_front();
- visited.insert(idx);
const Operation& op = __ input_graph().Get(idx);
for (OpIndex input : op.inputs()) {
- if (input > start_marker && !visited.contains(input)) {
+ if (input > start_marker) {
+ if (!visited.insert(input).second) continue;
inputs.push_back(input);
}
}
diff --git a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc
index 8200263867f..f21c0cd6e76 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.cc
@@ -215,6 +215,134 @@ void DemandedByteAnalysis::Revisit() {
revisit_limit_reached_ = false;
}
+WasmShuffleAnalyzer::Reduction::SearchResult
+WasmShuffleAnalyzer::Reduction::Search(const Operation& op) {
+ if (auto binop = op.TryCast<Simd128BinopOp>()) {
+ return Search(*binop);
+ } else if (auto phi = op.TryCast<PhiOp>()) {
+ return Search(*phi);
+ }
+ return SearchResult::kContinue;
+}
+
+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());
+ return SimdShuffle::TryMatchCanonical(shuffle_bytes) ==
+ SimdShuffle::CanonicalShuffle::kS16x8TopBottomInterleave;
+ }
+ return false;
+}
+} // end namespace
+
+WasmShuffleAnalyzer::Reduction::SearchResult
+WasmShuffleAnalyzer::Reduction::Search(const Simd128BinopOp& binop) {
+ // Starting at the input to an I32x4AddReduce, walk backwards through a
+ // reduction tree:
+ // * I32x4Add keeps the search inside the tree by visiting both inputs.
+ // * I32x4DotI8x16S is a leaf candidate. We only record it when both inputs
+ // are the canonical generated shuffle used before dot-product lowering.
+ //
+ // Dots already accepted by an earlier reduction search abort this search.
+ //
+ // Example:
+ // -----
+ // | |
+ // v |
+ // Phi |
+ // Sub Dot / |
+ // \ / / |
+ // Mul Dot Add / ^
+ // \ / \ / |
+ // Add Add |
+ // \ / |
+ // Add -------->-----
+ // |
+ // AddReduce
+ // TODO(sparker): Is it worth exploring through Sub operations?
+
+ OpIndex binop_index = input_graph().Index(binop);
+ if (!visited_.insert(binop_index).second) return SearchResult::kContinue;
+
+ if (binop.kind != Simd128BinopOp::Kind::kI32x4Add &&
+ binop.kind != Simd128BinopOp::Kind::kI32x4DotI8x16S) {
+ return SearchResult::kContinue;
+ }
+
+ nodes_.insert(binop_index);
+
+ const Operation& left = input_graph().Get(binop.left());
+ const Operation& right = input_graph().Get(binop.right());
+
+ if (binop.kind == Simd128BinopOp::Kind::kI32x4Add) {
+ if (Search(left) == SearchResult::kAbort) return SearchResult::kAbort;
+ if (Search(right) == SearchResult::kAbort) return SearchResult::kAbort;
+ } else if (binop.kind == Simd128BinopOp::Kind::kI32x4DotI8x16S) {
+ if (existing_dot_candidates_.contains(binop_index)) {
+ TRACE("Aborting reduction search at already discovered dot %d\n",
+ binop_index.id());
+ dot_candidates_.clear();
+ return SearchResult::kAbort;
+ }
+ auto shuffle_left = left.TryCast<Simd128ShuffleOp>();
+ auto shuffle_right = right.TryCast<Simd128ShuffleOp>();
+ if (IsTopBottomInterleave(shuffle_left) &&
+ IsTopBottomInterleave(shuffle_right)) {
+ // When we generate kI32x4DotI8x16S, we use shuffles to reorder the
+ // inputs to preserve the semantics. But now that we've discovered that
+ // the result is being horizontally reduced, we know the order of the
+ // summation is not important. So, we can remove those shuffles.
+ TRACE("Found a Dot candidate: %d\n", input_graph().Index(binop).id());
+ dot_candidates_.emplace_back(input_graph().Index(binop),
+ shuffle_left->left(), shuffle_right->left());
+ }
+ }
+ return SearchResult::kContinue;
+}
+
+WasmShuffleAnalyzer::Reduction::SearchResult
+WasmShuffleAnalyzer::Reduction::Search(const PhiOp& phi) {
+ // We search through phis so we can support an in-loop reduction, and the
+ // search supports unrolled loops too.
+ OpIndex phi_index = input_graph().Index(phi);
+ if (!visited_.insert(phi_index).second) return SearchResult::kContinue;
+
+ nodes_.insert(phi_index);
+ TRACE("Found new phi %d\n", phi_index.id());
+ for (OpIndex input : phi.inputs()) {
+ if (Search(input_graph().Get(input)) == SearchResult::kAbort) {
+ return SearchResult::kAbort;
+ }
+ }
+ return SearchResult::kContinue;
+}
+
+// Iterate through all the discovered nodes and look at their users, which we
+// should have discovered them all. The other manual checks are for reduce node
+// users.
+bool WasmShuffleAnalyzer::Reduction::UsesStayInReduction(
+ const Simd128UseMap& use_map) const {
+ for (OpIndex node : nodes_) {
+ for (OpIndex use : use_map.uses(node)) {
+ if (nodes_.contains(use)) continue;
+ const Operation& use_op = input_graph().Get(use);
+ if (use_op.saturated_use_count.Is(0) && !use_op.IsRequiredWhenUnused()) {
+ continue;
+ }
+ // We allow any other I32x4AddReduce operation that we didn't discover as
+ // part of the search.
+ if (const Simd128ReduceOp* reduce = use_op.TryCast<Simd128ReduceOp>()) {
+ if (reduce->kind == Simd128ReduceOp::Kind::kI32x4AddReduce) continue;
+ }
+ TRACE("Reduction node %d has outside user %d\n", node.id(), use.id());
+ return false;
+ }
+ }
+ return true;
+}
+
void WasmShuffleAnalyzer::Run() {
TRACE("Running WasmShuffleAnalyzer\n");
for (uint32_t processed = input_graph().block_count(); processed > 0;
@@ -267,6 +395,11 @@ void WasmShuffleAnalyzer::Process(const Operation& op) {
ProcessLaneMemory(*lane_op);
return;
}
+
+ if (auto* reduce_op = op.TryCast<Simd128ReduceOp>()) {
+ ProcessReduce(*reduce_op);
+ return;
+ }
}
void WasmShuffleAnalyzer::ProcessUnary(const Simd128UnaryOp& unop) {
@@ -304,13 +437,38 @@ void WasmShuffleAnalyzer::ProcessLaneMemory(
demanded_byte_analysis_.AddOp(lane_op, DemandedBytes::All());
}
+void WasmShuffleAnalyzer::ProcessReduce(const Simd128ReduceOp& reduce_op) {
+#if V8_TARGET_ARCH_ARM64
+ if (reduce_op.kind != Simd128ReduceOp::Kind::kI32x4AddReduce) return;
+
+ Reduction reduction(input_graph(), dot_candidate_nodes_, phase_zone_);
+ // We use a Simd128UseMap to validate that none of the nodes in the reduction
+ // are used outside of the tree that we've discovered. Creating the map is
+ // quite expensive so only do it once we've discovered a candidate reduction.
+ TRACE("Searching from I32x4AddReduce op %d\n",
+ input_graph().Index(reduce_op).id());
+ if (reduction.Search(input_graph().Get(reduce_op.input())) !=
+ Reduction::SearchResult::kAbort &&
+ !reduction.candidates().empty() &&
+ reduction.UsesStayInReduction(GetOrCreateUseMap())) {
+ TRACE("Found valid reduction:\n");
+ for (const auto& candidate : reduction.candidates()) {
+ bool inserted = dot_candidate_nodes_.insert(candidate.dot).second;
+ DCHECK(inserted);
+ USE(inserted);
+ TRACE(" - with dot %d\n", candidate.dot.id());
+ dot_candidates_.push_back(candidate);
+ }
+ }
+#endif // V8_TARGET_ARCH_ARM64
+}
+
namespace {
struct ShuffleWindows {
WasmShuffleAnalyzer::ShuffleWindow shuffle_out_window;
WasmShuffleAnalyzer::ShuffleWindow shuffle_in_window;
};
-
// Searches for a contiguous window of size `shuffle_in_demanded` within
// `shuffle` such that all elements in the window are sourced from `side`, and
// all elements outside of the window are sourced from the other side. Returns
@@ -411,6 +569,11 @@ bool WasmShuffleAnalyzer::ProcessShuffleOfShuffle(
// shuffle_out will be added to the shuffles_to_read_shifted list which will
// update its shuffle array to look at indices 0 and 1, instead of 2 and 3.
+ // If shuffle_out is already scheduled to be shifted to expose a specific
+ // window at index 0, its unshifted elements cannot be used as shuffle_out
+ // without conflicting coordinate transformations.
+ if (IsShuffleToShift(shuffle_out)) return false;
+
DemandedBytes shuffle_out_demanded = GetDemandedBytes(&shuffle_out);
std::span<const uint8_t> shuffle_out_bytes(shuffle_out.shuffle,
shuffle_out_demanded.bytes());
@@ -605,11 +768,14 @@ void WasmShuffleAnalyzer::ProcessShuffleOfLoads(const Simd128ShuffleOp& shuffle,
void WasmShuffleAnalyzer::TryReduceFromMSB(OpIndex input,
const Simd128ShuffleOp& shuffle,
const ShuffleSide side) {
- DemandedBytes demanded = GetDemandedBytes(&shuffle);
+ const ShuffleWindow* shift_window = FindShiftWindow(shuffle);
+ uint8_t start_index = shift_window ? shift_window->begin_index() : 0;
+ uint8_t count = shift_window ? shift_window->OutputDemanded().bytes()
+ : GetDemandedBytes(&shuffle).bytes();
std::optional<uint8_t> max = {};
- for (unsigned i = 0; i < demanded.bytes(); ++i) {
- uint8_t index = shuffle.shuffle[i];
+ for (unsigned i = 0; i < count; ++i) {
+ uint8_t index = shuffle.shuffle[start_index + i];
if (InRange(index, side)) {
max = std::max(static_cast<uint8_t>(index % kSimd128Size),
max.value_or(uint8_t{0}));
diff --git a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h
index ae4dfaa09dc..49be8879c1b 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-shuffle-reducer.h
@@ -17,6 +17,7 @@
#include "src/compiler/turboshaft/operations.h"
#include "src/compiler/turboshaft/opmasks.h"
#include "src/compiler/turboshaft/phase.h"
+#include "src/compiler/turboshaft/use-map.h"
#include "src/compiler/turboshaft/utils.h"
#include "src/zone/zone-containers.h"
@@ -360,6 +361,58 @@ class WasmShuffleAnalyzer {
DemandedBytes demanded_;
};
+ struct DotCandidate {
+ OpIndex dot;
+ OpIndex left;
+ OpIndex right;
+ };
+
+ // Represents one candidate dot-product reduction rooted at an
+ // I32x4AddReduce. The search walks backwards through a tree of I32x4Add,
+ // Phi, and I32x4DotI8x16S operations, collecting dots whose generated input
+ // shuffles can be removed. For each discovered Dot we may remove the input
+ // shuffles, which are introduced in the machine-optimization-reducer, because
+ // we know that we have a partial sum and each addition can be performed in
+ // any lane.
+ //
+ // The use map is intentionally not needed during the backwards search. It is
+ // created lazily only after the cheap search finds at least one dot, and is
+ // then used to prove that all live uses of the discovered add/Phi/dot nodes
+ // stay inside the reduction, except for I32x4AddReduce users.
+ class Reduction {
+ public:
+ enum class SearchResult { kContinue, kAbort };
+
+ Reduction(const Graph& graph,
+ const ZoneUnorderedSet<OpIndex>& existing_dot_candidates,
+ Zone* phase_zone)
+ : input_graph_(graph),
+ existing_dot_candidates_(existing_dot_candidates),
+ phase_zone_(phase_zone) {}
+ SearchResult Search(const Operation& op);
+ SearchResult Search(const Simd128BinopOp& binop);
+ SearchResult Search(const PhiOp& phi);
+ const Graph& input_graph() const { return input_graph_; }
+ const base::SmallVector<DotCandidate, 2>& candidates() const {
+ return dot_candidates_;
+ }
+ bool UsesStayInReduction(const Simd128UseMap& use_map) const;
+
+ private:
+ const Graph& input_graph_;
+ // The set of I32x4DotI8x16S operations that we've previously discovered
+ // in a different search.
+ const ZoneUnorderedSet<OpIndex>& existing_dot_candidates_;
+ Zone* phase_zone_;
+ // All the operations that we've discovered during the search.
+ ZoneUnorderedSet<OpIndex> visited_{phase_zone_};
+ // All the operations that are considered a part of the reduction, which
+ // are: I32x4Add, I32x4DotI8x16S and Phis.
+ ZoneUnorderedSet<OpIndex> nodes_{phase_zone_};
+ // The list of candidates that this search discovers.
+ base::SmallVector<DotCandidate, 2> dot_candidates_;
+ };
+
void ProcessShuffleOfLoads(const Simd128ShuffleOp& shfop, const LoadOp& left,
const LoadOp& right);
bool CouldLoadPair(const LoadOp& load0, const LoadOp& load1) const;
@@ -378,11 +431,16 @@ class WasmShuffleAnalyzer {
return {};
}
- WasmShuffleAnalyzer(Zone* phase_zone, const Graph& input_graph)
- : phase_zone_(phase_zone), input_graph_(input_graph) {
- Run();
+ std::optional<DotCandidate> GetDotCandidate(OpIndex node) {
+ for (auto& candidate : dot_candidates_) {
+ if (candidate.dot == node) return candidate;
+ }
+ return {};
}
+ WasmShuffleAnalyzer(Zone* phase_zone, const Graph& input_graph)
+ : phase_zone_(phase_zone), input_graph_(input_graph) {}
+
V8_EXPORT_PRIVATE void Run();
void Process(const Operation& op);
@@ -391,6 +449,7 @@ class WasmShuffleAnalyzer {
void ProcessReplaceLane(const Simd128ReplaceLaneOp& replace_op);
void ProcessExtractLane(const Simd128ExtractLaneOp& extract_op);
void ProcessLaneMemory(const Simd128LaneMemoryOp& lane_op);
+ void ProcessReduce(const Simd128ReduceOp& reduce_op);
void ProcessShuffle(const Simd128ShuffleOp& shuffle_op);
void TryReduceFromMSB(OpIndex input, const Simd128ShuffleOp& shuffle,
const ShuffleSide side);
@@ -401,7 +460,7 @@ class WasmShuffleAnalyzer {
bool ShouldReduce() const {
return !demanded_byte_analysis_.demanded_bytes().empty() ||
- !deinterleave_load_candidates_.empty() ||
+ !dot_candidates_.empty() || !deinterleave_load_candidates_.empty() ||
!load_lane_candidates_.empty() ||
!shuffles_to_read_shifted_.empty() || !shuffles_to_shift_.empty();
}
@@ -442,6 +501,17 @@ class WasmShuffleAnalyzer {
load_lanes_[replace] = load_lane;
}
+ const ShuffleWindow* FindShiftWindow(const Simd128ShuffleOp& shuffle) const {
+ for (const auto& window : shuffles_to_shift_) {
+ if (window.shuffle() == &shuffle) return &window;
+ }
+ return nullptr;
+ }
+
+ bool IsShuffleToShift(const Simd128ShuffleOp& shuffle) const {
+ return FindShiftWindow(shuffle) != nullptr;
+ }
+
const SmallZoneVector<ShuffleWindow, 8>& shuffles_to_shift() const {
return shuffles_to_shift_;
}
@@ -453,6 +523,13 @@ class WasmShuffleAnalyzer {
const Graph& input_graph() const { return input_graph_; }
private:
+ const Simd128UseMap& GetOrCreateUseMap() {
+ if (use_map_ == nullptr) {
+ use_map_ = phase_zone_->New<Simd128UseMap>(input_graph_, phase_zone_);
+ }
+ return *use_map_;
+ }
+
std::optional<const Simd128ShuffleOp*> GetOtherShuffleUser(
const LoadOp& left, const LoadOp& right,
const SmallShuffleVector& shuffles) const {
@@ -471,6 +548,7 @@ class WasmShuffleAnalyzer {
Zone* phase_zone_;
const Graph& input_graph_;
DemandedByteAnalysis demanded_byte_analysis_{phase_zone_, input_graph_};
+ Simd128UseMap* use_map_ = nullptr;
SmallZoneVector<ShuffleWindow, 8> shuffles_to_shift_{phase_zone_};
SmallZoneVector<ShuffleWindow, 8> shuffles_to_read_shifted_{phase_zone_};
ZoneUnorderedMap<const LoadOp*, const Simd128ReplaceLaneOp*>
@@ -486,12 +564,14 @@ class WasmShuffleAnalyzer {
SmallShuffleVector even_8x16_shuffles_{phase_zone_};
SmallShuffleVector odd_8x16_shuffles_{phase_zone_};
base::SmallVector<DeinterleaveLoadCandidate, 8> deinterleave_load_candidates_;
+ ZoneUnorderedSet<OpIndex> dot_candidate_nodes_{phase_zone_};
+ base::SmallVector<DotCandidate, 4> dot_candidates_;
};
template <class Next>
class WasmShuffleReducer : public Next {
private:
- std::optional<WasmShuffleAnalyzer> analyzer_;
+ WasmShuffleAnalyzer* analyzer_ = nullptr;
struct DeinterleaveLoadShuffle {
const Simd128ShuffleOp* shuffle;
@@ -538,11 +618,34 @@ class WasmShuffleReducer : public Next {
TURBOSHAFT_REDUCER_BOILERPLATE(WasmShuffleReducer)
void Analyze() {
- analyzer_.emplace(__ phase_zone(), __ input_graph());
- analyzer_->Run();
+ PipelineData* data = __ data();
+ if (data->has_wasm_shuffle_analyzer()) {
+ analyzer_ = data->wasm_shuffle_analyzer();
+ } else {
+ Zone* phase_zone = __ phase_zone();
+ analyzer_ = phase_zone->template New<WasmShuffleAnalyzer>(
+ phase_zone, __ input_graph());
+ analyzer_->Run();
+ }
Next::Analyze();
}
+ OpIndex REDUCE_INPUT_GRAPH(Simd128Binop)(OpIndex ig_index,
+ const Simd128BinopOp& binop) {
+ LABEL_BLOCK(no_change) {
+ return Next::ReduceInputGraphSimd128Binop(ig_index, binop);
+ }
+ if (ShouldSkipOptimizationStep()) goto no_change;
+
+ if (auto maybe_dot = analyzer_->GetDotCandidate(ig_index)) {
+ return __ Simd128Binop(__ MapToNewGraph(maybe_dot->left),
+ __ MapToNewGraph(maybe_dot->right),
+ Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ }
+
+ goto no_change;
+ }
+
OpIndex REDUCE_INPUT_GRAPH(Simd128ReplaceLane)(
OpIndex ig_index, const Simd128ReplaceLaneOp& replace_lane) {
if (!ShouldSkipOptimizationStep()) {
diff --git a/deps/v8/src/compiler/turboshaft/wasm-simd-phase.cc b/deps/v8/src/compiler/turboshaft/wasm-simd-phase.cc
index b014a3f455b..b52a6820fe4 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-simd-phase.cc
+++ b/deps/v8/src/compiler/turboshaft/wasm-simd-phase.cc
@@ -11,6 +11,7 @@ namespace v8::internal::compiler::turboshaft {
void WasmSimdPhase::Run(PipelineData* data, Zone* temp_zone) {
WasmShuffleAnalyzer analyzer(temp_zone, data->graph());
+ analyzer.Run();
if (analyzer.ShouldReduce()) {
data->set_wasm_shuffle_analyzer(&analyzer);
diff --git a/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h b/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h
index c8ead36f28c..d15cb3b948c 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-wrappers-inl.h
@@ -335,8 +335,13 @@ auto WasmWrapperTSGraphBuilder<Assembler>::BuildJSToWasmWrapper(
base::SmallVector<OpIndex, 16> args(args_count);
args[0] = instance_data;
for (int i = 0; i < wasm_param_count; ++i) {
- args[i + 1] =
+ OptionalOpIndex arg =
FromJS(params[i], js_context, sig_->GetParam(i), caller_frame_state);
+ if (!arg.has_value()) {
+ DCHECK(__ generating_unreachable_operations());
+ return OpIndex::Invalid();
+ }
+ args[i + 1] = arg.value();
}
// Inline the Wasm function body, if possible.
@@ -560,19 +565,29 @@ void WasmWrapperTSGraphBuilder<Assembler>::BuildWasmToJSWrapper(
// Convert the return value(s) back.
OpIndex val;
base::SmallVector<OpIndex, 8> wasm_values;
- if (sig_->return_count() <= 1) {
- val = sig_->return_count() == 0
- ? __ Word32Constant(0)
- : FromJS(call, native_context, sig_->GetReturn());
+ if (sig_->return_count() == 0) {
+ val = __ Word32Constant(0);
+ } else if (sig_->return_count() == 1) {
+ OptionalOpIndex from_js_val =
+ FromJS(call, native_context, sig_->GetReturn());
+ if (!from_js_val.has_value()) return;
+ val = from_js_val.value();
} else {
V<FixedArray> fixed_array =
BuildMultiReturnFixedArrayFromIterable(call, native_context);
wasm_values.resize(sig_->return_count());
for (unsigned i = 0; i < sig_->return_count(); ++i) {
- wasm_values[i] = FromJS(__ LoadFixedArrayElement(fixed_array, i),
- native_context, sig_->GetReturn(i));
+ OptionalOpIndex from_js_val =
+ FromJS(__ LoadFixedArrayElement(fixed_array, i), native_context,
+ sig_->GetReturn(i));
+ if (!from_js_val.has_value()) {
+ DCHECK(__ generating_unreachable_operations());
+ return;
+ }
+ wasm_values[i] = from_js_val.value();
}
}
+
this->BuildSwitchBackFromCentralStack(old_sp, old_limit);
if (sig_->return_count() <= 1) {
__ Return(val);
diff --git a/deps/v8/src/compiler/turboshaft/wasm-wrappers.h b/deps/v8/src/compiler/turboshaft/wasm-wrappers.h
index e3e6c9dbf8d..3bccdab1a64 100644
--- a/deps/v8/src/compiler/turboshaft/wasm-wrappers.h
+++ b/deps/v8/src/compiler/turboshaft/wasm-wrappers.h
@@ -181,6 +181,422 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
return result;
}
+ // Returns the Word32 value equal to `input` if `input` is in i31 range,
+ // otherwise jumps to `not_i31`.
+ void CanonicalizeHeapNumber(V<HeapNumber> input, Block* not_i31,
+ ScopedVar<Object>& result) {
+ V<Float64> float_value = __ LoadHeapNumberValue(input);
+
+ // Check if value is integral.
+ V<Word32> int_value =
+ __ TruncateFloat64ToInt32OverflowUndefined(float_value);
+ V<Word32> is_integral =
+ __ Float64Equal(float_value, __ ChangeInt32ToFloat64(int_value));
+ __ GotoIfNot(is_integral, not_i31);
+
+ // Check if value is -0.
+ Block* is_zero = __ NewBlock();
+ Block* is_not_zero = __ NewBlock();
+ Block* done = __ NewBlock();
+ __ Branch(__ Word32Equal(int_value, 0), is_zero, is_not_zero);
+
+ __ Bind(is_zero);
+ V<Word32> is_minus_zero =
+ __ Int32LessThan(__ Float64ExtractHighWord32(float_value), 0);
+ __ Branch(is_minus_zero, not_i31, done);
+
+ __ Bind(is_not_zero);
+ // Check range of float value.
+ V<Word32> in_range = __ Word32BitwiseAnd(
+ __ Float64LessThanOrEqual(__ Float64Constant(wasm::kInt31MinValue),
+ float_value),
+ __ Float64LessThanOrEqual(float_value,
+ __ Float64Constant(wasm::kInt31MaxValue)));
+ __ Branch(in_range, done, not_i31);
+
+ __ Bind(done);
+ result = __ TagSmi(int_value);
+ }
+
+ // If the object is shared, sets `result = input`, otherwise falls back to
+ // `fallback`.
+ void EnsureObjectShareness(V<HeapObject> input, Block* done, Block* fallback,
+ ScopedVar<Object>& result) {
+#if CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
+ // Bail out for read-only objects.
+ V<Word32> lower32 =
+ __ TruncateWordPtrToWord32(__ BitcastTaggedToWordPtr(input));
+ IF (__ Uint32LessThan(lower32, __ Word32Constant(static_cast<uint32_t>(
+ kContiguousReadOnlyReservationSize)))) {
+ result = input;
+ __ Goto(done);
+ }
+ // Bail out for already-shared objects.
+ V<WordPtr> flags = __ LoadPageFlags(input);
+ V<WordPtr> page_flags = __ WordPtrBitwiseAnd(
+ flags, static_cast<uintptr_t>(MemoryChunk::kInSharedHeap));
+#else // !CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
+ V<WordPtr> flags = __ LoadPageFlags(input);
+ V<WordPtr> page_flags = __ WordPtrBitwiseAnd(
+ flags,
+ static_cast<uintptr_t>(MemoryChunk::kIsReadOnlyOrSharedHeapMask));
+#endif // !CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
+ IF (UNLIKELY(__ WordPtrEqual(page_flags, 0))) {
+ // If it isn't shared, yet, use the runtime function.
+ __ Goto(fallback);
+ }
+ result = input;
+ __ Goto(done);
+ }
+
+ // Checks that the object is shared or not according to `type`. If not, jumps
+ // to `type_error`. Assumes the object cannot be allocated in read-only space.
+ void CheckWasmObjectSharedness(V<Object> input, CanonicalValueType type,
+ Block* type_error) {
+ if (v8_flags.wasm_shared) {
+ V<WordPtr> flags = __ LoadPageFlags(V<HeapObject>::Cast(input));
+ V<WordPtr> page_flags = __ WordPtrBitwiseAnd(
+ flags, static_cast<uintptr_t>(MemoryChunk::kInSharedHeap));
+ if (type.is_shared()) {
+ __ GotoIf(__ WordPtrEqual(page_flags, 0), type_error);
+ } else {
+ __ GotoIfNot(__ WordPtrEqual(page_flags, 0), type_error);
+ }
+#ifdef DEBUG
+#if CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
+ // Wasm GC objects (structs/arrays) are currently never allocated in
+ // read-only space. Verify this invariant to guard against future changes
+ // where constant Wasm objects might be placed in RO space.
+ V<Word32> lower32 = __ TruncateWordPtrToWord32(
+ __ BitcastTaggedToWordPtr(V<HeapObject>::Cast(input)));
+ // TSA_DCHECK is only usable in isolate-dependent code.
+ if (__ data()->isolate() != nullptr) {
+ TSA_DCHECK(this, __ Uint32LessThanOrEqual(
+ __ Word32Constant(static_cast<uint32_t>(
+ kContiguousReadOnlyReservationSize)),
+ lower32));
+ }
+#endif // CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
+#endif // DEBUG
+ }
+ }
+
+ void CheckSmiInI31Range(V<Smi> input, Block* done, Block* not_in_range,
+ ScopedVar<Object>& result) {
+ if constexpr (SmiValuesAre31Bits()) {
+ result = input;
+ __ Goto(done);
+ } else {
+ V<Word32> val = __ UntagSmi(input);
+ V<Word32> in_range = __ Word32BitwiseAnd(
+ __ Int32LessThanOrEqual(wasm::kInt31MinValue, val),
+ __ Int32LessThanOrEqual(val, wasm::kInt31MaxValue));
+ result = input;
+ __ GotoIf(in_range, done);
+ __ Goto(not_in_range);
+ }
+ }
+
+ V<Object> BuildCheckExternRef(V<Object> input, V<Context> context,
+ CanonicalValueType type) {
+ if (type.is_non_nullable()) {
+ IF (UNLIKELY(__ TaggedEqual(
+ input, __ template LoadRoot<RootIndex::kNullValue>()))) {
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
+ context);
+ __ Unreachable();
+ }
+ }
+ if (v8_flags.wasm_shared && type.is_shared()) {
+ Block* done = __ NewBlock();
+ Block* fallback = __ NewBlock();
+ ScopedVar<Object> result(this, input);
+ IF (__ IsSmi(input)) {
+ __ Goto(done);
+ }
+
+ EnsureObjectShareness(V<HeapObject>::Cast(input), done, fallback, result);
+
+ __ Bind(fallback);
+ std::initializer_list<const OpIndex> inputs = {
+ input,
+ __ SmiConstant(Smi::FromInt(static_cast<int>(type.raw_bit_field())))};
+ result = __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmJSToWasmObject,
+ inputs, context);
+ __ Goto(done);
+
+ __ Bind(done);
+ return result;
+ } else {
+ return input;
+ }
+ }
+
+ V<Object> BuildCheckAnyRef(V<Object> input, V<Context> context,
+ CanonicalValueType type) {
+ Block* done = __ NewBlock();
+ Block* type_error = __ NewBlock();
+ Block* process_smi = __ NewBlock();
+ Block* process_heap_number = __ NewBlock();
+ Block* ensure_sharedness = __ NewBlock();
+ Block* fallback = __ NewBlock();
+
+ DCHECK(type.use_wasm_null());
+ ScopedVar<Object> result(this,
+ __ template LoadRoot<RootIndex::kWasmNull>());
+
+ // null is not allowed for non-nullable (ref any).
+ __ GotoIf(
+ __ TaggedEqual(input, __ template LoadRoot<RootIndex::kNullValue>()),
+ type.is_nullable() ? done : type_error);
+
+ __ GotoIf(__ IsSmi(input), process_smi);
+
+ __ GotoIf(__ HasInstanceType(input, HEAP_NUMBER_TYPE), process_heap_number);
+
+ __ Goto(ensure_sharedness);
+
+ __ Bind(process_smi);
+ CheckSmiInI31Range(V<Smi>::Cast(input), done, fallback, result);
+
+ __ Bind(process_heap_number);
+ CanonicalizeHeapNumber(V<HeapNumber>::Cast(input), ensure_sharedness,
+ result);
+ __ Goto(done);
+
+ __ Bind(ensure_sharedness);
+ if (v8_flags.wasm_shared && type.is_shared()) {
+ EnsureObjectShareness(V<HeapObject>::Cast(input), done, fallback, result);
+ } else {
+ result = input;
+ __ Goto(done);
+ }
+
+ __ Bind(fallback);
+ // Make sure ValueType fits in a Smi.
+ static_assert(wasm::ValueType::kLastUsedBit + 1 <= kSmiValueSize);
+ std::initializer_list<const OpIndex> inputs = {
+ input,
+ __ SmiConstant(Smi::FromInt(static_cast<int>(type.raw_bit_field())))};
+ result = __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmJSToWasmObject,
+ inputs, context);
+ __ Goto(done);
+
+ __ Bind(type_error);
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
+ context);
+ __ Unreachable();
+
+ __ Bind(done);
+ return result;
+ }
+
+ V<Object> BuildCheckEqRef(V<Object> input, V<Context> js_context,
+ CanonicalValueType type) {
+ Block* done = __ NewBlock();
+ Block* type_error = __ NewBlock();
+ Block* check_number = __ NewBlock();
+ DCHECK(type.use_wasm_null());
+ ScopedVar<Object> result(this,
+ __ template LoadRoot<RootIndex::kWasmNull>());
+
+ if (type.is_nullable()) {
+ __ GotoIf(
+ __ TaggedEqual(input, __ template LoadRoot<RootIndex::kNullValue>()),
+ done);
+ }
+
+ __ GotoIf(__ IsSmi(input), check_number);
+
+ V<Map> map = LoadMap(input);
+ V<Word32> instance_type = __ LoadInstanceTypeField(map);
+ V<Word32> is_wasm_object =
+ __ Word32BitwiseOr(__ Word32Equal(instance_type, WASM_STRUCT_TYPE),
+ __ Word32Equal(instance_type, WASM_ARRAY_TYPE));
+ __ GotoIfNot(is_wasm_object, check_number, BranchHint::kTrue);
+
+ CheckWasmObjectSharedness(input, type, type_error);
+
+ result = input;
+ __ Goto(done);
+
+ __ Bind(check_number);
+ BuildCheckI31Impl(input, result, done, type_error);
+
+ __ Bind(type_error);
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
+ js_context);
+ __ Unreachable();
+
+ __ Bind(done);
+ return result;
+ }
+
+ void BuildCheckI31Impl(V<Object> input, ScopedVar<Object>& result,
+ Block* done, Block* type_error) {
+ Block* is_heap_object = __ NewBlock();
+ __ GotoIfNot(__ IsSmi(input), is_heap_object);
+
+ CheckSmiInI31Range(V<Smi>::Cast(input), done, type_error, result);
+
+ __ Bind(is_heap_object);
+ __ GotoIfNot(__ HasInstanceType(input, HEAP_NUMBER_TYPE), type_error);
+
+ CanonicalizeHeapNumber(V<HeapNumber>::Cast(input), type_error, result);
+ __ Goto(done);
+ }
+
+ V<Object> BuildCheckI31Ref(V<Object> input, V<Context> js_context,
+ CanonicalValueType type) {
+ Block* done = __ NewBlock();
+ Block* type_error = __ NewBlock();
+ ScopedVar<Object> result(this,
+ __ template LoadRoot<RootIndex::kWasmNull>());
+
+ if (type.is_nullable()) {
+ __ GotoIf(
+ __ TaggedEqual(input, __ template LoadRoot<RootIndex::kNullValue>()),
+ done);
+ }
+
+ BuildCheckI31Impl(input, result, done, type_error);
+
+ __ Bind(type_error);
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
+ js_context);
+ __ Unreachable();
+
+ __ Bind(done);
+ return result;
+ }
+
+ V<Object> BuildCheckWasmObject(V<Object> input, V<Context> js_context,
+ CanonicalValueType type,
+ InstanceType instance_type) {
+ Block* done = __ NewBlock();
+ Block* type_error = __ NewBlock();
+ DCHECK(type.use_wasm_null());
+ ScopedVar<Object> result(this,
+ __ template LoadRoot<RootIndex::kWasmNull>());
+
+ __ GotoIf(__ IsSmi(input), type_error, BranchHint::kFalse);
+
+ if (type.is_nullable()) {
+ __ GotoIf(
+ __ TaggedEqual(input, __ template LoadRoot<RootIndex::kNullValue>()),
+ done);
+ }
+
+ V<Map> map = LoadMap(input);
+ V<Word32> is_wasm_object_of_instance_type =
+ __ Word32Equal(__ LoadInstanceTypeField(map), instance_type);
+ __ GotoIfNot(is_wasm_object_of_instance_type, type_error,
+ BranchHint::kTrue);
+
+ CheckWasmObjectSharedness(input, type, type_error);
+
+ result = input;
+ __ Goto(done);
+
+ __ Bind(type_error);
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
+ js_context);
+ __ Unreachable();
+
+ __ Bind(done);
+ return result;
+ }
+
+ V<Object> BuildCheckIndexedStructOrArray(V<Object> input, V<Context> context,
+ CanonicalValueType type) {
+ Block* done = __ NewBlock();
+ Block* mismatch = __ NewBlock();
+
+ ScopedVar<Object> result(this,
+ __ template LoadRoot<RootIndex::kWasmNull>());
+
+ __ GotoIf(__ IsSmi(input), mismatch, BranchHint::kFalse);
+
+ if (type.is_nullable()) {
+ __ GotoIf(
+ __ TaggedEqual(input, __ template LoadRoot<RootIndex::kNullValue>()),
+ done);
+ }
+
+ V<Map> object_map = LoadMap(input);
+ // Fetch the canonical-types array from isolate roots.
+ V<WeakFixedArray> canonical_rtts =
+ __ template LoadRoot<RootIndex::kWasmCanonicalRtts>();
+ V<Object> cached_map = V<Object>::Cast(__ LoadField(
+ canonical_rtts, compiler::AccessBuilder::ForWeakFixedArraySlot(
+ type.ref_index().index)));
+ V<Map> supertype_rtt =
+ __ template BitcastWordPtrToTagged<Map>(__ WordPtrBitwiseAnd(
+ __ BitcastTaggedToWordPtr(cached_map), ~kWeakHeapObjectMask));
+
+ IF (__ TaggedEqual(object_map, supertype_rtt)) {
+ result = input;
+ __ Goto(done);
+ }
+
+ if (type.is_exact()) {
+ __ Goto(mismatch);
+ } else {
+ wasm::TypeCanonicalizer* type_canonicalizer =
+ wasm::GetTypeCanonicalizer();
+
+ V<Word32> instance_type = __ LoadInstanceTypeField(object_map);
+
+ InstanceType expected_instance_type;
+ switch (type.ref_type_kind()) {
+ case wasm::RefTypeKind::kStruct:
+ expected_instance_type = WASM_STRUCT_TYPE;
+ break;
+ case wasm::RefTypeKind::kArray:
+ expected_instance_type = WASM_ARRAY_TYPE;
+ break;
+ case wasm::RefTypeKind::kCont:
+ case wasm::RefTypeKind::kFunction:
+ case wasm::RefTypeKind::kOther:
+ UNREACHABLE();
+ }
+
+ V<Word32> has_type_info =
+ __ Word32Equal(instance_type, expected_instance_type);
+
+ IF (has_type_info) {
+ uint8_t rtt_depth =
+ type_canonicalizer->GetSubtypingDepth_Slow(type.ref_index());
+
+ V<Object> type_info = __ LoadWasmTypeInfo(object_map);
+ V<Word32> supertypes_length = __ UntagSmi(
+ __ Load(type_info, LoadOp::Kind::TaggedBase().Immutable(),
+ MemoryRepresentation::TaggedSigned(),
+ offsetof(WasmTypeInfo, supertypes_length_)));
+
+ IF (__ Uint32LessThan(rtt_depth, supertypes_length)) {
+ V<Object> maybe_match = __ Load(
+ type_info, LoadOp::Kind::TaggedBase().Immutable(),
+ MemoryRepresentation::TaggedPointer(),
+ WasmTypeInfo::kSupertypesOffset + kTaggedSize * rtt_depth);
+ IF (__ TaggedEqual(maybe_match, supertype_rtt)) {
+ result = input;
+ __ Goto(done);
+ }
+ }
+ }
+ __ Goto(mismatch);
+ }
+
+ __ Bind(mismatch);
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError, {},
+ context);
+ __ Unreachable();
+
+ __ Bind(done);
+ return result;
+ }
+
V<Float32> BuildChangeTaggedToFloat32(
V<Object> value, V<Context> context,
OptionalV<EagerFrameState> caller_frame_state) {
@@ -342,8 +758,9 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
// passes, the BigIntToI64 builtin cannot throw (ToBigInt short-circuits
// for BigInt inputs, and the conversion is modular truncation).
// (crbug.com/498709150)
- OpIndex FromJS(V<Object> input, V<Context> context, CanonicalValueType type,
- OptionalV<EagerFrameState> caller_frame_state = {}) {
+ OptionalOpIndex FromJS(V<Object> input, V<Context> context,
+ CanonicalValueType type,
+ OptionalV<EagerFrameState> caller_frame_state = {}) {
if (type.is_numeric()) {
switch (type.numeric_kind()) {
case NumericKind::kI32:
@@ -375,67 +792,43 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
// lazy deopt on throw.
DCHECK_IMPLIES(caller_frame_state.valid(), type == wasm::kWasmExternRef);
switch (type.generic_kind()) {
- // TODO(14034): Add more fast paths?
- case GenericKind::kExtern: {
- if (type.is_non_nullable()) {
- IF (UNLIKELY(__ TaggedEqual(
- input, __ template LoadRoot<RootIndex::kNullValue>()))) {
- __ WasmCallRuntime(__ phase_zone(),
- Runtime::kWasmThrowJSTypeError, {}, context);
- __ Unreachable();
- }
- }
- if (v8_flags.wasm_shared && type.is_shared()) {
- Label<Object> done(&Asm());
- IF (__ IsSmi(input)) {
- GOTO(done, input);
- }
-#if CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
- // Bail out for read-only objects.
- V<Word32> lower32 = __ TruncateWordPtrToWord32(
- __ BitcastTaggedToWordPtr(V<HeapObject>::Cast(input)));
- IF (__ Uint32LessThan(lower32,
- __ Word32Constant(static_cast<uint32_t>(
- kContiguousReadOnlyReservationSize)))) {
- GOTO(done, input);
- }
- // Bail out for already-shared objects.
- V<WordPtr> flags = __ LoadPageFlags(V<HeapObject>::Cast(input));
- V<WordPtr> page_flags = __ WordPtrBitwiseAnd(
- flags, static_cast<uintptr_t>(MemoryChunk::kInSharedHeap));
-#else // !CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
- V<WordPtr> flags = __ LoadPageFlags(V<HeapObject>::Cast(input));
- V<WordPtr> page_flags = __ WordPtrBitwiseAnd(
- flags, static_cast<uintptr_t>(
- MemoryChunk::kIsReadOnlyOrSharedHeapMask));
-#endif // !CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
- IF (UNLIKELY(__ WordPtrEqual(page_flags, 0))) {
- // If it isn't shared, yet, use the runtime function.
- std::initializer_list<const OpIndex> inputs = {
- input, __ IntPtrConstant(
- IntToSmi(static_cast<int>(type.raw_bit_field())))};
- GOTO(done, __ WasmCallRuntime(__ phase_zone(),
- Runtime::kWasmJSToWasmObject,
- inputs, context));
- }
- GOTO(done, input);
- BIND(done, result);
- return result;
- }
- return input;
- }
+ // TODO(548685083): Add fast paths for function/continuation types?
+ case GenericKind::kExtern:
+ return BuildCheckExternRef(input, context, type);
case GenericKind::kString:
return BuildCheckString(input, context, type);
-
+ case GenericKind::kStruct:
+ return BuildCheckWasmObject(input, context, type, WASM_STRUCT_TYPE);
+ case GenericKind::kArray:
+ return BuildCheckWasmObject(input, context, type, WASM_ARRAY_TYPE);
+ case GenericKind::kI31:
+ return BuildCheckI31Ref(input, context, type);
+ case GenericKind::kEq:
+ return BuildCheckEqRef(input, context, type);
+ case GenericKind::kAny:
+ return BuildCheckAnyRef(input, context, type);
case GenericKind::kNoExtern:
case GenericKind::kNoFunc:
- case GenericKind::kNone:
+ case GenericKind::kNone: {
+ if (type.is_nullable()) {
+ Block* done = __ NewBlock();
+ V<Object> js_null = __ template LoadRoot<RootIndex::kNullValue>();
+ __ GotoIf(__ TaggedEqual(input, js_null), done);
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError,
+ {}, context);
+ __ Unreachable();
+ __ Bind(done);
+ return type.use_wasm_null()
+ ? __ template LoadRoot<RootIndex::kWasmNull>()
+ : js_null;
+ } else {
+ __ WasmCallRuntime(__ phase_zone(), Runtime::kWasmThrowJSTypeError,
+ {}, context);
+ __ Unreachable();
+ return OptionalOpIndex::Nullopt();
+ }
+ }
case GenericKind::kFunc:
- case GenericKind::kAny:
- case GenericKind::kEq:
- case GenericKind::kI31:
- case GenericKind::kStruct:
- case GenericKind::kArray:
break; // Fall through.
case GenericKind::kVoid:
@@ -456,7 +849,15 @@ class WasmWrapperTSGraphBuilder : public wasm::WasmGraphBuilderBase<Assembler> {
UNREACHABLE();
}
}
- // Both indexed and allow-listed generic references get here.
+ // Both indexed types and remaining references to abstract types get here.
+
+ if (type.has_index() &&
+ (type.ref_type_kind() == wasm::RefTypeKind::kStruct ||
+ type.ref_type_kind() == wasm::RefTypeKind::kArray) &&
+ // TODO(manoskouk, jkummerow): Also implement descriptor support.
+ !wasm::GetTypeCanonicalizer()->has_descriptor(type.ref_index())) {
+ return BuildCheckIndexedStructOrArray(input, context, type);
+ }
// Make sure ValueType fits in a Smi.
static_assert(wasm::ValueType::kLastUsedBit + 1 <= kSmiValueSize);
diff --git a/deps/v8/src/compiler/wasm-gc-lowering.cc b/deps/v8/src/compiler/wasm-gc-lowering.cc
index 47fc630c050..79aa92f271e 100644
--- a/deps/v8/src/compiler/wasm-gc-lowering.cc
+++ b/deps/v8/src/compiler/wasm-gc-lowering.cc
@@ -120,7 +120,6 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) {
Node* control_input = NodeProperties::GetControlInput(node);
auto config = OpParameter<WasmTypeCheckConfig>(node->op());
int rtt_depth = wasm::GetSubtypingDepth(module_, config.to.ref_index());
- bool object_can_be_null = config.from.is_nullable();
bool object_can_be_i31 =
wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(), config.from, module_);
@@ -129,10 +128,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCheck(Node* node) {
auto end_label = gasm_.MakeLabel(MachineRepresentation::kWord32);
bool is_cast_from_any = config.from.is_reference_to(wasm::GenericKind::kAny);
- // If we are casting from any and null results in check failure, then the
- // {IsDataRefMap} check below subsumes the null check. Otherwise, perform
- // an explicit null check now.
- if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
+ if (config.from.is_nullable()) {
const int kResult = config.to.is_nullable() ? 1 : 0;
gasm_.GotoIf(IsNull(object, wasm::kWasmAnyRef), &end_label,
BranchHint::kFalse, gasm_.Int32Constant(kResult));
@@ -199,8 +195,6 @@ Reduction WasmGCLowering::ReduceWasmTypeCheckAbstract(Node* node) {
Node* effect_input = NodeProperties::GetEffectInput(node);
Node* control_input = NodeProperties::GetControlInput(node);
WasmTypeCheckConfig config = OpParameter<WasmTypeCheckConfig>(node->op());
- const bool object_can_be_null = config.from.is_nullable();
- const bool null_succeeds = config.to.is_nullable();
const bool object_can_be_i31 =
wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(), config.from, module_) ||
config.from.is_reference_to(wasm::GenericKind::kExtern);
@@ -219,10 +213,9 @@ Reduction WasmGCLowering::ReduceWasmTypeCheckAbstract(Node* node) {
break;
}
// Null checks performed by any other type check need control flow. We can
- // skip the null check if null fails, because it's covered by the Smi check
- // or instance type check we'll do later.
- if (object_can_be_null && null_succeeds) {
- const int kResult = null_succeeds ? 1 : 0;
+ // skip the null check if success is determined by a Smi check.
+ if (config.from.is_nullable() && config.to != wasm::kWasmRefI31) {
+ const int kResult = config.to.is_nullable() ? 1 : 0;
gasm_.GotoIf(IsNull(object, wasm::kWasmAnyRef), &end_label,
BranchHint::kFalse, gasm_.Int32Constant(kResult));
}
@@ -285,7 +278,6 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) {
Node* control_input = NodeProperties::GetControlInput(node);
auto config = OpParameter<WasmTypeCheckConfig>(node->op());
int rtt_depth = wasm::GetSubtypingDepth(module_, config.to.ref_index());
- bool object_can_be_null = config.from.is_nullable();
bool object_can_be_i31 =
wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(), config.from, module_);
@@ -294,10 +286,7 @@ Reduction WasmGCLowering::ReduceWasmTypeCast(Node* node) {
auto end_label = gasm_.MakeLabel();
bool is_cast_from_any = config.from.is_reference_to(wasm::GenericKind::kAny);
- // If we are casting from any and null results in check failure, then the
- // {IsDataRefMap} check below subsumes the null check. Otherwise, perform
- // an explicit null check now.
- if (object_can_be_null && (!is_cast_from_any || config.to.is_nullable())) {
+ if (config.from.is_nullable()) {
Node* is_null = IsNull(object, wasm::kWasmAnyRef);
if (config.to.is_nullable()) {
gasm_.GotoIf(is_null, &end_label, BranchHint::kFalse);
@@ -374,8 +363,6 @@ Reduction WasmGCLowering::ReduceWasmTypeCastAbstract(Node* node) {
Node* effect_input = NodeProperties::GetEffectInput(node);
Node* control_input = NodeProperties::GetControlInput(node);
WasmTypeCheckConfig config = OpParameter<WasmTypeCheckConfig>(node->op());
- const bool object_can_be_null = config.from.is_nullable();
- const bool null_succeeds = config.to.is_nullable();
const bool object_can_be_i31 =
wasm::IsSubtypeOf(wasm::kWasmI31Ref.AsNonNull(), config.from, module_) ||
config.from.is_reference_to(wasm::GenericKind::kExtern);
@@ -393,12 +380,17 @@ Reduction WasmGCLowering::ReduceWasmTypeCastAbstract(Node* node) {
UpdateSourcePosition(gasm_.effect(), node);
break;
}
- // Null checks performed by any other type cast can be skipped if null
- // fails, because it's covered by the Smi check
- // or instance type check we'll do later.
- if (object_can_be_null && null_succeeds &&
- !v8_flags.wasm_skip_null_checks) {
- gasm_.GotoIf(IsNull(object, config.from), &end_label, BranchHint::kFalse);
+ // Null checks performed by any other type cast can only be skipped if
+ // a Smi check is the only operation we'll need (i.e. the target type
+ // is non-nullable (ref i31).
+ if (config.from.is_nullable() && config.to != wasm::kWasmRefI31) {
+ Node* is_null = IsNull(object, config.from);
+ if (config.to.is_nullable()) {
+ gasm_.GotoIf(is_null, &end_label, BranchHint::kFalse);
+ } else if (!v8_flags.wasm_skip_null_checks) {
+ gasm_.TrapIf(is_null, TrapId::kTrapIllegalCast);
+ UpdateSourcePosition(gasm_.effect(), node);
+ }
}
if (to_kind == wasm::GenericKind::kI31) {
// If earlier optimization passes reached the limit of possible graph
@@ -535,11 +527,6 @@ Reduction WasmGCLowering::ReduceRttCanon(Node* node) {
FixedArray::OffsetOfElementAt(type_index) - kHeapObjectTag));
}
-namespace {
-constexpr int32_t kInt31MaxValue = 0x3fffffff;
-constexpr int32_t kInt31MinValue = -kInt31MaxValue - 1;
-} // namespace
-
Reduction WasmGCLowering::ReduceWasmAnyConvertExtern(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kWasmAnyConvertExtern);
Node* input = NodeProperties::GetValueInput(node, 0);
@@ -572,12 +559,12 @@ Reduction WasmGCLowering::ReduceWasmAnyConvertExtern(Node* node) {
Node* int_value = gasm_.BuildChangeSmiToInt32(input);
// Convert to heap number if the int32 does not fit into an i31ref.
- gasm_.GotoIf(
- gasm_.Int32LessThan(gasm_.Int32Constant(kInt31MaxValue), int_value),
- &to_heap_number_label);
- gasm_.GotoIf(
- gasm_.Int32LessThan(int_value, gasm_.Int32Constant(kInt31MinValue)),
- &to_heap_number_label);
+ gasm_.GotoIf(gasm_.Int32LessThan(gasm_.Int32Constant(wasm::kInt31MaxValue),
+ int_value),
+ &to_heap_number_label);
+ gasm_.GotoIf(gasm_.Int32LessThan(int_value,
+ gasm_.Int32Constant(wasm::kInt31MinValue)),
+ &to_heap_number_label);
gasm_.Goto(&end_label, input);
gasm_.Bind(&to_heap_number_label);
@@ -592,12 +579,12 @@ Reduction WasmGCLowering::ReduceWasmAnyConvertExtern(Node* node) {
MachineType::Float64(), input,
AccessBuilder::ForHeapNumberValue().offset - kHeapObjectTag);
// Check range of float value.
- gasm_.GotoIf(
- gasm_.Float64LessThan(float_value, gasm_.Float64Constant(kInt31MinValue)),
- &end_label, input);
- gasm_.GotoIf(
- gasm_.Float64LessThan(gasm_.Float64Constant(kInt31MaxValue), float_value),
- &end_label, input);
+ gasm_.GotoIf(gasm_.Float64LessThan(
+ float_value, gasm_.Float64Constant(wasm::kInt31MinValue)),
+ &end_label, input);
+ gasm_.GotoIf(gasm_.Float64LessThan(
+ gasm_.Float64Constant(wasm::kInt31MaxValue), float_value),
+ &end_label, input);
// Check if value is -0.
Node* is_minus_zero = nullptr;
if (mcgraph_->machine()->Is64()) {
diff --git a/deps/v8/src/compiler/wasm-inlining-into-js.cc b/deps/v8/src/compiler/wasm-inlining-into-js.cc
index a8ef32e1f4d..560e9b4f36e 100644
--- a/deps/v8/src/compiler/wasm-inlining-into-js.cc
+++ b/deps/v8/src/compiler/wasm-inlining-into-js.cc
@@ -27,6 +27,10 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
struct Value {
Node* node = nullptr;
wasm::ValueType type = wasm::kWasmBottom;
+
+ CheckForNull null_check() const {
+ return type.is_nullable() ? kWithNullCheck : kWithoutNullCheck;
+ }
};
public:
@@ -219,10 +223,8 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
return {};
}
const bool is_signed = opcode == wasm::kExprStructGetS;
- const CheckForNull null_check =
- struct_val.type.is_nullable() ? kWithNullCheck : kWithoutNullCheck;
Node* member = gasm_.StructGet(struct_val.node, struct_type, field_index,
- is_signed, null_check);
+ is_signed, struct_val.null_check());
SetSourcePosition(member);
return TypeNode(member, struct_type->field(field_index).Unpacked());
}
@@ -237,10 +239,8 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
is_inlineable_ = false;
return;
}
- const CheckForNull null_check =
- wasm_struct.type.is_nullable() ? kWithNullCheck : kWithoutNullCheck;
gasm_.StructSet(wasm_struct.node, value.node, struct_type, field_index,
- null_check);
+ wasm_struct.null_check());
SetSourcePosition(gasm_.effect());
}
@@ -254,29 +254,14 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
is_inlineable_ = false;
return {};
}
- auto done = gasm_.MakeLabel();
- // Abstract cast to array.
- if (input.type.is_nullable() && null_succeeds) {
- gasm_.GotoIf(gasm_.IsNull(input.node, input.type), &done);
- }
- gasm_.TrapIf(gasm_.IsSmi(input.node), TrapId::kTrapIllegalCast);
- gasm_.TrapUnless(gasm_.HasInstanceType(input.node, WASM_ARRAY_TYPE),
- TrapId::kTrapIllegalCast);
- SetSourcePosition(gasm_.effect());
- gasm_.Goto(&done);
- gasm_.Bind(&done);
- // Add TypeGuard for graph typing.
- TFGraph* graph = mcgraph_->graph();
- wasm::ValueType result_type = wasm::ValueType::Generic(
+ wasm::ValueType target_type = wasm::ValueType::Generic(
wasm::GenericKind::kArray,
null_succeeds ? wasm::kNullable : wasm::kNonNullable,
SharedFlag{false});
- Node* type_guard =
- graph->NewNode(mcgraph_->common()->TypeGuard(
- Type::Wasm(result_type, module_, graph->zone())),
- input.node, gasm_.effect(), gasm_.control());
- gasm_.InitializeEffectControl(type_guard, gasm_.control());
- return TypeNode(type_guard, result_type);
+ Node* cast =
+ gasm_.WasmTypeCastAbstract(input.node, {input.type, target_type});
+ SetSourcePosition(cast);
+ return TypeNode(cast, target_type);
}
wasm::ModuleTypeIndex target_type_index{static_cast<uint32_t>(heap_index)};
if (module_->has_signature(target_type_index)) {
@@ -311,9 +296,7 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
wasm::IndependentHeapType{wasm::GenericKind::kArray,
wasm::kNullable, SharedFlag{true}},
module_));
- const CheckForNull null_check =
- input.type.is_nullable() ? kWithNullCheck : kWithoutNullCheck;
- Node* len = gasm_.ArrayLength(input.node, null_check);
+ Node* len = gasm_.ArrayLength(input.node, input.null_check());
SetSourcePosition(len);
return TypeNode(len, wasm::kWasmI32);
}
@@ -327,10 +310,8 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
return {};
}
const bool is_signed = opcode == WasmOpcode::kExprArrayGetS;
- const CheckForNull null_check =
- array.type.is_nullable() ? kWithNullCheck : kWithoutNullCheck;
// Perform bounds check.
- Node* length = gasm_.ArrayLength(array.node, null_check);
+ Node* length = gasm_.ArrayLength(array.node, array.null_check());
SetSourcePosition(length);
gasm_.TrapUnless(gasm_.Uint32LessThan(index.node, length),
TrapId::kTrapArrayOutOfBounds);
@@ -349,10 +330,8 @@ class WasmIntoJSInlinerImpl : private wasm::Decoder {
is_inlineable_ = false;
return;
}
- const CheckForNull null_check =
- array.type.is_nullable() ? kWithNullCheck : kWithoutNullCheck;
// Perform bounds check.
- Node* length = gasm_.ArrayLength(array.node, null_check);
+ Node* length = gasm_.ArrayLength(array.node, array.null_check());
SetSourcePosition(length);
gasm_.TrapUnless(gasm_.Uint32LessThan(index.node, length),
TrapId::kTrapArrayOutOfBounds);
diff --git a/deps/v8/src/d8/OWNERS b/deps/v8/src/d8/OWNERS
index 5b4c2dbd472..ff7de8eaade 100644
--- a/deps/v8/src/d8/OWNERS
+++ b/deps/v8/src/d8/OWNERS
@@ -1,7 +1 @@
-ahaas@chromium.org
-cbruni@chromium.org
-clemensb@chromium.org
-ishell@chromium.org
-marja@chromium.org
-nikolaos@chromium.org
-verwaest@chromium.org
\ No newline at end of file
+file:../../COMMON_OWNERS
\ No newline at end of file
diff --git a/deps/v8/src/d8/async-hooks-wrapper.cc b/deps/v8/src/d8/async-hooks-wrapper.cc
index ebd12325168..bc7ea751c3a 100644
--- a/deps/v8/src/d8/async-hooks-wrapper.cc
+++ b/deps/v8/src/d8/async-hooks-wrapper.cc
@@ -17,7 +17,7 @@
namespace v8 {
namespace {
-i::Managed<AsyncHooksWrap>::Ptr UnwrapHook(
+i::CppGCManaged<AsyncHooksWrap>::Ptr UnwrapHook(
const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
v8::Isolate* v8_isolate = info.GetIsolate();
@@ -34,7 +34,7 @@ i::Managed<AsyncHooksWrap>::Ptr UnwrapHook(
i::DirectHandle<i::Object> handle =
Utils::OpenDirectHandle(*hook->GetInternalField(0));
- return Cast<i::Managed<AsyncHooksWrap>>(handle)->ptr();
+ return Cast<i::CppGCManaged<AsyncHooksWrap>>(handle)->ptr();
}
void EnableHook(const v8::FunctionCallbackInfo<v8::Value>& info) {
@@ -165,8 +165,10 @@ Local<Object> AsyncHooks::CreateHook(
Local<Object> obj = async_hooks_templ.Get(v8_isolate)
->NewInstance(currentContext)
.ToLocalChecked();
- i::DirectHandle<i::Object> managed = i::Managed<AsyncHooksWrap>::From(
- reinterpret_cast<i::Isolate*>(v8_isolate), sizeof(AsyncHooksWrap), wrap);
+ i::DirectHandle<i::Object> managed =
+ i::CppGCManaged<AsyncHooksWrap>::Create(
+ reinterpret_cast<i::Isolate*>(v8_isolate), sizeof(AsyncHooksWrap),
+ wrap);
obj->SetInternalField(0, Utils::ToLocal(managed));
async_wraps_.push_back(std::move(wrap));
diff --git a/deps/v8/src/d8/async-hooks-wrapper.h b/deps/v8/src/d8/async-hooks-wrapper.h
index 45b58044d0d..5cbd5d95da7 100644
--- a/deps/v8/src/d8/async-hooks-wrapper.h
+++ b/deps/v8/src/d8/async-hooks-wrapper.h
@@ -28,8 +28,8 @@ struct AsyncContext {
class AsyncHooksWrap {
public:
- static constexpr internal::ExternalPointerTag kManagedTag =
- internal::kGenericManagedTag;
+ static constexpr internal::ManagedTypeId kTypeID =
+ internal::ManagedTypeId::kD8AsyncHooksWrap;
explicit AsyncHooksWrap(Isolate* isolate)
: isolate_(isolate), enabled_(false) {}
diff --git a/deps/v8/src/d8/d8-console.cc b/deps/v8/src/d8/d8-console.cc
index 70967f00704..daa8e6d1e7b 100644
--- a/deps/v8/src/d8/d8-console.cc
+++ b/deps/v8/src/d8/d8-console.cc
@@ -19,9 +19,11 @@
namespace v8 {
namespace {
-void WriteToFile(const char* prefix, FILE* file, Isolate* isolate,
- const debug::ConsoleCallArguments& args) {
+V8_WARN_UNUSED_RESULT bool WriteToFile(
+ const char* prefix, FILE* file, Isolate* isolate,
+ const debug::ConsoleCallArguments& args) {
if (prefix) fprintf(file, "%s: ", prefix);
+ v8::TryCatch try_catch(isolate);
for (int i = 0; i < args.Length(); i++) {
HandleScope handle_scope(isolate);
if (i > 0) fprintf(file, " ");
@@ -30,7 +32,12 @@ void WriteToFile(const char* prefix, FILE* file, Isolate* isolate,
Local<String> str_obj;
if (arg->IsSymbol()) arg = Local<Symbol>::Cast(arg)->Description(isolate);
- if (!arg->ToString(isolate->GetCurrentContext()).ToLocal(&str_obj)) return;
+ if (!arg->ToString(isolate->GetCurrentContext()).ToLocal(&str_obj)) {
+ if (try_catch.HasCaught()) {
+ try_catch.ReThrow();
+ }
+ return false;
+ }
v8::String::Utf8Value str(isolate, str_obj);
size_t n = fwrite(*str, sizeof(**str), str.length(), file);
@@ -43,6 +50,7 @@ void WriteToFile(const char* prefix, FILE* file, Isolate* isolate,
// Flush the file to avoid output to pile up in a buffer. Console output is
// often used for timing, so it should appear as soon as the code is executed.
fflush(file);
+ return true;
}
static constexpr const char* kCpuProfileOutputFilename = "v8.prof";
@@ -50,10 +58,8 @@ static constexpr const char* kCpuProfileOutputFilename = "v8.prof";
std::optional<std::string> GetTimerLabel(
const debug::ConsoleCallArguments& args) {
if (args.Length() == 0) return "default";
- Isolate* isolate = args.GetIsolate();
- v8::TryCatch try_catch(isolate);
- v8::String::Utf8Value label(isolate, args[0]);
- if (*label == nullptr) return std::nullopt;
+ SafeUtf8Value label(args.GetIsolate(), args[0]);
+ if (!label) return std::nullopt;
return std::string(*label, label.length());
}
@@ -80,33 +86,33 @@ void D8Console::Assert(const debug::ConsoleCallArguments& args,
// If no arguments given, the "first" argument is undefined which is
// false-ish.
if (args.Length() > 0 && args[0]->BooleanValue(isolate_)) return;
- WriteToFile("console.assert", stdout, isolate_, args);
+ if (!WriteToFile("console.assert", stdout, isolate_, args)) return;
isolate_->ThrowError("console.assert failed");
}
void D8Console::Log(const debug::ConsoleCallArguments& args,
const v8::debug::ConsoleContext&) {
- WriteToFile(nullptr, stdout, isolate_, args);
+ USE(WriteToFile(nullptr, stdout, isolate_, args));
}
void D8Console::Error(const debug::ConsoleCallArguments& args,
const v8::debug::ConsoleContext&) {
- WriteToFile("console.error", stderr, isolate_, args);
+ USE(WriteToFile("console.error", stderr, isolate_, args));
}
void D8Console::Warn(const debug::ConsoleCallArguments& args,
const v8::debug::ConsoleContext&) {
- WriteToFile("console.warn", stdout, isolate_, args);
+ USE(WriteToFile("console.warn", stdout, isolate_, args));
}
void D8Console::Info(const debug::ConsoleCallArguments& args,
const v8::debug::ConsoleContext&) {
- WriteToFile("console.info", stdout, isolate_, args);
+ USE(WriteToFile("console.info", stdout, isolate_, args));
}
void D8Console::Debug(const debug::ConsoleCallArguments& args,
const v8::debug::ConsoleContext&) {
- WriteToFile("console.debug", stdout, isolate_, args);
+ USE(WriteToFile("console.debug", stdout, isolate_, args));
}
void D8Console::Profile(const debug::ConsoleCallArguments& args,
diff --git a/deps/v8/src/d8/d8-posix.cc b/deps/v8/src/d8/d8-posix.cc
index 5da6c54c669..b8bc0ea2b8f 100644
--- a/deps/v8/src/d8/d8-posix.cc
+++ b/deps/v8/src/d8/d8-posix.cc
@@ -163,12 +163,8 @@ class ExecArgs {
public:
ExecArgs() { exec_args_[0] = nullptr; }
bool Init(Isolate* isolate, Local<Value> arg0, Local<Array> command_args) {
- String::Utf8Value prog(isolate, arg0);
- if (*prog == nullptr) {
- ThrowError(isolate,
- "os.system(): String conversion of program name failed");
- return false;
- }
+ SafeUtf8Value prog(isolate, arg0);
+ if (!prog) return false;
{
size_t len = prog.length() + 3;
char* c_arg = new char[len];
@@ -177,15 +173,16 @@ class ExecArgs {
}
int i = 1;
for (unsigned j = 0; j < command_args->Length(); i++, j++) {
- Local<Value> arg(
- command_args
- ->Get(isolate->GetCurrentContext(), Integer::New(isolate, j))
- .ToLocalChecked());
- String::Utf8Value utf8_arg(isolate, arg);
- if (*utf8_arg == nullptr) {
+ Local<Value> arg;
+ if (!command_args
+ ->Get(isolate->GetCurrentContext(), Integer::New(isolate, j))
+ .ToLocal(&arg)) {
+ exec_args_[i] = nullptr;
+ return false;
+ }
+ SafeUtf8Value utf8_arg(isolate, arg);
+ if (!utf8_arg) {
exec_args_[i] = nullptr; // Consistent state for destructor.
- ThrowError(isolate,
- "os.system(): String conversion of argument failed.");
return false;
}
size_t len = utf8_arg.length() + 1;
@@ -568,11 +565,8 @@ void Shell::MakeDirectory(const v8::FunctionCallbackInfo<v8::Value>& info) {
ThrowError(isolate, "mkdirp() takes one or two arguments");
return;
}
- String::Utf8Value directory(isolate, info[0]);
- if (*directory == nullptr) {
- ThrowError(isolate, "os.mkdirp(): String conversion of argument failed.");
- return;
- }
+ SafeUtf8Value directory(isolate, info[0]);
+ if (!directory) return;
mkdirp(isolate, *directory, mask);
}
@@ -583,11 +577,8 @@ void Shell::RemoveDirectory(const v8::FunctionCallbackInfo<v8::Value>& info) {
ThrowError(isolate, "rmdir() takes one arguments");
return;
}
- String::Utf8Value directory(isolate, info[0]);
- if (*directory == nullptr) {
- ThrowError(isolate, "os.rmdir(): String conversion of argument failed.");
- return;
- }
+ SafeUtf8Value directory(isolate, info[0]);
+ if (!directory) return;
rmdir(*directory);
}
@@ -598,18 +589,10 @@ void Shell::SetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& info) {
ThrowError(isolate, "setenv() takes two arguments");
return;
}
- String::Utf8Value var(isolate, info[0]);
- String::Utf8Value value(isolate, info[1]);
- if (*var == nullptr) {
- ThrowError(isolate,
- "os.setenv(): String conversion of variable name failed.");
- return;
- }
- if (*value == nullptr) {
- ThrowError(isolate,
- "os.setenv(): String conversion of variable contents failed.");
- return;
- }
+ SafeUtf8Value var(isolate, info[0]);
+ if (!var) return;
+ SafeUtf8Value value(isolate, info[1]);
+ if (!value) return;
setenv(*var, *value, 1);
}
@@ -620,12 +603,8 @@ void Shell::UnsetEnvironment(const v8::FunctionCallbackInfo<v8::Value>& info) {
ThrowError(isolate, "unsetenv() takes one argument");
return;
}
- String::Utf8Value var(isolate, info[0]);
- if (*var == nullptr) {
- ThrowError(isolate,
- "os.setenv(): String conversion of variable name failed.");
- return;
- }
+ SafeUtf8Value var(isolate, info[0]);
+ if (!var) return;
unsetenv(*var);
}
@@ -753,12 +732,8 @@ void Shell::FileExists(const v8::FunctionCallbackInfo<v8::Value>& info) {
ThrowError(isolate, "exists() takes one argument");
return;
}
- String::Utf8Value file_name(isolate, info[0]);
- if (*file_name == nullptr) {
- ThrowError(isolate,
- "d8.file.exists(): String conversion of argument failed.");
- return;
- }
+ SafeUtf8Value file_name(isolate, info[0]);
+ if (!file_name) return;
struct stat stat_buf;
bool exists = (stat(*file_name, &stat_buf) == 0);
diff --git a/deps/v8/src/d8/d8-test.cc b/deps/v8/src/d8/d8-test.cc
index fa81bfa60fa..a6dd1f5785e 100644
--- a/deps/v8/src/d8/d8-test.cc
+++ b/deps/v8/src/d8/d8-test.cc
@@ -5,6 +5,7 @@
#include "src/d8/d8.h"
#include "include/v8-fast-api-calls.h"
+#include "include/v8-function.h"
#include "include/v8-template.h"
#include "src/api/api-inl.h"
@@ -2141,4 +2142,227 @@ Local<FunctionTemplate> Shell::CreateLeafInterfaceTypeTemplate(
return leaf_object_ctor;
}
+namespace {
+
+v8::Intercepted D8InterceptCallback(Local<Name> property,
+ const PropertyCallbackInfo<Value>& info) {
+ Isolate* isolate = info.GetIsolate();
+ Local<Value> data = info.Data();
+ if (!data->IsFunction()) {
+ isolate->ThrowError("Interceptor callback must be a function");
+ return v8::Intercepted::kYes;
+ }
+ Local<Context> context = isolate->GetCurrentContext();
+ Local<Function> fn = data.As<Function>();
+ Local<Value> argv[1] = {property};
+ Local<Value> ret;
+ if (fn->Call(context, info.Holder(), 1, argv).ToLocal(&ret)) {
+ info.GetReturnValue().Set(ret);
+ }
+ // TODO(leszeks): Add a mechanism to allow not intercepting.
+ return v8::Intercepted::kYes;
+}
+
+enum class AccessPolicy : uintptr_t {
+ kDeny = 0,
+ kAllow = 1,
+ kSameContext = 2,
+ kSecurityToken = 3,
+};
+
+bool ParseAccessPolicy(Isolate* isolate, Local<Value> val,
+ AccessPolicy* policy) {
+ if (val->IsBoolean()) {
+ *policy =
+ val->BooleanValue(isolate) ? AccessPolicy::kAllow : AccessPolicy::kDeny;
+ return true;
+ }
+ if (val->IsString()) {
+ String::Utf8Value str(isolate, val);
+ if (strcmp(*str, "same-context") == 0) {
+ *policy = AccessPolicy::kSameContext;
+ return true;
+ }
+ if (strcmp(*str, "security-token") == 0) {
+ *policy = AccessPolicy::kSecurityToken;
+ return true;
+ }
+ }
+ isolate->ThrowError(
+ "Invalid access policy: expected true, false, \"same-context\", or "
+ "\"security-token\"");
+ return false;
+}
+
+bool D8AccessCheck(Local<Context> accessing_context,
+ Local<Object> accessed_object, Local<Value> data) {
+ if (accessed_object->InternalFieldCount() == 0) return true;
+
+ auto policy = static_cast<AccessPolicy>(reinterpret_cast<uintptr_t>(
+ accessed_object->GetAlignedPointerFromInternalField(
+ 0, kEmbedderDataTypeTagDefault)));
+
+ switch (policy) {
+ case AccessPolicy::kAllow:
+ return true;
+ case AccessPolicy::kDeny:
+ return false;
+ case AccessPolicy::kSameContext: {
+ Isolate* isolate = Isolate::GetCurrent();
+ Local<Context> creation_context;
+ if (accessed_object->GetCreationContext(isolate).ToLocal(
+ &creation_context)) {
+ return accessing_context == creation_context;
+ }
+ return false;
+ }
+ case AccessPolicy::kSecurityToken: {
+ Isolate* isolate = Isolate::GetCurrent();
+ Local<Context> creation_context;
+ if (accessed_object->GetCreationContext(isolate).ToLocal(
+ &creation_context)) {
+ return accessing_context->GetSecurityToken()->StrictEquals(
+ creation_context->GetSecurityToken());
+ }
+ return false;
+ }
+ }
+ UNREACHABLE();
+}
+
+} // namespace
+
+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");
+ return;
+ }
+ Local<Context> context = isolate->GetCurrentContext();
+ Local<FunctionTemplate> ctor = FunctionTemplate::New(isolate);
+ Local<ObjectTemplate> templ = ctor->InstanceTemplate();
+ templ->SetHandler(NamedPropertyHandlerConfiguration(
+ D8InterceptCallback, nullptr, nullptr, nullptr, nullptr, info[0]));
+
+ Local<Function> fn;
+ if (!ctor->GetFunction(context).ToLocal(&fn)) return;
+ Local<Object> instance;
+ if (!fn->NewInstance(context).ToLocal(&instance)) return;
+ info.GetReturnValue().Set(instance);
+}
+
+void Shell::CreateAccessCheckedObject(const FunctionCallbackInfo<Value>& info) {
+ Isolate* isolate = info.GetIsolate();
+ if (info.Length() == 0) {
+ isolate->ThrowError(
+ "d8.test.createAccessCheckedObject requires a policy argument");
+ 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->SetAccessCheckCallback(D8AccessCheck);
+
+ 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()) {
+ isolate->ThrowError("Usage: d8.test.setAccessPolicy(object, policy)");
+ return;
+ }
+ Local<Object> obj = info[0].As<Object>();
+ if (obj->InternalFieldCount() == 0) {
+ isolate->ThrowError("Object does not support access checks");
+ return;
+ }
+ AccessPolicy policy;
+ if (!ParseAccessPolicy(isolate, info[1], &policy)) return;
+
+ obj->SetAlignedPointerInInternalField(
+ 0, reinterpret_cast<void*>(static_cast<uintptr_t>(policy)),
+ 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-windows.cc b/deps/v8/src/d8/d8-windows.cc
index 11a091a1876..b8958fc2da9 100644
--- a/deps/v8/src/d8/d8-windows.cc
+++ b/deps/v8/src/d8/d8-windows.cc
@@ -55,12 +55,8 @@ void Shell::FileExists(const v8::FunctionCallbackInfo<v8::Value>& info) {
ThrowError(isolate, "exists() takes one argument");
return;
}
- String::Utf8Value file_name(isolate, info[0]);
- if (*file_name == nullptr) {
- ThrowError(isolate,
- "d8.file.exists(): String conversion of argument failed.");
- return;
- }
+ SafeUtf8Value file_name(isolate, info[0]);
+ if (!file_name) return;
std::wstring wide_name = v8::base::OS::ConvertUtf8StringToUtf16(*file_name);
DWORD attr = GetFileAttributesW(wide_name.c_str());
diff --git a/deps/v8/src/d8/d8.cc b/deps/v8/src/d8/d8.cc
index 696185cff01..12799d598dd 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/compiler.h"
#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/d8/d8-console.h"
#include "src/d8/d8-platforms.h"
@@ -431,13 +432,8 @@ static MaybeLocal<Value> TryGetValue(v8::Isolate* isolate,
return object->Get(context, v8_str.ToLocalChecked());
}
-static Local<Value> GetValue(v8::Isolate* isolate, Local<Context> context,
- Local<v8::Object> object, const char* property) {
- return TryGetValue(isolate, context, object, property).ToLocalChecked();
-}
-
-i::Managed<Worker>::Ptr GetWorkerFromInternalField(Isolate* isolate,
- Local<Object> object) {
+i::CppGCManaged<Worker>::Ptr GetWorkerFromInternalField(Isolate* isolate,
+ Local<Object> object) {
if (object->InternalFieldCount() != 1) {
ThrowError(isolate, "this is not a Worker");
return {};
@@ -449,7 +445,7 @@ i::Managed<Worker>::Ptr GetWorkerFromInternalField(Isolate* isolate,
ThrowError(isolate, "Worker is defunct because main thread is terminating");
return {};
}
- auto managed = i::Cast<i::Managed<Worker>>(handle);
+ auto managed = i::Cast<i::CppGCManaged<Worker>>(handle);
return managed->ptr();
}
@@ -572,17 +568,38 @@ class TraceConfigParser {
Context::Scope context_scope(context);
HandleScope inner_scope(isolate);
+ TryCatch try_catch(isolate);
+ FillTraceConfigImpl(isolate, context, trace_config, json_str);
+ if (try_catch.HasCaught()) {
+ printf("Failed to parse trace config.\n\n");
+ Shell::ReportException(isolate, try_catch);
+ base::OS::ExitProcess(1);
+ }
+ }
+
+ private:
+ static void FillTraceConfigImpl(v8::Isolate* isolate, Local<Context> context,
+ platform::tracing::TraceConfig* trace_config,
+ base::Vector<char> json_str) {
+ if (json_str.size() > v8::String::kMaxLength) {
+ isolate->ThrowError("Trace config is too big.");
+ return;
+ }
int length = base::checked_cast<int>(json_str.size());
Local<String> source = String::NewFromUtf8(isolate, json_str.data(),
NewStringType::kNormal, length)
.ToLocalChecked();
- Local<Value> result = JSON::Parse(context, source).ToLocalChecked();
+ Local<Value> result;
+ if (!JSON::Parse(context, source).ToLocal(&result)) return;
+ CHECK(result->IsObject());
+
Local<v8::Object> trace_config_object = result.As<v8::Object>();
// Try reading 'trace_config' property from a full chrome trace config.
// https://chromium.googlesource.com/chromium/src/+/master/docs/memory-infra/memory_infra_startup_tracing.md#the-advanced-way
- Local<Value> maybe_trace_config_object =
- GetValue(isolate, context, trace_config_object, kTraceConfigParam);
- if (maybe_trace_config_object->IsObject()) {
+ Local<Value> maybe_trace_config_object;
+ if (TryGetValue(isolate, context, trace_config_object, kTraceConfigParam)
+ .ToLocal(&maybe_trace_config_object) &&
+ maybe_trace_config_object->IsObject()) {
trace_config_object = maybe_trace_config_object.As<Object>();
}
@@ -594,16 +611,19 @@ class TraceConfigParser {
static int UpdateIncludedCategoriesList(
v8::Isolate* isolate, Local<Context> context, Local<v8::Object> object,
platform::tracing::TraceConfig* trace_config) {
- Local<Value> value =
- GetValue(isolate, context, object, kIncludedCategoriesParam);
+ Local<Value> value;
+ if (!TryGetValue(isolate, context, object, kIncludedCategoriesParam)
+ .ToLocal(&value)) {
+ return 0;
+ }
if (value->IsArray()) {
Local<Array> v8_array = value.As<Array>();
for (int i = 0, length = v8_array->Length(); i < length; ++i) {
- Local<Value> v = v8_array->Get(context, i)
- .ToLocalChecked()
- ->ToString(context)
- .ToLocalChecked();
- String::Utf8Value str(isolate, v->ToString(context).ToLocalChecked());
+ Local<Value> v;
+ if (!v8_array->Get(context, i).ToLocal(&v)) return 0;
+ Local<String> str_val;
+ if (!v->ToString(context).ToLocal(&str_val)) return 0;
+ String::Utf8Value str(isolate, str_val);
trace_config->AddIncludedCategory(*str);
}
return v8_array->Length();
@@ -643,8 +663,7 @@ std::unordered_set<std::shared_ptr<Worker>> Shell::running_workers_;
std::atomic<bool> Shell::script_executed_{false};
std::atomic<bool> Shell::valid_fuzz_script_{false};
base::LazyMutex Shell::cached_code_mutex_;
-std::map<std::string, std::unique_ptr<ScriptCompiler::CachedData>>
- Shell::cached_code_map_;
+Shell::CodeCacheMap Shell::cached_code_map_;
std::atomic<int> Shell::unhandled_promise_rejections_{0};
bool Shell::fuzzilli_reprl_failed_ = false;
@@ -661,14 +680,16 @@ ShellOptions Shell::options;
base::OnceType Shell::quit_once_ = V8_ONCE_INIT;
ScriptCompiler::CachedData* Shell::LookupCodeCache(Isolate* isolate,
- Local<Value> source) {
+ Local<Value> source,
+ ScriptType type) {
i::ParkedMutexGuard lock_guard(
reinterpret_cast<i::Isolate*>(isolate)->main_thread_local_isolate(),
cached_code_mutex_.Pointer());
CHECK(source->IsString());
- v8::String::Utf8Value key(isolate, source);
- DCHECK(*key);
- auto entry = cached_code_map_.find(*key);
+ v8::String::Utf8Value source_str(isolate, source);
+ DCHECK(*source_str);
+ CodeCacheKey key(*source_str, type);
+ auto entry = cached_code_map_.find(key);
if (entry != cached_code_map_.end() && entry->second) {
int length = entry->second->length;
uint8_t* cache = new uint8_t[length];
@@ -681,27 +702,54 @@ ScriptCompiler::CachedData* Shell::LookupCodeCache(Isolate* isolate,
}
void Shell::StoreInCodeCache(Isolate* isolate, Local<Value> source,
- const ScriptCompiler::CachedData* cache_data) {
+ const ScriptCompiler::CachedData* cache_data,
+ ScriptType type) {
i::ParkedMutexGuard lock_guard(
reinterpret_cast<i::Isolate*>(isolate)->main_thread_local_isolate(),
cached_code_mutex_.Pointer());
CHECK(source->IsString());
if (cache_data == nullptr) return;
- v8::String::Utf8Value key(isolate, source);
- DCHECK(*key);
+ v8::String::Utf8Value source_str(isolate, source);
+ DCHECK(*source_str);
int length = cache_data->length;
uint8_t* cache = new uint8_t[length];
memcpy(cache, cache_data->data, length);
- cached_code_map_[*key] = std::unique_ptr<ScriptCompiler::CachedData>(
+ CodeCacheKey key(*source_str, type);
+ cached_code_map_[key] = std::unique_ptr<ScriptCompiler::CachedData>(
new ScriptCompiler::CachedData(cache, length,
ScriptCompiler::CachedData::BufferOwned));
}
+MaybeLocal<String> CreateStringFromExternalData(Isolate* isolate,
+ std::string_view source) {
+ constexpr std::string_view kUtf8Bom = "\xEF\xBB\xBF";
+ if (source.starts_with(kUtf8Bom)) {
+ source.remove_prefix(kUtf8Bom.size());
+ }
+ int size = static_cast<int>(source.size());
+ if (i::v8_flags.use_external_strings &&
+ i::String::IsAscii(source.data(), size)) {
+ String::ExternalOneByteStringResource* resource =
+ new i::OwningExternalOneByteStringResource(source);
+ return String::NewExternalOneByte(isolate, resource);
+ }
+ return String::NewFromUtf8(isolate, source.data(), NewStringType::kNormal,
+ size);
+}
+
+// Dummy external source stream which returns the whole source in one go.
+// TODO(leszeks): Also test chunking the data.
+class CompileSourceStream : public v8::ScriptCompiler::ExternalSourceStream {
+ public:
+ virtual MaybeLocal<String> GetSourceString(Isolate* isolate) = 0;
+};
+
// Dummy external source stream which returns the whole source in one go.
// TODO(leszeks): Also test chunking the data.
-class DummySourceStream : public v8::ScriptCompiler::ExternalSourceStream {
+class DummySourceStream : public CompileSourceStream {
public:
- DummySourceStream(Isolate* isolate, Local<String> source) : done_(false) {
+ DummySourceStream(Isolate* isolate, Local<String> source)
+ : source_(source), done_(false) {
source_length_ = source->Length();
source_buffer_ = std::make_unique<uint16_t[]>(source_length_);
source->Write(isolate, 0, source_length_, source_buffer_.get());
@@ -717,13 +765,18 @@ class DummySourceStream : public v8::ScriptCompiler::ExternalSourceStream {
return source_length_ * 2;
}
+ MaybeLocal<String> GetSourceString(Isolate* isolate) override {
+ return source_;
+ }
+
private:
+ Local<String> source_;
uint32_t source_length_;
std::unique_ptr<uint16_t[]> source_buffer_;
bool done_;
};
-class FileSourceStream : public v8::ScriptCompiler::ExternalSourceStream {
+class FileSourceStream : public CompileSourceStream {
public:
FileSourceStream(Isolate* isolate, const char* filename) {
file_ = base::Fopen(filename, "rb");
@@ -749,15 +802,25 @@ class FileSourceStream : public v8::ScriptCompiler::ExternalSourceStream {
return 0;
}
+ if (data_.size() + bytes_read > size_t{String::kMaxLength}) {
+ FATAL("Input file too large (> %d bytes)", String::kMaxLength);
+ }
+ data_.append(reinterpret_cast<const char*>(buffer.get()), bytes_read);
+
*src = buffer.release();
return bytes_read;
}
bool IsValid() const { return file_ != nullptr; }
+ MaybeLocal<String> GetSourceString(Isolate* isolate) override {
+ return CreateStringFromExternalData(isolate, data_);
+ }
+
private:
static constexpr size_t kChunkSize = 4096;
FILE* file_ = nullptr;
+ std::string data_;
};
// Run a ScriptStreamingTask in a separate thread.
@@ -843,14 +906,12 @@ MaybeLocal<T> Shell::CompileSource(Isolate* isolate, Local<Context> context,
const Source& source,
const ScriptOrigin& origin) {
if (options.streaming_compile) {
- std::unique_ptr<v8::ScriptCompiler::ExternalSourceStream> source_stream;
+ std::unique_ptr<CompileSourceStream> source_stream;
v8::ScriptCompiler::StreamedSource::Encoding encoding;
- Local<String> source_string;
if (source.type() == Source::Type::kString) {
- source_string = source.string();
source_stream =
- std::make_unique<DummySourceStream>(isolate, source_string);
+ std::make_unique<DummySourceStream>(isolate, source.string());
encoding = v8::ScriptCompiler::StreamedSource::TWO_BYTE;
} else {
DCHECK_EQ(source.type(), Source::Type::kFile);
@@ -877,10 +938,11 @@ MaybeLocal<T> Shell::CompileSource(Isolate* isolate, Local<Context> context,
if (streaming_task) {
StreamerThread::StartThreadForTaskAndJoin(streaming_task.get());
- if (source_string.IsEmpty()) {
- if (!source.ConvertToString(isolate).ToLocal(&source_string)) {
- return MaybeLocal<T>();
- }
+ auto* stream = static_cast<CompileSourceStream*>(
+ streamed_source.impl()->source_stream.get());
+ Local<String> source_string;
+ if (!stream->GetSourceString(isolate).ToLocal(&source_string)) {
+ return MaybeLocal<T>();
}
update_script_size(source_string->Length());
return CompileStreamed<T>(context, &streamed_source, source_string,
@@ -896,7 +958,13 @@ MaybeLocal<T> Shell::CompileSource(Isolate* isolate, Local<Context> context,
ScriptCompiler::CachedData* cached_code = nullptr;
if (options.compile_options & ScriptCompiler::kConsumeCodeCache) {
- cached_code = LookupCodeCache(isolate, source_string);
+ if constexpr (std::is_same_v<T, Script>) {
+ cached_code =
+ LookupCodeCache(isolate, source_string, ScriptType::kClassic);
+ } else if constexpr (std::is_same_v<T, Module>) {
+ cached_code =
+ LookupCodeCache(isolate, source_string, ScriptType::kModule);
+ }
}
ScriptCompiler::Source script_source(source_string, origin, cached_code);
MaybeLocal<T> result =
@@ -937,8 +1005,8 @@ class ModuleEmbedderData {
};
public:
- static constexpr i::ExternalPointerTag kManagedTag =
- i::kD8ModuleEmbedderDataTag;
+ static constexpr i::ManagedTypeId kTypeID =
+ i::ManagedTypeId::kD8ModuleEmbedderData;
explicit ModuleEmbedderData(Isolate* isolate)
: isolate_(isolate),
@@ -1015,16 +1083,20 @@ class ModuleEmbedderData {
// Origin location used for resolving modules when referrer is null.
std::string origin;
+
+ // List of compiled JavaScript modules awaiting code cache production.
+ std::vector<std::pair<Global<String>, Global<Module>>>
+ modules_pending_code_cache;
};
enum { kModuleEmbedderDataIndex, kInspectorClientIndex };
-i::Managed<ModuleEmbedderData>::Ptr InitializeModuleEmbedderData(
+i::CppGCManaged<ModuleEmbedderData>::Ptr InitializeModuleEmbedderData(
Local<Context> context) {
i::Isolate* i_isolate = i::Isolate::Current();
const size_t kModuleEmbedderDataEstimate = 4 * 1024; // module map.
- i::DirectHandle<i::Managed<ModuleEmbedderData>> module_data_managed =
- i::Managed<ModuleEmbedderData>::From(
+ i::DirectHandle<i::CppGCManaged<ModuleEmbedderData>> module_data_managed =
+ i::CppGCManaged<ModuleEmbedderData>::Create(
i_isolate, kModuleEmbedderDataEstimate,
std::make_shared<ModuleEmbedderData>(
reinterpret_cast<v8::Isolate*>(i_isolate)));
@@ -1033,12 +1105,12 @@ i::Managed<ModuleEmbedderData>::Ptr InitializeModuleEmbedderData(
return module_data_managed->ptr();
}
-i::Managed<ModuleEmbedderData>::Ptr GetModuleDataFromContext(
+i::CppGCManaged<ModuleEmbedderData>::Ptr GetModuleDataFromContext(
Local<Context> context) {
v8::Local<v8::Data> module_data =
context->GetEmbedderDataV2(kModuleEmbedderDataIndex);
- i::DirectHandle<i::Managed<ModuleEmbedderData>> module_data_managed =
- i::Cast<i::Managed<ModuleEmbedderData>>(
+ i::DirectHandle<i::CppGCManaged<ModuleEmbedderData>> module_data_managed =
+ i::Cast<i::CppGCManaged<ModuleEmbedderData>>(
Utils::OpenDirectHandle<Data, i::Object>(module_data));
return module_data_managed->ptr();
}
@@ -1127,6 +1199,10 @@ bool Shell::ExecuteSource(Isolate* isolate, const Source& source,
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
if (i_isolate->is_execution_terminating()) return true;
+ HandleScope handle_scope(isolate);
+ TryCatch try_catch(isolate);
+ try_catch.SetVerbose(report_exceptions == kReportExceptions);
+
Local<String> source_str;
if (i::v8_flags.parse_only ||
options.code_cache_options ==
@@ -1171,10 +1247,6 @@ bool Shell::ExecuteSource(Isolate* isolate, const Source& source,
return true;
}
- HandleScope handle_scope(isolate);
- TryCatch try_catch(isolate);
- try_catch.SetVerbose(report_exceptions == kReportExceptions);
-
// Explicitly check for stack overflows. This method can be called
// recursively, and since we consume quite some stack space for the C++
// frames, the stack check in the called frame might be too late.
@@ -1190,7 +1262,7 @@ bool Shell::ExecuteSource(Isolate* isolate, const Source& source,
Local<Context> context(isolate->GetCurrentContext());
ScriptOrigin origin = CreateScriptOrigin(isolate, name, ScriptType::kClassic);
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(realm);
module_data->origin = ToSTLString(isolate, name);
@@ -1382,7 +1454,7 @@ MaybeLocal<Module> ResolveModuleCallback(Local<Context> context,
Local<FixedArray> import_attributes,
Local<Module> referrer) {
Isolate* isolate = Isolate::GetCurrent();
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(context);
std::string referrer_specifier = module_data->GetModuleSpecifier(referrer);
@@ -1399,7 +1471,7 @@ MaybeLocal<Object> ResolveModuleSourceCallback(
Local<Context> context, Local<String> specifier,
Local<FixedArray> import_attributes, Local<Module> referrer) {
Isolate* isolate = Isolate::GetCurrent();
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(context);
std::string referrer_specifier = module_data->GetModuleSpecifier(referrer);
@@ -1420,7 +1492,7 @@ MaybeLocal<Object> Shell::FetchModuleSource(Local<Module> referrer,
const std::string& module_specifier,
ModuleType module_type) {
Isolate* isolate = Isolate::GetCurrent();
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(context);
// Loading modules is only allowed for local absolute paths.
@@ -1487,7 +1559,7 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Module> referrer,
const std::string& module_specifier,
ModuleType module_type) {
Isolate* isolate = Isolate::GetCurrent();
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(context);
MaybeLocal<String> source_text;
std::unique_ptr<base::OS::MemoryMappedFile> raw_file;
@@ -1561,6 +1633,19 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Module> referrer,
.ToLocal(&module)) {
return MaybeLocal<Module>();
}
+ if (options.code_cache_options ==
+ ShellOptions::CodeCacheOptions::kProduceCache) {
+ ScriptCompiler::CachedData* cached_data =
+ ScriptCompiler::CreateCodeCache(module->GetUnboundModuleScript());
+ StoreInCodeCache(isolate, source_text.ToLocalChecked(), cached_data,
+ ScriptType::kModule);
+ delete cached_data;
+ } else if (options.code_cache_options ==
+ ShellOptions::CodeCacheOptions::kProduceCacheAfterExecute) {
+ module_data->modules_pending_code_cache.emplace_back(
+ Global<String>(isolate, source_text.ToLocalChecked()),
+ Global<Module>(isolate, module));
+ }
} else if (module_type == ModuleType::kJSON) {
Local<Value> parsed_json;
if (!v8::JSON::Parse(context, source_text.ToLocalChecked())
@@ -1678,8 +1763,8 @@ MaybeLocal<Module> Shell::FetchModuleTree(Local<Module> referrer,
return result;
}
-MaybeLocal<Value> Shell::JSONModuleEvaluationSteps(Local<Context> context,
- Local<Module> module) {
+MaybeLocal<Promise> Shell::JSONModuleEvaluationSteps(Local<Context> context,
+ Local<Module> module) {
Isolate* isolate = Isolate::GetCurrent();
Local<Value> json_value =
@@ -1702,8 +1787,8 @@ MaybeLocal<Value> Shell::JSONModuleEvaluationSteps(Local<Context> context,
return resolver->GetPromise();
}
-MaybeLocal<Value> Shell::TextModuleEvaluationSteps(Local<Context> context,
- Local<Module> module) {
+MaybeLocal<Promise> Shell::TextModuleEvaluationSteps(Local<Context> context,
+ Local<Module> module) {
Isolate* isolate = Isolate::GetCurrent();
Local<Value> text_value =
@@ -1726,8 +1811,8 @@ MaybeLocal<Value> Shell::TextModuleEvaluationSteps(Local<Context> context,
return resolver->GetPromise();
}
-MaybeLocal<Value> Shell::BytesModuleEvaluationSteps(Local<Context> context,
- Local<Module> module) {
+MaybeLocal<Promise> Shell::BytesModuleEvaluationSteps(Local<Context> context,
+ Local<Module> module) {
Isolate* isolate = Isolate::GetCurrent();
Local<Value> bytes_value =
@@ -1889,7 +1974,7 @@ void Shell::HostInitializeImportMetaObject(Local<Context> context,
Isolate* isolate = Isolate::GetCurrent();
HandleScope handle_scope(isolate);
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(context);
std::string specifier = module_data->GetModuleSpecifier(module);
@@ -1908,9 +1993,9 @@ MaybeLocal<Context> Shell::HostCreateShadowRealmContext(
ThrowError(isolate, "Failed to create ShadowRealm context");
return MaybeLocal<Context>();
}
- i::Managed<ModuleEmbedderData>::Ptr shadow_realm_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr shadow_realm_data =
InitializeModuleEmbedderData(context);
- i::Managed<ModuleEmbedderData>::Ptr initiator_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr initiator_data =
GetModuleDataFromContext(initiator_context);
// ShadowRealms are synchronously accessible and are always in the same origin
@@ -2025,7 +2110,7 @@ void Shell::DoHostImportModuleDynamically(v8::Local<v8::Data> data) {
return;
}
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(realm);
std::string source_url = referrer->IsNull()
@@ -2135,6 +2220,30 @@ void Shell::DoHostImportModuleDynamically(v8::Local<v8::Data> data) {
}
}
+void Shell::ProduceModuleCodeCacheAfterExecute(Isolate* isolate) {
+ if (options.code_cache_options !=
+ ShellOptions::CodeCacheOptions::kProduceCacheAfterExecute ||
+ isolate->IsExecutionTerminating()) {
+ return;
+ }
+ PerIsolateData* data = PerIsolateData::Get(isolate);
+ Local<Context> realm =
+ data->realms_[data->realm_current_].context.Get(isolate);
+ Context::Scope context_scope(realm);
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
+ GetModuleDataFromContext(realm);
+ for (const auto& [source_str, mod] :
+ module_data->modules_pending_code_cache) {
+ Local<Module> m = mod.Get(isolate);
+ ScriptCompiler::CachedData* cached_data =
+ ScriptCompiler::CreateCodeCache(m->GetUnboundModuleScript());
+ StoreInCodeCache(isolate, source_str.Get(isolate), cached_data,
+ ScriptType::kModule);
+ delete cached_data;
+ }
+ module_data->modules_pending_code_cache.clear();
+}
+
bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
HandleScope handle_scope(isolate);
Global<Module> global_root_module;
@@ -2155,8 +2264,9 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
std::string absolute_path =
NormalizeModuleSpecifier(file_name, GetWorkingDirectory());
- i::Managed<ModuleEmbedderData>::Ptr module_data =
+ i::CppGCManaged<ModuleEmbedderData>::Ptr module_data =
GetModuleDataFromContext(realm);
+
Local<Module> root_module;
auto module_it = module_data->module_map.find(
std::make_pair(absolute_path, ModuleType::kJavaScript));
@@ -2173,6 +2283,8 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
module_data->origin = absolute_path;
+ if (options.compile_only) return true;
+
if (root_module
->InstantiateModule(realm, ResolveModuleCallback,
ResolveModuleSourceCallback)
@@ -2246,6 +2358,8 @@ bool Shell::ExecuteModule(Isolate* isolate, const char* file_name) {
}
}
+ ProduceModuleCodeCacheAfterExecute(isolate);
+
DCHECK(!try_catch.HasCaught());
return true;
}
@@ -2491,10 +2605,10 @@ int PerIsolateData::RealmIndexOrThrow(
}
// GetTimestamp() returns a time stamp as double, measured in milliseconds.
-// When v8_flags.verify_predictable mode is enabled it returns result of
+// When v8_flags.predictable mode is enabled it returns result of
// v8::Platform::MonotonicallyIncreasingTime().
double Shell::GetTimestamp() {
- if (i::v8_flags.verify_predictable) {
+ if (i::v8_flags.predictable) {
return g_platform->MonotonicallyIncreasingTime();
} else {
base::TimeDelta delta = base::TimeTicks::Now() - kInitialTicks;
@@ -2503,9 +2617,9 @@ double Shell::GetTimestamp() {
}
uint64_t Shell::GetTracingTimestampFromPerformanceTimestamp(
double performance_timestamp) {
- // Don't use this in --verify-predictable mode, predictable timestamps don't
+ // Don't use this in --predictable mode, predictable timestamps don't
// work well with tracing.
- DCHECK(!i::v8_flags.verify_predictable);
+ DCHECK(!i::v8_flags.predictable);
base::TimeDelta delta =
base::TimeDelta::FromMillisecondsD(performance_timestamp);
// See TracingController::CurrentTimestampMicroseconds().
@@ -2528,8 +2642,9 @@ bool SendPerfControlCommand(const char* command) {
return false;
}
- char ack[5];
+ char ack[6] = {0};
ret = read(Shell::options.perf_ack_fd, ack, 5);
+ ack[5] = '\0';
if (ret == -1) {
fprintf(stderr, "perf_ack read error: %s\n", strerror(errno));
return false;
@@ -2851,19 +2966,9 @@ MaybeLocal<Context> Shell::CreateRealm(
Local<ObjectTemplate> global_template = CreateGlobalTemplate(isolate);
v8::MicrotaskQueue* microtask_queue = nullptr;
-#ifdef V8_CPPGC_MICROTASK_QUEUE
if (create_own_microtask_queue) {
microtask_queue = v8::MicrotaskQueue::New(isolate);
}
-#else
- std::unique_ptr<v8::MicrotaskQueue> new_mq;
- if (create_own_microtask_queue) {
- START_ALLOW_USE_DEPRECATED()
- new_mq = v8::MicrotaskQueue::New(isolate);
- END_ALLOW_USE_DEPRECATED()
- microtask_queue = new_mq.get();
- }
-#endif // V8_CPPGC_MICROTASK_QUEUE
Local<Context> context =
Context::New(isolate, nullptr, global_template, global_object,
@@ -2874,16 +2979,9 @@ MaybeLocal<Context> Shell::CreateRealm(
if (index < 0) {
index = static_cast<int>(data->realms_.size());
-#ifdef V8_CPPGC_MICROTASK_QUEUE
data->realms_.emplace_back(isolate, context);
-#else
- data->realms_.emplace_back(isolate, context, std::move(new_mq));
-#endif
} else {
data->realms_[index].context.Reset(isolate, context);
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- data->realms_[index].microtask_queue = std::move(new_mq);
-#endif
}
data->realms_[index].context.AnnotateStrongRetainer(kGlobalHandleLabel);
@@ -2899,9 +2997,6 @@ void Shell::DisposeRealm(const v8::FunctionCallbackInfo<v8::Value>& info,
PerIsolateData* data = PerIsolateData::Get(isolate);
Local<Context> context = data->realms_[index].context.Get(isolate);
data->realms_[index].context.Reset();
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- data->realms_[index].microtask_queue.reset();
-#endif
context->DetachGlobal();
// ContextDisposedNotification expects the disposed context to be entered.
v8::Context::Scope scope(context);
@@ -2927,6 +3022,8 @@ void Shell::RealmCreate(const v8::FunctionCallbackInfo<v8::Value>& info) {
Local<Object> realm_options = info[0].As<Object>();
Local<Context> context = info.GetIsolate()->GetCurrentContext();
Local<Value> value;
+ v8::TryCatch try_catch(info.GetIsolate());
+ try_catch.SetVerbose(true);
if (realm_options
->Get(context, String::NewFromUtf8Literal(
info.GetIsolate(), "create_own_microtask_queue"))
@@ -3404,7 +3501,7 @@ void Shell::WasmSerializeModule(
i::DirectHandle<i::WasmModuleObject> module_obj =
i::Cast<i::WasmModuleObject>(Utils::OpenHandle(*info[0]));
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
module_obj->native_module();
DCHECK(!native_module->compilation_state()->failed());
@@ -3591,6 +3688,10 @@ void Shell::ResetOnProfileEndListener(Isolate* isolate) {
void Shell::ProfilerTriggerSample(
const v8::FunctionCallbackInfo<v8::Value>& info) {
+ // If the inspector is enabled, then the installed console is not the
+ // D8Console.
+ if (options.enable_inspector) return;
+
Isolate* isolate = info.GetIsolate();
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
D8Console* console =
@@ -3680,11 +3781,8 @@ void Shell::WriteStdout(const v8::FunctionCallbackInfo<v8::Value>& info) {
void Shell::WriteFile(const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate = info.GetIsolate();
- String::Utf8Value file_name(isolate, info[0]);
- if (*file_name == nullptr) {
- ThrowError(isolate, "Error converting filename to string");
- return;
- }
+ SafeUtf8Value file_name(isolate, info[0]);
+ if (!file_name) return;
FILE* file;
if (info.Length() == 2 &&
(info[1]->IsArrayBuffer() || info[1]->IsArrayBufferView())) {
@@ -3722,14 +3820,12 @@ void Shell::WriteFile(const v8::FunctionCallbackInfo<v8::Value>& info) {
void Shell::ReadFile(const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate = info.GetIsolate();
- String::Utf8Value file_name(isolate, info[0]);
- if (*file_name == nullptr) {
- ThrowError(isolate, "Error converting filename to string");
- return;
- }
+ SafeUtf8Value file_name(isolate, info[0]);
+ if (!file_name) return;
if (info.Length() == 2) {
- String::Utf8Value format(isolate, info[1]);
- if (*format && std::strcmp(*format, "binary") == 0) {
+ SafeUtf8Value format(isolate, info[1]);
+ if (!format) return;
+ if (std::strcmp(*format, "binary") == 0) {
ReadBuffer(info);
return;
}
@@ -3745,11 +3841,8 @@ void Shell::CreateWasmMemoryMapDescriptor(
Isolate* isolate = info.GetIsolate();
CHECK(i::v8_flags.wasm_memory_control);
DCHECK(i::ValidateCallbackInfo(info));
- String::Utf8Value file_name(isolate, info[0]);
- if (*file_name == nullptr) {
- ThrowError(isolate, "Error converting filename to string");
- return;
- }
+ SafeUtf8Value file_name(isolate, info[0]);
+ if (!file_name) return;
int file_descriptor = open(*file_name, O_RDWR);
@@ -3815,13 +3908,8 @@ void Shell::ExecuteFile(const v8::FunctionCallbackInfo<v8::Value>& info) {
for (int i = 0; i < info.Length(); i++) {
if (isolate->IsExecutionTerminating()) return;
HandleScope handle_scope(isolate);
- String::Utf8Value file_name(isolate, info[i]);
- if (*file_name == nullptr) {
- std::ostringstream oss;
- oss << "Cannot convert file[" << i << "] name to string.";
- ThrowError(isolate, oss.view());
- return;
- }
+ SafeUtf8Value file_name(isolate, info[i]);
+ if (!file_name) return;
if (!ExecuteSource(
isolate, Source::FromFile(*file_name),
String::NewFromUtf8(isolate, *file_name).ToLocalChecked(),
@@ -4105,14 +4193,14 @@ void Shell::WorkerNew(const v8::FunctionCallbackInfo<v8::Value>& info) {
return;
}
- // The C++ worker object's lifetime is shared between the Managed<Worker>
- // object on the heap, which the JavaScript object points to, and an
- // internal std::shared_ptr in the worker thread itself.
+ // The C++ worker object's lifetime is shared between the
+ // CppGCManaged<Worker> object on the heap, which the JavaScript object
+ // points to, and an internal std::shared_ptr in the worker thread itself.
auto worker = std::make_shared<Worker>(isolate, *script, flush_denormals);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
const size_t kWorkerSizeEstimate = 4 * 1024 * 1024; // stack + heap.
i::DirectHandle<i::Object> managed =
- i::Managed<Worker>::From(i_isolate, kWorkerSizeEstimate, worker);
+ i::CppGCManaged<Worker>::Create(i_isolate, kWorkerSizeEstimate, worker);
info.This()->SetInternalField(0, Utils::ToLocal(managed));
base::Thread::Priority priority =
options.apply_priority ? base::Thread::Priority::kUserBlocking
@@ -4135,7 +4223,7 @@ void Shell::WorkerPostMessage(const v8::FunctionCallbackInfo<v8::Value>& info) {
return;
}
- i::Managed<Worker>::Ptr worker =
+ i::CppGCManaged<Worker>::Ptr worker =
GetWorkerFromInternalField(isolate, info.This());
if (!worker) {
return;
@@ -4155,7 +4243,7 @@ void Shell::WorkerGetMessage(const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate = info.GetIsolate();
HandleScope handle_scope(isolate);
- i::Managed<Worker>::Ptr worker =
+ i::CppGCManaged<Worker>::Ptr worker =
GetWorkerFromInternalField(isolate, info.This());
if (!worker) {
return;
@@ -4285,7 +4373,7 @@ void Shell::WorkerOnMessageGetter(
Isolate* isolate = info.GetIsolate();
HandleScope handle_scope(isolate);
- i::Managed<Worker>::Ptr worker =
+ i::CppGCManaged<Worker>::Ptr worker =
GetWorkerFromInternalField(isolate, info.This());
if (!worker) {
return;
@@ -4311,7 +4399,7 @@ void Shell::WorkerOnMessageSetter(
return;
}
- i::Managed<Worker>::Ptr worker =
+ i::CppGCManaged<Worker>::Ptr worker =
GetWorkerFromInternalField(isolate, info.This());
if (!worker) {
return;
@@ -4329,7 +4417,7 @@ void Shell::WorkerTerminate(const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate = info.GetIsolate();
HandleScope handle_scope(isolate);
- i::Managed<Worker>::Ptr worker =
+ i::CppGCManaged<Worker>::Ptr worker =
GetWorkerFromInternalField(isolate, info.This());
if (!worker) return;
worker->Terminate();
@@ -4340,7 +4428,7 @@ void Shell::WorkerTerminateAndWait(
DCHECK(i::ValidateCallbackInfo(info));
Isolate* isolate = info.GetIsolate();
HandleScope handle_scope(isolate);
- i::Managed<Worker>::Ptr worker =
+ i::CppGCManaged<Worker>::Ptr worker =
GetWorkerFromInternalField(isolate, info.This());
if (!worker) {
return;
@@ -4777,11 +4865,8 @@ void Shell::ChangeDirectoryCallback(
ThrowError(isolate, "chdir() takes one argument");
return;
}
- String::Utf8Value directory(isolate, info[0]);
- if (*directory == nullptr) {
- ThrowError(isolate, "os.chdir(): String conversion of argument failed.");
- return;
- }
+ SafeUtf8Value directory(isolate, info[0]);
+ if (!directory) return;
if (!Shell::ChangeWorkingDirectory(*directory, /*print_error=*/false)) {
ThrowError(isolate, "os.chdir(): Failed to change directory");
return;
@@ -4972,6 +5057,18 @@ Local<ObjectTemplate> Shell::CreateD8Template(Isolate* isolate) {
isolate, "setFlushDenormals",
FunctionTemplate::New(isolate, Shell::SetFlushDenormals));
+ test_template->Set(
+ isolate, "createInterceptorObject",
+ FunctionTemplate::New(isolate, Shell::CreateInterceptorObject));
+ test_template->Set(
+ isolate, "createAccessCheckedObject",
+ FunctionTemplate::New(isolate, Shell::CreateAccessCheckedObject));
+ test_template->Set(
+ isolate, "createSpecialObject",
+ FunctionTemplate::New(isolate, Shell::CreateSpecialObject));
+ test_template->Set(isolate, "setAccessPolicy",
+ FunctionTemplate::New(isolate, Shell::SetAccessPolicy));
+
d8_template->Set(isolate, "test", test_template);
}
{
@@ -5311,7 +5408,7 @@ void WriteWasmLcovData(v8::Isolate* isolate, const char* file) {
debug::Coverage::ScriptData script_data = coverage.GetScriptData(i_script);
Local<debug::Script> script = script_data.GetScript();
auto wasm_script = Utils::OpenDirectHandle(*script);
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
wasm_script->wasm_native_module();
const i::wasm::WasmModule* wasm_module = native_module->module();
@@ -5715,11 +5812,8 @@ void Shell::ReadBuffer(const v8::FunctionCallbackInfo<v8::Value>& info) {
static_assert(sizeof(char) == sizeof(uint8_t),
"char and uint8_t should both have 1 byte");
Isolate* isolate = info.GetIsolate();
- String::Utf8Value filename(isolate, info[0]);
- if (*filename == nullptr) {
- ThrowError(isolate, "Error loading file");
- return;
- }
+ SafeUtf8Value filename(isolate, info[0]);
+ if (!filename) return;
base::OwnedVector<char> data = ReadChars(*filename);
if (data.data() == nullptr) {
@@ -5779,13 +5873,7 @@ MaybeLocal<String> Shell::ReadFile(Isolate* isolate, const char* name,
static_assert(String::kMaxLength <= i::kMaxInt);
int size = static_cast<int>(full_file_size);
char* chars = static_cast<char*>(file->memory());
- if (i::v8_flags.use_external_strings && i::String::IsAscii(chars, size)) {
- String::ExternalOneByteStringResource* resource =
- new i::OwningExternalOneByteStringResource(
- std::string_view(chars, size));
- return String::NewExternalOneByte(isolate, resource);
- }
- return String::NewFromUtf8(isolate, chars, NewStringType::kNormal, size);
+ return CreateStringFromExternalData(isolate, std::string_view(chars, size));
}
void Shell::WriteChars(const char* name, uint8_t* buffer, size_t buffer_size) {
@@ -5883,12 +5971,12 @@ class InspectorFrontend final : public v8_inspector::V8Inspector::Channel {
.ToLocalChecked();
Local<String> callback_name = v8::String::NewFromUtf8Literal(
isolate_, "receive", NewStringType::kInternalized);
+ v8::TryCatch try_catch(isolate_);
Local<Value> callback;
if (!context->Global()->Get(context, callback_name).ToLocal(&callback)) {
return;
}
if (callback->IsFunction()) {
- v8::TryCatch try_catch(isolate_);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate_);
i::DirectHandle<i::Object> i_callback =
Utils::OpenDirectHandle(*callback);
@@ -5965,6 +6053,7 @@ class InspectorClient : public v8_inspector::V8InspectorClient {
void runMessageLoopOnPause(int contextGroupId) override {
v8::Isolate::AllowJavascriptExecutionScope allow_script(isolate_);
v8::HandleScope handle_scope(isolate_);
+ v8::TryCatch try_catch(isolate_);
Local<String> callback_name = v8::String::NewFromUtf8Literal(
isolate_, "handleInspectorMessage", NewStringType::kInternalized);
Local<Context> context = context_.Get(isolate_);
@@ -5982,7 +6071,6 @@ class InspectorClient : public v8_inspector::V8InspectorClient {
heap, i::EmbedderStackStateOrigin::kExplicitInvocation,
v8::StackState::kMayContainHeapPointers);
- v8::TryCatch try_catch(isolate_);
try_catch.SetVerbose(true);
is_paused = true;
@@ -6017,7 +6105,8 @@ class InspectorClient : public v8_inspector::V8InspectorClient {
v8::HandleScope handle_scope(isolate);
Local<Context> context = isolate->GetCurrentContext();
info.GetReturnValue().Set(Undefined(isolate));
- Local<String> message = info[0]->ToString(context).ToLocalChecked();
+ Local<String> message;
+ if (!info[0]->ToString(context).ToLocal(&message)) return;
v8_inspector::V8InspectorSession* session =
InspectorClient::GetSession(context);
if (!session) return;
@@ -6034,9 +6123,9 @@ class InspectorClient : public v8_inspector::V8InspectorClient {
static const int kContextGroupId = 1;
+ std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_;
std::unique_ptr<v8_inspector::V8Inspector> inspector_;
std::unique_ptr<v8_inspector::V8InspectorSession> session_;
- std::unique_ptr<v8_inspector::V8Inspector::Channel> channel_;
bool is_paused = false;
Global<Context> context_;
Isolate* isolate_ = nullptr;
@@ -6344,6 +6433,7 @@ void SourceGroup::ExecuteInThread() {
for (int i = 0; i < Shell::options.stress_runs; ++i) {
next_semaphore_.ParkedWait(
reinterpret_cast<i::Isolate*>(isolate)->main_thread_local_isolate());
+ if (terminate_) break;
{
Global<Context> global_context;
HandleScope scope(isolate);
@@ -6395,7 +6485,11 @@ void SourceGroup::WaitForThread(const i::ParkedScope& parked) {
void SourceGroup::JoinThread(const i::ParkedScope& parked) {
USE(parked);
if (thread_ == nullptr) return;
+ terminate_ = true;
+ next_semaphore_.Signal();
thread_->Join();
+ delete thread_;
+ thread_ = nullptr;
}
void SerializationDataQueue::Enqueue(std::unique_ptr<SerializationData> data) {
@@ -6427,7 +6521,8 @@ Worker::Worker(Isolate* parent_isolate, const char* script,
bool flush_denormals)
: script_(i::StrDup(script)),
flush_denormals_(flush_denormals),
- parent_isolate_(parent_isolate) {
+ parent_isolate_(parent_isolate),
+ parent_task_runner_(g_platform->GetForegroundTaskRunner(parent_isolate)) {
state_.store(State::kReady);
}
@@ -6450,7 +6545,17 @@ bool Worker::StartWorkerThread(Isolate* requester,
worker->state_.compare_exchange_strong(expected, State::kPrepareRunning));
auto thread = new WorkerThread(worker, priority);
worker->thread_ = thread;
- if (!thread->Start()) return false;
+ if (!thread->Start()) {
+ // If starting the thread fails, we must clean up the thread object and
+ // clear worker->thread_. Otherwise, the strong reference cycle (Worker <->
+ // WorkerThread) prevents the Worker shared_ptr from being freed, leaking
+ // script_ and the Worker instance.
+ // If starting succeeds, this cycle is resolved in WorkerThread::Run().
+ worker->thread_ = nullptr;
+ worker->state_.store(State::kTerminated);
+ delete thread;
+ return false;
+ }
// Wait until the worker is ready to receive messages.
worker->started_semaphore_.ParkedWait(
reinterpret_cast<i::Isolate*>(requester)->main_thread_local_isolate());
@@ -6790,9 +6895,8 @@ void Worker::ExecuteInThread() {
out_semaphore_.Signal();
// Also post an cleanup task to the parent isolate, so that it sees that this
// worker is terminated and can clean it up in a thread-safe way.
- g_platform->GetForegroundTaskRunner(parent_isolate_)
- ->PostTask(std::make_unique<CleanUpWorkerTask>(parent_isolate_,
- this->shared_from_this()));
+ parent_task_runner_->PostTask(std::make_unique<CleanUpWorkerTask>(
+ parent_isolate_, this->shared_from_this()));
}
void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& info) {
@@ -6817,8 +6921,8 @@ void Worker::PostMessageOut(const v8::FunctionCallbackInfo<v8::Value>& info) {
worker->out_queue_.Enqueue(std::move(data));
worker->out_semaphore_.Signal();
- g_platform->GetForegroundTaskRunner(worker->parent_isolate_)
- ->PostTask(std::make_unique<CheckMessageFromWorkerTask>(
+ worker->parent_task_runner_->PostTask(
+ std::make_unique<CheckMessageFromWorkerTask>(
worker->parent_isolate_, worker->shared_from_this()));
}
}
@@ -7116,6 +7220,9 @@ bool Shell::SetOptions(int argc, char* argv[]) {
#ifdef V8_FUZZILLI
} else if (FlagMatches("--fuzzilli-enable-builtins-coverage", &argv[i])) {
options.fuzzilli_enable_builtins_coverage = true;
+ } else if (FlagMatches("--no-fuzzilli-enable-builtins-coverage",
+ &argv[i])) {
+ options.fuzzilli_enable_builtins_coverage = false;
} else if (FlagMatches("--fuzzilli-coverage-statistics", &argv[i])) {
options.fuzzilli_coverage_statistics = true;
#endif
@@ -7208,6 +7315,17 @@ bool Shell::SetOptions(int argc, char* argv[]) {
}
#endif
+ if (options.compile_only &&
+ options.code_cache_options ==
+ ShellOptions::CodeCacheOptions::kProduceCacheAfterExecute) {
+ fprintf(stderr,
+ "Flag --compile-only is incompatible with --cache=after-execute:\n"
+ " --compile-only: Only parse and compile; do not execute.\n"
+ " --cache=after-execute: Execute first, then serialize and cache "
+ "the post-execution state.\n");
+ return false;
+ }
+
const char* usage =
"Synopsis:\n"
" shell [options] [--shell] [<file>...]\n"
@@ -7239,6 +7357,17 @@ bool Shell::SetOptions(int argc, char* argv[]) {
FATAL("Flag --expose-fast-api is incompatible with --stress-snapshot.");
}
+ if (options.trace_enabled && i::v8_flags.predictable) {
+ if (check_d8_flag_contradictions) {
+ FATAL("Flag --enable-tracing is incompatible with --predictable.");
+ } else {
+ fprintf(stderr,
+ "Warning: disabling flag --enable-tracing due to conflicting "
+ "flags\n");
+ options.trace_enabled = false;
+ }
+ }
+
// Set up isolated source groups.
options.num_isolates = 1;
for (int i = 1; i < argc; i++) {
@@ -7277,6 +7406,36 @@ bool Shell::SetOptions(int argc, char* argv[]) {
return true;
}
+namespace {
+
+void WaitForAllWorkerAndIsolateThreads(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i_isolate->main_thread_local_heap()->ExecuteMainThreadWhileParked(
+ [](const i::ParkedScope& parked) {
+ for (int i = 1; i < Shell::options.num_isolates; ++i) {
+ if (!Shell::options.bundle) {
+ Shell::options.isolate_sources[i].WaitForThread(parked);
+ }
+ }
+ Shell::WaitForRunningWorkers(parked);
+ });
+}
+
+void JoinAllWorkerAndIsolateThreads(Isolate* isolate) {
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ i_isolate->main_thread_local_heap()->ExecuteMainThreadWhileParked(
+ [](const i::ParkedScope& parked) {
+ for (int i = 1; i < Shell::options.num_isolates; ++i) {
+ if (!Shell::options.bundle) {
+ Shell::options.isolate_sources[i].JoinThread(parked);
+ }
+ }
+ Shell::WaitForRunningWorkers(parked);
+ });
+}
+
+} // namespace
+
int Shell::RunMain(v8::Isolate* isolate, bool last_run) {
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@@ -7295,19 +7454,11 @@ int Shell::RunMain(v8::Isolate* isolate, bool last_run) {
// Park the main thread here to prevent deadlocks in shared GCs when
// waiting in JoinThread.
- i_isolate->main_thread_local_heap()->ExecuteMainThreadWhileParked(
- [last_run](const i::ParkedScope& parked) {
- for (int i = 1; i < options.num_isolates; ++i) {
- if (!options.bundle) {
- if (last_run) {
- options.isolate_sources[i].JoinThread(parked);
- } else {
- options.isolate_sources[i].WaitForThread(parked);
- }
- }
- }
- WaitForRunningWorkers(parked);
- });
+ if (last_run) {
+ JoinAllWorkerAndIsolateThreads(isolate);
+ } else {
+ WaitForAllWorkerAndIsolateThreads(isolate);
+ }
// Other threads have terminated, we can now run the artificial
// serialize-deserialize pass (which destructively mutates heap state).
@@ -7433,7 +7584,7 @@ bool ProcessMessages(
// task queue of the {kProcessGlobalPredictablePlatformWorkerTaskQueue}
// isolate. We execute all background tasks after running one foreground
// task.
- if (i::v8_flags.verify_predictable) {
+ if (i::v8_flags.predictable) {
TryCatch inner_try_catch(isolate);
inner_try_catch.SetVerbose(true);
while (v8::platform::PumpMessageLoop(
@@ -7468,7 +7619,7 @@ bool Shell::CompleteMessageLoop(Isolate* isolate) {
}
return platform::MessageLoopBehavior::kDoNotWait;
};
- if (i::v8_flags.verify_predictable) {
+ if (i::v8_flags.predictable) {
bool ran_tasks = ProcessMessages(
isolate, [] { return platform::MessageLoopBehavior::kDoNotWait; });
if (get_waiting_behaviour() ==
@@ -7512,7 +7663,8 @@ class Serializer : public ValueSerializer::Delegate {
public:
explicit Serializer(Isolate* isolate)
: isolate_(isolate),
- serializer_(isolate, this),
+ serializer_(isolate, this,
+ ValueSerializer::SharedImmutableArrayBufferMode::kEnabled),
current_memory_usage_(0) {}
Serializer(const Serializer&) = delete;
@@ -7540,6 +7692,8 @@ class Serializer : public ValueSerializer::Delegate {
std::pair<uint8_t*, size_t> pair = serializer_.Release();
data_->data_.reset(pair.first);
data_->size_ = pair.second;
+ data_->shared_immutable_backing_stores_ =
+ serializer_.ReleaseSharedImmutableBackingStores();
return Just(true);
}
@@ -7689,6 +7843,8 @@ class Deserializer : public ValueDeserializer::Delegate {
deserializer_(isolate, data->data(), data->size(), this),
data_(std::move(data)) {
deserializer_.SetSupportsLegacyWireFormat(true);
+ deserializer_.SetSharedImmutableBackingStores(
+ data_->shared_immutable_backing_stores());
}
Deserializer(const Deserializer&) = delete;
@@ -7923,7 +8079,7 @@ int Shell::Main(int argc, char* argv[]) {
std::ofstream trace_file;
std::unique_ptr<platform::tracing::TracingController> tracing;
- if (options.trace_enabled && !i::v8_flags.verify_predictable) {
+ if (options.trace_enabled && !i::v8_flags.predictable) {
tracing = std::make_unique<platform::tracing::TracingController>();
if (!options.enable_etw_stack_walking) {
@@ -8108,10 +8264,11 @@ int Shell::Main(int argc, char* argv[]) {
#ifdef V8_FUZZILLI
if (options.fuzzilli_enable_builtins_coverage) {
- cov_init_builtins_edges(static_cast<uint32_t>(
- i::BasicBlockProfiler::Get()
- ->GetCoverageBitmap(reinterpret_cast<i::Isolate*>(isolate))
- .size()));
+ uint32_t count = i::BasicBlockProfiler::Get()->GetBuiltinsBlockCount(
+ reinterpret_cast<i::Isolate*>(isolate));
+ if (count > 0) {
+ cov_init_builtins_edges(count);
+ }
}
// Let the parent process (Fuzzilli) know we are ready.
@@ -8169,6 +8326,11 @@ int Shell::Main(int argc, char* argv[]) {
if (options.trace_config) {
base::OwnedVector<char> trace_config_json_str =
ReadChars(options.trace_config);
+ if (trace_config_json_str.data() == nullptr) {
+ printf("Failed to read trace config from '%s'\n",
+ options.trace_config.get());
+ base::OS::ExitProcess(1);
+ }
trace_config = tracing::CreateTraceConfigFromJSON(
isolate, trace_config_json_str.as_vector());
} else {
@@ -8193,9 +8355,15 @@ int Shell::Main(int argc, char* argv[]) {
for (int i = 0; i < options.stress_runs; i++) {
printf("============ Run %d/%d ============\n", i + 1,
options.stress_runs.get());
- bool last_run = i == options.stress_runs - 1;
- int this_result = RunMain(isolate, last_run);
- if (this_result != 0) result = this_result;
+ bool is_last_run = i == options.stress_runs - 1;
+ int this_result = RunMain(isolate, is_last_run);
+ if (this_result != 0) {
+ result = this_result;
+ if (!is_last_run) {
+ JoinAllWorkerAndIsolateThreads(isolate);
+ }
+ break;
+ }
}
} else if (options.code_cache_options != ShellOptions::kNoProduceCache) {
// Park the main thread here in case the new isolate wants to perform
@@ -8219,7 +8387,7 @@ int Shell::Main(int argc, char* argv[]) {
Initialize(isolate2, console2);
PerIsolateData data2(isolate2);
- result = RunMain(isolate2, false);
+ result = RunMain(isolate2, /*last_run=*/false);
ResetOnProfileEndListener(isolate2);
}
// D8WasmAsyncResolvePromiseTask may be still in the runner at
@@ -8245,12 +8413,11 @@ int Shell::Main(int argc, char* argv[]) {
printf("============ Run: Consume code cache ============\n");
// Second run to consume the cache in current isolate
- result = RunMain(isolate, true);
+ result = RunMain(isolate, /*last_run=*/true);
options.compile_options.Overwrite(
v8::ScriptCompiler::kNoCompileOptions);
} else {
- bool last_run = true;
- result = RunMain(isolate, last_run);
+ result = RunMain(isolate, /*last_run=*/true);
}
// Run interactive shell if explicitly requested or if no script has been
@@ -8289,13 +8456,10 @@ int Shell::Main(int argc, char* argv[]) {
// Send result to parent (fuzzilli) and reset edge guards.
if (fuzzilli_reprl) {
int status = result << 8;
- std::vector<bool> bitmap;
- if (options.fuzzilli_enable_builtins_coverage) {
- bitmap = i::BasicBlockProfiler::Get()->GetCoverageBitmap(
- reinterpret_cast<i::Isolate*>(isolate));
- cov_update_builtins_basic_block_coverage(bitmap);
- }
if (options.fuzzilli_coverage_statistics) {
+ std::vector<bool> bitmap =
+ i::BasicBlockProfiler::Get()->GetCoverageBitmap(
+ reinterpret_cast<i::Isolate*>(isolate));
int tot = 0;
for (bool b : bitmap) {
if (b) tot++;
@@ -8307,16 +8471,21 @@ int Shell::Main(int argc, char* argv[]) {
<< bitmap.size() << std::endl;
iteration_counter++;
}
+ // This is run once per REPRL loop. In case of crash the coverage of
+ // crash will not be stored in shared memory. Therefore, it would be
+ // useful, if we could store these coverage information into shared
+ // memory in real time.
+ if (options.fuzzilli_enable_builtins_coverage &&
+ cov_has_builtins_edges()) {
+ i::BasicBlockProfiler::Get()->ForEachExecutedBlockAndReset(
+ reinterpret_cast<i::Isolate*>(isolate), cov_set_builtin_edge);
+ }
// In REPRL mode, stdout and stderr can be regular files, so they need
// to be flushed after every execution
fflush(stdout);
fflush(stderr);
CHECK_EQ(write(REPRL_CWFD, &status, 4), 4);
sanitizer_cov_reset_edgeguards();
- if (options.fuzzilli_enable_builtins_coverage) {
- i::BasicBlockProfiler::Get()->ResetCounts(
- reinterpret_cast<i::Isolate*>(isolate));
- }
}
#endif // V8_FUZZILLI
} while (fuzzilli_reprl);
diff --git a/deps/v8/src/d8/d8.h b/deps/v8/src/d8/d8.h
index f9991694ff8..c6a696def8e 100644
--- a/deps/v8/src/d8/d8.h
+++ b/deps/v8/src/d8/d8.h
@@ -5,6 +5,7 @@
#ifndef V8_D8_D8_H_
#define V8_D8_D8_H_
+#include <atomic>
#include <iterator>
#include <map>
#include <memory>
@@ -61,6 +62,36 @@ inline Local<Value> ThrowException(Isolate* isolate, Local<Value> exception) {
return isolate->ThrowException(exception);
}
+// Converts a v8::Value to a UTF-8 string safely.
+// Unlike v8::String::Utf8Value, this does not swallow user exceptions or
+// terminate silently on string conversion failure.
+class SafeUtf8Value {
+ public:
+ SafeUtf8Value(Isolate* isolate, Local<Value> value)
+ : SafeUtf8Value(isolate, isolate->GetCurrentContext(), value) {}
+
+ SafeUtf8Value(Isolate* isolate, Local<Context> context, Local<Value> value) {
+ if (value.IsEmpty()) return;
+ Local<String> str;
+ if (value->ToString(context).ToLocal(&str)) {
+ utf8_.emplace(isolate, str);
+ }
+ }
+
+ bool is_valid() const { return utf8_.has_value(); }
+ explicit operator bool() const { return is_valid(); }
+
+ const char* operator*() const { return is_valid() ? **utf8_ : nullptr; }
+ char* operator*() { return is_valid() ? **utf8_ : nullptr; }
+ size_t length() const { return is_valid() ? utf8_->length() : 0; }
+ std::string_view as_view() const {
+ return is_valid() ? utf8_->as_view() : std::string_view();
+ }
+
+ private:
+ std::optional<v8::String::Utf8Value> utf8_;
+};
+
class BackingStore;
class CompiledWasmModule;
class D8Console;
@@ -168,6 +199,7 @@ class SourceGroup {
i::ParkingSemaphore next_semaphore_;
i::ParkingSemaphore done_semaphore_;
base::Thread* thread_;
+ std::atomic<bool> terminate_{false};
void ExitShell(int exit_code);
@@ -193,6 +225,10 @@ class SerializationData {
const std::vector<CompiledWasmModule>& compiled_wasm_modules() {
return compiled_wasm_modules_;
}
+ const std::vector<std::shared_ptr<v8::BackingStore>>&
+ shared_immutable_backing_stores() {
+ return shared_immutable_backing_stores_;
+ }
const std::optional<v8::SharedValueConveyor>& shared_value_conveyor() {
return shared_value_conveyor_;
}
@@ -206,6 +242,8 @@ class SerializationData {
size_t size_ = 0;
std::vector<std::shared_ptr<v8::BackingStore>> backing_stores_;
std::vector<std::shared_ptr<v8::BackingStore>> sab_backing_stores_;
+ std::vector<std::shared_ptr<v8::BackingStore>>
+ shared_immutable_backing_stores_;
std::vector<CompiledWasmModule> compiled_wasm_modules_;
std::optional<v8::SharedValueConveyor> shared_value_conveyor_;
@@ -227,7 +265,7 @@ class SerializationDataQueue {
class Worker : public std::enable_shared_from_this<Worker> {
public:
- static constexpr i::ExternalPointerTag kManagedTag = i::kD8WorkerTag;
+ static constexpr i::ManagedTypeId kTypeID = i::ManagedTypeId::kD8Worker;
explicit Worker(Isolate* parent_isolate, const char* script,
bool flush_denormals);
@@ -328,6 +366,7 @@ class Worker : public std::enable_shared_from_this<Worker> {
// the worker_mutex_ and after checking the worker state.
Isolate* isolate_ = nullptr;
Isolate* parent_isolate_;
+ std::shared_ptr<TaskRunner> parent_task_runner_;
// Only accessed by the worker thread.
Global<Context> context_;
@@ -335,22 +374,10 @@ class Worker : public std::enable_shared_from_this<Worker> {
struct Realm {
Global<Context> context;
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- std::unique_ptr<v8::MicrotaskQueue> microtask_queue;
-#endif
Realm() = default;
-#ifdef V8_CPPGC_MICROTASK_QUEUE
Realm(Isolate* isolate, const Global<Context>& ctx) : context(isolate, ctx) {}
Realm(Isolate* isolate, Local<Context> ctx) : context(isolate, ctx) {}
-#else
- Realm(Isolate* isolate, const Global<Context>& ctx,
- std::unique_ptr<v8::MicrotaskQueue> mq = nullptr)
- : context(isolate, ctx), microtask_queue(std::move(mq)) {}
- Realm(Isolate* isolate, Local<Context> ctx,
- std::unique_ptr<v8::MicrotaskQueue> mq = nullptr)
- : context(isolate, ctx), microtask_queue(std::move(mq)) {}
-#endif
};
class PerIsolateData {
@@ -519,7 +546,13 @@ class ShellOptions {
DisallowReassignment<bool> fuzzilli_coverage_statistics = {
"fuzzilli-coverage-statistics", false};
DisallowReassignment<bool> fuzzilli_enable_builtins_coverage = {
- "fuzzilli-enable-builtins-coverage", false};
+ "fuzzilli-enable-builtins-coverage",
+#ifdef V8_ENABLE_BUILTINS_PROFILING
+ true
+#else
+ false
+#endif
+ };
DisallowReassignment<bool> send_idle_notification = {"send-idle-notification",
false};
DisallowReassignment<bool> invoke_weak_callbacks = {"invoke-weak-callbacks",
@@ -980,6 +1013,13 @@ class Shell : public i::AllStatic {
static Local<FunctionTemplate> CreateTestFastCApiTemplate(Isolate* isolate);
static Local<FunctionTemplate> CreateLeafInterfaceTypeTemplate(
Isolate* isolate);
+ static void CreateInterceptorObject(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void CreateAccessCheckedObject(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void CreateSpecialObject(
+ const v8::FunctionCallbackInfo<v8::Value>& info);
+ static void SetAccessPolicy(const v8::FunctionCallbackInfo<v8::Value>& info);
static MaybeLocal<Context> CreateRealm(
const v8::FunctionCallbackInfo<v8::Value>& info, int index,
@@ -996,22 +1036,25 @@ class Shell : public i::AllStatic {
const std::string& file_name,
ModuleType module_type);
- static MaybeLocal<Value> JSONModuleEvaluationSteps(Local<Context> context,
- Local<Module> module);
- static MaybeLocal<Value> TextModuleEvaluationSteps(Local<Context> context,
- Local<Module> module);
- static MaybeLocal<Value> BytesModuleEvaluationSteps(Local<Context> context,
- Local<Module> module);
+ static MaybeLocal<Promise> JSONModuleEvaluationSteps(Local<Context> context,
+ Local<Module> module);
+ static MaybeLocal<Promise> TextModuleEvaluationSteps(Local<Context> context,
+ Local<Module> module);
+ static MaybeLocal<Promise> BytesModuleEvaluationSteps(Local<Context> context,
+ Local<Module> module);
template <class T>
static MaybeLocal<T> CompileSource(Isolate* isolate, Local<Context> context,
const Source& source,
const ScriptOrigin& origin);
- static ScriptCompiler::CachedData* LookupCodeCache(Isolate* isolate,
- Local<Value> name);
+ static ScriptCompiler::CachedData* LookupCodeCache(
+ Isolate* isolate, Local<Value> name,
+ ScriptType type = ScriptType::kClassic);
static void StoreInCodeCache(Isolate* isolate, Local<Value> name,
- const ScriptCompiler::CachedData* data);
+ const ScriptCompiler::CachedData* data,
+ ScriptType type = ScriptType::kClassic);
+ static void ProduceModuleCodeCacheAfterExecute(Isolate* isolate);
// We may have multiple isolates running concurrently, so the access to
// the isolate_status_ needs to be concurrency-safe.
@@ -1019,9 +1062,12 @@ class Shell : public i::AllStatic {
static std::map<Isolate*, bool> isolate_status_;
static std::map<Isolate*, int> isolate_running_streaming_tasks_;
+ using CodeCacheKey = std::pair<std::string, ScriptType>;
+ using CodeCacheMap =
+ std::map<CodeCacheKey, std::unique_ptr<ScriptCompiler::CachedData>>;
+
static base::LazyMutex cached_code_mutex_;
- static std::map<std::string, std::unique_ptr<ScriptCompiler::CachedData>>
- cached_code_map_;
+ static CodeCacheMap cached_code_map_;
static std::atomic<int> unhandled_promise_rejections_;
#if V8_ENABLE_WEBASSEMBLY
diff --git a/deps/v8/src/d8/hardware-watchpoints.cc b/deps/v8/src/d8/hardware-watchpoints.cc
index 0d2e7b9a2f4..547bd73fb6f 100644
--- a/deps/v8/src/d8/hardware-watchpoints.cc
+++ b/deps/v8/src/d8/hardware-watchpoints.cc
@@ -4,6 +4,7 @@
#include "src/d8/hardware-watchpoints.h"
+#include "src/d8/d8.h"
#include "src/d8/memory-access-information.h"
#ifdef V8_ENABLE_HARDWARE_WATCHPOINT_SUPPORT
@@ -865,11 +866,8 @@ void SetHardwareWatchpointCallback(
int32_t offset;
if (!info[1]->IsInt32() || !info[1]->Int32Value(context).To(&offset)) {
- v8::String::Utf8Value field_name(isolate, info[1]);
- if (!*field_name) {
- ThrowTypeError(isolate, "Second argument must be an integer or a string");
- return;
- }
+ SafeUtf8Value field_name(isolate, info[1]);
+ if (!field_name) return;
i::InstanceType instance_type = object->map()->instance_type();
if (std::optional<int> offset_from_name = i::SandboxTesting::GetFieldOffset(
diff --git a/deps/v8/src/debug/debug-coverage.cc b/deps/v8/src/debug/debug-coverage.cc
index 3666b1a52a7..9f041644d09 100644
--- a/deps/v8/src/debug/debug-coverage.cc
+++ b/deps/v8/src/debug/debug-coverage.cc
@@ -646,7 +646,7 @@ std::unique_ptr<Coverage> Coverage::CollectWasmData(Isolate* isolate) {
// Create and add new script data.
result->emplace_back(handle(script, isolate));
std::vector<CoverageFunction>* functions = &result->back().functions;
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const wasm::WasmModule* wasm_module = native_module->module();
const wasm::WasmModuleCoverageData* coverage_data =
diff --git a/deps/v8/src/debug/debug-evaluate.cc b/deps/v8/src/debug/debug-evaluate.cc
index d14f6806a01..654f7cca139 100644
--- a/deps/v8/src/debug/debug-evaluate.cc
+++ b/deps/v8/src/debug/debug-evaluate.cc
@@ -78,11 +78,9 @@ MaybeDirectHandle<Object> DebugEvaluate::Global(Isolate* isolate,
return result;
}
-MaybeDirectHandle<Object> DebugEvaluate::Local(Isolate* isolate,
- StackFrameId frame_id,
- int inlined_jsframe_index,
- DirectHandle<String> source,
- bool throw_on_side_effect) {
+MaybeDirectHandle<Object> DebugEvaluate::Local(
+ Isolate* isolate, StackFrameId frame_id, int inlined_jsframe_index,
+ DirectHandle<String> source, bool throw_on_side_effect, int scope_index) {
// Handle the processing of break.
DisableBreak disable_break_scope(isolate->debug());
@@ -115,10 +113,12 @@ MaybeDirectHandle<Object> DebugEvaluate::Local(Isolate* isolate,
// the materialized object are written back afterwards.
// Note that the native context is taken from the original context chain,
// which may not be the current native context of the isolate.
- ContextBuilder context_builder(isolate, frame, inlined_jsframe_index);
+ ContextBuilder context_builder(isolate, frame, inlined_jsframe_index,
+ scope_index);
if (isolate->has_exception()) return {};
DirectHandle<Context> context = context_builder.evaluation_context();
+ if (context.is_null()) return {};
DirectHandle<JSObject> receiver(context->global_proxy(), isolate);
MaybeDirectHandle<Object> maybe_result =
Evaluate(isolate, context_builder.outer_info(), context, receiver, source,
@@ -201,17 +201,25 @@ DirectHandle<SharedFunctionInfo> DebugEvaluate::ContextBuilder::outer_info()
DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
JavaScriptFrame* frame,
- int inlined_jsframe_index)
+ int inlined_jsframe_index,
+ int scope_index)
: isolate_(isolate),
frame_inspector_(frame, inlined_jsframe_index, isolate),
scope_iterator_(isolate, &frame_inspector_,
- ScopeIterator::ReparseStrategy::kScriptIfNeeded) {
- Handle<Context> outer_context(frame_inspector_.GetFunction()->context(),
- isolate);
- evaluation_context_ = outer_context;
+ ScopeIterator::ReparseStrategy::kScriptIfNeeded),
+ scope_index_(scope_index) {
Factory* factory = isolate->factory();
- if (scope_iterator_.Done()) return;
+ if (!scope_iterator_.AdvanceToScopeNumber(scope_index)) {
+ return;
+ }
+
+ if (scope_iterator_.InInnerScope()) {
+ evaluation_context_ =
+ handle(frame_inspector_.GetFunction()->context(), isolate);
+ } else {
+ evaluation_context_ = scope_iterator_.CurrentContext();
+ }
// To evaluate as if we were running eval at the point of the debug break,
// we reconstruct the context chain as follows:
@@ -279,10 +287,24 @@ DebugEvaluate::ContextBuilder::ContextBuilder(Isolate* isolate,
evaluation_context_, scope_info, element.materialized_object,
element.wrapped_context);
}
+
+ 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.
+ scope_info = ScopeInfo::CreateForWithScope(isolate, scope_info);
+ scope_info->SetIsDebugEvaluateScope();
+ evaluation_context_ = factory->NewDebugEvaluateContext(
+ evaluation_context_, scope_info, DirectHandle<JSReceiver>(),
+ evaluation_context_);
+ }
}
void DebugEvaluate::ContextBuilder::UpdateValues() {
scope_iterator_.Restart();
+ scope_iterator_.AdvanceToScopeNumber(scope_index_);
for (ContextChainElement& element : context_chain_) {
if (!element.materialized_object.is_null()) {
DirectHandle<FixedArray> keys =
diff --git a/deps/v8/src/debug/debug-evaluate.h b/deps/v8/src/debug/debug-evaluate.h
index ad004f89d85..208f9f85412 100644
--- a/deps/v8/src/debug/debug-evaluate.h
+++ b/deps/v8/src/debug/debug-evaluate.h
@@ -38,7 +38,8 @@ class DebugEvaluate : public AllStatic {
// provided to peek into the Wasm state.
static V8_EXPORT_PRIVATE MaybeDirectHandle<Object> Local(
Isolate* isolate, StackFrameId frame_id, int inlined_jsframe_index,
- DirectHandle<String> source, bool throw_on_side_effect);
+ DirectHandle<String> source, bool throw_on_side_effect,
+ int scope_index = 0);
// This is used for break-at-entry for builtins and API functions.
// Evaluate a piece of JavaScript in the native context, but with the
@@ -77,7 +78,7 @@ class DebugEvaluate : public AllStatic {
class ContextBuilder {
public:
ContextBuilder(Isolate* isolate, JavaScriptFrame* frame,
- int inlined_jsframe_index);
+ int inlined_jsframe_index, int scope_index = 0);
void UpdateValues();
@@ -98,6 +99,7 @@ class DebugEvaluate : public AllStatic {
Isolate* isolate_;
FrameInspector frame_inspector_;
ScopeIterator scope_iterator_;
+ int scope_index_;
};
static MaybeDirectHandle<Object> Evaluate(
diff --git a/deps/v8/src/debug/debug-interface.cc b/deps/v8/src/debug/debug-interface.cc
index 313d625d254..08deeaefdf4 100644
--- a/deps/v8/src/debug/debug-interface.cc
+++ b/deps/v8/src/debug/debug-interface.cc
@@ -26,6 +26,7 @@
#include "src/objects/js-generator-inl.h"
#include "src/objects/script-inl.h"
#include "src/objects/shared-function-info-inl.h"
+#include "src/objects/templates-inl.h"
#include "src/profiler/heap-profiler.h"
#include "src/strings/string-builder-inl.h"
@@ -456,8 +457,8 @@ size_t ScriptSource::Length() const {
size_t ScriptSource::Size() const {
auto source = Utils::OpenDirectHandle(this);
#if V8_ENABLE_WEBASSEMBLY
- if (IsForeign(*source)) {
- return i::Cast<i::Managed<i::wasm::NativeModule>>(*source)
+ if (i::Is<i::CppGCManaged<i::wasm::NativeModule>>(*source)) {
+ return i::Cast<i::CppGCManaged<i::wasm::NativeModule>>(*source)
->ptr()
->wire_bytes()
.size();
@@ -478,8 +479,8 @@ MaybeLocal<String> ScriptSource::JavaScriptCode() const {
Maybe<std::vector<uint8_t>> ScriptSource::GetWasmBytecode(
size_t max_size) const {
auto source = Utils::OpenDirectHandle(this);
- if (!IsForeign(*source)) return {};
- auto ptr = i::Cast<i::Managed<i::wasm::NativeModule>>(*source)->ptr();
+ if (!i::Is<i::CppGCManaged<i::wasm::NativeModule>>(*source)) return {};
+ auto ptr = i::Cast<i::CppGCManaged<i::wasm::NativeModule>>(*source)->ptr();
base::Vector<const uint8_t> wire_bytes = ptr->wire_bytes();
if (wire_bytes.size() > max_size) return Just(std::vector<uint8_t>());
return Just(std::vector<uint8_t>(wire_bytes.begin(), wire_bytes.end()));
@@ -635,7 +636,7 @@ bool Script::GetPossibleBreakpoints(
i::Handle<i::Script> script = Utils::OpenHandle(this);
#if V8_ENABLE_WEBASSEMBLY
if (script->type() == i::Script::Type::kWasm) {
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
return i::WasmScript::GetPossibleBreakpoints(native_module.raw(), start,
end, locations);
@@ -752,16 +753,6 @@ Location Script::GetSourceLocation(int offset) const {
return Location(info.line, info.column);
}
-bool Script::SetScriptSource(Local<String> newSource, bool preview,
- bool allow_top_frame_live_editing,
- LiveEditResult* result) const {
- i::Handle<i::Script> script = Utils::OpenHandle(this);
- i::Isolate* isolate = i::Isolate::Current();
- return isolate->debug()->SetScriptSource(
- script, Utils::OpenHandle(*newSource), preview,
- allow_top_frame_live_editing, result);
-}
-
bool Script::SetBreakpoint(Local<String> condition, Location* location,
BreakpointId* id) const {
i::Handle<i::Script> script = Utils::OpenHandle(this);
@@ -854,7 +845,7 @@ std::vector<WasmScript::DebugSymbols> WasmScript::GetDebugSymbols() const {
DCHECK_EQ(i::Script::Type::kWasm, script->type());
std::vector<WasmScript::DebugSymbols> debug_symbols;
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
auto symbols = native_module->module()->debug_symbols;
for (size_t i = 0; i < symbols.size(); ++i) {
@@ -875,7 +866,7 @@ int WasmScript::NumFunctions() const {
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
DCHECK_GE(i::kMaxInt, module->functions.size());
@@ -886,7 +877,7 @@ int WasmScript::NumImportedFunctions() const {
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
DCHECK_GE(i::kMaxInt, module->num_imported_functions);
@@ -897,7 +888,7 @@ std::pair<int, int> WasmScript::GetFunctionRange(int function_index) const {
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
DCHECK_LE(0, function_index);
@@ -913,7 +904,7 @@ int WasmScript::GetContainingFunction(int byte_offset) const {
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
DCHECK_LE(0, byte_offset);
@@ -926,7 +917,7 @@ void WasmScript::Disassemble(DisassemblyCollector* collector,
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
i::wasm::ModuleWireBytes wire_bytes(native_module->wire_bytes());
@@ -944,7 +935,7 @@ uint32_t WasmScript::GetFunctionHash(int function_index) {
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
DCHECK_LE(0, function_index);
@@ -963,7 +954,7 @@ Maybe<std::span<const uint8_t>> WasmScript::GetModuleBuildId() const {
i::DisallowGarbageCollection no_gc;
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* wasm_module = native_module->module();
const i::wasm::WireBytesRef& build_id = wasm_module->build_id;
@@ -978,7 +969,7 @@ Maybe<std::span<const uint8_t>> WasmScript::GetModuleBuildId() const {
int WasmScript::CodeOffset() const {
auto script = Utils::OpenDirectHandle(this);
DCHECK_EQ(i::Script::Type::kWasm, script->type());
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const i::wasm::WasmModule* module = native_module->module();
@@ -1293,6 +1284,17 @@ MaybeLocal<v8::Value> EvaluateGlobal(v8::Isolate* isolate,
return api_scope.EscapeMaybe(result);
}
+bool IsAPIFunctionWithSideEffects(v8::Local<v8::Value> value) {
+ if (!value->IsFunction()) return false;
+ auto function = v8::Utils::OpenDirectHandle(*value.As<v8::Function>());
+ if (!i::IsJSFunction(*function)) return false;
+ i::DirectHandle<i::JSFunction> js_function = i::Cast<i::JSFunction>(function);
+ if (!js_function->shared()->IsApiFunction()) return false;
+ i::Tagged<i::FunctionTemplateInfo> info =
+ js_function->shared()->api_func_data();
+ return info->has_side_effects();
+}
+
void GlobalLexicalScopeNames(v8::Local<v8::Context> v8_context,
std::vector<v8::Global<v8::String>>* names) {
auto context = Utils::OpenDirectHandle(*v8_context);
diff --git a/deps/v8/src/debug/debug-interface.h b/deps/v8/src/debug/debug-interface.h
index 67266c3b16f..b63ecede773 100644
--- a/deps/v8/src/debug/debug-interface.h
+++ b/deps/v8/src/debug/debug-interface.h
@@ -162,26 +162,6 @@ bool CanBreakProgram(Isolate* isolate);
class Script;
-struct LiveEditResult {
- enum Status {
- OK,
- COMPILE_ERROR,
- BLOCKED_BY_RUNNING_GENERATOR,
- BLOCKED_BY_ACTIVE_FUNCTION,
- BLOCKED_BY_TOP_LEVEL_ES_MODULE_CHANGE,
- FEATURE_DISABLED,
- };
- Status status = OK;
- bool stack_changed = false;
- // Available only for OK.
- v8::Local<v8::debug::Script> script;
- bool restart_top_frame_required = false;
- // Fields below are available only for COMPILE_ERROR.
- v8::Local<v8::String> message;
- int line_number = -1;
- int column_number = -1;
-};
-
/**
* An internal representation of the source for a given
* `v8::debug::Script`, which can be a `v8::String`, in
@@ -235,9 +215,6 @@ class V8_EXPORT_PRIVATE Script {
const debug::Location& location,
GetSourceOffsetMode mode = GetSourceOffsetMode::kStrict) const;
v8::debug::Location GetSourceLocation(int offset) const;
- bool SetScriptSource(v8::Local<v8::String> newSource, bool preview,
- bool allow_top_frame_live_editing,
- LiveEditResult* result) const;
bool SetBreakpoint(v8::Local<v8::String> condition, debug::Location* location,
BreakpointId* id) const;
#if V8_ENABLE_WEBASSEMBLY
@@ -306,7 +283,7 @@ enum ExceptionType { kException, kPromiseRejection };
class DebugDelegate {
public:
virtual ~DebugDelegate() = default;
- virtual void ScriptCompiled(v8::Local<Script> script, bool is_live_edited,
+ virtual void ScriptCompiled(v8::Local<Script> script,
bool has_compile_error) {}
// |inspector_break_points_hit| contains id of breakpoints installed with
// debug::Script::SetBreakpoint API.
@@ -544,9 +521,12 @@ class V8_EXPORT_PRIVATE StackTraceIterator {
virtual bool CanBeRestarted() const = 0;
virtual v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source,
- bool throw_on_side_effect) = 0;
+ bool throw_on_side_effect,
+ int scope_index = 0) = 0;
};
+V8_EXPORT_PRIVATE bool IsAPIFunctionWithSideEffects(v8::Local<v8::Value> value);
+
void GlobalLexicalScopeNames(v8::Local<v8::Context> context,
std::vector<v8::Global<v8::String>>* names);
diff --git a/deps/v8/src/debug/debug-property-iterator.cc b/deps/v8/src/debug/debug-property-iterator.cc
index 9d496203ada..3994a2ffbce 100644
--- a/deps/v8/src/debug/debug-property-iterator.cc
+++ b/deps/v8/src/debug/debug-property-iterator.cc
@@ -8,6 +8,7 @@
#include "src/base/flags.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/keys.h"
+#include "src/objects/module-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/objects/property-details.h"
@@ -199,6 +200,11 @@ bool DebugPropertyIterator::FillKeysForCurrentPrototypeAndStage() {
typed_array->WasDetached() ? 0 : typed_array->GetLength();
return true;
}
+ if (IsJSDeferredModuleNamespace(*receiver) &&
+ Cast<JSDeferredModuleNamespace>(receiver)->module()->status() !=
+ Module::kEvaluated) [[unlikely]] {
+ return true;
+ }
PropertyFilter filter =
stage_ == kEnumerableStrings ? ENUMERABLE_STRINGS : ALL_PROPERTIES;
if (KeyAccumulator::GetKeys(isolate_, receiver, KeyCollectionMode::kOwnOnly,
diff --git a/deps/v8/src/debug/debug-scope-info.cc b/deps/v8/src/debug/debug-scope-info.cc
new file mode 100644
index 00000000000..84c7840540f
--- /dev/null
+++ b/deps/v8/src/debug/debug-scope-info.cc
@@ -0,0 +1,783 @@
+// 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-scope-info.h"
+
+#include <cstddef>
+#include <iterator>
+#include <type_traits>
+
+#include "src/ast/ast-value-factory.h"
+#include "src/ast/scopes.h"
+#include "src/base/bit-field.h"
+#include "src/base/numerics/safe_conversions.h"
+#include "src/base/vector.h"
+#include "src/common/globals.h"
+#include "src/debug/debug.h"
+#include "src/execution/isolate-inl.h"
+#include "src/handles/handles-inl.h"
+#include "src/heap/factory.h"
+#include "src/objects/debug-objects-inl.h"
+#include "src/objects/fixed-array-inl.h"
+#include "src/objects/string-inl.h"
+#include "src/parsing/parse-info.h"
+#include "src/parsing/parsing.h"
+#include "src/zone/zone-containers.h"
+
+namespace v8 {
+namespace internal {
+
+// ===========================================================================
+// ByteArray: numeric_data
+// ===========================================================================
+// +-------------------------------------------------------------------------+
+// | Header (4 bytes): |
+// | int32_t scope_count |
+// +-------------------------------------------------------------------------+
+// | Offset Table (scope_count * 4 bytes): |
+// | uint32_t scope_offsets[scope_count] |
+// +-------------------------------------------------------------------------+
+// | Scope Record 0 (at scope_offsets[0]): |
+// | +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 |
+// | --- Dynamic Optional Fields (present conditionally based on flags) --- |
+// | [+16: 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) --- |
+// | [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) |
+// | [DebugVariableEntry 1]... |
+// +-------------------------------------------------------------------------+
+// | Scope Record 1 (at scope_offsets[1])... |
+// +-------------------------------------------------------------------------+
+
+namespace {
+
+struct ScopeRecord {
+ int32_t start_position;
+ int32_t end_position;
+ int32_t parent_scope_index;
+ uint16_t flags;
+ uint16_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;
+ uint16_t location_mode_flags;
+ int32_t initializer_position;
+ int32_t name_index;
+};
+
+static_assert(std::is_trivial_v<DebugVariableEntry>);
+static_assert(std::is_standard_layout_v<DebugVariableEntry>);
+static_assert(sizeof(DebugVariableEntry) == 12);
+
+using ScopeTypeBits = base::BitField<ScopeType, 0, 4, uint16_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 HasThisDeclarationBit = IsArrowScopeBit::Next<bool, 1>;
+using HasThisReferenceBit = HasThisDeclarationBit::Next<bool, 1>;
+using HasSimpleParametersBit = HasThisReferenceBit::Next<bool, 1>;
+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);
+
+using VariableLocationBits = base::BitField<VariableLocation, 0, 4, uint16_t>;
+using VariableModeBits = VariableLocationBits::Next<VariableMode, 4>;
+using IsSyntheticBit = VariableModeBits::Next<bool, 1>;
+using IsReceiverBit = IsSyntheticBit::Next<bool, 1>;
+static_assert(IsReceiverBit::kLastUsedBit < 16);
+
+// Encodes receiver, arguments, or function variable allocation info into a
+// 16-bit word:
+// - Bits 0..1: VariableAllocationInfo (NONE, STACK, CONTEXT, UNUSED)
+// - Bits 2..15: 14-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
+// treated as a signed two's-complement integer, requiring sign-extension upon
+// decoding.
+uint16_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);
+}
+
+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};
+}
+
+int32_t GetScopeCount(Tagged<DebugScriptScopeInfo> info) {
+ Tagged<ByteArray> bytes = info->numeric_data();
+ DCHECK_GE(bytes->length().value(), kInt32Size);
+ return base::ReadUnalignedValue<int32_t>(bytes->begin());
+}
+
+uint32_t GetScopeOffset(Tagged<DebugScriptScopeInfo> info, int scope_index) {
+ CHECK_GE(scope_index, 0);
+ CHECK_LT(scope_index, GetScopeCount(info));
+ const uint8_t* ptr =
+ info->numeric_data()->begin() + kInt32Size + scope_index * kUInt32Size;
+ return base::ReadUnalignedValue<uint32_t>(ptr);
+}
+
+class ByteArrayWriter {
+ public:
+ explicit ByteArrayWriter(Address cursor) : cursor_(cursor) {}
+
+ template <typename T>
+ void Write(const T& value) {
+ static_assert(std::is_trivially_copyable_v<T>);
+ base::WriteUnalignedValue<T>(cursor_, value);
+ cursor_ += sizeof(T);
+ }
+
+ Address cursor() const { return cursor_; }
+
+ private:
+ Address cursor_;
+};
+
+} // namespace
+
+const uint8_t* DebugScriptScope::payload() const {
+ return info_->numeric_data()->begin() + offset_;
+}
+
+uint16_t DebugScriptScope::flags() const {
+ return base::ReadUnalignedValue<ScopeRecord>(payload()).flags;
+}
+
+DebugScriptScope DebugScriptScope::FromIndex(
+ DirectHandle<DebugScriptScopeInfo> info, int scope_index) {
+ CHECK_GE(scope_index, 0);
+ CHECK_LT(scope_index, GetScopeCount(*info));
+ uint32_t offset = GetScopeOffset(*info, scope_index);
+ return DebugScriptScope(info, scope_index, offset);
+}
+
+std::optional<DebugScriptScope> DebugScriptScope::parent() const {
+ int parent_idx = parent_index();
+ if (parent_idx == -1) return std::nullopt;
+ return FromIndex(info_, parent_idx);
+}
+
+std::optional<DebugScriptScope> DebugScriptScope::first_child() const {
+ if (!HasChildrenBit::decode(flags())) return std::nullopt;
+ return FromIndex(info_, scope_index_ + 1);
+}
+
+std::optional<DebugScriptScope> DebugScriptScope::next_sibling() const {
+ if (!HasSiblingBit::decode(flags())) return std::nullopt;
+ const uint8_t* sibling_ptr = payload() + next_sibling_offset();
+ int sibling_idx = base::ReadUnalignedValue<int32_t>(sibling_ptr);
+ return FromIndex(info_, sibling_idx);
+}
+
+int DebugScriptScope::start_position() const {
+ return base::ReadUnalignedValue<ScopeRecord>(payload()).start_position;
+}
+
+int DebugScriptScope::end_position() const {
+ return base::ReadUnalignedValue<ScopeRecord>(payload()).end_position;
+}
+
+int DebugScriptScope::parent_index() const {
+ return base::ReadUnalignedValue<ScopeRecord>(payload()).parent_scope_index;
+}
+
+ScopeType DebugScriptScope::scope_type() const {
+ return ScopeTypeBits::decode(flags());
+}
+
+bool DebugScriptScope::is_script_scope() const {
+ return scope_type() == ScopeType::SCRIPT_SCOPE ||
+ scope_type() == ScopeType::REPL_MODE_SCOPE;
+}
+
+bool DebugScriptScope::is_function_scope() const {
+ return scope_type() == ScopeType::FUNCTION_SCOPE;
+}
+
+bool DebugScriptScope::is_block_scope() const {
+ return scope_type() == ScopeType::BLOCK_SCOPE ||
+ scope_type() == ScopeType::CLASS_SCOPE;
+}
+
+bool DebugScriptScope::is_declaration_scope() const {
+ return is_script_scope() || is_function_scope() ||
+ scope_type() == ScopeType::MODULE_SCOPE ||
+ scope_type() == ScopeType::EVAL_SCOPE;
+}
+
+LanguageMode DebugScriptScope::language_mode() const {
+ return LanguageModeBit::decode(flags());
+}
+
+bool DebugScriptScope::is_arrow_scope() const {
+ return IsArrowScopeBit::decode(flags());
+}
+
+bool DebugScriptScope::is_class_scope() const {
+ return scope_type() == ScopeType::CLASS_SCOPE;
+}
+
+bool DebugScriptScope::is_with_scope() const {
+ return scope_type() == ScopeType::WITH_SCOPE;
+}
+
+bool DebugScriptScope::is_module_scope() const {
+ return scope_type() == ScopeType::MODULE_SCOPE;
+}
+
+bool DebugScriptScope::is_eval_scope() const {
+ return scope_type() == ScopeType::EVAL_SCOPE;
+}
+
+bool DebugScriptScope::is_catch_scope() const {
+ return scope_type() == ScopeType::CATCH_SCOPE;
+}
+
+bool DebugScriptScope::is_repl_mode_scope() const {
+ return scope_type() == ScopeType::REPL_MODE_SCOPE;
+}
+
+bool DebugScriptScope::is_hidden() const {
+ return IsHiddenBit::decode(flags());
+}
+
+bool DebugScriptScope::has_this_declaration() const {
+ return HasThisDeclarationBit::decode(flags());
+}
+
+bool DebugScriptScope::has_this_reference() const {
+ return HasThisReferenceBit::decode(flags());
+}
+
+bool DebugScriptScope::has_simple_parameters() const {
+ return HasSimpleParametersBit::decode(flags());
+}
+
+bool DebugScriptScope::has_arguments() const {
+ return HasArgumentsBit::decode(flags());
+}
+
+bool DebugScriptScope::has_function_variable() const {
+ return HasFunctionVarBit::decode(flags());
+}
+
+bool DebugScriptScope::sloppy_eval_can_extend_vars() const {
+ return SloppyEvalCanExtendVarsBit::decode(flags());
+}
+
+bool DebugScriptScope::needs_context() const {
+ return NeedsContextBit::decode(flags());
+}
+
+size_t DebugScriptScope::next_sibling_offset() const {
+ return sizeof(ScopeRecord);
+}
+
+size_t DebugScriptScope::context_id_offset() const {
+ return next_sibling_offset() +
+ (HasSiblingBit::decode(flags()) ? kInt32Size : 0);
+}
+
+size_t DebugScriptScope::receiver_info_offset() const {
+ return context_id_offset() +
+ (NeedsContextBit::decode(flags()) ? kInt32Size : 0);
+}
+
+size_t DebugScriptScope::arguments_info_offset() const {
+ return receiver_info_offset() +
+ (HasThisDeclarationBit::decode(flags()) ? kUInt16Size : 0);
+}
+
+size_t DebugScriptScope::function_variable_offset() const {
+ return arguments_info_offset() +
+ (HasArgumentsBit::decode(flags()) ? kUInt16Size : 0);
+}
+
+size_t DebugScriptScope::variables_offset() const {
+ return function_variable_offset() +
+ (HasFunctionVarBit::decode(flags()) ? (kUInt16Size + kInt32Size) : 0);
+}
+
+size_t DebugScriptScope::record_size() const {
+ return variables_offset() + variable_count() * sizeof(DebugVariableEntry);
+}
+
+int DebugScriptScope::unique_id_in_script() const {
+ if (!needs_context()) return -3;
+ return base::ReadUnalignedValue<int32_t>(payload() + context_id_offset());
+}
+
+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()));
+}
+
+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()));
+}
+
+const uint8_t* DebugScriptScope::function_variable_payload() const {
+ if (!has_function_variable()) return nullptr;
+ return payload() + function_variable_offset();
+}
+
+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));
+}
+
+Tagged<String> 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));
+}
+
+int DebugScriptScope::variable_count() const {
+ return base::ReadUnalignedValue<ScopeRecord>(payload()).var_count;
+}
+
+const uint8_t* DebugScriptScope::variables_payload() const {
+ return payload() + variables_offset();
+}
+
+DebugVariableInfo DebugScriptScope::variable(int index) const {
+ CHECK_GE(index, 0);
+ CHECK_LT(index, variable_count());
+ const uint8_t* entry_ptr =
+ 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));
+ }
+ return DebugVariableInfo{
+ .name = name,
+ .location = VariableLocationBits::decode(entry.location_mode_flags),
+ .index = entry.slot_index,
+ .mode = VariableModeBits::decode(entry.location_mode_flags),
+ .initializer_position = entry.initializer_position,
+ .is_synthetic = IsSyntheticBit::decode(entry.location_mode_flags),
+ .is_receiver = IsReceiverBit::decode(entry.location_mode_flags),
+ };
+}
+
+Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
+ Isolate* isolate, DeclarationScope* script_scope) {
+ DCHECK_NOT_NULL(script_scope);
+ DCHECK(script_scope->is_toplevel_scope());
+
+ Zone* zone = script_scope->zone();
+ ZoneVector<const AstRawString*> string_table(zone);
+ 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;
+ 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());
+ string_map.emplace(raw_name, index);
+ string_table.push_back(raw_name);
+ return index;
+ };
+
+ std::vector<Scope*> all_scopes;
+ std::unordered_map<Scope*, int32_t> scope_to_index;
+
+ auto collect = [&](auto& self, Scope* scope) -> void {
+ int32_t index = base::checked_cast<int32_t>(all_scopes.size());
+ all_scopes.push_back(scope);
+ scope_to_index.emplace(scope, index);
+ for (Scope* inner = scope->inner_scope(); inner != nullptr;
+ inner = inner->sibling()) {
+ self(self, inner);
+ }
+ };
+ collect(collect, script_scope);
+ DCHECK(!all_scopes.empty());
+ DCHECK(!all_scopes[0]->is_with_scope());
+
+ auto find_scope_index = [&](Scope* s) -> int32_t {
+ if (s == nullptr) return -1;
+ auto it = scope_to_index.find(s);
+ return it != scope_to_index.end() ? it->second : -1;
+ };
+ DCHECK_EQ(find_scope_index(all_scopes[0]->outer_scope()), -1);
+
+ // Stage 1: Pre-calculate exact required byte size and scope offsets.
+ size_t total_size = kInt32Size + all_scopes.size() * kUInt32Size;
+ std::vector<uint32_t> offsets;
+ offsets.reserve(all_scopes.size());
+
+ for (size_t i = 0; i < all_scopes.size(); ++i) {
+ offsets.push_back(base::checked_cast<uint32_t>(total_size));
+ total_size += sizeof(ScopeRecord);
+ if (find_scope_index(all_scopes[i]->sibling()) != -1) {
+ total_size += kInt32Size;
+ }
+ if (all_scopes[i]->NeedsContext()) {
+ total_size += kInt32Size;
+ }
+ if (all_scopes[i]->is_declaration_scope() &&
+ all_scopes[i]->AsDeclarationScope()->has_this_declaration()) {
+ total_size += kUInt16Size;
+ }
+ if (all_scopes[i]->is_declaration_scope() &&
+ all_scopes[i]->AsDeclarationScope()->arguments() != nullptr) {
+ total_size += kUInt16Size;
+ }
+ if (all_scopes[i]->is_declaration_scope() &&
+ all_scopes[i]->AsDeclarationScope()->function_var() != nullptr) {
+ total_size += kUInt16Size + kInt32Size;
+ }
+ uint16_t var_count = base::checked_cast<uint16_t>(std::distance(
+ all_scopes[i]->locals()->begin(), all_scopes[i]->locals()->end()));
+ total_size += var_count * sizeof(DebugVariableEntry);
+ }
+
+ // Stage 2: Allocate a ByteArray and write directly into it with
+ // ByteArrayWriter.
+ Handle<ByteArray> byte_array = isolate->factory()->NewByteArray(
+ base::checked_cast<uint32_t>(total_size), AllocationType::kOld);
+
+ ByteArrayWriter header_writer(reinterpret_cast<Address>(byte_array->begin()));
+ header_writer.Write<int32_t>(base::checked_cast<int32_t>(all_scopes.size()));
+
+ for (size_t i = 0; i < all_scopes.size(); ++i) {
+ header_writer.Write<uint32_t>(offsets[i]);
+ }
+
+ for (size_t i = 0; i < all_scopes.size(); ++i) {
+ Address record =
+ reinterpret_cast<Address>(byte_array->begin()) + offsets[i];
+ Scope* scope = all_scopes[i];
+
+ int32_t next_sibling = find_scope_index(scope->sibling());
+ bool has_sibling = next_sibling != -1;
+ bool needs_context = scope->NeedsContext();
+ bool has_this_decl = false;
+ bool has_arguments = false;
+ bool has_function_var = false;
+
+ uint16_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 = HasThisReferenceBit::update(flags, scope->HasThisReference());
+ flags = NeedsContextBit::update(flags, needs_context);
+ if (scope->is_declaration_scope()) {
+ DeclarationScope* decl_scope = scope->AsDeclarationScope();
+ has_this_decl = decl_scope->has_this_declaration();
+ has_arguments = decl_scope->arguments() != nullptr;
+ has_function_var = decl_scope->function_var() != nullptr;
+ flags = IsArrowScopeBit::update(flags, decl_scope->is_arrow_scope());
+ flags = HasThisDeclarationBit::update(flags, has_this_decl);
+ flags = HasSimpleParametersBit::update(
+ flags, decl_scope->has_simple_parameters());
+ flags = SloppyEvalCanExtendVarsBit::update(
+ flags, decl_scope->sloppy_eval_can_extend_vars());
+ }
+ flags = HasArgumentsBit::update(flags, has_arguments);
+ flags = HasFunctionVarBit::update(flags, has_function_var);
+
+ uint16_t var_count = base::checked_cast<uint16_t>(
+ std::distance(scope->locals()->begin(), scope->locals()->end()));
+
+ int32_t parent_scope_index = find_scope_index(scope->outer_scope());
+ DCHECK_EQ(parent_scope_index == -1, i == 0);
+
+ ByteArrayWriter writer(record);
+ writer.Write<ScopeRecord>(ScopeRecord{
+ .start_position = scope->start_position(),
+ .end_position = scope->end_position(),
+ .parent_scope_index = parent_scope_index,
+ .flags = flags,
+ .var_count = var_count,
+ });
+
+ if (has_sibling) {
+ writer.Write<int32_t>(next_sibling);
+ }
+ if (needs_context) {
+ // We only need the context ID to match DebugScopeInfo against runtime
+ // ScopeInfo. V8 omits runtime ScopeInfo for any scope that doesn't need a
+ // context so we don't need to waste the bytes.
+ writer.Write<int32_t>(scope->UniqueIdInScript());
+ }
+ if (has_this_decl) {
+ Variable* var = scope->AsDeclarationScope()->receiver();
+ DCHECK_NE(var->location(), VariableLocation::LOOKUP);
+ VariableAllocationInfo info = var->location() == VariableLocation::CONTEXT
+ ? VariableAllocationInfo::CONTEXT
+ : VariableAllocationInfo::STACK;
+ writer.Write<uint16_t>(EncodeAllocInfo(info, var->index()));
+ }
+ if (has_arguments) {
+ Variable* var = scope->AsDeclarationScope()->arguments();
+ DCHECK_NE(var->location(), VariableLocation::LOOKUP);
+ VariableAllocationInfo info = var->location() == VariableLocation::CONTEXT
+ ? VariableAllocationInfo::CONTEXT
+ : VariableAllocationInfo::STACK;
+ writer.Write<uint16_t>(EncodeAllocInfo(info, var->index()));
+ }
+ if (has_function_var) {
+ Variable* var = scope->AsDeclarationScope()->function_var();
+ DCHECK_NE(var->location(), VariableLocation::LOOKUP);
+ VariableAllocationInfo info = var->location() == VariableLocation::CONTEXT
+ ? VariableAllocationInfo::CONTEXT
+ : VariableAllocationInfo::STACK;
+ writer.Write<uint16_t>(EncodeAllocInfo(info, var->index()));
+ int32_t name_index = get_or_insert_string(var->raw_name());
+ writer.Write<int32_t>(name_index);
+ }
+
+ for (Variable* var : *scope->locals()) {
+ DCHECK_EQ(var->scope(), scope);
+ // Variables declared in locals() must be statically allocated (or
+ // unallocated if unused). They must never require dynamic lookup against
+ // an outer context (e.g. VariableLocation::LOOKUP), which would indicate
+ // dependence on outer runtime scopes such as WithScopes.
+ DCHECK_NE(var->location(), VariableLocation::LOOKUP);
+ const AstRawString* raw = var->raw_name();
+ // LINT.IfChange(VariableIsSynthetic)
+ // Keep in sync with ScopeInfo::VariableIsSynthetic() in
+ // src/objects/scope-info.cc.
+ bool is_synthetic =
+ raw != nullptr &&
+ (raw->IsEmpty() || raw->FirstCharacter() == '.' ||
+ raw->IsPrivateName() || raw->IsOneByteEqualTo("this"));
+ // LINT.ThenChange(/src/objects/scope-info.cc:VariableIsSynthetic)
+ // LINT.IfChange(VariableIsReceiver)
+ // Keep in sync with Variable::IsReceiver() in src/ast/variables.h.
+ // Variable::IsReceiver() asserts IsParameter() in debug builds.
+ bool is_receiver = var->IsParameter() && var->IsReceiver();
+ // LINT.ThenChange(/src/ast/variables.h:VariableIsReceiver)
+ uint16_t var_flags = 0;
+ var_flags = VariableLocationBits::update(var_flags, var->location());
+ var_flags = VariableModeBits::update(var_flags, var->mode());
+ var_flags = IsSyntheticBit::update(var_flags, is_synthetic);
+ var_flags = IsReceiverBit::update(var_flags, is_receiver);
+
+ writer.Write<DebugVariableEntry>(DebugVariableEntry{
+ .slot_index = base::checked_cast<int16_t>(var->index()),
+ .location_mode_flags = var_flags,
+ .initializer_position = var->initializer_position(),
+ .name_index = get_or_insert_string(var->raw_name()),
+ });
+ }
+
+ size_t expected_size =
+ (i + 1 < all_scopes.size() ? offsets[i + 1] : total_size) - offsets[i];
+ CHECK_EQ(writer.cursor(), record + expected_size);
+ }
+
+ DirectHandle<FixedArray> final_string_table;
+ if (string_table.empty()) {
+ final_string_table = isolate->factory()->empty_fixed_array();
+ } else {
+ uint32_t string_count = base::checked_cast<uint32_t>(string_table.size());
+ 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());
+ }
+ final_string_table = table;
+ }
+ return isolate->factory()->NewDebugScriptScopeInfo(byte_array,
+ final_string_table);
+}
+
+Handle<DebugScriptScopeInfo> EnsureDebugScriptScopeInfo(
+ Isolate* isolate, DirectHandle<Script> script) {
+ DirectHandle<DebugScriptScopeInfo> cached_info =
+ isolate->debug()->GetScriptScopeInfo(script);
+ if (!cached_info.is_null()) {
+ return handle(*cached_info, isolate);
+ }
+
+ CHECK(IsString(script->source()));
+
+ // UnoptimizedCompileFlags::ForScriptCompile automatically initializes flags
+ // from the script object:
+ // - Sets is_toplevel(true) and preserves REPL and module flags.
+ // - Restores outer_language_mode and compilation kind (host, eval, wrapped,
+ // Function constructor).
+ // - For wrapped scripts, sets function_syntax_kind to kWrapped and is_eval.
+ //
+ // Eager compilation ensures all inner function scopes are parsed rather
+ // than skipped. Marking as reparse prevents spawning background parallel
+ // compile tasks and preserves context allocation flags.
+ UnoptimizedCompileFlags flags =
+ UnoptimizedCompileFlags::ForScriptCompile(isolate, *script)
+ .set_is_eager(true);
+ flags.set_is_reparse(true);
+
+ MaybeDirectHandle<ScopeInfo> maybe_outer_scope;
+ if (script->has_eval_from_scope_info()) {
+ maybe_outer_scope =
+ direct_handle(Cast<ScopeInfo>(script->eval_from_scope_info()), isolate);
+ }
+
+ UnoptimizedCompileState compile_state;
+ ReusableUnoptimizedCompileState reusable_state(isolate);
+ ParseInfo info(isolate, flags, &compile_state, &reusable_state);
+
+ if (!parsing::ParseProgram(&info, script, maybe_outer_scope, isolate,
+ parsing::ReportStatisticsMode{false})) {
+ return Handle<DebugScriptScopeInfo>::null();
+ }
+
+ Handle<DebugScriptScopeInfo> debug_info =
+ SerializeDebugScriptScopeInfo(isolate, info.literal()->scope());
+ isolate->debug()->SetScriptScopeInfo(script, debug_info);
+ return debug_info;
+}
+
+#ifdef VERIFY_HEAP
+// DebugScriptScopeInfo::DebugScriptScopeInfoVerify is placed here instead of in
+// objects-debug.cc to keep the exact layout of numeric_data local to
+// debug-scope-info.cc.
+void DebugScriptScopeInfo::DebugScriptScopeInfoVerify(Isolate* isolate) {
+ CHECK(Is<Struct>(this));
+ CHECK(Is<DebugScriptScopeInfo>(this));
+ Object::VerifyPointer(isolate, numeric_data_.load());
+ Object::VerifyPointer(isolate, string_table_.load());
+ CHECK(IsByteArray(numeric_data()));
+ CHECK(IsFixedArray(string_table()));
+
+ Tagged<ByteArray> bytes = numeric_data();
+ CHECK_GE(bytes->length().value(), kInt32Size);
+ int scope_count = GetScopeCount(this);
+ CHECK_GE(scope_count, 0);
+
+ size_t header_and_table_size = kInt32Size + scope_count * kUInt32Size;
+ CHECK_GE(static_cast<size_t>(bytes->length().value()), header_and_table_size);
+
+ HandleScope handle_scope(isolate);
+ DirectHandle<DebugScriptScopeInfo> info_handle(this, isolate);
+
+ for (int i = 0; i < scope_count; ++i) {
+ uint32_t offset = GetScopeOffset(this, i);
+ CHECK_EQ(offset % kUInt16Size, 0);
+ CHECK_GE(offset, header_and_table_size);
+ CHECK_LE(offset + sizeof(ScopeRecord),
+ static_cast<size_t>(bytes->length().value()));
+ DebugScriptScope scope = DebugScriptScope::FromIndex(info_handle, i);
+ CHECK_EQ(scope.scope_index(), i);
+ CHECK_LE(scope.start_position(), scope.end_position());
+
+ size_t record_size = scope.record_size();
+ CHECK_LE(offset + record_size,
+ static_cast<size_t>(bytes->length().value()));
+
+ if (scope.needs_context()) {
+ CHECK_GE(scope.unique_id_in_script(), -2);
+ } else {
+ CHECK_EQ(scope.unique_id_in_script(), -3);
+ }
+
+ if (!scope.has_this_declaration()) {
+ CHECK_EQ(scope.receiver_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ }
+
+ if (!scope.has_arguments()) {
+ CHECK_EQ(scope.arguments_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ }
+
+ if (!scope.has_function_variable()) {
+ CHECK_EQ(scope.function_variable_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ CHECK(scope.function_variable_name().is_null());
+ } else {
+ 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);
+ 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_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));
+ }
+ }
+
+ if (i == 0) {
+ CHECK(!scope.parent().has_value());
+ } else {
+ CHECK(scope.parent().has_value());
+ CHECK_GE(scope.parent()->scope_index(), 0);
+ CHECK_LT(scope.parent()->scope_index(), i);
+ }
+
+ if (auto first_child = scope.first_child()) {
+ CHECK_LT(i + 1, scope_count);
+ CHECK_EQ(first_child->scope_index(), i + 1);
+ CHECK(first_child->parent().has_value());
+ CHECK_EQ(first_child->parent()->scope_index(), i);
+ }
+
+ if (auto sibling = scope.next_sibling()) {
+ CHECK_GT(i, 0);
+ CHECK_GT(sibling->scope_index(), i);
+ CHECK_LT(sibling->scope_index(), scope_count);
+ CHECK(sibling->parent().has_value());
+ CHECK_EQ(sibling->parent()->scope_index(), scope.parent()->scope_index());
+ }
+ }
+}
+#endif // VERIFY_HEAP
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/src/debug/debug-scope-info.h b/deps/v8/src/debug/debug-scope-info.h
new file mode 100644
index 00000000000..cbf6313a478
--- /dev/null
+++ b/deps/v8/src/debug/debug-scope-info.h
@@ -0,0 +1,140 @@
+// 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_SCOPE_INFO_H_
+#define V8_DEBUG_DEBUG_SCOPE_INFO_H_
+
+#include <optional>
+#include <utility>
+
+#include "src/base/macros.h"
+#include "src/common/globals.h"
+#include "src/handles/handles.h"
+#include "src/objects/debug-objects.h"
+
+namespace v8 {
+namespace internal {
+
+class DeclarationScope;
+class Isolate;
+class Script;
+class String;
+
+// Structure holding deserialized variable information for debugger inspection.
+struct DebugVariableInfo {
+ Tagged<String> name;
+ VariableLocation location;
+ int index;
+ VariableMode mode;
+ int initializer_position;
+ bool is_synthetic;
+ bool is_receiver;
+};
+
+// Stack-allocated cursor for navigating and querying serialized scope trees
+// stored in DebugScriptScopeInfo.
+class V8_EXPORT_PRIVATE DebugScriptScope {
+ V8_STACK_ALLOCATED();
+
+ public:
+ static DebugScriptScope FromIndex(DirectHandle<DebugScriptScopeInfo> info,
+ int scope_index);
+
+ // Tree Navigation
+ std::optional<DebugScriptScope> parent() const;
+ std::optional<DebugScriptScope> first_child() const;
+ std::optional<DebugScriptScope> next_sibling() const;
+
+ // Position & Type Accessors
+ int start_position() const;
+ int end_position() const;
+ int scope_index() const { return scope_index_; }
+ ScopeType scope_type() const;
+ LanguageMode language_mode() const;
+
+ // Scope Predicates
+ bool is_script_scope() const;
+ bool is_function_scope() const;
+ bool is_block_scope() const;
+ bool is_declaration_scope() const;
+ bool is_arrow_scope() const;
+ bool is_class_scope() const;
+ bool is_with_scope() const;
+ bool is_module_scope() const;
+ bool is_eval_scope() const;
+ bool is_catch_scope() const;
+ bool is_repl_mode_scope() const;
+ bool is_hidden() const;
+ bool has_this_declaration() const;
+ bool has_this_reference() const;
+ bool has_simple_parameters() const;
+ bool has_arguments() const;
+ bool has_function_variable() const;
+ bool sloppy_eval_can_extend_vars() const;
+ bool needs_context() const;
+
+ // Context Info, returns a valid ID only when needs_context() == true.
+ int unique_id_in_script() const;
+
+ // Special Variables Info
+ // Returns a pair of {VariableAllocationInfo, index}. When allocated, the
+ // second element represents the stack slot index or context slot index of the
+ // receiver variable (or -1 if none/unallocated).
+ std::pair<VariableAllocationInfo, int> receiver_info() const;
+ // Returns a pair of {VariableAllocationInfo, index}. When allocated, the
+ // second element represents the stack slot index or context slot index of the
+ // 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;
+
+ // Local Variables Info
+ int variable_count() const;
+ DebugVariableInfo variable(int index) const;
+
+ private:
+ DebugScriptScope(DirectHandle<DebugScriptScopeInfo> info, int scope_index,
+ uint32_t offset)
+ : info_(info), scope_index_(scope_index), offset_(offset) {}
+
+ const uint8_t* payload() const;
+ const uint8_t* function_variable_payload() const;
+ const uint8_t* variables_payload() const;
+ uint16_t flags() const;
+ int parent_index() const;
+
+ // Chained offset calculation methods (private to DebugScriptScope).
+ size_t next_sibling_offset() const;
+ size_t context_id_offset() const;
+ size_t receiver_info_offset() const;
+ size_t arguments_info_offset() const;
+ size_t function_variable_offset() const;
+ size_t variables_offset() const;
+ size_t record_size() const;
+
+ friend class DebugScriptScopeInfo;
+
+ DirectHandle<DebugScriptScopeInfo> info_;
+ int scope_index_;
+ uint32_t offset_;
+};
+
+// Serializes the start/end positions of the AST scopes rooted at `script_scope`
+// into a DebugScriptScopeInfo.
+V8_EXPORT_PRIVATE Handle<DebugScriptScopeInfo> SerializeDebugScriptScopeInfo(
+ Isolate* isolate, DeclarationScope* script_scope);
+
+// Ensures that `script` has an associated DebugScriptScopeInfo. If not yet
+// created, parses the script once eagerly, builds the scope info, and
+// caches it in the Debug ephemeron side table.
+//
+// All necessary scoping information (caller ScopeInfo for eval scripts,
+// wrapped arguments for wrapped scripts) is retained on the Script itself.
+V8_EXPORT_PRIVATE Handle<DebugScriptScopeInfo> EnsureDebugScriptScopeInfo(
+ Isolate* isolate, DirectHandle<Script> script);
+
+} // namespace internal
+} // namespace v8
+
+#endif // V8_DEBUG_DEBUG_SCOPE_INFO_H_
diff --git a/deps/v8/src/debug/debug-scope-iterator.cc b/deps/v8/src/debug/debug-scope-iterator.cc
index 8af53c6a0cb..cd834f2954e 100644
--- a/deps/v8/src/debug/debug-scope-iterator.cc
+++ b/deps/v8/src/debug/debug-scope-iterator.cc
@@ -45,19 +45,19 @@ DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
: iterator_(
isolate, frame_inspector,
::v8::internal::ScopeIterator::ReparseStrategy::kFunctionLiteral) {
- if (!Done() && ShouldIgnore()) Advance();
+ iterator_.AdvanceToScopeNumber(0);
}
DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
DirectHandle<JSFunction> function)
: iterator_(isolate, function) {
- if (!Done() && ShouldIgnore()) Advance();
+ iterator_.AdvanceToScopeNumber(0);
}
DebugScopeIterator::DebugScopeIterator(Isolate* isolate,
Handle<JSGeneratorObject> generator)
: iterator_(isolate, generator) {
- if (!Done() && ShouldIgnore()) Advance();
+ iterator_.AdvanceToScopeNumber(0);
}
bool DebugScopeIterator::Done() { return iterator_.Done(); }
@@ -65,15 +65,10 @@ bool DebugScopeIterator::Done() { return iterator_.Done(); }
void DebugScopeIterator::Advance() {
DCHECK(!Done());
iterator_.Next();
- while (!Done() && ShouldIgnore()) {
- iterator_.Next();
- }
+ iterator_.AdvanceToScopeNumber(0);
}
-bool DebugScopeIterator::ShouldIgnore() {
- if (GetType() == debug::ScopeIterator::ScopeTypeLocal) return false;
- return !iterator_.DeclaresLocals(i::ScopeIterator::Mode::ALL);
-}
+bool DebugScopeIterator::ShouldIgnore() { return iterator_.ShouldIgnore(); }
v8::debug::ScopeIterator::ScopeType DebugScopeIterator::GetType() {
DCHECK(!Done());
diff --git a/deps/v8/src/debug/debug-scopes.cc b/deps/v8/src/debug/debug-scopes.cc
index 5b83562318c..365489da889 100644
--- a/deps/v8/src/debug/debug-scopes.cc
+++ b/deps/v8/src/debug/debug-scopes.cc
@@ -271,8 +271,7 @@ void ScopeIterator::TryParseAndRetrieveScopes(ReparseStrategy strategy) {
flags.set_is_reparse(true);
MaybeDirectHandle<ScopeInfo> maybe_outer_scope;
- if (flags.is_toplevel() &&
- script->compilation_type() == Script::CompilationType::kEval) {
+ 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.
//
@@ -433,6 +432,24 @@ bool ScopeIterator::DeclaresLocals(Mode mode) const {
return declares_local;
}
+bool ScopeIterator::ShouldIgnore() const {
+ if (Type() == ScopeTypeLocal ||
+ (Type() == ScopeTypeModule && InInnerScope())) {
+ return false;
+ }
+ return !DeclaresLocals(Mode::ALL);
+}
+
+bool ScopeIterator::AdvanceToScopeNumber(int scope_number) {
+ while (!Done() && ShouldIgnore()) Next();
+ while (!Done() && scope_number > 0) {
+ --scope_number;
+ Next();
+ while (!Done() && ShouldIgnore()) Next();
+ }
+ return scope_number == 0 && !Done();
+}
+
bool ScopeIterator::HasContext() const {
// In rare cases we pause in a scope that doesn't have its context pushed yet.
// E.g. when pausing in for-of loop headers (see https://crbug.com/399002824).
@@ -461,7 +478,9 @@ bool ScopeIterator::NeedsContext() const {
// 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() && !function_.is_null(),
+ (current_scope_->is_function_scope() ||
+ current_scope_->is_eval_scope()) &&
+ !function_.is_null(),
function_->context() != *context_);
return needs_context;
@@ -1306,6 +1325,7 @@ class LocalBlocklistsCollector {
Handle<StringSet> context_blocklist_;
std::map<Scope*, IndirectHandle<StringSet>> function_blocklists_;
+ bool has_matched_first_context_ = false;
};
LocalBlocklistsCollector::LocalBlocklistsCollector(
@@ -1320,7 +1340,8 @@ LocalBlocklistsCollector::LocalBlocklistsCollector(
void LocalBlocklistsCollector::InitializeWithClosureScope() {
CHECK(scope_->is_declaration_scope());
function_blocklists_.emplace(scope_, StringSet::New(isolate_));
- if (scope_->NeedsContext()) context_blocklist_ = StringSet::New(isolate_);
+ context_blocklist_ = StringSet::New(isolate_);
+ has_matched_first_context_ = scope_->NeedsContext();
}
void LocalBlocklistsCollector::AdvanceToNextNonHiddenScope() {
@@ -1382,6 +1403,11 @@ void LocalBlocklistsCollector::CollectAndStore() {
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();
@@ -1389,9 +1415,9 @@ void LocalBlocklistsCollector::CollectAndStore() {
// here and we store them. Next, advance the current context so
// `context_` and `scope_` match again.
if (scope_->NeedsContext()) {
- if (!context_blocklist_.is_null()) {
- // Only store the block list and advance the context if the
- // context_blocklist is set. This handles the case when we start on
+ 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_`.
@@ -1400,11 +1426,11 @@ void LocalBlocklistsCollector::CollectAndStore() {
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_));
-
- context_blocklist_ = StringSet::New(isolate_);
function_blocklists_.clear();
} else if (scope_->is_function_scope()) {
// 3. If `scope` is a function scope with an SFI, start recording
@@ -1414,6 +1440,13 @@ void LocalBlocklistsCollector::CollectAndStore() {
}
}
+ 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_));
diff --git a/deps/v8/src/debug/debug-scopes.h b/deps/v8/src/debug/debug-scopes.h
index f5736220f6b..ca7a8717f4f 100644
--- a/deps/v8/src/debug/debug-scopes.h
+++ b/deps/v8/src/debug/debug-scopes.h
@@ -79,6 +79,14 @@ class V8_EXPORT_PRIVATE ScopeIterator {
// Returns whether the current scope declares any variables.
bool DeclaresLocals(Mode mode) const;
+ // Returns whether the current scope should be ignored by debugger scope
+ // numbers.
+ bool ShouldIgnore() const;
+
+ // Advances the iterator by the given scope number, skipping ignored scopes.
+ // Returns true if the scope was found, false otherwise.
+ bool AdvanceToScopeNumber(int scope_number = 0);
+
// Set variable value and return true on success.
bool SetVariableValue(Handle<String> variable_name,
DirectHandle<Object> new_value);
diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.cc b/deps/v8/src/debug/debug-stack-trace-iterator.cc
index fdbba1b7313..6bc3e90deef 100644
--- a/deps/v8/src/debug/debug-stack-trace-iterator.cc
+++ b/deps/v8/src/debug/debug-stack-trace-iterator.cc
@@ -260,14 +260,14 @@ void DebugStackTraceIterator::UpdateInlineFrameIndexAndResumableFnOnStack() {
}
v8::MaybeLocal<v8::Value> DebugStackTraceIterator::Evaluate(
- v8::Local<v8::String> source, bool throw_on_side_effect) {
+ v8::Local<v8::String> source, bool throw_on_side_effect, int scope_index) {
DCHECK(!Done());
DirectHandle<Object> value;
i::SafeForInterruptsScope safe_for_interrupt_scope(isolate_);
if (!DebugEvaluate::Local(
isolate_, iterator_.frame()->id(), inlined_frame_index_,
- Utils::OpenDirectHandle(*source), throw_on_side_effect)
+ Utils::OpenDirectHandle(*source), throw_on_side_effect, scope_index)
.ToHandle(&value)) {
return v8::MaybeLocal<v8::Value>();
}
diff --git a/deps/v8/src/debug/debug-stack-trace-iterator.h b/deps/v8/src/debug/debug-stack-trace-iterator.h
index dd2d743cafe..91cdc13b13b 100644
--- a/deps/v8/src/debug/debug-stack-trace-iterator.h
+++ b/deps/v8/src/debug/debug-stack-trace-iterator.h
@@ -34,7 +34,8 @@ class DebugStackTraceIterator final : public debug::StackTraceIterator {
bool CanBeRestarted() const override;
v8::MaybeLocal<v8::Value> Evaluate(v8::Local<v8::String> source,
- bool throw_on_side_effect) override;
+ bool throw_on_side_effect,
+ int scope_index = 0) override;
void PrepareRestart();
Handle<SharedFunctionInfo> GetSharedFunctionInfo() const;
diff --git a/deps/v8/src/debug/debug-wasm-objects.cc b/deps/v8/src/debug/debug-wasm-objects.cc
index d37313d0125..9ab74cd1176 100644
--- a/deps/v8/src/debug/debug-wasm-objects.cc
+++ b/deps/v8/src/debug/debug-wasm-objects.cc
@@ -363,7 +363,7 @@ struct GlobalsProxy : NamedDebugProxy<GlobalsProxy, kGlobalsProxy> {
static DirectHandle<String> GetName(Isolate* isolate,
DirectHandle<WasmInstanceObject> instance,
uint32_t index) {
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
instance->module_object()->native_module();
wasm::NamesProvider* names = native_module->GetNamesProvider();
StringBuilder sb;
@@ -391,7 +391,7 @@ struct MemoriesProxy : NamedDebugProxy<MemoriesProxy, kMemoriesProxy> {
static DirectHandle<String> GetName(Isolate* isolate,
DirectHandle<WasmInstanceObject> instance,
uint32_t index) {
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
instance->module_object()->native_module();
wasm::NamesProvider* names = native_module->GetNamesProvider();
StringBuilder sb;
@@ -419,7 +419,7 @@ struct TablesProxy : NamedDebugProxy<TablesProxy, kTablesProxy> {
static DirectHandle<String> GetName(Isolate* isolate,
DirectHandle<WasmInstanceObject> instance,
uint32_t index) {
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
instance->module_object()->native_module();
wasm::NamesProvider* names = native_module->GetNamesProvider();
StringBuilder sb;
@@ -466,7 +466,7 @@ struct LocalsProxy : NamedDebugProxy<LocalsProxy, kLocalsProxy, FixedArray> {
DirectHandle<FixedArray> values,
uint32_t index) {
uint32_t count = Count(isolate, values);
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
Cast<WasmModuleObject>(values->get(count + 0))->native_module();
auto function_index = Smi::ToInt(Cast<Smi>(values->get(count + 1)));
wasm::NamesProvider* names = native_module->GetNamesProvider();
@@ -1052,6 +1052,9 @@ DirectHandle<WasmValueObject> WasmValueObject::New(
t = isolate->factory()->InternalizeString(
base::StaticCharVector("exnref"));
v = ref;
+ } else if (IsWasmNull(*ref)) {
+ v = isolate->factory()->null_value();
+ t = GetRefTypeName(isolate, value.type());
} else if (IsWasmStruct(*ref)) {
Tagged<WasmTypeInfo> type_info =
Cast<HeapObject>(*ref)->map()->wasm_type_info();
@@ -1067,9 +1070,6 @@ DirectHandle<WasmValueObject> WasmValueObject::New(
Cast<WasmFuncRef>(*ref)->internal(isolate), isolate};
v = WasmInternalFunction::GetOrCreateExternal(internal_fct);
t = GetRefTypeName(isolate, value.type());
- } else if (IsWasmNull(*ref)) {
- v = isolate->factory()->null_value();
- t = GetRefTypeName(isolate, value.type());
} else if (IsJSFunction(*ref) || IsSmi(*ref) || IsNull(*ref) ||
IsString(*ref) ||
value.type().is_reference_to(wasm::GenericKind::kExtern) ||
diff --git a/deps/v8/src/debug/debug-wasm-objects.h b/deps/v8/src/debug/debug-wasm-objects.h
index 9f4441d8209..22dc7d4966a 100644
--- a/deps/v8/src/debug/debug-wasm-objects.h
+++ b/deps/v8/src/debug/debug-wasm-objects.h
@@ -36,6 +36,8 @@ class WasmModuleObject;
class WasmTableObject;
V8_OBJECT class WasmValueObject : public JSObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
DECL_ACCESSORS(type, Tagged<String>)
DECL_ACCESSORS(value, Tagged<Object>)
diff --git a/deps/v8/src/debug/debug.cc b/deps/v8/src/debug/debug.cc
index b239a5c433f..def10a51cd7 100644
--- a/deps/v8/src/debug/debug.cc
+++ b/deps/v8/src/debug/debug.cc
@@ -17,7 +17,7 @@
#include "src/common/globals.h"
#include "src/common/message-template.h"
#include "src/debug/debug-evaluate.h"
-#include "src/debug/liveedit.h"
+#include "src/debug/debug-scope-info.h"
#include "src/deoptimizer/deoptimizer.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
@@ -33,6 +33,7 @@
#include "src/objects/abstract-code-inl.h"
#include "src/objects/api-callbacks-inl.h"
#include "src/objects/debug-objects-inl.h"
+#include "src/objects/hash-table-inl.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/js-promise-inl.h"
#include "src/objects/slots.h"
@@ -189,6 +190,39 @@ Debug::Debug(Isolate* isolate)
Debug::~Debug() { DCHECK_NULL(debug_delegate_); }
+DirectHandle<DebugScriptScopeInfo> Debug::GetScriptScopeInfo(
+ DirectHandle<Script> script) {
+ if (script_scope_infos_.is_null()) return {};
+ Tagged<Object> obj = script_scope_infos_->Lookup(script);
+ if (IsTheHole(obj)) return {};
+ return direct_handle(Cast<DebugScriptScopeInfo>(obj), isolate_);
+}
+
+void Debug::SetScriptScopeInfo(DirectHandle<Script> script,
+ DirectHandle<DebugScriptScopeInfo> info) {
+ HandleScope scope(isolate_);
+ Handle<EphemeronHashTable> table;
+ if (script_scope_infos_.is_null()) {
+ table = EphemeronHashTable::New(isolate_, 16);
+ } else {
+ table = script_scope_infos_;
+ }
+ table = EphemeronHashTable::Put(isolate_, table, script, info);
+ if (script_scope_infos_.is_null()) {
+ script_scope_infos_ = isolate_->global_handles()->Create(*table);
+ } else if (*table != *script_scope_infos_) {
+ GlobalHandles::Destroy(script_scope_infos_.location());
+ script_scope_infos_ = isolate_->global_handles()->Create(*table);
+ }
+}
+
+void Debug::ClearScriptScopeInfos() {
+ if (!script_scope_infos_.is_null()) {
+ GlobalHandles::Destroy(script_scope_infos_.location());
+ script_scope_infos_ = {};
+ }
+}
+
BreakLocation BreakLocation::FromFrame(Handle<DebugInfo> debug_info,
JavaScriptFrame* frame) {
if (debug_info->CanBreakAtEntry()) {
@@ -480,7 +514,7 @@ void Debug::ThreadInit() {
base::Relaxed_Store(&thread_local_.current_debug_scope_,
static_cast<base::AtomicWord>(0));
thread_local_.break_on_next_function_call_ = false;
- thread_local_.scheduled_break_on_next_function_call_ = false;
+ thread_local_.scheduled_break_on_next_function_call_ = {};
UpdateHookOnFunctionCall();
thread_local_.muted_function_ = Smi::zero();
thread_local_.muted_position_ = -1;
@@ -621,6 +655,7 @@ void Debug::Unload() {
ClearStepping();
RemoveAllCoverageInfos();
ClearAllDebuggerHints();
+ ClearScriptScopeInfos();
debug_delegate_ = nullptr;
}
@@ -687,8 +722,9 @@ void Debug::Break(JavaScriptFrame* frame,
if (!break_points_hit.is_null() || break_on_next_function_call() ||
scheduled_break) {
StepAction lastStepAction = last_step_action();
- debug::BreakReasons break_reasons;
- if (scheduled_break) {
+ debug::BreakReasons break_reasons =
+ thread_local_.scheduled_break_on_next_function_call_;
+ if (shouldPauseAfterInstrumentation) {
break_reasons.Add(debug::BreakReason::kScheduled);
}
// If it's a debugger statement, add the reason and then mute the location
@@ -1393,7 +1429,8 @@ void Debug::PrepareStepOnThrow() {
if (last_step_action() == StepInto) {
// Deoptimize frame to ensure calls are checked for step-in.
Deoptimizer::DeoptimizeFunction(frame->function(),
- LazyDeoptimizeReason::kDebugger);
+ LazyDeoptimizeReason::kDebugger,
+ frame->LookupCode());
}
FrameSummaries summaries = frame->Summarize();
for (size_t i = summaries.size(); i != 0; i--, current_frame_count--) {
@@ -1596,7 +1633,8 @@ void Debug::PrepareStep(StepAction step_action) {
if (last_step_action() == StepInto) {
// Deoptimize frame to ensure calls are checked for step-in.
Deoptimizer::DeoptimizeFunction(js_frame->function(),
- LazyDeoptimizeReason::kDebugger);
+ LazyDeoptimizeReason::kDebugger,
+ js_frame->LookupCode());
}
HandleScope inner_scope(isolate_);
std::vector<Handle<SharedFunctionInfo>> infos;
@@ -1673,7 +1711,7 @@ void Debug::ClearStepping() {
thread_local_.last_frame_count_ = -1;
thread_local_.target_frame_count_ = -1;
thread_local_.break_on_next_function_call_ = false;
- thread_local_.scheduled_break_on_next_function_call_ = false;
+ thread_local_.scheduled_break_on_next_function_call_ = {};
clear_restart_frame();
UpdateHookOnFunctionCall();
}
@@ -2002,8 +2040,7 @@ void FindBreakablePositions(Handle<DebugInfo> debug_info, int start_position,
bool CompileTopLevel(Isolate* isolate, Handle<Script> script,
MaybeHandle<SharedFunctionInfo>* result = nullptr) {
- if (script->compilation_type() == Script::CompilationType::kEval ||
- script->is_wrapped()) {
+ if (!script->is_host()) {
return false;
}
UnoptimizedCompileState compile_state;
@@ -2321,13 +2358,19 @@ bool Debug::EnsureBreakInfo(Handle<SharedFunctionInfo> shared) {
&is_compiled_scope, CreateSourcePositions{true})) {
return false;
}
- CreateBreakInfo(shared);
- return true;
+ return CreateBreakInfo(shared);
}
-void Debug::CreateBreakInfo(DirectHandle<SharedFunctionInfo> shared) {
+bool Debug::CreateBreakInfo(DirectHandle<SharedFunctionInfo> shared) {
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger);
HandleScope scope(isolate_);
+
+ SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate_, shared);
+ if (shared->HasBytecodeArray() &&
+ !shared->GetBytecodeArray(isolate_)->HasSourcePositionTable()) {
+ return false;
+ }
+
DirectHandle<DebugInfo> debug_info = GetOrCreateDebugInfo(shared);
// Initialize with break information.
@@ -2344,7 +2387,7 @@ void Debug::CreateBreakInfo(DirectHandle<SharedFunctionInfo> shared) {
debug_info->set_flags(flags, kRelaxedStore);
debug_info->set_break_points(*break_points);
- SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate_, shared);
+ return true;
}
Handle<DebugInfo> Debug::GetOrCreateDebugInfo(
@@ -2778,24 +2821,6 @@ bool Debug::CanBreakAtEntry(DirectHandle<SharedFunctionInfo> shared) {
return false;
}
-bool Debug::SetScriptSource(Handle<Script> script, Handle<String> source,
- bool preview, bool allow_top_frame_live_editing,
- debug::LiveEditResult* result) {
- RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger);
- DebugScope debug_scope(this);
-
- if (v8_flags.inspector_live_edit) {
- running_live_edit_ = true;
- LiveEdit::PatchScript(isolate_, script, source, preview,
- allow_top_frame_live_editing, result);
- running_live_edit_ = false;
- } else {
- result->status = debug::LiveEditResult::FEATURE_DISABLED;
- }
-
- return result->status == debug::LiveEditResult::OK;
-}
-
void Debug::OnCompileError(DirectHandle<Script> script) {
ProcessCompileEvent(true, script);
}
@@ -2809,9 +2834,6 @@ void Debug::ProcessCompileEvent(bool has_compile_error,
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebugger);
// Ignore temporary scripts.
if (script->id() == Script::kTemporaryScriptId) return;
- // TODO(kozyatinskiy): teach devtools to work with liveedit scripts better
- // first and then remove this fast return.
- if (running_live_edit_) return;
// Attach the correct debug id to the script. The debug id is used by the
// inspector to filter scripts by native context.
script->set_context_data(isolate_->native_context()->debug_context_id());
@@ -2826,7 +2848,7 @@ void Debug::ProcessCompileEvent(bool has_compile_error,
{
RCS_SCOPE(isolate_, RuntimeCallCounterId::kDebuggerCallback);
debug_delegate_->ScriptCompiled(ToApiHandle<debug::Script>(script),
- running_live_edit_, has_compile_error);
+ has_compile_error);
}
}
@@ -2911,18 +2933,19 @@ void Debug::HandleDebugBreak(IgnoreBreakMode ignore_break_mode,
// caller frames are at a call site, which acts as a memory serialization
// barrier, forcing them to reload all heap state upon return anyway.
if (frame->is_optimized()) {
- Deoptimizer::DeoptimizeFunction(*function,
- LazyDeoptimizeReason::kDebugger);
+ Deoptimizer::DeoptimizeFunction(
+ *function, LazyDeoptimizeReason::kDebugger, frame->LookupCode());
}
- // kScheduled breaks are triggered by the stack check. While we could
- // pause here, the JSFunction didn't have time yet to create and push
- // it's context. Instead, we step into the function and pause at the
+ // kScheduled and kOOM breaks are triggered by the stack check. While we
+ // could pause here, the JSFunction didn't have time yet to create and
+ // push its context. Instead, we step into the function and pause at the
// first official breakable position.
// This behavior mirrors "BreakOnNextFunctionCall".
- if (break_reasons.contains(v8::debug::BreakReason::kScheduled) &&
+ if ((break_reasons.contains(v8::debug::BreakReason::kScheduled) ||
+ break_reasons.contains(v8::debug::BreakReason::kOOM)) &&
BreakLocation::IsPausedInJsFunctionEntry(frame)) {
- thread_local_.scheduled_break_on_next_function_call_ = true;
+ thread_local_.scheduled_break_on_next_function_call_.Add(break_reasons);
PrepareStepIn(function);
return;
}
@@ -3434,7 +3457,8 @@ void Debug::PrepareRestartFrame(JavaScriptFrame* frame,
int inlined_frame_index) {
if (frame->is_optimized()) {
Deoptimizer::DeoptimizeFunction(frame->function(),
- LazyDeoptimizeReason::kDebugger);
+ LazyDeoptimizeReason::kDebugger,
+ frame->LookupCode());
}
thread_local_.restart_frame_id_ = frame->id();
diff --git a/deps/v8/src/debug/debug.h b/deps/v8/src/debug/debug.h
index c2d02feb073..4a093800e6d 100644
--- a/deps/v8/src/debug/debug.h
+++ b/deps/v8/src/debug/debug.h
@@ -27,6 +27,8 @@ namespace internal {
// Forward declarations.
class AbstractCode;
class DebugScope;
+class DebugScriptScopeInfo;
+class EphemeronHashTable;
class InterpretedFrame;
class JavaScriptFrame;
class JSGeneratorObject;
@@ -350,7 +352,7 @@ class V8_EXPORT_PRIVATE Debug {
// Returns whether the operation succeeded.
bool EnsureBreakInfo(Handle<SharedFunctionInfo> shared);
- void CreateBreakInfo(DirectHandle<SharedFunctionInfo> shared);
+ bool CreateBreakInfo(DirectHandle<SharedFunctionInfo> shared);
Handle<DebugInfo> GetOrCreateDebugInfo(
DirectHandle<SharedFunctionInfo> shared);
@@ -382,14 +384,6 @@ class V8_EXPORT_PRIVATE Debug {
// Walks the call stack to see if any frames are not ignore listed.
bool AllFramesOnStackAreBlackboxed();
- // Set new script source, throw an exception if error occurred. When preview
- // is true: try to set source, throw exception if any without actual script
- // change. stack_changed is true if after editing script on pause stack is
- // changed and client should request stack trace again.
- bool SetScriptSource(Handle<Script> script, Handle<String> source,
- bool preview, bool allow_top_frame_live_editing,
- debug::LiveEditResult* result);
-
int GetFunctionDebuggingId(DirectHandle<JSFunction> function);
// Threading support.
@@ -464,7 +458,7 @@ class V8_EXPORT_PRIVATE Debug {
}
bool scheduled_break_on_function_call() const {
- return thread_local_.scheduled_break_on_next_function_call_;
+ return !thread_local_.scheduled_break_on_next_function_call_.empty();
}
bool IsRestartFrameScheduled() const {
@@ -506,6 +500,12 @@ class V8_EXPORT_PRIVATE Debug {
bool IsTemporaryObject(DirectHandle<HeapObject> object) const;
+ DirectHandle<DebugScriptScopeInfo> GetScriptScopeInfo(
+ DirectHandle<Script> script);
+ void SetScriptScopeInfo(DirectHandle<Script> script,
+ DirectHandle<DebugScriptScopeInfo> info);
+ void ClearScriptScopeInfos();
+
private:
explicit Debug(Isolate* isolate);
~Debug();
@@ -606,8 +606,6 @@ class V8_EXPORT_PRIVATE Debug {
bool hook_on_function_call_;
// Suppress debug events.
bool is_suppressed_;
- // Running liveedit.
- bool running_live_edit_ = false;
// Do not trigger debug break events.
bool break_disabled_;
// Do not break on break points.
@@ -672,10 +670,10 @@ class V8_EXPORT_PRIVATE Debug {
// debugger to break on next function call.
bool break_on_next_function_call_;
- // This flag is true when we break via stack check (BreakReason::kScheduled)
- // We don't stay paused there but instead "step in" to the function similar
- // to what "BreakOnNextFunctionCall" does.
- bool scheduled_break_on_next_function_call_;
+ // Non-empty when we break via stack check (BreakReason::kScheduled or
+ // BreakReason::kOOM). We don't stay paused there but instead "step in" to
+ // the function similar to what "BreakOnNextFunctionCall" does.
+ v8::debug::BreakReasons scheduled_break_on_next_function_call_;
// Frame ID for the frame that needs to be restarted. StackFrameId::NO_ID
// otherwise. The unwinder uses the id to restart execution in this frame
@@ -710,6 +708,10 @@ class V8_EXPORT_PRIVATE Debug {
IndirectHandle<WeakArrayList> wasm_scripts_with_break_points_;
#endif // V8_ENABLE_WEBASSEMBLY
+ // Ephemeron table caching DebugScriptScopeInfo for Scripts.
+ // This is a global handle, lazily initialized.
+ IndirectHandle<EphemeronHashTable> script_scope_infos_;
+
// This is a part of machinery for allowing to ignore side effects for one
// call to this API function. See Function::NewInstanceWithSideEffectType().
// Since the FunctionTemplateInfo is allowlisted right before the call to
@@ -728,7 +730,6 @@ class V8_EXPORT_PRIVATE Debug {
friend class DebugScope;
friend class DisableBreak;
friend class DisableTemporaryObjectTracking;
- friend class LiveEdit;
friend class SuppressDebug;
friend DirectHandle<ProtectedFixedArray>
diff --git a/deps/v8/src/debug/liveedit-diff.cc b/deps/v8/src/debug/liveedit-diff.cc
deleted file mode 100644
index 25108f19578..00000000000
--- a/deps/v8/src/debug/liveedit-diff.cc
+++ /dev/null
@@ -1,412 +0,0 @@
-// Copyright 2022 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/liveedit-diff.h"
-
-#include <cmath>
-#include <map>
-#include <optional>
-#include <vector>
-
-#include "src/base/logging.h"
-
-namespace v8 {
-namespace internal {
-
-namespace {
-
-// Implements Myer's Algorithm from
-// "An O(ND) Difference Algorithm and Its Variations", particularly the
-// linear space refinement mentioned in section 4b.
-//
-// The differ is input agnostic.
-//
-// The algorithm works by finding the shortest edit string (SES) in the edit
-// graph. The SES describes how to get from a string A of length N to a string
-// B of length M via deleting from A and inserting from B.
-//
-// Example: A = "abbaa", B = "abab"
-//
-// A
-//
-// a b b a a
-// o---o---o---o---o---o
-// a | \ | | | \ | \ |
-// o---o---o---o---o---o
-// b | | \ | \ | | |
-// B o---o---o---o---o---o
-// a | \ | | | \ | \ |
-// o---o---o---o---o---o
-// b | | \ | \ | | |
-// o---o---o---o---o---o
-//
-// The edit graph is constructed with the characters from string A on the x-axis
-// and the characters from string B on the y-axis. Starting from (0, 0) we can:
-//
-// - Move right, which is equivalent to deleting from A
-// - Move downwards, which is equivalent to inserting from B
-// - Move diagonally if the characters from string A and B match, which
-// means no insertion or deletion.
-//
-// Any path from (0, 0) to (N, M) describes a valid edit string, but we try to
-// find the path with the most diagonals, conversely that is the path with the
-// least insertions or deletions.
-// Note that a path with "D" insertions/deletions is called a D-path.
-class MyersDiffer {
- private:
- // A point in the edit graph.
- struct Point {
- int x, y;
-
- // Less-than for a point in the edit graph is defined as less than in both
- // components (i.e. at least one diagonal away).
- bool operator<(const Point& other) const {
- return x < other.x && y < other.y;
- }
- };
-
- // Describes a rectangle in the edit graph.
- struct EditGraphArea {
- Point top_left, bottom_right;
-
- int width() const { return bottom_right.x - top_left.x; }
- int height() const { return bottom_right.y - top_left.y; }
- int size() const { return width() + height(); }
- int delta() const { return width() - height(); }
- };
-
- // A path or path-segment through the edit graph. Not all points along
- // the path are necessarily listed since it is trivial to figure out all
- // the concrete points along a snake.
- struct Path {
- std::vector<Point> points;
-
- void Add(const Point& p) { points.push_back(p); }
- void Add(const Path& p) {
- points.insert(points.end(), p.points.begin(), p.points.end());
- }
- };
-
- // A snake is a path between two points that is either:
- //
- // - A single right or down move followed by a (possibly empty) list of
- // diagonals (in the normal case).
- // - A (possibly empty) list of diagonals followed by a single right or
- // or down move (in the reverse case).
- struct Snake {
- Point from, to;
- };
-
- // A thin wrapper around std::vector<int> that allows negative indexing.
- //
- // This class stores the x-value of the furthest reaching path
- // for each k-diagonal. k-diagonals are numbered from -M to N and defined
- // by y(x) = x - k.
- //
- // We only store the x-value instead of the full point since we can
- // calculate y via y = x - k.
- class FurthestReaching {
- public:
- explicit FurthestReaching(std::vector<int>::size_type size) : v_(size) {}
-
- int& operator[](int index) {
- const size_t idx = index >= 0 ? index : v_.size() + index;
- return v_[idx];
- }
-
- const int& operator[](int index) const {
- const size_t idx = index >= 0 ? index : v_.size() + index;
- return v_[idx];
- }
-
- private:
- std::vector<int> v_;
- };
-
- class ResultWriter;
-
- Comparator::Input* input_;
- Comparator::Output* output_;
-
- // Stores the x-value of the furthest reaching path for each k-diagonal.
- // k-diagonals are numbered from '-height' to 'width', centered on (0,0) and
- // are defined by y(x) = x - k.
- FurthestReaching fr_forward_;
-
- // Stores the x-value of the furthest reaching reverse path for each
- // l-diagonal. l-diagonals are numbered from '-width' to 'height' and centered
- // on 'bottom_right' of the edit graph area.
- // k-diagonals and l-diagonals represent the same diagonals. While we refer to
- // the diagonals as k-diagonals when calculating SES from (0,0), we refer to
- // the diagonals as l-diagonals when calculating SES from (M,N).
- // The corresponding k-diagonal name of an l-diagonal is: k = l + delta
- // where delta = width -height.
- FurthestReaching fr_reverse_;
-
- MyersDiffer(Comparator::Input* input, Comparator::Output* output)
- : input_(input),
- output_(output),
- fr_forward_(input->GetLength1() + input->GetLength2() + 1),
- fr_reverse_(input->GetLength1() + input->GetLength2() + 1) {
- // Length1 + Length2 + 1 is the upper bound for our work arrays.
- // We allocate the work arrays once and reuse them for all invocations of
- // `FindMiddleSnake`.
- }
-
- std::optional<Path> FindEditPath() {
- return FindEditPath(Point{0, 0},
- Point{input_->GetLength1(), input_->GetLength2()});
- }
-
- // Returns the path of the SES between `from` and `to`.
- std::optional<Path> FindEditPath(Point from, Point to) {
- // Divide the area described by `from` and `to` by finding the
- // middle snake ...
- std::optional<Snake> snake = FindMiddleSnake(from, to);
-
- if (!snake) return std::nullopt;
-
- // ... and then conquer the two resulting sub-areas.
- std::optional<Path> head = FindEditPath(from, snake->from);
- std::optional<Path> tail = FindEditPath(snake->to, to);
-
- // Combine `head` and `tail` or use the snake start/end points for
- // zero-size areas.
- Path result;
- if (head) {
- result.Add(*head);
- } else {
- result.Add(snake->from);
- }
-
- if (tail) {
- result.Add(*tail);
- } else {
- result.Add(snake->to);
- }
- return result;
- }
-
- // Returns the snake in the middle of the area described by `from` and `to`.
- //
- // Incrementally calculates the D-paths (starting from 'from') and the
- // "reverse" D-paths (starting from 'to') until we find a "normal" and a
- // "reverse" path that overlap. That is we first calculate the normal
- // and reverse 0-path, then the normal and reverse 1-path and so on.
- //
- // If a step from a (d-1)-path to a d-path overlaps with a reverse path on
- // the same diagonal (or the other way around), then we consider that step
- // our middle snake and return it immediately.
- std::optional<Snake> FindMiddleSnake(Point from, Point to) {
- EditGraphArea area{from, to};
- if (area.size() == 0) return std::nullopt;
-
- // Initialise the furthest reaching vectors with an "artificial" edge
- // from (0, -1) -> (0, 0) and (N, -M) -> (N, M) to serve as the initial
- // snake when d = 0.
- fr_forward_[1] = area.top_left.x;
- fr_reverse_[-1] = area.bottom_right.x;
-
- for (int d = 0; d <= std::ceil(area.size() / 2.0f); ++d) {
- if (auto snake = ShortestEditForward(area, d)) return snake;
- if (auto snake = ShortestEditReverse(area, d)) return snake;
- }
-
- return std::nullopt;
- }
-
- // Greedily calculates the furthest reaching `d`-paths for each k-diagonal
- // where k is in [-d, d]. For each k-diagonal we look at the furthest
- // reaching `d-1`-path on the `k-1` and `k+1` depending on which is further
- // along the x-axis we either add an insertion from the `k+1`-diagonal or
- // a deletion from the `k-1`-diagonal. Then we follow all possible diagonal
- // moves and finally record the result as the furthest reaching path on the
- // k-diagonal.
- std::optional<Snake> ShortestEditForward(const EditGraphArea& area, int d) {
- Point from, to;
- // We alternate between looking at odd and even k-diagonals. That is
- // because when we extend a `d-path` by a single move we can at most move
- // one diagonal over. That is either move from `k-1` to `k` or from `k+1` to
- // `k`. That is if `d` is even (odd) then we require only the odd (even)
- // k-diagonals calculated in step `d-1`.
- for (int k = -d; k <= d; k += 2) {
- if (k == -d || (k != d && fr_forward_[k - 1] < fr_forward_[k + 1])) {
- // Move downwards, i.e. add an insertion, because either we are at the
- // edge and downwards is the only way we can move, or because the
- // `d-1`-path along the `k+1` diagonal reaches further on the x-axis
- // than the `d-1`-path along the `k-1` diagonal.
- from.x = to.x = fr_forward_[k + 1];
- } else {
- // Move right, i.e. add a deletion.
- from.x = fr_forward_[k - 1];
- to.x = from.x + 1;
- }
-
- // Calculate y via y = x - k. We need to adjust k though since the k=0
- // diagonal is centered on `area.top_left` and not (0, 0).
- to.y = area.top_left.y + (to.x - area.top_left.x) - k;
- from.y = (d == 0 || from.x != to.x) ? to.y : to.y - 1;
-
- // Extend the snake diagonally as long as we can.
- while (to < area.bottom_right && input_->Equals(to.x, to.y)) {
- ++to.x;
- ++to.y;
- }
-
- fr_forward_[k] = to.x;
-
- // Check whether there is a reverse path on this k-diagonal which we
- // are overlapping with. If yes, that is our snake.
- const bool odd = area.delta() % 2 != 0;
- const int l = k - area.delta();
- if (odd && l >= (-d + 1) && l <= d - 1 && to.x >= fr_reverse_[l]) {
- return Snake{from, to};
- }
- }
- return std::nullopt;
- }
-
- // Greedily calculates the furthest reaching reverse `d`-paths for each
- // l-diagonal where l is in [-d, d].
- // Works the same as `ShortestEditForward` but we move upwards and left
- // instead.
- std::optional<Snake> ShortestEditReverse(const EditGraphArea& area, int d) {
- Point from, to;
- // We alternate between looking at odd and even l-diagonals. That is
- // because when we extend a `d-path` by a single move we can at most move
- // one diagonal over. That is either move from `l-1` to `l` or from `l+1` to
- // `l`. That is if `d` is even (odd) then we require only the odd (even)
- // l-diagonals calculated in step `d-1`.
- for (int l = d; l >= -d; l -= 2) {
- if (l == d || (l != -d && fr_reverse_[l - 1] > fr_reverse_[l + 1])) {
- // Move upwards, i.e. add an insertion, because either we are at the
- // edge and upwards is the only way we can move, or because the
- // `d-1`-path along the `l-1` diagonal reaches further on the x-axis
- // than the `d-1`-path along the `l+1` diagonal.
- from.x = to.x = fr_reverse_[l - 1];
- } else {
- // Move left, i.e. add a deletion.
- from.x = fr_reverse_[l + 1];
- to.x = from.x - 1;
- }
-
- // Calculate y via y = x - k. We need to adjust k though since the k=0
- // diagonal is centered on `area.top_left` and not (0, 0).
- const int k = l + area.delta();
- to.y = area.top_left.y + (to.x - area.top_left.x) - k;
- from.y = (d == 0 || from.x != to.x) ? to.y : to.y + 1;
-
- // Extend the snake diagonally as long as we can.
- while (area.top_left < to && input_->Equals(to.x - 1, to.y - 1)) {
- --to.x;
- --to.y;
- }
-
- fr_reverse_[l] = to.x;
-
- // Check whether there is a path on this k-diagonal which we
- // are overlapping with. If yes, that is our snake.
- const bool even = area.delta() % 2 == 0;
- if (even && k >= -d && k <= d && to.x <= fr_forward_[k]) {
- // Invert the points so the snake goes left to right, top to bottom.
- return Snake{to, from};
- }
- }
- return std::nullopt;
- }
-
- // Small helper class that converts a "shortest edit script" path into a
- // source mapping. The result is a list of "chunks" where each "chunk"
- // describes a range in the input string and where it can now be found
- // in the output string.
- //
- // The list of chunks can be calculated in a simple pass over all the points
- // of the edit path:
- //
- // - For any diagonal we close and report the current chunk if there is
- // one open at the moment.
- // - For an insertion or deletion we open a new chunk if none is ongoing.
- class ResultWriter {
- public:
- explicit ResultWriter(Comparator::Output* output) : output_(output) {}
-
- void RecordNoModification(const Point& from) {
- if (!change_is_ongoing_) return;
-
- // We close the current chunk, going from `change_start_` to `from`.
- CHECK(change_start_);
- output_->AddChunk(change_start_->x, change_start_->y,
- from.x - change_start_->x, from.y - change_start_->y);
- change_is_ongoing_ = false;
- }
-
- void RecordInsertionOrDeletion(const Point& from) {
- if (change_is_ongoing_) return;
-
- // We start a new chunk beginning at `from`.
- change_start_ = from;
- change_is_ongoing_ = true;
- }
-
- private:
- Comparator::Output* output_;
- bool change_is_ongoing_ = false;
- std::optional<Point> change_start_;
- };
-
- // Takes an edit path and "fills in the blanks". That is we notify the
- // `ResultWriter` after each single downwards, left or diagonal move.
- void WriteResult(const Path& path) {
- ResultWriter writer(output_);
-
- for (size_t i = 1; i < path.points.size(); ++i) {
- Point p1 = path.points[i - 1];
- Point p2 = path.points[i];
-
- p1 = WalkDiagonal(writer, p1, p2);
- const int cmp = (p2.x - p1.x) - (p2.y - p1.y);
- if (cmp == -1) {
- writer.RecordInsertionOrDeletion(p1);
- p1.y++;
- } else if (cmp == 1) {
- writer.RecordInsertionOrDeletion(p1);
- p1.x++;
- }
-
- p1 = WalkDiagonal(writer, p1, p2);
- DCHECK(p1.x == p2.x && p1.y == p2.y);
- }
-
- // Write one diagonal in the end to flush out any open chunk.
- writer.RecordNoModification(path.points.back());
- }
-
- Point WalkDiagonal(ResultWriter& writer, Point p1, Point p2) {
- while (p1.x < p2.x && p1.y < p2.y && input_->Equals(p1.x, p1.y)) {
- writer.RecordNoModification(p1);
- p1.x++;
- p1.y++;
- }
- return p1;
- }
-
- public:
- static void MyersDiff(Comparator::Input* input, Comparator::Output* output) {
- MyersDiffer differ(input, output);
- auto result = differ.FindEditPath();
- if (!result) return; // Empty input doesn't produce a path.
-
- differ.WriteResult(*result);
- }
-};
-
-} // namespace
-
-void Comparator::CalculateDifference(Comparator::Input* input,
- Comparator::Output* result_writer) {
- MyersDiffer::MyersDiff(input, result_writer);
-}
-
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/src/debug/liveedit-diff.h b/deps/v8/src/debug/liveedit-diff.h
deleted file mode 100644
index 15bedc3eacf..00000000000
--- a/deps/v8/src/debug/liveedit-diff.h
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2022 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_LIVEEDIT_DIFF_H_
-#define V8_DEBUG_LIVEEDIT_DIFF_H_
-
-namespace v8 {
-namespace internal {
-
-// A general-purpose comparator between 2 arrays.
-class Comparator {
- public:
- // Holds 2 arrays of some elements allowing to compare any pair of
- // element from the first array and element from the second array.
- class Input {
- public:
- virtual int GetLength1() = 0;
- virtual int GetLength2() = 0;
- virtual bool Equals(int index1, int index2) = 0;
-
- protected:
- virtual ~Input() = default;
- };
-
- // Receives compare result as a series of chunks.
- class Output {
- public:
- // Puts another chunk in result list. Note that technically speaking
- // only 3 arguments actually needed with 4th being derivable.
- virtual void AddChunk(int pos1, int pos2, int len1, int len2) = 0;
-
- protected:
- virtual ~Output() = default;
- };
-
- // Finds the difference between 2 arrays of elements.
- static void CalculateDifference(Input* input, Output* result_writer);
-};
-
-} // namespace internal
-} // namespace v8
-
-#endif // V8_DEBUG_LIVEEDIT_DIFF_H_
diff --git a/deps/v8/src/debug/liveedit.cc b/deps/v8/src/debug/liveedit.cc
deleted file mode 100644
index 6c509e35e60..00000000000
--- a/deps/v8/src/debug/liveedit.cc
+++ /dev/null
@@ -1,1155 +0,0 @@
-// Copyright 2012 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/liveedit.h"
-
-#include <optional>
-
-#include "src/api/api-inl.h"
-#include "src/ast/ast-traversal-visitor.h"
-#include "src/ast/ast.h"
-#include "src/ast/scopes.h"
-#include "src/base/strong-alias.h"
-#include "src/codegen/compilation-cache.h"
-#include "src/codegen/compiler.h"
-#include "src/codegen/source-position-table.h"
-#include "src/common/globals.h"
-#include "src/debug/debug-interface.h"
-#include "src/debug/debug-stack-trace-iterator.h"
-#include "src/debug/debug.h"
-#include "src/debug/liveedit-diff.h"
-#include "src/execution/frames-inl.h"
-#include "src/execution/v8threads.h"
-#include "src/logging/log.h"
-#include "src/objects/js-generator-inl.h"
-#include "src/objects/js-objects.h"
-#include "src/objects/objects-inl.h"
-#include "src/parsing/parse-info.h"
-#include "src/parsing/parsing.h"
-
-namespace v8 {
-namespace internal {
-namespace {
-
-bool CompareSubstrings(DirectHandle<String> s1, int pos1,
- DirectHandle<String> s2, int pos2, int len) {
- for (int i = 0; i < len; i++) {
- if (s1->Get(i + pos1) != s2->Get(i + pos2)) return false;
- }
- return true;
-}
-
-// Additional to Input interface. Lets switch Input range to subrange.
-// More elegant way would be to wrap one Input as another Input object
-// and translate positions there, but that would cost us additional virtual
-// call per comparison.
-class SubrangableInput : public Comparator::Input {
- public:
- virtual void SetSubrange1(int offset, int len) = 0;
- virtual void SetSubrange2(int offset, int len) = 0;
-};
-
-
-class SubrangableOutput : public Comparator::Output {
- public:
- virtual void SetSubrange1(int offset, int len) = 0;
- virtual void SetSubrange2(int offset, int len) = 0;
-};
-
-// Finds common prefix and suffix in input. This parts shouldn't take space in
-// linear programming table. Enable subranging in input and output.
-void NarrowDownInput(SubrangableInput* input, SubrangableOutput* output) {
- const int len1 = input->GetLength1();
- const int len2 = input->GetLength2();
-
- int common_prefix_len;
- int common_suffix_len;
-
- {
- common_prefix_len = 0;
- int prefix_limit = std::min(len1, len2);
- while (common_prefix_len < prefix_limit &&
- input->Equals(common_prefix_len, common_prefix_len)) {
- common_prefix_len++;
- }
-
- common_suffix_len = 0;
- int suffix_limit =
- std::min(len1 - common_prefix_len, len2 - common_prefix_len);
-
- while (common_suffix_len < suffix_limit &&
- input->Equals(len1 - common_suffix_len - 1,
- len2 - common_suffix_len - 1)) {
- common_suffix_len++;
- }
- }
-
- if (common_prefix_len > 0 || common_suffix_len > 0) {
- int new_len1 = len1 - common_suffix_len - common_prefix_len;
- int new_len2 = len2 - common_suffix_len - common_prefix_len;
-
- input->SetSubrange1(common_prefix_len, new_len1);
- input->SetSubrange2(common_prefix_len, new_len2);
-
- output->SetSubrange1(common_prefix_len, new_len1);
- output->SetSubrange2(common_prefix_len, new_len2);
- }
-}
-
-// Represents 2 strings as 2 arrays of tokens.
-// TODO(LiveEdit): Currently it's actually an array of charactres.
-// Make array of tokens instead.
-class TokensCompareInput : public Comparator::Input {
- public:
- TokensCompareInput(Handle<String> s1, int offset1, int len1,
- Handle<String> s2, int offset2, int len2)
- : s1_(s1), offset1_(offset1), len1_(len1),
- s2_(s2), offset2_(offset2), len2_(len2) {
- }
- int GetLength1() override { return len1_; }
- int GetLength2() override { return len2_; }
- bool Equals(int index1, int index2) override {
- return s1_->Get(offset1_ + index1) == s2_->Get(offset2_ + index2);
- }
-
- private:
- Handle<String> s1_;
- int offset1_;
- int len1_;
- Handle<String> s2_;
- int offset2_;
- int len2_;
-};
-
-// Stores compare result in std::vector. Converts substring positions
-// to absolute positions.
-class TokensCompareOutput : public Comparator::Output {
- public:
- TokensCompareOutput(int offset1, int offset2,
- std::vector<SourceChangeRange>* output)
- : output_(output), offset1_(offset1), offset2_(offset2) {}
-
- void AddChunk(int pos1, int pos2, int len1, int len2) override {
- output_->emplace_back(
- SourceChangeRange{pos1 + offset1_, pos1 + len1 + offset1_,
- pos2 + offset2_, pos2 + offset2_ + len2});
- }
-
- private:
- std::vector<SourceChangeRange>* output_;
- int offset1_;
- int offset2_;
-};
-
-// Wraps raw n-elements line_ends array as a list of n+1 lines. The last line
-// never has terminating new line character.
-class LineEndsWrapper {
- public:
- explicit LineEndsWrapper(Isolate* isolate, DirectHandle<String> string)
- : ends_array_(String::CalculateLineEnds(isolate, string, false)),
- string_len_(string->length()) {}
- int length() {
- // TODO(375937549): Consider returning uint32_t.
- return static_cast<int>(ends_array_->ulength().value() + 1);
- }
- // Returns start for any line including start of the imaginary line after
- // the last line.
- int GetLineStart(int index) { return index == 0 ? 0 : GetLineEnd(index - 1); }
- int GetLineEnd(int index) {
- if (static_cast<uint32_t>(index) == ends_array_->ulength().value()) {
- // End of the last line is always an end of the whole string.
- // If the string ends with a new line character, the last line is an
- // empty string after this character.
- return string_len_;
- } else {
- return GetPosAfterNewLine(index);
- }
- }
-
- private:
- Handle<FixedArray> ends_array_;
- int string_len_;
-
- int GetPosAfterNewLine(int index) {
- return Smi::ToInt(ends_array_->get(index)) + 1;
- }
-};
-
-// Represents 2 strings as 2 arrays of lines.
-class LineArrayCompareInput : public SubrangableInput {
- public:
- LineArrayCompareInput(Handle<String> s1, Handle<String> s2,
- LineEndsWrapper line_ends1, LineEndsWrapper line_ends2)
- : s1_(s1), s2_(s2), line_ends1_(line_ends1),
- line_ends2_(line_ends2),
- subrange_offset1_(0), subrange_offset2_(0),
- subrange_len1_(line_ends1_.length()),
- subrange_len2_(line_ends2_.length()) {
- }
- int GetLength1() override { return subrange_len1_; }
- int GetLength2() override { return subrange_len2_; }
- bool Equals(int index1, int index2) override {
- index1 += subrange_offset1_;
- index2 += subrange_offset2_;
-
- int line_start1 = line_ends1_.GetLineStart(index1);
- int line_start2 = line_ends2_.GetLineStart(index2);
- int line_end1 = line_ends1_.GetLineEnd(index1);
- int line_end2 = line_ends2_.GetLineEnd(index2);
- int len1 = line_end1 - line_start1;
- int len2 = line_end2 - line_start2;
- if (len1 != len2) {
- return false;
- }
- return CompareSubstrings(s1_, line_start1, s2_, line_start2,
- len1);
- }
- void SetSubrange1(int offset, int len) override {
- subrange_offset1_ = offset;
- subrange_len1_ = len;
- }
- void SetSubrange2(int offset, int len) override {
- subrange_offset2_ = offset;
- subrange_len2_ = len;
- }
-
- private:
- Handle<String> s1_;
- Handle<String> s2_;
- LineEndsWrapper line_ends1_;
- LineEndsWrapper line_ends2_;
- int subrange_offset1_;
- int subrange_offset2_;
- int subrange_len1_;
- int subrange_len2_;
-};
-
-// Stores compare result in std::vector. For each chunk tries to conduct
-// a fine-grained nested diff token-wise.
-class TokenizingLineArrayCompareOutput : public SubrangableOutput {
- public:
- TokenizingLineArrayCompareOutput(Isolate* isolate, LineEndsWrapper line_ends1,
- LineEndsWrapper line_ends2,
- Handle<String> s1, Handle<String> s2,
- std::vector<SourceChangeRange>* output)
- : isolate_(isolate),
- line_ends1_(line_ends1),
- line_ends2_(line_ends2),
- s1_(s1),
- s2_(s2),
- subrange_offset1_(0),
- subrange_offset2_(0),
- output_(output) {}
-
- void AddChunk(int line_pos1, int line_pos2, int line_len1,
- int line_len2) override {
- line_pos1 += subrange_offset1_;
- line_pos2 += subrange_offset2_;
-
- int char_pos1 = line_ends1_.GetLineStart(line_pos1);
- int char_pos2 = line_ends2_.GetLineStart(line_pos2);
- int char_len1 = line_ends1_.GetLineStart(line_pos1 + line_len1) - char_pos1;
- int char_len2 = line_ends2_.GetLineStart(line_pos2 + line_len2) - char_pos2;
-
- if (char_len1 < CHUNK_LEN_LIMIT && char_len2 < CHUNK_LEN_LIMIT) {
- // Chunk is small enough to conduct a nested token-level diff.
- HandleScope subTaskScope(isolate_);
-
- TokensCompareInput tokens_input(s1_, char_pos1, char_len1,
- s2_, char_pos2, char_len2);
- TokensCompareOutput tokens_output(char_pos1, char_pos2, output_);
-
- Comparator::CalculateDifference(&tokens_input, &tokens_output);
- } else {
- output_->emplace_back(SourceChangeRange{
- char_pos1, char_pos1 + char_len1, char_pos2, char_pos2 + char_len2});
- }
- }
- void SetSubrange1(int offset, int len) override {
- subrange_offset1_ = offset;
- }
- void SetSubrange2(int offset, int len) override {
- subrange_offset2_ = offset;
- }
-
- private:
- static const int CHUNK_LEN_LIMIT = 800;
-
- Isolate* isolate_;
- LineEndsWrapper line_ends1_;
- LineEndsWrapper line_ends2_;
- Handle<String> s1_;
- Handle<String> s2_;
- int subrange_offset1_;
- int subrange_offset2_;
- std::vector<SourceChangeRange>* output_;
-};
-
-struct SourcePositionEvent {
- enum Type { LITERAL_STARTS, LITERAL_ENDS, DIFF_STARTS, DIFF_ENDS };
-
- int position;
- Type type;
-
- union {
- FunctionLiteral* literal;
- int pos_diff;
- };
-
- SourcePositionEvent(FunctionLiteral* literal, bool is_start)
- : position(is_start ? literal->start_position()
- : literal->end_position()),
- type(is_start ? LITERAL_STARTS : LITERAL_ENDS),
- literal(literal) {}
- SourcePositionEvent(const SourceChangeRange& change, bool is_start)
- : position(is_start ? change.start_position : change.end_position),
- type(is_start ? DIFF_STARTS : DIFF_ENDS),
- pos_diff((change.new_end_position - change.new_start_position) -
- (change.end_position - change.start_position)) {}
-
- static bool LessThan(const SourcePositionEvent& a,
- const SourcePositionEvent& b) {
- if (a.position != b.position) return a.position < b.position;
- if (a.type != b.type) return a.type < b.type;
- if (a.type == LITERAL_STARTS && b.type == LITERAL_STARTS) {
- // If the literals start in the same position, we want the one with the
- // furthest (i.e. largest) end position to be first.
- if (a.literal->end_position() != b.literal->end_position()) {
- return a.literal->end_position() > b.literal->end_position();
- }
- // If they also end in the same position, we want the first in order of
- // literal ids to be first.
- return a.literal->function_literal_id() <
- b.literal->function_literal_id();
- } else if (a.type == LITERAL_ENDS && b.type == LITERAL_ENDS) {
- // If the literals end in the same position, we want the one with the
- // nearest (i.e. largest) start position to be first.
- if (a.literal->start_position() != b.literal->start_position()) {
- return a.literal->start_position() > b.literal->start_position();
- }
- // If they also end in the same position, we want the last in order of
- // literal ids to be first.
- return a.literal->function_literal_id() >
- b.literal->function_literal_id();
- } else {
- return a.pos_diff < b.pos_diff;
- }
- }
-};
-
-struct FunctionLiteralChange {
- // If any of start/end position is kNoSourcePosition, this literal is
- // considered damaged and will not be mapped and edited at all.
- int new_start_position;
- int new_end_position;
- bool has_changes;
- FunctionLiteral* outer_literal;
-
- explicit FunctionLiteralChange(int new_start_position, FunctionLiteral* outer)
- : new_start_position(new_start_position),
- new_end_position(kNoSourcePosition),
- has_changes(false),
- outer_literal(outer) {}
-};
-
-using FunctionLiteralChanges =
- std::unordered_map<FunctionLiteral*, FunctionLiteralChange>;
-void CalculateFunctionLiteralChanges(
- const std::vector<FunctionLiteral*>& literals,
- const std::vector<SourceChangeRange>& diffs,
- FunctionLiteralChanges* result) {
- std::vector<SourcePositionEvent> events;
- events.reserve(literals.size() * 2 + diffs.size() * 2);
- for (FunctionLiteral* literal : literals) {
- events.emplace_back(literal, true);
- events.emplace_back(literal, false);
- }
- for (const SourceChangeRange& diff : diffs) {
- events.emplace_back(diff, true);
- events.emplace_back(diff, false);
- }
- std::sort(events.begin(), events.end(), SourcePositionEvent::LessThan);
- bool inside_diff = false;
- int delta = 0;
- std::stack<std::pair<FunctionLiteral*, FunctionLiteralChange>> literal_stack;
- for (const SourcePositionEvent& event : events) {
- switch (event.type) {
- case SourcePositionEvent::DIFF_ENDS:
- DCHECK(inside_diff);
- inside_diff = false;
- delta += event.pos_diff;
- break;
- case SourcePositionEvent::LITERAL_ENDS: {
- DCHECK_EQ(literal_stack.top().first, event.literal);
- FunctionLiteralChange& change = literal_stack.top().second;
- change.new_end_position = inside_diff
- ? kNoSourcePosition
- : event.literal->end_position() + delta;
- result->insert(literal_stack.top());
- literal_stack.pop();
- break;
- }
- case SourcePositionEvent::LITERAL_STARTS:
- literal_stack.push(std::make_pair(
- event.literal,
- FunctionLiteralChange(
- inside_diff ? kNoSourcePosition
- : event.literal->start_position() + delta,
- literal_stack.empty() ? nullptr : literal_stack.top().first)));
- break;
- case SourcePositionEvent::DIFF_STARTS:
- DCHECK(!inside_diff);
- inside_diff = true;
- if (!literal_stack.empty()) {
- // Note that outer literal has not necessarily changed, unless the
- // diff goes past the end of this literal. In this case, we'll mark
- // this function as damaged and parent as changed later in
- // MapLiterals.
- literal_stack.top().second.has_changes = true;
- }
- break;
- }
- }
-}
-
-// Function which has not changed itself, but if any variable in its
-// outer context has been added/removed, we must consider this function
-// as damaged and not update references to it.
-// This is because old compiled function has hardcoded references to
-// it's outer context.
-bool HasChangedScope(FunctionLiteral* a, FunctionLiteral* b) {
- Scope* scope_a = a->scope()->outer_scope();
- Scope* scope_b = b->scope()->outer_scope();
- while (scope_a && scope_b) {
- std::unordered_map<int, Handle<String>> vars;
- for (Variable* var : *scope_a->locals()) {
- if (!var->IsContextSlot()) continue;
- vars[var->index()] = var->name();
- }
- for (Variable* var : *scope_b->locals()) {
- if (!var->IsContextSlot()) continue;
- auto it = vars.find(var->index());
- if (it == vars.end()) return true;
- if (*it->second != *var->name()) return true;
- }
- scope_a = scope_a->outer_scope();
- scope_b = scope_b->outer_scope();
- }
- return scope_a != scope_b;
-}
-
-enum ChangeState { UNCHANGED, CHANGED, DAMAGED };
-
-using LiteralMap = std::unordered_map<FunctionLiteral*, FunctionLiteral*>;
-void MapLiterals(const FunctionLiteralChanges& changes,
- const std::vector<FunctionLiteral*>& new_literals,
- LiteralMap* unchanged, LiteralMap* changed) {
- // Track the top-level script function separately as it can overlap fully with
- // another function, e.g. the script "()=>42".
- const std::pair<int, int> kTopLevelMarker = std::make_pair(-1, -1);
- std::map<std::pair<int, int>, FunctionLiteral*> position_to_new_literal;
- for (FunctionLiteral* literal : new_literals) {
- DCHECK(literal->start_position() != kNoSourcePosition);
- DCHECK(literal->end_position() != kNoSourcePosition);
- std::pair<int, int> key =
- literal->function_literal_id() == kFunctionLiteralIdTopLevel
- ? kTopLevelMarker
- : std::make_pair(literal->start_position(),
- literal->end_position());
- // Make sure there are no duplicate keys.
- DCHECK_EQ(position_to_new_literal.find(key), position_to_new_literal.end());
- position_to_new_literal[key] = literal;
- }
- LiteralMap mappings;
- std::unordered_map<FunctionLiteral*, ChangeState> change_state;
- for (const auto& change_pair : changes) {
- FunctionLiteral* literal = change_pair.first;
- const FunctionLiteralChange& change = change_pair.second;
- std::pair<int, int> key =
- literal->function_literal_id() == kFunctionLiteralIdTopLevel
- ? kTopLevelMarker
- : std::make_pair(change.new_start_position,
- change.new_end_position);
- auto it = position_to_new_literal.find(key);
- if (it == position_to_new_literal.end() ||
- HasChangedScope(literal, it->second)) {
- change_state[literal] = ChangeState::DAMAGED;
- if (!change.outer_literal) continue;
- if (change_state[change.outer_literal] != ChangeState::DAMAGED) {
- change_state[change.outer_literal] = ChangeState::CHANGED;
- }
- } else {
- mappings[literal] = it->second;
- if (change_state.find(literal) == change_state.end()) {
- change_state[literal] =
- change.has_changes ? ChangeState::CHANGED : ChangeState::UNCHANGED;
- }
- }
- }
- for (const auto& mapping : mappings) {
- if (change_state[mapping.first] == ChangeState::UNCHANGED) {
- (*unchanged)[mapping.first] = mapping.second;
- } else if (change_state[mapping.first] == ChangeState::CHANGED) {
- (*changed)[mapping.first] = mapping.second;
- }
- }
-}
-
-class CollectFunctionLiterals final
- : public AstTraversalVisitor<CollectFunctionLiterals> {
- public:
- CollectFunctionLiterals(Isolate* isolate, AstNode* root)
- : AstTraversalVisitor<CollectFunctionLiterals>(isolate, root) {}
- void VisitFunctionLiteral(FunctionLiteral* lit) {
- uint32_t parent_id = function_literal_id_;
- function_literal_id_ = lit->function_literal_id();
- AstTraversalVisitor::VisitFunctionLiteral(lit);
- literals_->push_back(lit);
- function_literal_id_ = parent_id;
- }
- void VisitCall(Call* call) {
- AstTraversalVisitor::VisitCall(call);
- if (call->is_possibly_eval()) {
- (*eval_calls_)[function_literal_id_].push_back(
- call->eval_scope_info_index());
- }
- }
- void Run(std::vector<FunctionLiteral*>* literals,
- std::map<uint32_t, std::vector<uint32_t>>* eval_calls) {
- literals_ = literals;
- eval_calls_ = eval_calls;
- AstTraversalVisitor::Run();
- literals_ = nullptr;
- eval_calls_ = nullptr;
- }
-
- private:
- uint32_t function_literal_id_ = 0;
- std::vector<FunctionLiteral*>* literals_;
- std::map<uint32_t, std::vector<uint32_t>>* eval_calls_;
-};
-
-bool ParseScript(Isolate* isolate, Handle<Script> script, ParseInfo* parse_info,
- MaybeDirectHandle<ScopeInfo> outer_scope_info,
- bool compile_as_well, std::vector<FunctionLiteral*>* literals,
- std::map<uint32_t, std::vector<uint32_t>>* eval_calls,
- debug::LiveEditResult* result) {
- v8::TryCatch try_catch(reinterpret_cast<v8::Isolate*>(isolate));
- DirectHandle<SharedFunctionInfo> shared;
- bool success = false;
- if (compile_as_well) {
- success = Compiler::CompileForLiveEdit(parse_info, script, outer_scope_info,
- isolate)
- .ToHandle(&shared);
- } else {
- success =
- parsing::ParseProgram(parse_info, script, outer_scope_info, isolate,
- parsing::ReportStatisticsMode{true});
- if (!success) {
- // Throw the parser error.
- parse_info->pending_error_handler()->PrepareErrors(
- isolate, parse_info->ast_value_factory());
- parse_info->pending_error_handler()->ReportErrors(isolate, script);
- }
- }
- if (!success) {
- DCHECK(try_catch.HasCaught());
- result->message = try_catch.Message()->Get();
- i::DirectHandle<i::JSMessageObject> msg =
- Utils::OpenDirectHandle(*try_catch.Message());
- i::JSMessageObject::EnsureSourcePositionsAvailable(isolate, msg);
- result->line_number = msg->GetLineNumber();
- result->column_number = msg->GetColumnNumber();
- result->status = debug::LiveEditResult::COMPILE_ERROR;
- return false;
- }
- CollectFunctionLiterals visitor(isolate, parse_info->literal());
- visitor.Run(literals, eval_calls);
- if (visitor.HasStackOverflow()) {
- visitor.ClearStackOverflow();
- return false;
- }
- return true;
-}
-
-struct FunctionData {
- explicit FunctionData(FunctionLiteral* literal)
- : literal(literal), stack_position(NOT_ON_STACK) {}
-
- FunctionLiteral* literal;
- MaybeHandle<SharedFunctionInfo> shared;
- std::vector<Handle<JSFunction>> js_functions;
- std::vector<Handle<JSGeneratorObject>> running_generators;
- // In case of multiple functions with different stack position, the latest
- // one (in the order below) is used, since it is the most restrictive.
- // This is important only for functions to be restarted.
- enum StackPosition { NOT_ON_STACK, ON_TOP_ONLY, ON_STACK };
- StackPosition stack_position;
-};
-
-class FunctionDataMap : public ThreadVisitor {
- public:
- void AddInterestingLiteral(int script_id, FunctionLiteral* literal) {
- map_.emplace(GetFuncId(script_id, literal), FunctionData{literal});
- }
-
- bool Lookup(Tagged<SharedFunctionInfo> sfi, FunctionData** data) {
- int start_position = sfi->StartPosition();
- if (!IsScript(sfi->script()) || start_position == -1) {
- return false;
- }
- Tagged<Script> script = Cast<Script>(sfi->script());
- return Lookup(GetFuncId(script->id(), sfi), data);
- }
-
- bool Lookup(DirectHandle<Script> script, FunctionLiteral* literal,
- FunctionData** data) {
- return Lookup(GetFuncId(script->id(), literal), data);
- }
-
- void Fill(Isolate* isolate) {
- {
- HeapObjectIterator iterator(isolate->heap(),
- HeapObjectIterator::kFilterUnreachable);
- for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
- obj = iterator.Next()) {
- if (IsSharedFunctionInfo(obj)) {
- Tagged<SharedFunctionInfo> sfi = Cast<SharedFunctionInfo>(obj);
- FunctionData* data = nullptr;
- if (!Lookup(sfi, &data)) continue;
- data->shared = handle(sfi, isolate);
- } else if (IsJSFunction(obj)) {
- Tagged<JSFunction> js_function = Cast<JSFunction>(obj);
- Tagged<SharedFunctionInfo> sfi = js_function->shared();
- FunctionData* data = nullptr;
- if (!Lookup(sfi, &data)) continue;
- data->js_functions.emplace_back(js_function, isolate);
- } else if (IsJSGeneratorObject(obj)) {
- Tagged<JSGeneratorObject> gen = Cast<JSGeneratorObject>(obj);
- if (gen->is_closed()) continue;
- Tagged<SharedFunctionInfo> sfi = gen->function()->shared();
- FunctionData* data = nullptr;
- if (!Lookup(sfi, &data)) continue;
- data->running_generators.emplace_back(gen, isolate);
- }
- }
- }
-
- // Visit the current thread stack.
- VisitCurrentThread(isolate);
-
- // Visit the stacks of all archived threads.
- isolate->thread_manager()->IterateArchivedThreads(this);
- }
-
- private:
- // Unique id for a function: script_id + start_position, where start_position
- // is special cased to -1 for top-level so that it does not overlap with a
- // function whose start position is 0.
- using FuncId = std::pair<int, int>;
-
- FuncId GetFuncId(int script_id, FunctionLiteral* literal) {
- int start_position = literal->start_position();
- if (literal->function_literal_id() == 0) {
- // This is the top-level script function literal, so special case its
- // start position
- DCHECK_EQ(start_position, 0);
- start_position = -1;
- }
- return FuncId(script_id, start_position);
- }
-
- FuncId GetFuncId(int script_id, Tagged<SharedFunctionInfo> sfi) {
- DCHECK_EQ(script_id, Cast<Script>(sfi->script())->id());
- int start_position = sfi->StartPosition();
- DCHECK_NE(start_position, -1);
- if (sfi->is_toplevel()) {
- // This is the top-level function, so special case its start position
- DCHECK_EQ(start_position, 0);
- start_position = -1;
- }
- return FuncId(script_id, start_position);
- }
-
- bool Lookup(FuncId id, FunctionData** data) {
- auto it = map_.find(id);
- if (it == map_.end()) return false;
- *data = &it->second;
- return true;
- }
-
- void VisitThread(Isolate* isolate, ThreadLocalTop* top) override {
- for (JavaScriptStackFrameIterator it(isolate, top); !it.done();
- it.Advance()) {
- std::vector<Handle<SharedFunctionInfo>> sfis;
- it.frame()->GetFunctions(&sfis);
- for (auto& sfi : sfis) {
- FunctionData* data = nullptr;
- if (!Lookup(*sfi, &data)) continue;
- data->stack_position = FunctionData::ON_STACK;
- }
- }
- }
-
- void VisitCurrentThread(Isolate* isolate) {
- // We allow live editing the function that's currently top-of-stack. But
- // only if no activation of that function is anywhere else on the stack.
- bool is_top = true;
- for (DebugStackTraceIterator it(isolate, /* index */ 0); !it.Done();
- it.Advance(), is_top = false) {
- auto sfi = it.GetSharedFunctionInfo();
- if (sfi.is_null()) continue;
- FunctionData* data = nullptr;
- if (!Lookup(*sfi, &data)) continue;
-
- // ON_TOP_ONLY will only be set on the first iteration (and if the frame
- // can be restarted). Further activations will change the ON_TOP_ONLY to
- // ON_STACK and prevent the live edit from happening.
- data->stack_position = is_top && it.CanBeRestarted()
- ? FunctionData::ON_TOP_ONLY
- : FunctionData::ON_STACK;
- }
- }
-
- std::map<FuncId, FunctionData> map_;
-};
-
-bool CanPatchScript(const LiteralMap& changed, DirectHandle<Script> script,
- DirectHandle<Script> new_script,
- FunctionDataMap& function_data_map,
- bool allow_top_frame_live_editing,
- debug::LiveEditResult* result) {
- for (const auto& mapping : changed) {
- FunctionData* data = nullptr;
- function_data_map.Lookup(script, mapping.first, &data);
- FunctionData* new_data = nullptr;
- function_data_map.Lookup(new_script, mapping.second, &new_data);
- Handle<SharedFunctionInfo> sfi;
- if (!data->shared.ToHandle(&sfi)) {
- continue;
- } else if (IsModule(sfi->kind())) {
- DCHECK(script->origin_options().IsModule() && sfi->is_toplevel());
- result->status =
- debug::LiveEditResult::BLOCKED_BY_TOP_LEVEL_ES_MODULE_CHANGE;
- return false;
- } else if (data->stack_position == FunctionData::ON_STACK) {
- result->status = debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION;
- return false;
- } else if (!data->running_generators.empty()) {
- result->status = debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR;
- return false;
- } else if (data->stack_position == FunctionData::ON_TOP_ONLY) {
- if (!allow_top_frame_live_editing) {
- result->status = debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION;
- return false;
- }
- result->restart_top_frame_required = true;
- }
- }
- return true;
-}
-
-void TranslateSourcePositionTable(Isolate* isolate,
- DirectHandle<BytecodeArray> code,
- const std::vector<SourceChangeRange>& diffs) {
- Zone zone(isolate->allocator(), ZONE_NAME);
- SourcePositionTableBuilder builder(&zone);
-
- DirectHandle<TrustedByteArray> source_position_table(
- code->SourcePositionTable(), isolate);
- for (SourcePositionTableIterator iterator(*source_position_table);
- !iterator.done(); iterator.Advance()) {
- SourcePosition position = iterator.source_position();
- position.SetScriptOffset(
- LiveEdit::TranslatePosition(diffs, position.ScriptOffset()));
- builder.AddPosition(iterator.code_offset(), position,
- iterator.is_statement());
- }
-
- DirectHandle<TrustedByteArray> new_source_position_table(
- builder.ToSourcePositionTable(isolate));
- code->set_source_position_table(*new_source_position_table, kReleaseStore);
- LOG_CODE_EVENT(isolate,
- CodeLinePosInfoRecordEvent(code->GetFirstBytecodeAddress(),
- *new_source_position_table,
- JitCodeEvent::BYTE_CODE));
-}
-
-void UpdatePositions(Isolate* isolate, DirectHandle<SharedFunctionInfo> sfi,
- FunctionLiteral* new_function,
- const std::vector<SourceChangeRange>& diffs) {
- sfi->UpdateFromFunctionLiteralForLiveEdit(isolate, new_function);
- if (sfi->HasBytecodeArray()) {
- TranslateSourcePositionTable(
- isolate, direct_handle(sfi->GetBytecodeArray(isolate), isolate), diffs);
- }
-}
-
-#ifdef DEBUG
-Tagged<ScopeInfo> FindOuterScopeInfoFromScriptSfi(Isolate* isolate,
- DirectHandle<Script> script) {
- // We take some SFI from the script and walk outwards until we find the
- // EVAL_SCOPE. Then we do the same search as `DetermineOuterScopeInfo` and
- // check that we found the same ScopeInfo.
- SharedFunctionInfo::ScriptIterator it(isolate, *script);
- Tagged<ScopeInfo> other_scope_info;
- for (Tagged<SharedFunctionInfo> sfi = it.Next(); !sfi.is_null();
- sfi = it.Next()) {
- if (!sfi->scope_info()->IsEmpty()) {
- other_scope_info = sfi->scope_info();
- break;
- }
- }
- if (other_scope_info.is_null()) return other_scope_info;
-
- while (!other_scope_info->IsEmpty() &&
- other_scope_info->scope_type() != EVAL_SCOPE &&
- other_scope_info->HasOuterScopeInfo()) {
- other_scope_info = other_scope_info->OuterScopeInfo();
- }
-
- // This function is only called when we found a ScopeInfo candidate, so
- // technically the EVAL_SCOPE must have an outer_scope_info. But, the GC can
- // clean up some ScopeInfos it thinks are no longer needed. Abort the check
- // in that case.
- if (!other_scope_info->HasOuterScopeInfo()) return {};
-
- DCHECK_EQ(other_scope_info->scope_type(), EVAL_SCOPE);
- other_scope_info = other_scope_info->OuterScopeInfo();
-
- while (!other_scope_info->IsEmpty() && !other_scope_info->HasContext() &&
- other_scope_info->HasOuterScopeInfo()) {
- other_scope_info = other_scope_info->OuterScopeInfo();
- }
- return other_scope_info;
-}
-#endif
-
-// For sloppy eval we need to know the ScopeInfo the eval was compiled in and
-// reuse it when we compile the new version of the script.
-MaybeDirectHandle<ScopeInfo> DetermineOuterScopeInfo(
- Isolate* isolate, DirectHandle<Script> script) {
- if (!script->has_eval_from_shared()) return kNullMaybeHandle;
- DCHECK_EQ(script->compilation_type(), Script::CompilationType::kEval);
- if (script->has_eval_from_scope_info()) {
- Tagged<ScopeInfo> scope_info =
- Cast<ScopeInfo>(script->eval_from_scope_info());
-#ifdef DEBUG
- Tagged<ScopeInfo> other_scope_info =
- FindOuterScopeInfoFromScriptSfi(isolate, script);
- DCHECK_IMPLIES(!other_scope_info.is_null(), scope_info == other_scope_info);
-#endif
- return direct_handle(scope_info, isolate);
- }
- return kNullMaybeHandle;
-}
-
-} // anonymous namespace
-
-void LiveEdit::PatchScript(Isolate* isolate, Handle<Script> script,
- Handle<String> new_source, bool preview,
- bool allow_top_frame_live_editing,
- debug::LiveEditResult* result) {
- std::vector<SourceChangeRange> diffs;
- LiveEdit::CompareStrings(isolate,
- handle(Cast<String>(script->source()), isolate),
- new_source, &diffs);
- if (diffs.empty()) {
- result->status = debug::LiveEditResult::OK;
- return;
- }
-
- ReusableUnoptimizedCompileState reusable_state(isolate);
-
- UnoptimizedCompileState compile_state;
- UnoptimizedCompileFlags flags =
- UnoptimizedCompileFlags::ForScriptCompile(isolate, *script);
- flags.set_is_eager(true);
- flags.set_is_reparse(true);
- ParseInfo parse_info(isolate, flags, &compile_state, &reusable_state);
- MaybeDirectHandle<ScopeInfo> outer_scope_info =
- DetermineOuterScopeInfo(isolate, script);
- std::vector<FunctionLiteral*> literals;
- std::map<uint32_t, std::vector<uint32_t>> eval_calls;
- if (!ParseScript(isolate, script, &parse_info, outer_scope_info, false,
- &literals, &eval_calls, result)) {
- return;
- }
-
- Handle<Script> new_script =
- isolate->factory()->CloneScript(script, new_source);
- UnoptimizedCompileState new_compile_state;
- UnoptimizedCompileFlags new_flags =
- UnoptimizedCompileFlags::ForScriptCompile(isolate, *new_script);
- new_flags.set_is_hoisted_in_context(flags.is_hoisted_in_context());
- new_flags.set_is_eager(true);
- ParseInfo new_parse_info(isolate, new_flags, &new_compile_state,
- &reusable_state);
- std::vector<FunctionLiteral*> new_literals;
- std::map<uint32_t, std::vector<uint32_t>> new_eval_calls;
- if (!ParseScript(isolate, new_script, &new_parse_info, outer_scope_info, true,
- &new_literals, &new_eval_calls, result)) {
- return;
- }
-
- FunctionLiteralChanges literal_changes;
- CalculateFunctionLiteralChanges(literals, diffs, &literal_changes);
-
- LiteralMap changed;
- LiteralMap unchanged;
- MapLiterals(literal_changes, new_literals, &unchanged, &changed);
-
- FunctionDataMap function_data_map;
- for (const auto& mapping : changed) {
- function_data_map.AddInterestingLiteral(script->id(), mapping.first);
- function_data_map.AddInterestingLiteral(new_script->id(), mapping.second);
- }
- for (const auto& mapping : unchanged) {
- function_data_map.AddInterestingLiteral(script->id(), mapping.first);
- }
- function_data_map.Fill(isolate);
-
- if (!CanPatchScript(changed, script, new_script, function_data_map,
- allow_top_frame_live_editing, result)) {
- return;
- }
-
- if (preview) {
- result->status = debug::LiveEditResult::OK;
- return;
- }
-
- // Patching a script means that the bytecode on the stack may no longer
- // correspond to the bytecode of the JSFunction for that frame. As a result
- // it is no longer safe to flush bytecode since we might flush the new
- // bytecode for a JSFunction that is on the stack with an old bytecode, which
- // breaks the invariant that any JSFunction active on the stack is compiled.
- isolate->set_disable_bytecode_flushing(true);
-
- std::map<int, int> start_position_to_unchanged_id;
- for (const auto& mapping : unchanged) {
- FunctionData* data = nullptr;
- if (!function_data_map.Lookup(script, mapping.first, &data)) continue;
- Handle<SharedFunctionInfo> sfi;
- if (!data->shared.ToHandle(&sfi)) continue;
- DCHECK_EQ(sfi->script(), *script);
-
- isolate->compilation_cache()->Remove(sfi);
- isolate->debug()->DeoptimizeFunction(sfi);
- if (std::optional<Tagged<DebugInfo>> di = sfi->TryGetDebugInfo(isolate)) {
- DirectHandle<DebugInfo> debug_info(di.value(), isolate);
- isolate->debug()->RemoveBreakInfoAndMaybeFree(debug_info);
- }
- SharedFunctionInfo::EnsureSourcePositionsAvailable(isolate, sfi);
- UpdatePositions(isolate, sfi, mapping.second, diffs);
-
- sfi->set_script(*new_script, kReleaseStore);
- std::vector<uint32_t> source_infos =
- eval_calls[sfi->function_literal_id(kRelaxedLoad)];
- sfi->set_function_literal_id(mapping.second->function_literal_id(),
- kRelaxedStore);
- std::vector<uint32_t> target_infos =
- new_eval_calls[sfi->function_literal_id(kRelaxedLoad)];
- new_script->infos()->set(mapping.second->function_literal_id(),
- MakeWeak(*sfi), kReleaseStore);
- if (sfi->HasBytecodeArray()) {
- for (size_t i = 0; i < source_infos.size(); i++) {
- Tagged<ScopeInfo> scope_info =
- Cast<ScopeInfo>(script->infos()
- ->get(source_infos[i], kAcquireLoad)
- .GetHeapObjectAssumeWeak());
- new_script->infos()->set(target_infos[i], MakeWeak(scope_info),
- kReleaseStore);
- }
- }
- DCHECK_EQ(sfi->function_literal_id(kRelaxedLoad),
- mapping.second->function_literal_id());
-
- // Save the new start_position -> id mapping, so that we can recover it when
- // iterating over changed functions' constant pools.
- start_position_to_unchanged_id[mapping.second->start_position()] =
- mapping.second->function_literal_id();
-
- if (sfi->HasUncompiledDataWithPreparseData(isolate)) {
- sfi->ClearPreparseData(isolate);
- }
-
- for (auto& js_function : data->js_functions) {
- js_function->set_raw_feedback_cell(
- *isolate->factory()->many_closures_cell());
- if (!js_function->is_compiled(isolate)) continue;
- IsCompiledScope is_compiled_scope(
- js_function->shared()->is_compiled_scope(isolate));
- JSFunction::EnsureFeedbackVector(isolate, js_function,
- &is_compiled_scope);
- }
-
- if (!sfi->HasBytecodeArray()) continue;
- Tagged<TrustedFixedArray> constants =
- sfi->GetBytecodeArray(isolate)->constant_pool();
- uint32_t constants_len = constants->ulength().value();
- for (uint32_t i = 0; i < constants_len; ++i) {
- if (!IsSharedFunctionInfo(constants->get(i))) continue;
- data = nullptr;
- if (!function_data_map.Lookup(Cast<SharedFunctionInfo>(constants->get(i)),
- &data)) {
- continue;
- }
- auto change_it = changed.find(data->literal);
- if (change_it == changed.end()) continue;
- if (!function_data_map.Lookup(new_script, change_it->second, &data)) {
- continue;
- }
- Handle<SharedFunctionInfo> new_sfi;
- if (!data->shared.ToHandle(&new_sfi)) continue;
- constants->set(i, *new_sfi);
- }
- }
- isolate->LocalsBlockListCacheRehash();
- for (const auto& mapping : changed) {
- FunctionData* data = nullptr;
- if (!function_data_map.Lookup(new_script, mapping.second, &data)) continue;
- Handle<SharedFunctionInfo> new_sfi;
- // In most cases the new FunctionLiteral should also have an SFI, but there
- // are some exceptions. E.g the compiler doesn't create SFIs for
- // inner functions that are never referenced.
- if (!data->shared.ToHandle(&new_sfi)) continue;
- DCHECK_EQ(new_sfi->script(), *new_script);
-
- if (!function_data_map.Lookup(script, mapping.first, &data)) continue;
- Handle<SharedFunctionInfo> sfi;
- if (!data->shared.ToHandle(&sfi)) continue;
-
- isolate->debug()->DeoptimizeFunction(sfi);
- isolate->compilation_cache()->Remove(sfi);
- for (auto& js_function : data->js_functions) {
- js_function->set_raw_feedback_cell(
- *isolate->factory()->many_closures_cell());
- auto code = handle(new_sfi->GetCode(isolate), isolate);
- JSFunction::AllocateDispatchHandle(
- direct_handle(js_function), isolate,
- new_sfi->internal_formal_parameter_count_with_receiver(), code);
- js_function->set_shared(*new_sfi);
-
- if (!js_function->is_compiled(isolate)) continue;
- IsCompiledScope is_compiled_scope(
- js_function->shared()->is_compiled_scope(isolate));
- JSFunction::EnsureFeedbackVector(isolate, js_function,
- &is_compiled_scope);
- }
- }
- SharedFunctionInfo::ScriptIterator it(isolate, *new_script);
- for (Tagged<SharedFunctionInfo> sfi = it.Next(); !sfi.is_null();
- sfi = it.Next()) {
- if (!sfi->HasBytecodeArray()) continue;
- Tagged<TrustedFixedArray> constants =
- sfi->GetBytecodeArray(isolate)->constant_pool();
- uint32_t constants_len = constants->ulength().value();
- for (uint32_t i = 0; i < constants_len; ++i) {
- if (!IsSharedFunctionInfo(constants->get(i))) continue;
- Tagged<SharedFunctionInfo> inner_sfi =
- Cast<SharedFunctionInfo>(constants->get(i));
- // See if there is a mapping from this function's start position to an
- // unchanged function's id.
- auto unchanged_it =
- start_position_to_unchanged_id.find(inner_sfi->StartPosition());
- if (unchanged_it == start_position_to_unchanged_id.end()) continue;
-
- // Grab that function id from the new script's SFI list, which should have
- // already been updated in in the unchanged pass.
- Tagged<SharedFunctionInfo> old_unchanged_inner_sfi =
- Cast<SharedFunctionInfo>(
- new_script->infos()->get(unchanged_it->second).GetHeapObject());
- if (old_unchanged_inner_sfi == inner_sfi) continue;
- DCHECK_NE(old_unchanged_inner_sfi, inner_sfi);
- // Now some sanity checks. Make sure that the unchanged SFI has already
- // been processed and patched to be on the new script ...
- DCHECK_EQ(old_unchanged_inner_sfi->script(), *new_script);
- constants->set(i, old_unchanged_inner_sfi);
- }
- }
-#ifdef DEBUG
- {
- // Check that all the functions in the new script are valid, that their
- // function literals match what is expected, and that start positions are
- // unique.
- DisallowGarbageCollection no_gc;
-
- SharedFunctionInfo::ScriptIterator script_it(isolate, *new_script);
- std::set<int> start_positions;
- for (Tagged<SharedFunctionInfo> sfi = script_it.Next(); !sfi.is_null();
- sfi = script_it.Next()) {
- DCHECK_EQ(sfi->script(), *new_script);
- DCHECK_EQ(static_cast<uint32_t>(sfi->function_literal_id(kRelaxedLoad)),
- script_it.CurrentIndex());
- // Don't check the start position of the top-level function, as it can
- // overlap with a function in the script.
- if (sfi->is_toplevel()) {
- DCHECK_EQ(start_positions.find(sfi->StartPosition()),
- start_positions.end());
- start_positions.insert(sfi->StartPosition());
- }
-
- if (!sfi->HasBytecodeArray()) continue;
- // Check that all the functions in this function's constant pool are also
- // on the new script, and that their id matches their index in the new
- // scripts function list.
- Tagged<TrustedFixedArray> constants =
- sfi->GetBytecodeArray(isolate)->constant_pool();
- uint32_t constants_len = constants->ulength().value();
- for (uint32_t i = 0; i < constants_len; ++i) {
- if (!IsSharedFunctionInfo(constants->get(i))) continue;
- Tagged<SharedFunctionInfo> inner_sfi =
- Cast<SharedFunctionInfo>(constants->get(i));
- DCHECK_EQ(inner_sfi->script(), *new_script);
- DCHECK_EQ(inner_sfi,
- new_script->infos()
- ->get(inner_sfi->function_literal_id(kRelaxedLoad))
- .GetHeapObject());
- }
- }
- }
-#endif
-
- int script_id = script->id();
- script->set_id(new_script->id());
- new_script->set_id(script_id);
- result->status = debug::LiveEditResult::OK;
- result->script = ToApiHandle<v8::debug::Script>(new_script);
-}
-
-void LiveEdit::CompareStrings(Isolate* isolate, Handle<String> s1,
- Handle<String> s2,
- std::vector<SourceChangeRange>* diffs) {
- s1 = String::Flatten(isolate, s1);
- s2 = String::Flatten(isolate, s2);
-
- LineEndsWrapper line_ends1(isolate, s1);
- LineEndsWrapper line_ends2(isolate, s2);
-
- LineArrayCompareInput input(s1, s2, line_ends1, line_ends2);
- TokenizingLineArrayCompareOutput output(isolate, line_ends1, line_ends2, s1,
- s2, diffs);
-
- NarrowDownInput(&input, &output);
-
- Comparator::CalculateDifference(&input, &output);
-}
-
-int LiveEdit::TranslatePosition(const std::vector<SourceChangeRange>& diffs,
- int position) {
- auto it = std::lower_bound(diffs.begin(), diffs.end(), position,
- [](const SourceChangeRange& change, int position) {
- return change.end_position < position;
- });
- if (it != diffs.end() && position == it->end_position) {
- return it->new_end_position;
- }
- if (it == diffs.begin()) return position;
- DCHECK(it == diffs.end() || position <= it->start_position);
- it = std::prev(it);
- return position + (it->new_end_position - it->end_position);
-}
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/src/debug/liveedit.h b/deps/v8/src/debug/liveedit.h
deleted file mode 100644
index 707daa9cb3e..00000000000
--- a/deps/v8/src/debug/liveedit.h
+++ /dev/null
@@ -1,72 +0,0 @@
-// Copyright 2012 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_LIVEEDIT_H_
-#define V8_DEBUG_LIVEEDIT_H_
-
-#include <vector>
-
-#include "src/common/globals.h"
-#include "src/handles/handles.h"
-
-namespace v8 {
-namespace debug {
-struct LiveEditResult;
-} // namespace debug
-namespace internal {
-
-class Script;
-class String;
-class Debug;
-class JavaScriptFrame;
-
-struct SourceChangeRange {
- int start_position;
- int end_position;
- int new_start_position;
- int new_end_position;
-};
-
-/**
- Liveedit step-by-step:
- 1. calculate diff between old source and new source,
- 2. map function literals from old source to new source,
- 3. create new script for new_source,
- 4. mark literals with changed code as changed, all others as unchanged,
- 5. check that for changed literals there are no:
- - running generators in the heap,
- - non droppable frames (e.g. running generator) above them on stack.
- 6. mark the bottom most frame with changed function as scheduled for restart
- if any,
- 7. for unchanged functions:
- - deoptimize,
- - remove from cache,
- - update source positions,
- - move to new script,
- - reset feedback information and preparsed scope information if any,
- - replace any sfi in constant pool with changed one if any.
- 8. for changed functions:
- - deoptimize
- - remove from cache,
- - reset feedback information,
- - update all links from js functions to old shared with new one.
- 9. swap scripts.
- */
-
-class V8_EXPORT_PRIVATE LiveEdit : AllStatic {
- public:
- static void CompareStrings(Isolate* isolate, Handle<String> a,
- Handle<String> b,
- std::vector<SourceChangeRange>* diffs);
- static int TranslatePosition(const std::vector<SourceChangeRange>& changed,
- int position);
- static void PatchScript(Isolate* isolate, Handle<Script> script,
- Handle<String> source, bool preview,
- bool allow_top_frame_live_editing,
- debug::LiveEditResult* result);
-};
-} // namespace internal
-} // namespace v8
-
-#endif // V8_DEBUG_LIVEEDIT_H_
diff --git a/deps/v8/src/debug/wasm/gdb-server/gdb-server.cc b/deps/v8/src/debug/wasm/gdb-server/gdb-server.cc
index 29bb9dafca4..8f953f30f23 100644
--- a/deps/v8/src/debug/wasm/gdb-server/gdb-server.cc
+++ b/deps/v8/src/debug/wasm/gdb-server/gdb-server.cc
@@ -420,7 +420,6 @@ GdbServer::DebugDelegate::~DebugDelegate() {
}
void GdbServer::DebugDelegate::ScriptCompiled(Local<debug::Script> script,
- bool is_live_edited,
bool has_compile_error) {
// Executed in the isolate thread.
if (script->IsWasm()) {
diff --git a/deps/v8/src/debug/wasm/gdb-server/gdb-server.h b/deps/v8/src/debug/wasm/gdb-server/gdb-server.h
index 40c8acad1b8..b6aeda647be 100644
--- a/deps/v8/src/debug/wasm/gdb-server/gdb-server.h
+++ b/deps/v8/src/debug/wasm/gdb-server/gdb-server.h
@@ -155,7 +155,7 @@ class GdbServer {
~DebugDelegate();
// debug::DebugDelegate
- void ScriptCompiled(Local<debug::Script> script, bool is_live_edited,
+ void ScriptCompiled(Local<debug::Script> script,
bool has_compile_error) override;
void BreakProgramRequested(
Local<v8::Context> paused_context,
diff --git a/deps/v8/src/debug/wasm/gdb-server/wasm-module-debug.cc b/deps/v8/src/debug/wasm/gdb-server/wasm-module-debug.cc
index c1cac998292..495a1e1e764 100644
--- a/deps/v8/src/debug/wasm/gdb-server/wasm-module-debug.cc
+++ b/deps/v8/src/debug/wasm/gdb-server/wasm-module-debug.cc
@@ -256,7 +256,8 @@ bool WasmModuleDebug::GetWasmLocal(Isolate* isolate, uint32_t frame_index,
if (!instance.is_null()) {
Handle<WasmModuleObject> module_object(instance->module_object(),
isolate);
- Managed<NativeModule>::Ptr native_module = module_object->native_module();
+ CppGCManaged<NativeModule>::Ptr native_module =
+ module_object->native_module();
DebugInfo* debug_info = native_module->GetDebugInfo();
if (static_cast<uint32_t>(debug_info->GetNumLocals(frame_it.frame()->pc(),
isolate)) > index) {
@@ -290,7 +291,8 @@ bool WasmModuleDebug::GetWasmStackValue(Isolate* isolate, uint32_t frame_index,
if (!instance.is_null()) {
Handle<WasmModuleObject> module_object(instance->module_object(),
isolate);
- Managed<NativeModule>::Ptr native_module = module_object->native_module();
+ CppGCManaged<NativeModule>::Ptr native_module =
+ module_object->native_module();
DebugInfo* debug_info = native_module->GetDebugInfo();
if (static_cast<uint32_t>(debug_info->GetStackDepth(
frame_it.frame()->pc(), isolate)) > index) {
@@ -370,7 +372,8 @@ uint32_t WasmModuleDebug::GetWasmModuleBytes(wasm_addr_t wasm_addr,
if (!instance.is_null()) {
Handle<WasmModuleObject> module_object(instance->module_object(),
GetIsolate());
- Managed<NativeModule>::Ptr native_module = module_object->native_module();
+ CppGCManaged<NativeModule>::Ptr native_module =
+ module_object->native_module();
const wasm::ModuleWireBytes wire_bytes(native_module->wire_bytes());
uint32_t offset = wasm_addr.Offset();
if (offset < wire_bytes.length()) {
diff --git a/deps/v8/src/deoptimizer/DEPS b/deps/v8/src/deoptimizer/DEPS
deleted file mode 100644
index 0e45cf04ecb..00000000000
--- a/deps/v8/src/deoptimizer/DEPS
+++ /dev/null
@@ -1,5 +0,0 @@
-specific_include_rules = {
- "frame-translation-builder.cc": [
- "+third_party/zlib",
- ],
-}
diff --git a/deps/v8/src/deoptimizer/deoptimizer.cc b/deps/v8/src/deoptimizer/deoptimizer.cc
index 18865be60a9..cddc0017959 100644
--- a/deps/v8/src/deoptimizer/deoptimizer.cc
+++ b/deps/v8/src/deoptimizer/deoptimizer.cc
@@ -501,7 +501,7 @@ void Deoptimizer::DeoptimizeFunction(Tagged<JSFunction> function,
TimerEventScope<TimerEventDeoptimizeCode> timer(isolate);
TRACE_EVENT("v8", "V8.DeoptimizeCode");
function->ResetIfCodeFlushed(isolate);
- if (code.is_null()) code = function->code(isolate);
+ DCHECK(!code.is_null());
if (CodeKindCanDeoptimize(code->kind())) {
// Mark the code for deoptimization and unlink any functions that also
@@ -1546,7 +1546,8 @@ void Deoptimizer::DoComputeOutputFramesWasmImpl() {
// code generator).
// Note that we explicitly allow deopts to exceed the limit by a certain
// number of slack bytes.
- CHECK_GT(
+ // GE and not GT because the runtime stack check allows SP == stack limit.
+ CHECK_GE(
static_cast<uintptr_t>(caller_frame_top_) - total_output_frame_size,
stack_guard->real_jslimit() - kStackLimitSlackForDeoptimizationInBytes);
}
@@ -1939,7 +1940,8 @@ void Deoptimizer::DoComputeOutputFrames() {
// code generator).
// Note that we explicitly allow deopts to exceed the limit by a certain
// number of slack bytes.
- CHECK_GT(
+ // GE and not GT because the runtime stack check allows SP == stack limit.
+ CHECK_GE(
static_cast<uintptr_t>(caller_frame_top_) - total_output_frame_size,
stack_guard->real_jslimit() - kStackLimitSlackForDeoptimizationInBytes);
}
diff --git a/deps/v8/src/deoptimizer/deoptimizer.h b/deps/v8/src/deoptimizer/deoptimizer.h
index 7c70e4c38b7..87703aa4d56 100644
--- a/deps/v8/src/deoptimizer/deoptimizer.h
+++ b/deps/v8/src/deoptimizer/deoptimizer.h
@@ -109,7 +109,7 @@ class Deoptimizer : public Malloced {
// instead of the function code (e.g. OSR code not installed on function).
static void DeoptimizeFunction(Tagged<JSFunction> function,
LazyDeoptimizeReason reason,
- Tagged<Code> code = {});
+ Tagged<Code> code);
// Deoptimize all code in the given isolate.
V8_EXPORT_PRIVATE static void DeoptimizeAll(Isolate* isolate);
diff --git a/deps/v8/src/deoptimizer/frame-translation-builder.cc b/deps/v8/src/deoptimizer/frame-translation-builder.cc
index d8d430ea39e..dc337a5a162 100644
--- a/deps/v8/src/deoptimizer/frame-translation-builder.cc
+++ b/deps/v8/src/deoptimizer/frame-translation-builder.cc
@@ -12,10 +12,6 @@
#include "src/objects/fixed-array-inl.h"
#include "src/objects/fixed-primitive-array-inl.h"
-#ifdef V8_USE_ZLIB
-#include "third_party/zlib/google/compression_utils_portable.h"
-#endif // V8_USE_ZLIB
-
namespace v8 {
namespace internal {
@@ -80,34 +76,20 @@ template <typename... T>
void FrameTranslationBuilder::AddRawToContents(TranslationOpcode opcode,
T... operands) {
DCHECK_EQ(sizeof...(T), TranslationOpcodeOperandCount(opcode));
- DCHECK(!v8_flags.turbo_compress_frame_translations);
contents_.push_back(static_cast<uint8_t>(opcode));
(..., operands.WriteVLQ(&contents_));
}
-template <typename... T>
-void FrameTranslationBuilder::AddRawToContentsForCompression(
- TranslationOpcode opcode, T... operands) {
- DCHECK_EQ(sizeof...(T), TranslationOpcodeOperandCount(opcode));
- DCHECK(v8_flags.turbo_compress_frame_translations);
- contents_for_compression_.push_back(static_cast<uint8_t>(opcode));
- (..., contents_for_compression_.push_back(operands.value()));
-}
-
template <typename... T>
void FrameTranslationBuilder::AddRawBegin(bool update_feedback, T... operands) {
auto opcode = update_feedback ? TranslationOpcode::BEGIN_WITH_FEEDBACK
: TranslationOpcode::BEGIN_WITHOUT_FEEDBACK;
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- AddRawToContentsForCompression(opcode, operands...);
- } else {
- AddRawToContents(opcode, operands...);
+ AddRawToContents(opcode, operands...);
#ifdef ENABLE_SLOW_DCHECKS
- if (v8_flags.enable_slow_asserts) {
- all_instructions_.emplace_back(opcode, operands...);
- }
-#endif
+ if (v8_flags.enable_slow_asserts) {
+ all_instructions_.emplace_back(opcode, operands...);
}
+#endif
}
int FrameTranslationBuilder::BeginTranslation(int frame_count,
@@ -177,10 +159,6 @@ void FrameTranslationBuilder::FinishPendingInstructionIfNeeded() {
template <typename... T>
void FrameTranslationBuilder::Add(TranslationOpcode opcode, T... operands) {
DCHECK_EQ(sizeof...(T), TranslationOpcodeOperandCount(opcode));
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- AddRawToContentsForCompression(opcode, operands...);
- return;
- }
#ifdef ENABLE_SLOW_DCHECKS
if (v8_flags.enable_slow_asserts) {
all_instructions_.emplace_back(opcode, operands...);
@@ -210,35 +188,6 @@ void FrameTranslationBuilder::Add(TranslationOpcode opcode, T... operands) {
DirectHandle<DeoptimizationFrameTranslation>
FrameTranslationBuilder::ToFrameTranslation(LocalFactory* factory) {
-#ifdef V8_USE_ZLIB
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- const uint32_t input_size = SizeInBytes();
- uLongf compressed_data_size = compressBound(input_size);
-
- ZoneVector<uint8_t> compressed_data(compressed_data_size, zone());
-
- CHECK_EQ(
- zlib_internal::CompressHelper(
- zlib_internal::ZRAW, compressed_data.data(), &compressed_data_size,
- reinterpret_cast<const Bytef*>(contents_for_compression_.data()),
- input_size, Z_DEFAULT_COMPRESSION, nullptr, nullptr),
- Z_OK);
-
- const uint32_t translation_array_size =
- static_cast<uint32_t>(compressed_data_size) +
- DeoptimizationFrameTranslation::kUncompressedSizeSize;
- DirectHandle<DeoptimizationFrameTranslation> result =
- factory->NewDeoptimizationFrameTranslation(translation_array_size);
-
- result->set_int(DeoptimizationFrameTranslation::kUncompressedSizeOffset,
- Size());
- std::memcpy(
- result->begin() + DeoptimizationFrameTranslation::kCompressedDataOffset,
- compressed_data.data(), compressed_data_size);
- return result;
- }
-#endif
- DCHECK(!v8_flags.turbo_compress_frame_translations);
FinishPendingInstructionIfNeeded();
const uint32_t input_size = SizeInBytes();
DirectHandle<DeoptimizationFrameTranslation> result =
@@ -253,7 +202,6 @@ FrameTranslationBuilder::ToFrameTranslation(LocalFactory* factory) {
}
base::Vector<const uint8_t> FrameTranslationBuilder::ToFrameTranslationWasm() {
- DCHECK(!v8_flags.turbo_compress_frame_translations);
FinishPendingInstructionIfNeeded();
base::Vector<const uint8_t> result = base::VectorOf(contents_);
#ifdef ENABLE_SLOW_DCHECKS
diff --git a/deps/v8/src/deoptimizer/frame-translation-builder.h b/deps/v8/src/deoptimizer/frame-translation-builder.h
index 704c99817be..cdabcb9166c 100644
--- a/deps/v8/src/deoptimizer/frame-translation-builder.h
+++ b/deps/v8/src/deoptimizer/frame-translation-builder.h
@@ -24,10 +24,7 @@ class LocalFactory;
class FrameTranslationBuilder {
public:
explicit FrameTranslationBuilder(Zone* zone)
- : contents_(zone),
- contents_for_compression_(zone),
- basis_instructions_(zone),
- zone_(zone) {}
+ : contents_(zone), basis_instructions_(zone) {}
DirectHandle<DeoptimizationFrameTranslation> ToFrameTranslation(
LocalFactory* factory);
@@ -122,38 +119,22 @@ class FrameTranslationBuilder {
void Add(TranslationOpcode opcode, T... operands);
// Adds the instruction to contents_, without performing the other steps of
- // Add(). Requires !v8_flags.turbo_compress_frame_translations.
+ // Add().
template <typename... T>
void AddRawToContents(TranslationOpcode opcode, T... operands);
- // Adds the instruction to contents_for_compression_, without performing the
- // other steps of Add(). Requires v8_flags.turbo_compress_frame_translations.
- template <typename... T>
- void AddRawToContentsForCompression(TranslationOpcode opcode, T... operands);
-
- // Adds a BEGIN instruction to contents_ or contents_for_compression_, but
- // does not update other state. Used by BeginTranslation.
+ // Adds a BEGIN instruction to contents_, but does not update other state.
+ // Used by BeginTranslation.
template <typename... T>
void AddRawBegin(bool update_feedback, T... operands);
- uint32_t Size() const {
- return V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)
- ? static_cast<uint32_t>(contents_for_compression_.size())
- : static_cast<uint32_t>(contents_.size());
- }
- uint32_t SizeInBytes() const {
- return V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)
- ? Size() * kInt32Size
- : Size();
- }
-
- Zone* zone() const { return zone_; }
+ uint32_t Size() const { return static_cast<uint32_t>(contents_.size()); }
+ uint32_t SizeInBytes() const { return Size(); }
void FinishPendingInstructionIfNeeded();
void ValidateBytes(DeoptTranslationIterator& iter) const;
ZoneVector<uint8_t> contents_;
- ZoneVector<int32_t> contents_for_compression_;
// If match_previous_allowed_ is false, then this vector contains the
// instructions written so far in the current translation (since the last
// BEGIN). If match_previous_allowed_ is true, then this vector contains the
@@ -165,7 +146,6 @@ class FrameTranslationBuilder {
#ifdef ENABLE_SLOW_DCHECKS
std::vector<Instruction> all_instructions_;
#endif
- Zone* const zone_;
// How many consecutive instructions we've skipped writing because they match
// the basis translation.
size_t matching_instructions_count_ = 0;
diff --git a/deps/v8/src/deoptimizer/riscv/deoptimizer-riscv.cc b/deps/v8/src/deoptimizer/riscv/deoptimizer-riscv.cc
index 3386d342f25..0d9b52355ff 100644
--- a/deps/v8/src/deoptimizer/riscv/deoptimizer-riscv.cc
+++ b/deps/v8/src/deoptimizer/riscv/deoptimizer-riscv.cc
@@ -22,6 +22,11 @@ void Deoptimizer::ZapCode(Address start, Address end, RelocIterator& it) {
void Deoptimizer::PatchToJump(Address pc, Address new_pc) {
RwxMemoryWriteScope rwx_write_scope("Patch jump to deopt trampoline");
intptr_t offset = (new_pc - pc);
+ // A single JAL can only encode a ±1 MiB displacement. If the deoptimization
+ // trampoline is farther away than that (possible for very large code
+ // objects), we abort instead of silently truncating the jump target.
+ CHECK_WITH_MSG(is_int21(offset),
+ "PatchToJump: deopt trampoline is out of JAL range");
// We'll overwrite only one instruction of 4-bytes. Give enough
// space not to try to grow the buffer.
constexpr int kSize = 128;
diff --git a/deps/v8/src/deoptimizer/translated-state.cc b/deps/v8/src/deoptimizer/translated-state.cc
index 704bab2b204..634b0334e5c 100644
--- a/deps/v8/src/deoptimizer/translated-state.cc
+++ b/deps/v8/src/deoptimizer/translated-state.cc
@@ -30,6 +30,7 @@
#include "src/objects/heap-object.h"
#include "src/objects/js-regexp-inl.h"
#include "src/objects/map-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/string.h"
@@ -2203,6 +2204,10 @@ void TranslatedState::MaterializeFixedDoubleArray(TranslatedFrame* frame,
DirectHandle<Object> value = frame->values_[*value_index].GetValue();
if (IsNumber(*value)) {
array->set(i, Object::NumberValue(*value));
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ } else if (value.is_identical_to(isolate()->factory()->undefined_value())) {
+ array->set_undefined(i);
+#endif // V8_ENABLE_UNDEFINED_DOUBLE
} else {
CHECK(value.is_identical_to(isolate()->factory()->the_hole_value()));
array->set_the_hole(isolate(), i);
diff --git a/deps/v8/src/diagnostics/basic-block-profiler.cc b/deps/v8/src/diagnostics/basic-block-profiler.cc
index 3acb3b2d93d..f062ec25020 100644
--- a/deps/v8/src/diagnostics/basic-block-profiler.cc
+++ b/deps/v8/src/diagnostics/basic-block-profiler.cc
@@ -203,16 +203,57 @@ void BasicBlockProfiler::Log(Isolate* isolate, std::ostream& os) {
}
}
+uint32_t BasicBlockProfiler::GetBuiltinsBlockCount(Isolate* isolate) {
+ DisallowGarbageCollection no_gc;
+ Tagged<ArrayList> list(isolate->heap()->basic_block_profiling_data());
+ const uint32_t list_length = list->ulength().value();
+ uint32_t total = 0;
+ for (uint32_t i = 0; i < list_length; ++i) {
+ Tagged<OnHeapBasicBlockProfilerData> profiler_data =
+ Cast<OnHeapBasicBlockProfilerData>(list->get(i));
+ Tagged<FixedUInt32Array> counts =
+ Cast<FixedUInt32Array>(profiler_data->counts());
+ total += counts->length().value();
+ }
+ return total;
+}
+
+void BasicBlockProfiler::ForEachExecutedBlockAndReset(
+ Isolate* isolate, base::FunctionRef<void(uint32_t)> callback) {
+ DisallowGarbageCollection no_gc;
+ Tagged<ArrayList> list(isolate->heap()->basic_block_profiling_data());
+ const uint32_t list_length = list->ulength().value();
+ uint32_t block_index = 0;
+ for (uint32_t i = 0; i < list_length; ++i) {
+ Tagged<OnHeapBasicBlockProfilerData> profiler_data =
+ Cast<OnHeapBasicBlockProfilerData>(list->get(i));
+ Tagged<FixedUInt32Array> counts =
+ Cast<FixedUInt32Array>(profiler_data->counts());
+ const uint32_t counts_len = counts->length().value();
+ uint32_t* data = reinterpret_cast<uint32_t*>(counts->begin());
+ for (uint32_t j = 0; j < counts_len; ++j, ++block_index) {
+ if (data[j] > 0) {
+ callback(block_index);
+ data[j] = 0;
+ }
+ }
+ }
+}
+
std::vector<bool> BasicBlockProfiler::GetCoverageBitmap(Isolate* isolate) {
DisallowGarbageCollection no_gc;
Tagged<ArrayList> list(isolate->heap()->basic_block_profiling_data());
std::vector<bool> out;
const uint32_t list_length = list->ulength().value();
for (uint32_t i = 0; i < list_length; ++i) {
- BasicBlockProfilerData data(
- Cast<OnHeapBasicBlockProfilerData>(list->get(i)));
- for (size_t j = 0; j < data.n_blocks(); ++j) {
- out.push_back(data.counts_[j] > 0);
+ Tagged<OnHeapBasicBlockProfilerData> profiler_data =
+ Cast<OnHeapBasicBlockProfilerData>(list->get(i));
+ Tagged<FixedUInt32Array> counts =
+ Cast<FixedUInt32Array>(profiler_data->counts());
+ const uint32_t counts_len = counts->length().value();
+ uint32_t* data = reinterpret_cast<uint32_t*>(counts->begin());
+ for (uint32_t j = 0; j < counts_len; ++j) {
+ out.push_back(data[j] > 0);
}
}
return out;
diff --git a/deps/v8/src/diagnostics/basic-block-profiler.h b/deps/v8/src/diagnostics/basic-block-profiler.h
index b86fa9e0b32..0245498718f 100644
--- a/deps/v8/src/diagnostics/basic-block-profiler.h
+++ b/deps/v8/src/diagnostics/basic-block-profiler.h
@@ -5,12 +5,14 @@
#ifndef V8_DIAGNOSTICS_BASIC_BLOCK_PROFILER_H_
#define V8_DIAGNOSTICS_BASIC_BLOCK_PROFILER_H_
+#include <cstdint>
#include <iosfwd>
#include <list>
#include <memory>
#include <string>
#include <vector>
+#include "src/base/functional/function-ref.h"
#include "src/base/macros.h"
#include "src/base/platform/mutex.h"
#include "src/common/globals.h"
@@ -93,6 +95,14 @@ class BasicBlockProfiler {
// snapshot.
V8_EXPORT_PRIVATE std::vector<bool> GetCoverageBitmap(Isolate* isolate);
+ // Fast zero-allocation count of total basic blocks across all builtins.
+ V8_EXPORT_PRIVATE uint32_t GetBuiltinsBlockCount(Isolate* isolate);
+
+ // Fast single-pass zero-allocation method to iterate over executed basic
+ // blocks across all builtins and reset block counters back to zero.
+ V8_EXPORT_PRIVATE void ForEachExecutedBlockAndReset(
+ Isolate* isolate, base::FunctionRef<void(uint32_t block_index)> callback);
+
const DataList* data_list() { return &data_list_; }
private:
diff --git a/deps/v8/src/diagnostics/disassembler.cc b/deps/v8/src/diagnostics/disassembler.cc
index 8b8a4e83e43..93903028029 100644
--- a/deps/v8/src/diagnostics/disassembler.cc
+++ b/deps/v8/src/diagnostics/disassembler.cc
@@ -493,7 +493,12 @@ 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) {
- DCHECK_WITH_MSG(v8_flags.text_is_readable,
+ // 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");
V8NameConverter v8NameConverter(isolate, code);
if (isolate) {
diff --git a/deps/v8/src/diagnostics/objects-debug.cc b/deps/v8/src/diagnostics/objects-debug.cc
index e68b04152e2..415f1befc23 100644
--- a/deps/v8/src/diagnostics/objects-debug.cc
+++ b/deps/v8/src/diagnostics/objects-debug.cc
@@ -43,6 +43,7 @@
#include "src/objects/js-disposable-stack.h"
#include "src/objects/js-proxy-inl.h"
#include "src/objects/literal-objects.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
#include "src/objects/property-details.h"
@@ -197,6 +198,8 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
// Cast away heapobject-ness so that the IsHeapObject test is non-trivial.
CHECK(IsHeapObject(Tagged<Object>(this)));
+ if (IsInaccessible(Tagged<HeapObject>(this))) return;
+
Object::VerifyPointer(isolate, map());
CHECK(IsMap(map()));
@@ -294,6 +297,13 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
case WASM_EXCEPTION_PACKAGE_TYPE:
Cast<WasmExceptionPackage>(this)->WasmExceptionPackageVerify(isolate);
break;
+ case WASM_NULL_TYPE:
+ // With static roots, WasmNull is caught by the IsInaccessible(...) check
+ // before the switch.
+ // Without static roots, WasmNull is accessible, and we reach here.
+ DCHECK(!V8_STATIC_ROOTS_BOOL);
+ Cast<WasmNull>(this)->WasmNullVerify(isolate);
+ break;
#endif // V8_ENABLE_WEBASSEMBLY
case JS_SET_KEY_VALUE_ITERATOR_TYPE:
case JS_SET_VALUE_ITERATOR_TYPE:
@@ -319,15 +329,12 @@ void HeapObject::HeapObjectVerify(Isolate* isolate) {
Cast<HashSeedWrapper>(this)->HashSeedWrapperVerify(isolate);
break;
-#define MAKE_TORQUE_CASE(Name, TYPE) \
+#define MAKE_VERIFY_CASE(Name, TYPE) \
case TYPE: \
TrustedCast<Name>(this)->Name##Verify(isolate); \
break;
- // Every class that has its fields defined in a .tq file and corresponds
- // to exactly one InstanceType value is included in the following list.
- TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
- TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
-#undef MAKE_TORQUE_CASE
+ HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST(MAKE_VERIFY_CASE)
+#undef MAKE_VERIFY_CASE
case HOLE_TYPE:
Cast<Hole>(this)->HoleVerify(isolate);
@@ -386,6 +393,9 @@ void HeapObject::VerifyHeapPointer(Isolate* isolate, Tagged<Object> p) {
// If you crashed here and {isolate->is_shared()}, there is a bug causing the
// host of {p} to point to a non-shared object.
CHECK(IsValidHeapObject(isolate->heap(), Cast<HeapObject>(p)));
+ // Before we can inspect instance types, we have to skip over inaccessible
+ // objects.
+ if (IsInaccessible(Cast<HeapObject>(p))) return;
CHECK_IMPLIES(V8_EXTERNAL_CODE_SPACE_BOOL, !IsInstructionStream(p));
}
@@ -1126,6 +1136,9 @@ void ScopeInfo::ScopeInfoVerify(Isolate* isolate) {
if (is_module) {
CHECK_LE(0, module_variable_count());
+ if (HasModuleVariablesHashtable()) {
+ CHECK(IsNameToIndexHashTable(module_variables_hashtable()));
+ }
}
if (has_hashtable) {
@@ -1693,7 +1706,8 @@ void JSFunction::JSFunctionVerify(Isolate* isolate) {
CHECK(IsAccessorInfo(*it.GetAccessors()));
} else {
CHECK(!it.IsFound() || it.state() != LookupIterator::ACCESSOR ||
- !IsAccessorInfo(*it.GetAccessors()));
+ !IsAccessorInfo(*it.GetAccessors()) ||
+ *it.GetAccessors() == *isolate->factory()->lazy_closure_accessor());
}
CHECK_IMPLIES(shared()->HasBuiltinId(),
@@ -1916,6 +1930,10 @@ void Hole::HoleVerify(Isolate* isolate) {
void Foreign::ForeignVerify(Isolate* isolate) { CHECK(Is<Foreign>(this)); }
+void CppGCManagedBase::CppGCManagedBaseVerify(Isolate* isolate) {
+ CHECK(Is<CppGCManagedBase>(this));
+}
+
void TrustedForeign::TrustedForeignVerify(Isolate* isolate) {
CHECK(Is<TrustedForeign>(this));
}
@@ -2158,12 +2176,12 @@ void JSShadowRealm::JSShadowRealmVerify(Isolate* isolate) {
#ifdef V8_INTL_SUPPORT
void JSLocale::JSLocaleVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsForeign(icu_locale()));
+ CHECK(IsCppGCManagedBase(icu_locale()));
}
void JSCollator::JSCollatorVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsForeign(icu_collator()));
+ CHECK(IsCppGCManagedBase(icu_collator()));
CHECK(IsUndefined(bound_compare()) || IsJSFunction(bound_compare()));
CHECK(IsString(locale()));
}
@@ -2171,7 +2189,7 @@ void JSCollator::JSCollatorVerify(Isolate* isolate) {
void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsForeign(icu_iterator_with_text_.load()));
+ CHECK(IsCppGCManagedBase(icu_iterator_with_text_.load()));
CHECK(IsUndefined(bound_adopt_text()) || IsJSFunction(bound_adopt_text()));
CHECK(IsUndefined(bound_first()) || IsJSFunction(bound_first()));
CHECK(IsUndefined(bound_next()) || IsJSFunction(bound_next()));
@@ -2182,16 +2200,16 @@ void JSV8BreakIterator::JSV8BreakIteratorVerify(Isolate* isolate) {
void JSDateTimeFormat::JSDateTimeFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsForeign(icu_locale_.load()));
- CHECK(IsForeign(icu_simple_date_format_.load()));
- CHECK(IsForeign(icu_date_interval_format_.load()));
+ CHECK(IsCppGCManagedBase(icu_locale_.load()));
+ CHECK(IsCppGCManagedBase(icu_simple_date_format_.load()));
+ CHECK(IsCppGCManagedBase(icu_date_interval_format_.load()));
CHECK(IsUndefined(bound_format()) || IsJSFunction(bound_format()));
CHECK(IsSmi(flags_.load()));
}
void JSDisplayNames::JSDisplayNamesVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsForeign(internal_.load()));
+ CHECK(IsCppGCManagedBase(internal_.load()));
CHECK(IsSmi(flags_.load()));
}
@@ -2199,21 +2217,21 @@ void JSDurationFormat::JSDurationFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsSmi(style_flags_.load()));
CHECK(IsSmi(display_flags_.load()));
- CHECK(IsForeign(icu_locale_.load()));
- CHECK(IsForeign(icu_number_formatter_.load()));
+ CHECK(IsCppGCManagedBase(icu_locale_.load()));
+ CHECK(IsCppGCManagedBase(icu_number_formatter_.load()));
}
void JSListFormat::JSListFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsForeign(icu_formatter_.load()));
+ CHECK(IsCppGCManagedBase(icu_formatter_.load()));
CHECK(IsSmi(flags_.load()));
}
void JSNumberFormat::JSNumberFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsForeign(icu_number_formatter_.load()));
+ CHECK(IsCppGCManagedBase(icu_number_formatter_.load()));
CHECK(IsUndefined(bound_format()) || IsJSFunction(bound_format()));
}
@@ -2221,35 +2239,35 @@ void JSPluralRules::JSPluralRulesVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
CHECK(IsSmi(flags_.load()));
- CHECK(IsForeign(icu_plural_rules_.load()));
- CHECK(IsForeign(icu_number_formatter_.load()));
+ CHECK(IsCppGCManagedBase(icu_plural_rules_.load()));
+ CHECK(IsCppGCManagedBase(icu_number_formatter_.load()));
}
void JSRelativeTimeFormat::JSRelativeTimeFormatVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
CHECK(IsString(numberingSystem()));
- CHECK(IsForeign(icu_formatter_.load()));
+ CHECK(IsCppGCManagedBase(icu_formatter_.load()));
CHECK(IsSmi(flags_.load()));
}
void JSSegmenter::JSSegmenterVerify(Isolate* isolate) {
JSObjectVerify(isolate);
CHECK(IsString(locale()));
- CHECK(IsForeign(icu_break_iterator_.load()));
+ CHECK(IsCppGCManagedBase(icu_break_iterator_.load()));
CHECK(IsSmi(flags_.load()));
}
void JSSegments::JSSegmentsVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsForeign(icu_iterator_with_text_.load()));
+ CHECK(IsCppGCManagedBase(icu_iterator_with_text_.load()));
CHECK(IsString(raw_string()));
CHECK(IsSmi(flags_.load()));
}
void JSSegmentIterator::JSSegmentIteratorVerify(Isolate* isolate) {
JSObjectVerify(isolate);
- CHECK(IsForeign(icu_iterator_with_text_.load()));
+ CHECK(IsCppGCManagedBase(icu_iterator_with_text_.load()));
CHECK(IsString(raw_string()));
CHECK(IsSmi(flags_.load()));
}
@@ -2789,7 +2807,7 @@ void RegExpData::RegExpDataVerify(Isolate* isolate) {
#define DEFINE_TEMPORAL_VERIFIER(JSType, field) \
void JSType::JSType##Verify(Isolate* isolate) { \
JSObjectVerify(isolate); \
- CHECK(IsForeign(field##_.load())); \
+ CHECK(IsCppGCManagedBase(field##_.load())); \
}
DEFINE_TEMPORAL_VERIFIER(JSTemporalDuration, duration)
@@ -3430,7 +3448,7 @@ void WasmCapiFunctionData::WasmCapiFunctionDataVerify(Isolate* isolate) {
CHECK(Is<WasmCapiFunctionData>(this));
WasmFunctionDataVerify(isolate);
Object::VerifyPointer(isolate, embedder_data_.load());
- CHECK(IsForeign(embedder_data_.load()));
+ CHECK(Is<CppGCManagedBase>(embedder_data_.load()));
}
void WasmSuspenderObject::WasmSuspenderObjectVerify(Isolate* isolate) {
@@ -3493,6 +3511,14 @@ void WasmStruct::WasmStructVerify(Isolate* isolate) {
CHECK(Is<WasmStruct>(this));
}
+void WasmCustomMap::WasmCustomMapVerify(Isolate* isolate) { UNIMPLEMENTED(); }
+
+void WasmCustomMapWrapper::WasmCustomMapWrapperVerify(Isolate* isolate) {
+ CHECK(Is<WasmCustomMapWrapper>(this));
+ CHECK(Is<WasmCustomMap>(wrapped()));
+ JSObjectVerify(isolate);
+}
+
void WasmArray::WasmArrayVerify(Isolate* isolate) {
CHECK(Is<WasmArray>(this));
}
@@ -3909,6 +3935,7 @@ void ErrorStackData::ErrorStackDataVerify(Isolate* isolate) {
Object::VerifyPointer(isolate, stack_trace_.load());
}
+
void SloppyArgumentsElements::SloppyArgumentsElementsVerify(Isolate* isolate) {
CHECK_LE(length_, kMaxCapacity);
{
diff --git a/deps/v8/src/diagnostics/objects-printer.cc b/deps/v8/src/diagnostics/objects-printer.cc
index e9be458051e..a59c8453c98 100644
--- a/deps/v8/src/diagnostics/objects-printer.cc
+++ b/deps/v8/src/diagnostics/objects-printer.cc
@@ -278,6 +278,13 @@ void HeapObject::PrintHeader(std::ostream& os, const char* id) {
}
void HeapObject::HeapObjectPrint(std::ostream& os) {
+#if V8_ENABLE_WEBASSEMBLY
+ if (IsWasmNull(Tagged<HeapObject>(this))) {
+ os << "WasmNull";
+ return;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
+
InstanceType instance_type = map()->instance_type();
if (instance_type < FIRST_NONSTRING_TYPE) {
@@ -392,6 +399,9 @@ void HeapObject::HeapObjectPrint(std::ostream& os) {
case WASM_EXCEPTION_PACKAGE_TYPE:
Cast<WasmExceptionPackage>(this)->WasmExceptionPackagePrint(os);
break;
+ case WASM_NULL_TYPE:
+ // Handled before the switch.
+ UNREACHABLE();
#endif // V8_ENABLE_WEBASSEMBLY
case INSTRUCTION_STREAM_TYPE:
TrustedCast<InstructionStream>(this)->InstructionStreamPrint(os);
@@ -411,15 +421,12 @@ void HeapObject::HeapObjectPrint(std::ostream& os) {
case JS_MAP_VALUE_ITERATOR_TYPE:
Cast<JSMapIterator>(this)->JSMapIteratorPrint(os);
break;
-#define MAKE_TORQUE_CASE(Name, TYPE) \
+#define MAKE_PRINT_CASE(Name, TYPE) \
case TYPE: \
TrustedCast<Name>(this)->Name##Print(os); \
break;
- // Every class that has its fields defined in a .tq file and corresponds
- // to exactly one InstanceType value is included in the following list.
- TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
- TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
-#undef MAKE_TORQUE_CASE
+ HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST(MAKE_PRINT_CASE)
+#undef MAKE_PRINT_CASE
case HOLE_TYPE:
Cast<Hole>(this)->HolePrint(os);
@@ -764,7 +771,7 @@ void PrintSloppyArgumentElements(std::ostream& os, ElementsKind kind,
}
}
-void PrintEmbedderData(IsolateForSandbox isolate, std::ostream& os,
+void PrintEmbedderData(IsolateForPointerCompression isolate, std::ostream& os,
EmbedderDataSlot slot) {
DisallowGarbageCollection no_gc;
Tagged<Object> value = slot.load_tagged();
@@ -882,11 +889,10 @@ void JSObjectPrintBody(std::ostream& os, Tagged<JSObject> obj,
}
int embedder_fields = obj->GetEmbedderFieldCount();
if (embedder_fields > 0) {
- IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
os << " - embedder fields = {";
for (int i = 0; i < embedder_fields; i++) {
os << "\n ";
- PrintEmbedderData(isolate, os, EmbedderDataSlot(obj, i));
+ PrintEmbedderData(Isolate::Current(), os, EmbedderDataSlot(obj, i));
}
os << "\n }\n";
}
@@ -1240,14 +1246,13 @@ void RegExpBoilerplateDescription::RegExpBoilerplateDescriptionPrint(
}
void EmbedderDataArray::EmbedderDataArrayPrint(std::ostream& os) {
- IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
PrintHeader(os, "EmbedderDataArray");
os << "\n - length: " << length();
EmbedderDataSlot start(this, 0);
EmbedderDataSlot end(this, length());
for (EmbedderDataSlot slot = start; slot < end; ++slot) {
os << "\n ";
- PrintEmbedderData(isolate, os, slot);
+ PrintEmbedderData(Isolate::Current(), os, slot);
}
os << "\n";
}
@@ -1400,6 +1405,8 @@ void InterceptorInfo::InterceptorInfoPrint(std::ostream& os) {
os << "\n - enumerator: " << AS_PTR(indexed_enumerator(isolate));
os << "\n - definer: " << AS_PTR(indexed_definer(isolate));
os << "\n - index_of: " << AS_PTR(indexed_index_of(isolate));
+ os << "\n - iterable_to_list: "
+ << AS_PTR(indexed_iterable_to_list(isolate));
}
os << "\n --- flags: ";
@@ -2964,6 +2971,11 @@ void Foreign::ForeignPrint(std::ostream& os) {
os << "\n";
}
+void CppGCManagedBase::CppGCManagedBasePrint(std::ostream& os) {
+ PrintHeader(os, "CppGCManagedBase");
+ os << "\n";
+}
+
void TrustedForeign::TrustedForeignPrint(std::ostream& os) {
PrintHeader(os, "TrustedForeign");
os << "\n - foreign address: " << reinterpret_cast<void*>(foreign_address());
@@ -3212,20 +3224,21 @@ void WasmTypeInfo::WasmTypeInfoPrint(std::ostream& os) {
os << "\n";
}
-void WasmStruct::WasmStructPrint(std::ostream& os) {
- PrintHeader(os, "WasmStruct");
+namespace {
+void WasmStructPrintImpl(std::ostream& os, HeapObject* obj, int header_size) {
const wasm::CanonicalStructType* struct_type =
wasm::GetTypeCanonicalizer()->LookupStruct(
- map()->wasm_type_info()->type_index());
- if (struct_type->is_descriptor()) {
- os << "\n - describes RTT: " << Brief(described_rtt());
+ obj->map()->wasm_type_info()->type_index());
+ if (!v8_flags.wasm_merged_descriptors && struct_type->is_descriptor()) {
+ os << "\n - describes RTT: "
+ << Brief(Cast<WasmStruct>(obj)->described_rtt());
}
os << "\n - fields (" << struct_type->field_count() << "):";
for (uint32_t i = 0; i < struct_type->field_count(); i++) {
wasm::CanonicalValueType field = struct_type->field(i);
os << "\n - " << field.short_name() << ": ";
- uint32_t field_offset = struct_type->field_offset(i);
- Address field_address = RawFieldAddress(field_offset);
+ uint32_t field_offset = header_size + struct_type->field_offset(i);
+ Address field_address = obj->GetFieldAddress(field_offset);
switch (field.kind()) {
case wasm::kI32:
os << base::ReadUnalignedValue<int32_t>(field_address);
@@ -3253,11 +3266,11 @@ void WasmStruct::WasmStructPrint(std::ostream& os) {
case wasm::kRefNull: {
Tagged_t raw = base::ReadUnalignedValue<Tagged_t>(field_address);
#if V8_COMPRESS_POINTERS
- Address obj = V8HeapCompressionScheme::DecompressTagged(raw);
+ Address value = V8HeapCompressionScheme::DecompressTagged(raw);
#else
- Address obj = raw;
+ Address value = raw;
#endif
- os << Brief(Tagged<Object>(obj));
+ os << Brief(Tagged<Object>(value));
break;
}
case wasm::kS128:
@@ -3280,6 +3293,21 @@ void WasmStruct::WasmStructPrint(std::ostream& os) {
}
os << "\n";
}
+} // namespace
+
+void WasmStruct::WasmStructPrint(std::ostream& os) {
+ PrintHeader(os, "WasmStruct");
+ WasmStructPrintImpl(os, this, WasmStruct::kHeaderSize);
+}
+void WasmCustomMap::WasmCustomMapPrint(std::ostream& os) {
+ PrintHeader(os, "WasmCustomMap");
+ WasmStructPrintImpl(os, this, WasmCustomMap::kHeaderSize);
+}
+
+void WasmCustomMapWrapper::WasmCustomMapWrapperPrint(std::ostream& os) {
+ PrintHeader(os, "WasmCustomMapWrapper");
+ os << "\n - wrapped: " << Brief(wrapped());
+}
void WasmArray::WasmArrayPrint(std::ostream& os) {
PrintHeader(os, "WasmArray");
@@ -3730,6 +3758,13 @@ void ErrorStackData::ErrorStackDataPrint(std::ostream& os) {
os << "\n";
}
+void DebugScriptScopeInfo::DebugScriptScopeInfoPrint(std::ostream& os) {
+ this->PrintHeader(os, "DebugScriptScopeInfo");
+ os << "\n - numeric_data: " << Brief(this->numeric_data());
+ os << "\n - string_table: " << Brief(this->string_table());
+ os << "\n";
+}
+
void LoadHandler::LoadHandlerPrint(std::ostream& os) {
PrintHeader(os, "LoadHandler");
// TODO(ishell): implement printing based on handler kind
@@ -3903,7 +3938,7 @@ void Script::ScriptPrint(std::ostream& os) {
os << "\n - source_url: " << Brief(source_url());
os << "\n - source_mapping_url: " << Brief(source_mapping_url());
os << "\n - host_defined_options: " << Brief(host_defined_options());
- os << "\n - compilation type: " << static_cast<int>(compilation_type());
+ os << "\n - compilation kind: " << ToString(compilation_kind());
os << "\n - compiled lazy function positions: "
<< compiled_lazy_function_positions();
bool is_wasm = false;
@@ -4274,7 +4309,12 @@ void HeapObject::Print(Tagged<Object> obj, std::ostream& os) {
void HeapObject::HeapObjectShortPrint(std::ostream& os) {
os << AsHex::Address(this->ptr()) << " ";
-
+#if V8_ENABLE_WEBASSEMBLY
+ if (IsWasmNull(Tagged<HeapObject>(this))) {
+ os << "WasmNull";
+ return;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
if (Is<String>(this)) {
HeapStringAllocator allocator;
StringStream accumulator(&allocator);
diff --git a/deps/v8/src/diagnostics/riscv/disasm-riscv.cc b/deps/v8/src/diagnostics/riscv/disasm-riscv.cc
index 655148a2e3d..0f133e4d0b8 100644
--- a/deps/v8/src/diagnostics/riscv/disasm-riscv.cc
+++ b/deps/v8/src/diagnostics/riscv/disasm-riscv.cc
@@ -101,6 +101,8 @@ class Decoder {
void PrintRvcImm8Addi4spn(Instruction* instr);
void PrintRvcImm11CJ(Instruction* instr);
void PrintRvcImm8B(Instruction* instr);
+ void PrintRvcImm2B(Instruction* instr);
+ void PrintRvcImm1H(Instruction* instr);
void PrintRvvVm(Instruction* instr);
void PrintAcquireRelease(Instruction* instr);
void PrintBranchOffset(Instruction* instr);
@@ -399,6 +401,18 @@ void Decoder::PrintRvcImm8B(Instruction* instr) {
out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
}
+void Decoder::PrintRvcImm2B(Instruction* instr) {
+ // Zcb byte load/store offset: uimm[1] = enc[5], uimm[0] = enc[6].
+ int32_t imm = (instr->Bits(5, 5) << 1) | instr->Bits(6, 6);
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
+}
+
+void Decoder::PrintRvcImm1H(Instruction* instr) {
+ // Zcb halfword load/store offset: uimm[1] = enc[5], uimm[0] = 0.
+ int32_t imm = instr->Bits(5, 5) << 1;
+ out_buffer_pos_ += base::SNPrintF(out_buffer_ + out_buffer_pos_, "%d", imm);
+}
+
void Decoder::PrintRvvVm(Instruction* instr) {
uint8_t imm = instr->RvvVM();
if (imm == 0) {
@@ -728,8 +742,16 @@ int Decoder::FormatRvcImm(Instruction* instr, const char* format) {
DCHECK(STRING_STARTS_WITH(format, "Cimm11CJ"));
PrintRvcImm11CJ(instr);
return 8;
+ } else if (format[5] == 'H') {
+ DCHECK(STRING_STARTS_WITH(format, "Cimm1H"));
+ PrintRvcImm1H(instr);
+ return 6;
}
UNREACHABLE();
+ } else if (format[4] == '2') {
+ DCHECK(STRING_STARTS_WITH(format, "Cimm2B"));
+ PrintRvcImm2B(instr);
+ return 6;
}
UNREACHABLE();
}
@@ -2262,6 +2284,9 @@ void Decoder::DecodeCAType(Instruction* instr) {
Format(instr, "addw 'Crs1s, 'Crs1s, 'Crs2s");
break;
#endif
+ case RO_C_MUL:
+ Format(instr, "mul 'Crs1s, 'Crs1s, 'Crs2s");
+ break;
default:
UNSUPPORTED_RISCV();
}
@@ -2365,7 +2390,19 @@ void Decoder::DecodeCLType(Instruction* instr) {
Format(instr, "flw 'Cfs2s, 'Cimm5D('Crs1s)");
break;
#endif
-
+ case RO_C_LBU: // Zcb loads, all sharing funct3=100.
+ if ((instr->InstructionBits() & (kRvcFunct6Mask | (1 << 6))) ==
+ RO_C_LHU) {
+ Format(instr, "lhu 'Crs2s, 'Cimm1H('Crs1s)");
+ } else if ((instr->InstructionBits() & (kRvcFunct6Mask | (1 << 6))) ==
+ RO_C_LH) {
+ Format(instr, "lh 'Crs2s, 'Cimm1H('Crs1s)");
+ } else if ((instr->InstructionBits() & kRvcFunct6Mask) == RO_C_LBU) {
+ Format(instr, "lbu 'Crs2s, 'Cimm2B('Crs1s)");
+ } else {
+ UNSUPPORTED_RISCV();
+ }
+ break;
default:
UNSUPPORTED_RISCV();
}
@@ -2388,6 +2425,16 @@ void Decoder::DecodeCSType(Instruction* instr) {
Format(instr, "fsw 'Cfs2s, 'Cimm5D('Crs1s)");
break;
#endif
+ case RO_C_LBU: // Zcb stores, all sharing funct3=100.
+ if ((instr->InstructionBits() & kRvcFunct6Mask) == RO_C_SB) {
+ Format(instr, "sb 'Crs2s, 'Cimm2B('Crs1s)");
+ } else if ((instr->InstructionBits() & (kRvcFunct6Mask | (1 << 6))) ==
+ RO_C_SH) {
+ Format(instr, "sh 'Crs2s, 'Cimm1H('Crs1s)");
+ } else {
+ UNSUPPORTED_RISCV();
+ }
+ break;
default:
UNSUPPORTED_RISCV();
}
@@ -2421,6 +2468,33 @@ void Decoder::DecodeCBType(Instruction* instr) {
} else if (instr->RvcFunct2BValue() == 0b10) {
Format(instr, "andi 'Crs1s, 'Crs1s, 'Cimm6");
break;
+ } else if (instr->RvcFunct2BValue() == 0b11) {
+ // Zcb unary instructions (CU format), distinguished by nzuimm[5:0].
+ switch (instr->RvcImm6Value() & 0b111111) {
+ case 0b111000:
+ Format(instr, "zext.b 'Crs1s, 'Crs1s");
+ break;
+ case 0b111001:
+ Format(instr, "sext.b 'Crs1s, 'Crs1s");
+ break;
+ case 0b111010:
+ Format(instr, "zext.h 'Crs1s, 'Crs1s");
+ break;
+ case 0b111011:
+ Format(instr, "sext.h 'Crs1s, 'Crs1s");
+ break;
+#ifdef V8_TARGET_ARCH_64_BIT
+ case 0b111100:
+ Format(instr, "zext.w 'Crs1s, 'Crs1s");
+ break;
+#endif
+ case 0b111101:
+ Format(instr, "not 'Crs1s, 'Crs1s");
+ break;
+ default:
+ UNSUPPORTED_RISCV();
+ }
+ break;
} else {
UNSUPPORTED_RISCV();
}
diff --git a/deps/v8/src/diagnostics/x64/disasm-x64.cc b/deps/v8/src/diagnostics/x64/disasm-x64.cc
index 0d148b51acd..1306d60cbcb 100644
--- a/deps/v8/src/diagnostics/x64/disasm-x64.cc
+++ b/deps/v8/src/diagnostics/x64/disasm-x64.cc
@@ -13,6 +13,7 @@
#include "src/base/lazy-instance.h"
#include "src/base/memory.h"
#include "src/base/strings.h"
+#include "src/codegen/x64/assembler-x64.h"
#include "src/codegen/x64/fma-instr.h"
#include "src/codegen/x64/register-x64.h"
#include "src/codegen/x64/sse-instr.h"
@@ -144,6 +145,9 @@ enum Prefixes {
REPEQ_PREFIX = REP_PREFIX
};
+using VexW = v8::internal::Assembler::VexW;
+using TupleType = v8::internal::Assembler::TupleType;
+
struct InstructionDesc {
const char* mnem;
InstructionType type;
@@ -284,9 +288,11 @@ int64_t Imm64(const uint8_t* data) {
//------------------------------------------------------------------------------
// DisassemblerX64 implementation.
-// Forward-declare NameOfYMMRegister to keep its implementation with the
-// NameConverter methods and register name arrays at bottom.
+// Forward-declare NameOfYMMRegister/NameOfZMMRegister to keep their
+// implementations with the NameConverter methods and register name arrays at
+// bottom.
const char* NameOfYMMRegister(int reg);
+const char* NameOfZMMRegister(int reg);
// A new DisassemblerX64 object is created to disassemble each instruction.
// The object can only disassemble a single instruction.
@@ -434,19 +440,51 @@ class DisassemblerX64 {
bool evex_pp_f2() const { return evex_pp() == 3; }
int evex_vvvv() const { return (~evex_byte2_ >> 3) & 0xF; }
+ // Vector length in bytes decoded from EVEX.L'L (evex_byte3 bits 6:5):
+ // 0b00 = 16 (xmm), 0b01 = 32 (ymm), 0b10 = 64 (zmm). 0b11 is reserved (when
+ // EVEX.b selects embedded rounding the whole L'L field instead encodes the
+ // rounding mode); embedded rounding is not decoded here, so fall back to
+ // 128-bit for the reserved value.
+ int evex_vector_length() const {
+ DCHECK(is_evex());
+ switch ((evex_byte3_ >> 5) & 0x3) {
+ case 1:
+ return 32;
+ case 2:
+ return 64;
+ default:
+ return 16; // 0b00, and the reserved 0b11 fallback.
+ }
+ }
+
bool evex_nd() const { return (evex_byte3_ & 0x10) != 0; }
bool evex_nf() const { return (evex_byte3_ & 0x04) == 0; }
int evex_scc() const { return evex_byte3_ & 0x0F; }
int evex_v4() const { return (evex_byte3_ & 0x08) != 0 ? 0 : 16; }
int evex_ndd_reg() const { return evex_vvvv() | evex_v4(); }
+ int evex_aaa() const {
+ DCHECK_EQ(evex_byte0_, EVEX_PREFIX);
+ return evex_byte3_ & 0x7;
+ }
+
+ // true: zeroing ({z}); false: merging.
+ bool evex_z() const {
+ DCHECK_EQ(evex_byte0_, EVEX_PREFIX);
+ return (evex_byte3_ & 0x80) != 0;
+ }
+
int evex_reg(int modrm_regop) const {
int r3 = (evex_byte1_ & 0x80) ? 0 : 8;
int r4 = (evex_byte1_ & 0x10) ? 0 : 16;
return (modrm_regop & 0x7) | r3 | r4;
}
- int evex_rm(int modrm_rm) const {
+ // ModRM.rm register number for an APX legacy-integer (map 4) instruction:
+ // the high bits are EVEX.B3 (byte1 bit 5) and EVEX.B4 (byte1 bit 3). This is
+ // the GPR convention; AVX10/AVX-512 vector operands instead extend rm with
+ // EVEX.X (byte1 bit 6) and are decoded by get_modrm.
+ int evex_rm_gpr(int modrm_rm) const {
int b3 = (evex_byte1_ & 0x20) ? 0 : 8;
int b4 = (evex_byte1_ & 0x08) ? 16 : 0;
return (modrm_rm & 0x7) | b3 | b4;
@@ -475,6 +513,19 @@ class DisassemblerX64 {
return (modrm_regop & 0x7) | r | r4;
}
+ // Prefix/opcode-map/register accessors shared by VEX- and EVEX-encoded AVX
+ // instructions, so AVXVectorInstruction can dispatch on both. For VEX these
+ // forward to the vex_* helpers; for EVEX to the evex_* helpers.
+ bool simd_prefix_none() { return is_evex() ? evex_pp_none() : vex_none(); }
+ bool simd_prefix_66() { return is_evex() ? evex_pp_66() : vex_66(); }
+ bool simd_prefix_f3() { return is_evex() ? evex_pp_f3() : vex_f3(); }
+ bool simd_prefix_f2() { return is_evex() ? evex_pp_f2() : vex_f2(); }
+ bool leading_0f() { return is_evex() ? evex_map1() : vex_0f(); }
+ bool leading_0f38() { return is_evex() ? evex_map2() : vex_0f38(); }
+ bool leading_0f3a() { return is_evex() ? evex_map3() : vex_0f3a(); }
+ int get_vreg() { return is_evex() ? (evex_vvvv() | evex_v4()) : vex_vreg(); }
+ bool vector_w() const { return is_evex() ? evex_w() : vex_w(); }
+
OperandSize operand_size() {
if (byte_size_operand_) return OPERAND_BYTE_SIZE;
if (rex_w()) return OPERAND_QUADWORD_SIZE;
@@ -499,11 +550,20 @@ class DisassemblerX64 {
}
const char* NameOfAVXRegister(int reg) const {
- if (!is_evex() && vex_256()) {
- return NameOfYMMRegister(reg);
- } else {
- return converter_.NameOfXMMRegister(reg);
+ // EVEX carries the full vector length (xmm/ymm/zmm) in EVEX.L'L; VEX only
+ // distinguishes 128/256-bit.
+ if (is_evex()) {
+ switch (evex_vector_length()) {
+ case 32:
+ return NameOfYMMRegister(reg);
+ case 64:
+ return NameOfZMMRegister(reg);
+ default:
+ return converter_.NameOfXMMRegister(reg);
+ }
}
+ return vex_256() ? NameOfYMMRegister(reg)
+ : converter_.NameOfXMMRegister(reg);
}
const char* NameOfKRegister(int reg) const {
@@ -514,6 +574,19 @@ class DisassemblerX64 {
return k_regs[reg];
}
+ // Returns the "{k1}" / "{k1}{z}" suffix for an EVEX-masked destination, or
+ // "" when there is no opmask (aaa == 0) or the instruction is not EVEX.
+ const char* EVEXMasking() const {
+ if (!is_evex() || evex_aaa() == 0) return "";
+ static constexpr const char* const kMasking[2][8] = {
+ {"", "{k1}", "{k2}", "{k3}", "{k4}", "{k5}", "{k6}", "{k7}"},
+ {"", "{k1}{z}", "{k2}{z}", "{k3}{z}", "{k4}{z}", "{k5}{z}", "{k6}{z}",
+ "{k7}{z}"},
+ };
+
+ return kMasking[evex_z() ? 1 : 0][evex_aaa()];
+ }
+
const char* NameOfAddress(uint8_t* addr) const {
return converter_.NameOfAddress(addr);
}
@@ -523,6 +596,15 @@ class DisassemblerX64 {
*mod = (data >> 6) & 3;
*regop = ((data & 0x38) >> 3) | (rex_r() ? 8 : 0);
*rm = (data & 7) | (rex_b() ? 8 : 0);
+ if (is_evex() && !evex_map4()) {
+ // AVX10/AVX-512 vector register extension to xmm0-31: reg gets EVEX.R'
+ // and a register-direct rm gets EVEX.X (synthesized into rex_x); rex_r/
+ // rex_b already supplied the low extension bit above. Map 4 is APX, which
+ // uses a different rm-extension bit and re-derives its own operands in
+ // APXInstruction, so it keeps the plain rex_r/rex_b decode.
+ *regop |= (evex_byte1_ & 0x10) ? 0 : 16; // EVEX.R'
+ if (*mod == 3) *rm |= rex_x() ? 16 : 0; // EVEX.X (register-direct rm)
+ }
}
void get_sib(uint8_t data, int* scale, int* index, int* base) {
@@ -534,11 +616,15 @@ class DisassemblerX64 {
using RegisterNameMapping = const char* (DisassemblerX64::*)(int reg) const;
void TryAppendRootRelativeName(int offset);
- int PrintRightOperandHelper(uint8_t* modrmp, RegisterNameMapping);
+ int PrintRightOperandHelper(uint8_t* modrmp, RegisterNameMapping,
+ uint8_t cd8_scale = 1);
int PrintRightOperand(uint8_t* modrmp);
int PrintRightByteOperand(uint8_t* modrmp);
int PrintRightXMMOperand(uint8_t* modrmp);
int PrintRightAVXOperand(uint8_t* modrmp);
+ int PrintRightEVEXOperand(
+ uint8_t* modrmp, TupleType tuple_type,
+ RegisterNameMapping mapping = &DisassemblerX64::NameOfAVXRegister);
int PrintOperands(const char* mnem, OperandType op_order, uint8_t* data);
int PrintImmediate(uint8_t* data, OperandSize size);
int PrintImmediateOp(uint8_t* data);
@@ -554,7 +640,7 @@ class DisassemblerX64 {
int FPUInstruction(uint8_t* data);
int MemoryFPUInstruction(int escape_opcode, int regop, uint8_t* modrm_start);
int RegisterFPUInstruction(int escape_opcode, uint8_t modrm_byte);
- int AVXInstruction(uint8_t* data);
+ int AVXVectorInstruction(uint8_t* data);
int APXInstruction(uint8_t* data);
int REX2Instruction(uint8_t* data);
PRINTF_FORMAT(2, 3) void AppendToBuffer(const char* format, ...);
@@ -584,16 +670,12 @@ void DisassemblerX64::TryAppendRootRelativeName(int offset) {
}
int DisassemblerX64::PrintRightOperandHelper(
- uint8_t* modrmp, RegisterNameMapping direct_register_name) {
+ uint8_t* modrmp, RegisterNameMapping direct_register_name,
+ uint8_t cd8_scale) {
int mod, regop, rm;
get_modrm(*modrmp, &mod, ®op, &rm);
RegisterNameMapping register_name =
(mod == 3) ? direct_register_name : &DisassemblerX64::NameOfCPURegister;
- if (is_evex() && mod == 3 &&
- (register_name == &DisassemblerX64::NameOfAVXRegister ||
- register_name == &DisassemblerX64::NameOfXMMRegister)) {
- rm = evex_rm(rm);
- }
switch (mod) {
case 0:
if ((rm & 7) == 5) {
@@ -634,7 +716,10 @@ int DisassemblerX64::PrintRightOperandHelper(
uint8_t sib = *(modrmp + 1);
int scale, index, base;
get_sib(sib, &scale, &index, &base);
- int disp = (mod == 2) ? Imm32(modrmp + 2) : Imm8(modrmp + 2);
+ // EVEX encodes the disp8 as a compressed displacement (disp8*N); for
+ // non-EVEX operands cd8_scale is 1.
+ int disp =
+ (mod == 2) ? Imm32(modrmp + 2) : Imm8(modrmp + 2) * cd8_scale;
if (index == 4 && (base & 7) == 4 && scale == 0 /*times_1*/) {
AppendToBuffer("[%s%s0x%x]", NameOfCPURegister(base),
disp < 0 ? "-" : "+", disp < 0 ? -disp : disp);
@@ -646,7 +731,8 @@ int DisassemblerX64::PrintRightOperandHelper(
return mod == 2 ? 6 : 3;
} else {
// No sib.
- int disp = (mod == 2) ? Imm32(modrmp + 1) : Imm8(modrmp + 1);
+ int disp =
+ (mod == 2) ? Imm32(modrmp + 1) : Imm8(modrmp + 1) * cd8_scale;
AppendToBuffer("[%s%s0x%x]", NameOfCPURegister(rm),
disp < 0 ? "-" : "+", disp < 0 ? -disp : disp);
if (rm == i::kRootRegister.code()) {
@@ -709,6 +795,19 @@ int DisassemblerX64::PrintRightAVXOperand(uint8_t* modrmp) {
return PrintRightOperandHelper(modrmp, &DisassemblerX64::NameOfAVXRegister);
}
+// Prints the ModR/M "right" operand of an EVEX-encoded (AVX10/AVX-512) vector
+// instruction. Register-direct operands use the 5-bit register number
+// {EVEX.X:EVEX.B:ModRM.rm} (rex_x/rex_b are synthesized from the EVEX prefix by
+// the caller); memory operands are printed with disp8*N compressed-displacement
+// scaling selected by |tuple_type|.
+int DisassemblerX64::PrintRightEVEXOperand(uint8_t* modrmp,
+ TupleType tuple_type,
+ RegisterNameMapping mapping) {
+ uint8_t cd8_scale = v8::internal::Assembler::TupleTypeToN(
+ tuple_type, evex_w() ? VexW::kW1 : VexW::kW0, evex_vector_length());
+ return PrintRightOperandHelper(modrmp, mapping, cd8_scale);
+}
+
// Returns number of bytes used including the current *data.
// Writes instruction's mnemonic, left and right operands to 'tmp_buffer_'.
int DisassemblerX64::PrintOperands(const char* mnem, OperandType op_order,
@@ -842,14 +941,10 @@ int DisassemblerX64::F6F7Instruction(uint8_t* data) {
AppendToBuffer("%s%c %s", mnem, operand_size_code(),
NameOfCPURegister(rm));
return 2;
- } else if (mod == 1 ||
- mod == 2) { // Byte displacement or 32-bit displacement
+ } else {
AppendToBuffer("%s%c ", mnem, operand_size_code());
int count = PrintRightOperand(data + 1); // Use name of 64-bit register.
return 1 + count;
- } else {
- UnimplementedInstruction();
- return 2;
}
} else if (regop == 0) {
AppendToBuffer("test%c ", operand_size_code());
@@ -964,11 +1059,25 @@ int DisassemblerX64::SetCC(uint8_t* data) {
const char* sf_str[4] = {"", "rl", "ra", "ll"};
-int DisassemblerX64::AVXInstruction(uint8_t* data) {
+// TODO(v8:536954139): Audit shared VEX/EVEX opcode cases below. Cases using
+// PrintRightOperand or PrintRightAVXOperand may require PrintRightEVEXOperand
+// to correctly decode EVEX memory instructions.
+int DisassemblerX64::AVXVectorInstruction(uint8_t* data) {
uint8_t opcode = *data;
uint8_t* current = data + 1;
- if (vex_66() && vex_0f38()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ if (is_evex()) {
+ // Synthesize rex_ from the EVEX prefix (rex.r = ~EVEX.R, rex.x = ~EVEX.X,
+ // rex.b = ~EVEX.B, rex.w = EVEX.W) so PrintRight{,EVEX}Operand decode
+ // extended base/index and register operands.
+ uint8_t synth_rex = 0x40;
+ if (!(evex_byte1_ & 0x80)) synth_rex |= 0x04;
+ if (!(evex_byte1_ & 0x40)) synth_rex |= 0x02;
+ if (!(evex_byte1_ & 0x20)) synth_rex |= 0x01;
+ if (evex_w()) synth_rex |= 0x08;
+ setRex(synth_rex);
+ }
+ if (simd_prefix_66() && leading_0f38()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0x13:
@@ -983,6 +1092,22 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
AppendToBuffer("vbroadcastsd %s,", NameOfAVXRegister(regop));
current += PrintRightXMMOperand(current);
break;
+ case 0x1F:
+ if (is_evex() && evex_w()) {
+ AppendToBuffer("vpabsq %s,", NameOfAVXRegister(regop));
+ current += PrintRightEVEXOperand(current, TupleType::kFull);
+ } else {
+ UnimplementedInstruction();
+ }
+ break;
+ case 0x54:
+ if (is_evex() && !evex_w()) {
+ AppendToBuffer("vpopcntb %s,", NameOfAVXRegister(regop));
+ current += PrintRightEVEXOperand(current, TupleType::kFullMem);
+ } else {
+ UnimplementedInstruction();
+ }
+ break;
case 0xF7:
AppendToBuffer("shlx%c %s,", operand_size_code(),
NameOfCPURegister(regop));
@@ -997,9 +1122,19 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, notUsed3, \
opcode) \
case 0x##opcode: { \
- AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
- NameOfAVXRegister(vvvv)); \
- current += PrintRightAVXOperand(current); \
+ if (0x##opcode == 0x39 && is_evex() && evex_w()) { \
+ AppendToBuffer("vpminsq %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightEVEXOperand(current, TupleType::kFull); \
+ } else if (0x##opcode == 0x40 && is_evex() && evex_w()) { \
+ AppendToBuffer("vpmullq %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightEVEXOperand(current, TupleType::kFull); \
+ } else { \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightAVXOperand(current); \
+ } \
break; \
}
@@ -1057,8 +1192,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
#undef DECLARE_FMA_DISASM
}
}
- } else if (vex_66() && vex_0f3a()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_66() && leading_0f3a()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0x00:
@@ -1154,12 +1289,34 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
current += PrintRightOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
+ case 0x25: {
+ if (is_evex()) {
+ AppendToBuffer("vpternlog%c %s%s,%s,", evex_w() ? 'q' : 'd',
+ NameOfAVXRegister(regop), EVEXMasking(),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightEVEXOperand(current, TupleType::kFull);
+ AppendToBuffer(",0x%x", *current++);
+ } else {
+ UnimplementedInstruction();
+ }
+ break;
+ }
case 0x38:
AppendToBuffer("vinserti128 %s,%s,", NameOfAVXRegister(regop),
NameOfAVXRegister(vvvv));
current += PrintRightXMMOperand(current);
AppendToBuffer(",0x%x", *current++);
break;
+ case 0x3F:
+ if (is_evex()) {
+ AppendToBuffer("vpcmpb %s,%s,", NameOfKRegister(regop & 0x7),
+ NameOfAVXRegister(vvvv));
+ current += PrintRightEVEXOperand(current, TupleType::kFullMem);
+ AppendToBuffer(",0x%x", *current++);
+ } else {
+ UnimplementedInstruction();
+ }
+ break;
case 0x4A: {
AppendToBuffer("vblendvps %s,%s,", NameOfAVXRegister(regop),
NameOfAVXRegister(vvvv));
@@ -1184,8 +1341,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_f3() && vex_0f()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_f3() && leading_0f()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0x10:
@@ -1208,12 +1365,12 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
current += PrintRightAVXOperand(current);
break;
case 0x2A:
- AppendToBuffer("%s %s,%s,", vex_w() ? "vcvtqsi2ss" : "vcvtlsi2ss",
+ AppendToBuffer("%s %s,%s,", vector_w() ? "vcvtqsi2ss" : "vcvtlsi2ss",
NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
current += PrintRightOperand(current);
break;
case 0x2C:
- AppendToBuffer("vcvttss2si%s %s,", vex_w() ? "q" : "",
+ AppendToBuffer("vcvttss2si%s %s,", vector_w() ? "q" : "",
NameOfCPURegister(regop));
current += PrintRightAVXOperand(current);
break;
@@ -1289,8 +1446,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_f2() && vex_0f()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_f2() && leading_0f()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0x10:
@@ -1313,17 +1470,17 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
current += PrintRightAVXOperand(current);
break;
case 0x2A:
- AppendToBuffer("%s %s,%s,", vex_w() ? "vcvtqsi2sd" : "vcvtlsi2sd",
+ AppendToBuffer("%s %s,%s,", vector_w() ? "vcvtqsi2sd" : "vcvtlsi2sd",
NameOfAVXRegister(regop), NameOfAVXRegister(vvvv));
current += PrintRightOperand(current);
break;
case 0x2C:
- AppendToBuffer("vcvttsd2si%s %s,", vex_w() ? "q" : "",
+ AppendToBuffer("vcvttsd2si%s %s,", vector_w() ? "q" : "",
NameOfCPURegister(regop));
current += PrintRightAVXOperand(current);
break;
case 0x2D:
- AppendToBuffer("vcvtsd2si%s %s,", vex_w() ? "q" : "",
+ AppendToBuffer("vcvtsd2si%s %s,", vector_w() ? "q" : "",
NameOfCPURegister(regop));
current += PrintRightAVXOperand(current);
break;
@@ -1369,8 +1526,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_none() && vex_0f38()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_none() && leading_0f38()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
const char* mnem = "?";
switch (opcode) {
@@ -1413,8 +1570,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_f2() && vex_0f38()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_f2() && leading_0f38()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0xF5:
@@ -1441,8 +1598,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_f3() && vex_0f38()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_f3() && leading_0f38()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0xF5:
@@ -1459,7 +1616,7 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_f2() && vex_0f3a()) {
+ } else if (simd_prefix_f2() && leading_0f3a()) {
int mod, regop, rm;
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
@@ -1482,8 +1639,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_none() && vex_0f()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_none() && leading_0f()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0x10:
@@ -1577,8 +1734,8 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
default:
UnimplementedInstruction();
}
- } else if (vex_66() && vex_0f()) {
- int mod, regop, rm, vvvv = vex_vreg();
+ } else if (simd_prefix_66() && leading_0f()) {
+ int mod, regop, rm, vvvv = get_vreg();
get_modrm(*current, &mod, ®op, &rm);
switch (opcode) {
case 0x10:
@@ -1604,7 +1761,7 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
current += PrintRightAVXOperand(current);
break;
case 0x6E:
- AppendToBuffer("vmov%c %s,", vex_w() ? 'q' : 'd',
+ AppendToBuffer("vmov%c %s,", vector_w() ? 'q' : 'd',
NameOfAVXRegister(regop));
current += PrintRightOperand(current);
break;
@@ -1624,10 +1781,16 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
AppendToBuffer(",%u", *current++);
break;
case 0x72:
- AppendToBuffer("vps%sd %s,", sf_str[regop / 2],
- NameOfAVXRegister(vvvv));
- current += PrintRightAVXOperand(current);
- AppendToBuffer(",%u", *current++);
+ if (is_evex() && evex_w() && regop == 4) {
+ AppendToBuffer("vpsraq %s,", NameOfAVXRegister(vvvv));
+ current += PrintRightEVEXOperand(current, TupleType::kFull);
+ AppendToBuffer(",%u", *current++);
+ } else {
+ AppendToBuffer("vps%sd %s,", sf_str[regop / 2],
+ NameOfAVXRegister(vvvv));
+ current += PrintRightAVXOperand(current);
+ AppendToBuffer(",%u", *current++);
+ }
break;
case 0x73:
AppendToBuffer("vps%sq %s,", sf_str[regop / 2],
@@ -1636,7 +1799,7 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
AppendToBuffer(",%u", *current++);
break;
case 0x7E:
- AppendToBuffer("vmov%c ", vex_w() ? 'q' : 'd');
+ AppendToBuffer("vmov%c ", vector_w() ? 'q' : 'd');
current += PrintRightOperand(current);
AppendToBuffer(",%s", NameOfAVXRegister(regop));
break;
@@ -1663,12 +1826,18 @@ int DisassemblerX64::AVXInstruction(uint8_t* data) {
AppendToBuffer("vpmovmskb %s,", NameOfCPURegister(regop));
current += PrintRightAVXOperand(current);
break;
-#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \
- case 0x##opcode: { \
- AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
- NameOfAVXRegister(vvvv)); \
- current += PrintRightAVXOperand(current); \
- break; \
+#define DECLARE_SSE_AVX_DIS_CASE(instruction, notUsed1, notUsed2, opcode) \
+ case 0x##opcode: { \
+ if (0x##opcode == 0xE2 && is_evex() && evex_w()) { \
+ AppendToBuffer("vpsraq %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightEVEXOperand(current, TupleType::kMem128); \
+ } else { \
+ AppendToBuffer("v" #instruction " %s,%s,", NameOfAVXRegister(regop), \
+ NameOfAVXRegister(vvvv)); \
+ current += PrintRightAVXOperand(current); \
+ } \
+ break; \
}
SSE2_INSTRUCTION_LIST(DECLARE_SSE_AVX_DIS_CASE)
@@ -2470,7 +2639,7 @@ int DisassemblerX64::APXInstruction(uint8_t* data) {
get_modrm(*data, &mod, ®op, &rm);
int full_regop = evex_reg(regop);
- int full_rm = evex_rm(rm);
+ int full_rm = evex_rm_gpr(rm);
int ndd_reg = evex_ndd_reg();
// Synthesize rex_ for PrintRightOperand.
@@ -2486,14 +2655,6 @@ int DisassemblerX64::APXInstruction(uint8_t* data) {
opcode == 0x80 || opcode == 0x81 || opcode == 0x83 || opcode == 0x84 ||
opcode == 0x85 || opcode == 0xF6 || opcode == 0xF7;
- if (evex_map3() && opcode == 0x3F) {
- AppendToBuffer("vpcmpeqb %s,%s,", NameOfKRegister(full_regop & 0x7),
- NameOfAVXRegister(evex_vvvv() | evex_v4()));
- data += PrintRightAVXOperand(data);
- AppendToBuffer(",0x%x", *data++);
- return static_cast<int>(data - start);
- }
-
if (!has_nd && is_ccmp_ctest_opcode) {
int scc = evex_scc();
const char* cc_suffix = conditional_code_suffix[scc];
@@ -2972,10 +3133,17 @@ int DisassemblerX64::InstructionDecode(v8::base::Vector<char> out_buffer,
// Decode AVX instructions.
if (vex_byte0_ != 0) {
processed = true;
- data += AVXInstruction(data);
+ data += AVXVectorInstruction(data);
} else if (is_evex()) {
processed = true;
- data += APXInstruction(data);
+ // Route EVEX by opcode map. APX promotes legacy-integer instructions into
+ // map 4, which APXInstruction decodes; every other map is an AVX10/AVX-512
+ // vector instruction and shares AVXVectorInstruction with the VEX forms.
+ if (evex_map4()) {
+ data += APXInstruction(data);
+ } else {
+ data += AVXVectorInstruction(data);
+ }
} else if (is_rex2()) {
processed = true;
data += REX2Instruction(data);
@@ -3417,10 +3585,17 @@ static constexpr const char* const xmm_regs[]{
static constexpr const char* const ymm_regs[]{
YMM_REGISTERS_AVX512(MAKE_REG_NAME)};
+static constexpr const char* const zmm_regs[32] = {
+ "zmm0", "zmm1", "zmm2", "zmm3", "zmm4", "zmm5", "zmm6", "zmm7",
+ "zmm8", "zmm9", "zmm10", "zmm11", "zmm12", "zmm13", "zmm14", "zmm15",
+ "zmm16", "zmm17", "zmm18", "zmm19", "zmm20", "zmm21", "zmm22", "zmm23",
+ "zmm24", "zmm25", "zmm26", "zmm27", "zmm28", "zmm29", "zmm30", "zmm31"};
+
static_assert(arraysize(cpu_regs) == 16);
static_assert(arraysize(byte_cpu_regs) == 16);
static_assert(arraysize(xmm_regs) == 32);
static_assert(arraysize(ymm_regs) == 32);
+static_assert(arraysize(zmm_regs) == 32);
#undef MAKE_REG_NAME
@@ -3453,6 +3628,11 @@ const char* NameOfYMMRegister(int reg) {
return "noymmreg";
}
+const char* NameOfZMMRegister(int reg) {
+ if (0 <= reg && reg < 32) return zmm_regs[reg];
+ return "nozmmreg";
+}
+
const char* NameConverter::NameInCode(uint8_t* addr) const {
// X64 does not embed debug strings at the moment.
UNREACHABLE();
diff --git a/deps/v8/src/dumpling/object-dumping.cc b/deps/v8/src/dumpling/object-dumping.cc
index 7aed491b960..6b479bc0994 100644
--- a/deps/v8/src/dumpling/object-dumping.cc
+++ b/deps/v8/src/dumpling/object-dumping.cc
@@ -10,6 +10,7 @@
#include "src/objects/dictionary-inl.h"
#include "src/objects/instance-type.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/tagged.h"
#include "src/strings/string-stream.h"
diff --git a/deps/v8/src/execution/arguments-inl.h b/deps/v8/src/execution/arguments-inl.h
index 8f3681acce2..c7354b9cb1b 100644
--- a/deps/v8/src/execution/arguments-inl.h
+++ b/deps/v8/src/execution/arguments-inl.h
@@ -9,6 +9,7 @@
// Include the non-inl header before the rest of the headers.
#include "src/handles/handles-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h" // TODO(jkummerow): Just smi-inl.h.
#include "src/objects/tagged-index.h"
diff --git a/deps/v8/src/execution/execution.cc b/deps/v8/src/execution/execution.cc
index 39d72063ef5..74d96a8898e 100644
--- a/deps/v8/src/execution/execution.cc
+++ b/deps/v8/src/execution/execution.cc
@@ -397,21 +397,6 @@ V8_WARN_UNUSED_RESULT MaybeHandle<Object> Invoke(Isolate* isolate,
GRACEFUL_FATAL("Invoke in DisallowJavascriptExecutionScope");
}
if (!ThrowOnJavascriptExecution::IsAllowed(isolate)) {
- // TODO(http://crbug.com/486958027): temporary measure for figuring out
- // who tries to throw exceptions in C++ microtasks.
- {
- Tagged<Object> maybe_microtask = *isolate->factory()->current_microtask();
- if (IsCallbackTask(maybe_microtask)) {
- Tagged<Map> maybe_microtask_map;
- if (IsHeapObject(maybe_microtask)) {
- maybe_microtask_map = Cast<HeapObject>(maybe_microtask)->map();
- }
- isolate->PushStackTraceAndContinue(
- reinterpret_cast<void*>((*params.target).ptr()),
- reinterpret_cast<void*>(maybe_microtask.ptr()),
- reinterpret_cast<void*>(maybe_microtask_map.ptr()));
- }
- }
isolate->ThrowIllegalOperation();
isolate->ReportPendingMessages(params.message_handling ==
Execution::MessageHandling::kReport);
@@ -563,6 +548,7 @@ MaybeDirectHandle<Object> InvokeWithTryCatch(Isolate* isolate,
v8::TryCatch catcher(reinterpret_cast<v8::Isolate*>(isolate));
catcher.SetVerbose(false);
catcher.SetCaptureMessage(false);
+ Isolate::MarkTryCatchInternal(&catcher);
maybe_result = Invoke(isolate, params);
diff --git a/deps/v8/src/execution/frame-constants.h b/deps/v8/src/execution/frame-constants.h
index e1128ec199c..3dbf91d6fe4 100644
--- a/deps/v8/src/execution/frame-constants.h
+++ b/deps/v8/src/execution/frame-constants.h
@@ -373,6 +373,10 @@ class WasmJspiFrameConstants : public JSToWasmWrapperFrameConstants {
// | spill slots | | GC scan scan_count slots
// | .... | <- spill_slot_base--|
// |- - - - - - - - -| |
+ // After switching back to a parent stack, its wrapper buffer is no longer
+ // needed. Preserve the parent's return address in this untagged slot while
+ // fulfilling or rejecting the promise, which can reenter JSPI.
+ static constexpr int kParentReturnAddressOffset = kWrapperBufferOffset;
// This slot contains the number of slots at the top of the frame that need to
// be scanned by the GC.
static constexpr int kGCScanSlotCountOffset =
diff --git a/deps/v8/src/execution/frames.cc b/deps/v8/src/execution/frames.cc
index 0b67898756f..51055f12e0c 100644
--- a/deps/v8/src/execution/frames.cc
+++ b/deps/v8/src/execution/frames.cc
@@ -258,33 +258,23 @@ StackFrame* StackFrameIterator::Reframe() {
}
namespace {
-StackFrame::Type GetStateForFastCCallCallerFP(Isolate* isolate, Address fp,
- Address pc, Address pc_address,
- StackFrame::State* state) {
+StackFrame::Type GetStateForFastCCallCallerFP(
+ const StackFrameIteratorBase* frame_iter, Address fp, Address pc_address,
+ StackFrame::State* state) {
// 'Fast C calls' are a special type of C call where we call directly from
// JS to C without an exit frame in between. The CEntryStub is responsible
// for setting Isolate::c_entry_fp, meaning that it won't be set for fast C
// calls. To keep the stack iterable, we store the FP and PC of the caller
- // of the fast C call on the isolate. This is guaranteed to be the topmost
- // JS frame, because fast C calls cannot call back into JS. We start
- // iterating the stack from this topmost JS frame.
- DCHECK_NE(kNullAddress, pc);
+ // of the fast C call on the isolate.
+ // We start iterating the stack from this topmost JS frame.
+ DCHECK_NE(kNullAddress, StackFrame::unauthenticated_pc(
+ reinterpret_cast<Address*>(pc_address)));
state->fp = fp;
state->sp = kNullAddress;
state->pc_address = reinterpret_cast<Address*>(pc_address);
state->callee_pc = kNullAddress;
state->constant_pool_address = nullptr;
-#if V8_ENABLE_WEBASSEMBLY
- if (wasm::WasmCode* code =
- wasm::GetWasmCodeManager()->LookupCode(isolate, pc)) {
- if (code->kind() == wasm::WasmCode::kWasmToJsWrapper) {
- return StackFrame::WASM_TO_JS;
- }
- DCHECK_EQ(code->kind(), wasm::WasmCode::kWasmFunction);
- return StackFrame::WASM;
- }
-#endif // V8_ENABLE_WEBASSEMBLY
- return StackFrame::TURBOFAN_JS;
+ return frame_iter->ComputeStackFrameType(state);
}
} // namespace
@@ -295,11 +285,10 @@ void StackFrameIterator::Reset(ThreadLocalTop* top) {
const Address fast_c_call_caller_fp =
isolate_->isolate_data()->fast_c_call_caller_fp();
if (fast_c_call_caller_fp != kNullAddress) {
- const Address caller_pc = isolate_->isolate_data()->fast_c_call_caller_pc();
const Address caller_pc_address =
isolate_->isolate_data()->fast_c_call_caller_pc_address();
- type = GetStateForFastCCallCallerFP(isolate_, fast_c_call_caller_fp,
- caller_pc, caller_pc_address, &state);
+ type = GetStateForFastCCallCallerFP(this, fast_c_call_caller_fp,
+ caller_pc_address, &state);
} else {
type = ExitFrame::GetStateForFramePointer(Isolate::c_entry_fp(top), &state);
}
@@ -696,6 +685,24 @@ bool StackFrameIteratorForProfiler::HasValidExitIfEntryFrame(
const StackFrame* frame) const {
if (!frame->is_entry() && !frame->is_construct_entry()) return true;
+ // See EntryFrame::GetCallerState. It checks the fast C call caller FP
+ // and if it's not null, it uses it. We need to be sure that caller FP
+ // address is valid to avoid an unaligned read in
+ // GetStateForFastCCallCallerFP.
+ Address next_fast_c_call_fp_address =
+ frame->fp() + EntryFrameConstants::kNextFastCallFrameFPOffset;
+ MSAN_MEMORY_IS_INITIALIZED(next_fast_c_call_fp_address, kSystemPointerSize);
+ Address next_fast_c_call_fp = Memory<Address>(next_fast_c_call_fp_address);
+ if (next_fast_c_call_fp != kNullAddress) {
+ if (!IsAligned(next_fast_c_call_fp, kSystemPointerSize) ||
+ !IsValidStackAddress(next_fast_c_call_fp)) {
+ return false;
+ }
+ // EntryFrame::GetCallerState will use this FP and won't read the
+ // next_exit_frame_fp, so we don't need to validate it.
+ return true;
+ }
+
// See EntryFrame::GetCallerState. It computes the caller FP address
// and calls ExitFrame::GetStateForFramePointer on it. We need to be
// sure that caller FP address is valid.
@@ -929,7 +936,9 @@ StackFrame::Type StackFrameIterator::ComputeStackFrameType(
}
#endif
- const Address pc = StackFrame::ReadPC(state->pc_address);
+ // We use unauthenticated_pc because it may come from
+ // fast_c_call_caller_pc_address, for which authentication does not work.
+ const Address pc = StackFrame::unauthenticated_pc(state->pc_address);
#if V8_ENABLE_WEBASSEMBLY
// If the {pc} does not point into WebAssembly code we can rely on the
@@ -1116,9 +1125,8 @@ StackFrame::Type EntryFrame::GetCallerState(State* state) const {
if (fast_c_call_caller_fp != kNullAddress) {
Address caller_pc_address =
fp() + EntryFrameConstants::kNextFastCallFramePCOffset;
- Address caller_pc = Memory<Address>(caller_pc_address);
- return GetStateForFastCCallCallerFP(isolate(), fast_c_call_caller_fp,
- caller_pc, caller_pc_address, state);
+ return GetStateForFastCCallCallerFP(iterator_, fast_c_call_caller_fp,
+ caller_pc_address, state);
}
Address next_exit_frame_fp =
Memory<Address>(fp() + EntryFrameConstants::kNextExitFrameFPOffset);
@@ -2057,8 +2065,9 @@ void TypedFrame::Iterate(RootVisitor* v) const {
// | return addr | v
// +-----------------+-----------------------------------------
- // Find the code and compute the safepoint information.
- Address inner_pointer = pc();
+ // Find the code and compute the safepoint information. The pc is
+ // unauthenticated when it comes from IsolateData, i.e. during a fast C call.
+ Address inner_pointer = maybe_unauthenticated_pc();
InnerPointerToCodeCache::Entry* entry =
isolate()->inner_pointer_to_code_cache()->GetCacheEntry(inner_pointer);
CHECK(entry->code.has_value());
@@ -2092,56 +2101,57 @@ void TypedFrame::Iterate(RootVisitor* v) const {
FullObjectSlot frame_header_base(&Memory<Address>(fp() - frame_header_size));
FullObjectSlot frame_header_limit(
&Memory<Address>(fp() - StandardFrameConstants::kCPSlotSize));
- // Parameters passed to the callee.
-#if V8_ENABLE_WEBASSEMBLY
- // Frame layout without stack switching (stack grows upwards):
- //
- // | callee |
- // | frame |
- // |-------------| <- sp()
- // | out params |
- // |-------------| <- frame_header_base - spill_slot_space
- // | spill slots |
- // |-------------| <- frame_header_base
- // | frame header|
- // |-------------| <- fp()
- //
- // With stack-switching:
- //
- // Secondary stack: Central stack:
- //
- // | callee |
- // | frame |
- // |------------| <- sp()
- // | out params |
- // |-------------| |------------| <- maybe_stack_switch.target_sp
- // | spill slots |
- // |-------------| <- frame_header_base
- // | frame header|
- // |-------------| <- fp()
- //
- // The base (lowest address) of the outgoing stack parameters area is always
- // sp(), and the limit (highest address) is either {frame_header_base -
- // spill_slot_size} or {maybe_stack_switch.target_sp} depending on
- // stack-switching.
- wasm::StackMemory::StackSwitchInfo maybe_stack_switch;
- if (iterator_->wasm_stack() != nullptr) {
- maybe_stack_switch = iterator_->wasm_stack()->stack_switch_info();
- }
- FullObjectSlot parameters_limit(
- maybe_stack_switch.has_value() && maybe_stack_switch.source_fp == fp()
- ? maybe_stack_switch.target_sp
- : frame_header_base.address() - spill_slots_size);
-#else
- FullObjectSlot parameters_limit(frame_header_base.address() -
- spill_slots_size);
-#endif
- FullObjectSlot parameters_base(&Memory<Address>(sp()));
FullObjectSlot spill_slots_end(frame_header_base.address() -
spill_slots_size);
- // Visit the rest of the parameters.
- if (HasTaggedOutgoingParams(code)) {
+ // Visit the rest of the parameters. A fast C call has no outgoing parameters
+ // to visit, and its sp() is unknown.
+ if (!InFastCCall() && HasTaggedOutgoingParams(code)) {
+ // Parameters passed to the callee.
+#if V8_ENABLE_WEBASSEMBLY
+ // Frame layout without stack switching (stack grows upwards):
+ //
+ // | callee |
+ // | frame |
+ // |-------------| <- sp()
+ // | out params |
+ // |-------------| <- frame_header_base - spill_slot_space
+ // | spill slots |
+ // |-------------| <- frame_header_base
+ // | frame header|
+ // |-------------| <- fp()
+ //
+ // With stack-switching:
+ //
+ // Secondary stack: Central stack:
+ //
+ // | callee |
+ // | frame |
+ // |------------| <- sp()
+ // | out params |
+ // |-------------| |------------|
+ // | spill slots | ^ maybe_stack_switch.target_sp
+ // |-------------| <- frame_header_base
+ // | frame header|
+ // |-------------| <- fp()
+ //
+ // The base (lowest address) of the outgoing stack parameters area is always
+ // sp(), and the limit (highest address) is either {frame_header_base -
+ // spill_slot_size} or {maybe_stack_switch.target_sp} depending on
+ // stack-switching.
+ wasm::StackMemory::StackSwitchInfo maybe_stack_switch;
+ if (iterator_->wasm_stack() != nullptr) {
+ maybe_stack_switch = iterator_->wasm_stack()->stack_switch_info();
+ }
+ FullObjectSlot parameters_limit(
+ maybe_stack_switch.has_value() && maybe_stack_switch.source_fp == fp()
+ ? maybe_stack_switch.target_sp
+ : frame_header_base.address() - spill_slots_size);
+#else
+ FullObjectSlot parameters_limit(frame_header_base.address() -
+ spill_slots_size);
+#endif
+ FullObjectSlot parameters_base(&Memory<Address>(sp()));
v->VisitRootPointers(Root::kStackRoots, nullptr, parameters_base,
parameters_limit);
}
@@ -2833,8 +2843,7 @@ FrameSummary::JavaScriptFrameSummary::CreateStackFrameInfo() const {
DirectHandle<Script> script(Cast<Script>(shared->script()), isolate());
DirectHandle<String> function_name =
JSFunction::GetDebugName(isolate(), function_);
- if (function_name->length() == 0 &&
- script->compilation_type() == Script::CompilationType::kEval) {
+ if (function_name->length() == 0 && script->is_eval()) {
function_name = isolate()->factory()->eval_string();
}
int bytecode_offset = code_offset();
@@ -3586,7 +3595,7 @@ void WasmFrame::Print(StringStream* accumulator, PrintMode mode, int index,
if (wasm_code()->index() == wasm::kAnonymousFuncIndex) {
accumulator->Add("Anonymous wasm wrapper [pc: %p]\n",
- reinterpret_cast<void*>(pc()));
+ reinterpret_cast<void*>(maybe_unauthenticated_pc()));
return;
}
wasm::WasmCodeRefScope code_ref_scope;
@@ -3608,9 +3617,11 @@ void WasmFrame::Print(StringStream* accumulator, PrintMode mode, int index,
int func_code_offset = module->functions[func_index].code.offset();
accumulator->Add(
"], function #%u ('%s'), pc=%p (+0x%x), pos=%d (+%d) instance=%p\n",
- func_index, func_name, reinterpret_cast<void*>(pc()),
- static_cast<int>(pc() - top_summary.code()->instruction_start()), pos,
- pos - func_code_offset,
+ func_index, func_name,
+ reinterpret_cast<void*>(maybe_unauthenticated_pc()),
+ static_cast<int>(maybe_unauthenticated_pc() -
+ top_summary.code()->instruction_start()),
+ pos, pos - func_code_offset,
reinterpret_cast<void*>(trusted_instance_data()->ptr()));
if (mode != OVERVIEW) accumulator->Add("\n");
}
@@ -3645,7 +3656,8 @@ Tagged<Script> WasmFrame::script() const { return module_object()->script(); }
std::tuple<SourcePosition, int>
WasmFrame::GetInnermostSourcePositionAndFunctionIndex() const {
wasm::WasmCode* code = wasm_code();
- int offset = static_cast<int>(pc() - code->instruction_start());
+ int offset =
+ static_cast<int>(maybe_unauthenticated_pc() - code->instruction_start());
SourcePosition pos = code->GetSourcePositionBefore(offset);
int func_index = code->index();
if (pos.isInlined()) {
@@ -3715,11 +3727,12 @@ FrameSummaries WasmFrame::Summarize(AllowAllocation allow_allocation) const {
}
int WasmFrame::LookupExceptionHandlerInTable() {
- wasm::WasmCode* code =
- wasm::GetWasmCodeManager()->LookupCode(isolate(), pc());
+ wasm::WasmCode* code = wasm::GetWasmCodeManager()->LookupCode(
+ isolate(), maybe_unauthenticated_pc());
if (!code->IsAnonymous() && code->handler_table_size() > 0) {
HandlerTable table(code);
- int pc_offset = static_cast<int>(pc() - code->instruction_start());
+ int pc_offset = static_cast<int>(maybe_unauthenticated_pc() -
+ code->instruction_start());
return table.LookupReturn(pc_offset);
}
return -1;
diff --git a/deps/v8/src/execution/futex-emulation.cc b/deps/v8/src/execution/futex-emulation.cc
index 00e0cb4b2a9..3d0c6913e2b 100644
--- a/deps/v8/src/execution/futex-emulation.cc
+++ b/deps/v8/src/execution/futex-emulation.cc
@@ -324,6 +324,23 @@ Tagged<Object> FutexEmulation::WaitWasm64(Isolate* isolate,
rel_timeout_ns, CallType::kIsWasm);
}
+namespace {
+class InSyncWaitScope {
+ public:
+ explicit InSyncWaitScope(FutexWaitListNode* node) : node_(node) {
+ DCHECK(!node_->IsInSyncWait());
+ node_->SetInSyncWait(true);
+ }
+ ~InSyncWaitScope() {
+ DCHECK(node_->IsInSyncWait());
+ node_->SetInSyncWait(false);
+ }
+
+ private:
+ FutexWaitListNode* node_;
+};
+} // namespace
+
#if V8_ENABLE_WEBASSEMBLY
Tagged<Object> FutexEmulation::WaitWasmManagedObject(
Isolate* isolate, Tagged<HeapObject> object, int32_t offset,
@@ -334,6 +351,12 @@ Tagged<Object> FutexEmulation::WaitWasmManagedObject(
base::TimeDelta::FromNanoseconds(rel_timeout_ns);
FutexWaitListNode* node = isolate->futex_wait_list_node();
+ if (node->IsInSyncWait()) {
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ MessageTemplate::kAtomicsOperationNotAllowed,
+ isolate->factory()->NewStringFromAsciiChecked("Atomics.wait")));
+ }
+ InSyncWaitScope wait_scope(node);
bool use_timeout = rel_timeout_ns >= 0;
@@ -401,6 +424,13 @@ Tagged<Object> FutexEmulation::WaitSync(Isolate* isolate, void* wait_location,
FutexWaitList* wait_list = GetWaitList();
FutexWaitListNode* node = isolate->futex_wait_list_node();
+ if (node->IsInSyncWait()) {
+ return isolate->Throw(*isolate->factory()->NewTypeError(
+ MessageTemplate::kAtomicsOperationNotAllowed,
+ isolate->factory()->NewStringFromAsciiChecked("Atomics.wait")));
+ }
+ InSyncWaitScope wait_scope(node);
+
base::TimeTicks timeout_time;
if (use_timeout) {
base::TimeTicks current_time = base::TimeTicks::Now();
@@ -430,9 +460,10 @@ DirectHandle<Object> FutexEmulation::WaitSyncImpl(
NoGarbageCollectionMutexGuard& lock_guard, bool use_timeout,
base::TimeTicks timeout_time, T value, T loaded_value,
std::optional<void*> wait_location) {
+ DCHECK(!node->IsWaiting());
+
DirectHandle<Object> result;
if (loaded_value != value) {
- DCHECK(!node->waiting_);
return direct_handle(Smi::FromInt(WaitReturnValue::kNotEqualValue),
isolate);
}
diff --git a/deps/v8/src/execution/futex-emulation.h b/deps/v8/src/execution/futex-emulation.h
index 8c1bb3d0305..baad1a236ad 100644
--- a/deps/v8/src/execution/futex-emulation.h
+++ b/deps/v8/src/execution/futex-emulation.h
@@ -64,6 +64,9 @@ class FutexWaitListNode {
void NotifyWake();
bool IsAsync() const { return async_state_ != nullptr; }
+ bool IsWaiting() const { return waiting_.load(std::memory_order_relaxed); }
+ bool IsInSyncWait() const { return in_sync_wait_; }
+ void SetInSyncWait(bool v) { in_sync_wait_ = v; }
// Returns false if the cancelling failed, true otherwise.
bool CancelTimeoutTask();
@@ -139,9 +142,13 @@ class FutexWaitListNode {
// this node is alive.
void* wait_location_ = nullptr;
- // waiting_ and interrupted_ are protected by `GetWaitList()::mutex()`.
- bool waiting_ = false;
+ // waiting_ is std::atomic<bool> to allow safe relaxed reads outside mutex
+ // locks.
+ std::atomic<bool> waiting_{false};
bool interrupted_ = false;
+ // in_sync_wait_ tracks whether the isolate thread is executing inside a
+ // WaitSync scope. Modified exclusively by the isolate thread itself.
+ bool in_sync_wait_ = false;
// State used for an async wait; nullptr on sync waits.
const std::unique_ptr<AsyncState> async_state_;
diff --git a/deps/v8/src/execution/isolate-inl.h b/deps/v8/src/execution/isolate-inl.h
index 6b704e0f13d..de710c8fad3 100644
--- a/deps/v8/src/execution/isolate-inl.h
+++ b/deps/v8/src/execution/isolate-inl.h
@@ -12,7 +12,6 @@
#include "src/objects/contexts-inl.h"
#include "src/objects/js-function.h"
#include "src/objects/lookup-inl.h"
-#include "src/objects/objects-inl.h"
#include "src/objects/oddball.h"
#include "src/objects/property-cell.h"
#include "src/objects/regexp-match-info.h"
@@ -125,6 +124,11 @@ bool Isolate::is_execution_terminating() {
i::ReadOnlyRoots(this).termination_exception();
}
+bool Isolate::is_javascript_execution_allowed() const {
+ return javascript_execution_assert() && javascript_execution_throws() &&
+ javascript_execution_dump();
+}
+
#ifdef DEBUG
Tagged<Object> Isolate::VerifyBuiltinsResult(Tagged<Object> result) {
if (is_execution_terminating() && !v8_flags.strict_termination_checks) {
diff --git a/deps/v8/src/execution/isolate.cc b/deps/v8/src/execution/isolate.cc
index 3dedd6a4de0..af0e139d671 100644
--- a/deps/v8/src/execution/isolate.cc
+++ b/deps/v8/src/execution/isolate.cc
@@ -102,6 +102,7 @@
#include "src/objects/js-weak-refs-inl.h"
#include "src/objects/managed-inl.h"
#include "src/objects/module-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects.h"
#include "src/objects/promise-inl.h"
#include "src/objects/property-descriptor.h"
@@ -730,6 +731,14 @@ void Isolate::UnregisterTryCatchHandler(v8::TryCatch* that) {
SimulatorStack::UnregisterJSStackComparableAddress(this);
}
+void Isolate::MarkTryCatchInternal(v8::TryCatch* that) {
+ that->SetIsInternal(true);
+}
+
+bool Isolate::IsInternalTryCatch(v8::TryCatch* that) {
+ return that->IsInternal();
+}
+
DirectHandle<String> Isolate::StackTraceString() {
if (stack_trace_nesting_level_ == 0) {
stack_trace_nesting_level_++;
@@ -853,7 +862,8 @@ StackTraceFailureMessage::StackTraceFailureMessage(
const size_t buffer_length = arraysize(js_stack_trace_);
FixedStringAllocator fixed(&js_stack_trace_[0], buffer_length - 1);
StringStream accumulator(&fixed, StringStream::kPrintObjectConcise);
- isolate_->PrintStack(&accumulator, Isolate::kPrintStackVerbose);
+ isolate_->PrintStack(&accumulator, Isolate::kPrintStackVerbose,
+ AllowAllocation{false});
// Keeping a reference to the last code objects to increase likelihood that
// they get included in the minidump.
const size_t code_objects_length = arraysize(code_objects_);
@@ -1789,15 +1799,12 @@ MaybeDirectHandle<JSObject> Isolate::CaptureAndSetErrorStack(
static_cast<uint32_t>(
stack_trace_for_uncaught_exceptions_frame_limit_));
DCHECK_GE(stack_trace_limit, 0);
- // Compare in frames rather than raw slots to avoid overflowing for
- // large Error.stackTraceLimit values.
- uint32_t frame_count = raw_data_for_call_site_infos->ulength().value() /
- CallSiteInfo::Fields::kCount;
- if (static_cast<uint32_t>(stack_trace_limit) < frame_count) {
+ if (static_cast<uint32_t>(stack_trace_limit) *
+ CallSiteInfo::Fields::kCount <
+ raw_data_for_call_site_infos->ulength().value()) {
call_site_infos_or_formatted_stack = FixedArray::RightTrimOrEmpty(
this, raw_data_for_call_site_infos,
- static_cast<uint32_t>(stack_trace_limit) *
- CallSiteInfo::Fields::kCount);
+ stack_trace_limit * CallSiteInfo::Fields::kCount);
}
// Notify the debugger.
OnStackTraceCaptured(stack_trace);
@@ -2616,6 +2623,13 @@ void Isolate::InvokeApiInterruptCallbacks() {
}
VMState<EXTERNAL> state(this);
HandleScope handle_scope(this);
+ // API interrupt callbacks are forbidden from executing JavaScript on the
+ // interrupted Isolate (see v8::Isolate::RequestInterrupt contract in
+ // v8-isolate.h: "Registered |callback| must not reenter interrupted
+ // Isolate.").
+#ifdef V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
+ DisallowJavascriptExecution no_js(this);
+#endif // V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
entry.first(reinterpret_cast<v8::Isolate*>(this), entry.second);
}
}
@@ -3484,7 +3498,9 @@ Isolate::CatchType PredictExceptionCatchAtFrame(
// The exception has been externally caught if and only if there is an
// external handler which is on top of the top-most JS_ENTRY handler.
if (external_handler != kNullAddress &&
- !iterator.isolate()->try_catch_handler()->IsVerbose()) {
+ !iterator.isolate()->try_catch_handler()->IsVerbose() &&
+ !Isolate::IsInternalTryCatch(
+ iterator.isolate()->try_catch_handler())) {
if (entry_handler == kNullAddress || entry_handler > external_handler) {
return Isolate::CAUGHT_BY_EXTERNAL;
}
@@ -3528,7 +3544,9 @@ Isolate::CatchType PredictExceptionCatchAtFrame(
Isolate::CatchType Isolate::PredictExceptionCatcher() {
if (TopExceptionHandlerType(Tagged<Object>()) ==
ExceptionHandlerType::kExternalTryCatch) {
- return CAUGHT_BY_EXTERNAL;
+ if (!try_catch_handler()->IsInternal()) {
+ return CAUGHT_BY_EXTERNAL;
+ }
}
// Search for an exception handler by performing a full walk over the stack.
@@ -4566,6 +4584,7 @@ void Isolate::SwitchStacks(wasm::StackMemory* from, wasm::StackMemory* to,
from->jmpbuf()->is_on_central_stack =
thread_local_top()->is_on_central_stack_flag_;
+ from->set_contains_only_old_pointers(false);
}
SBXCHECK_EQ(to->jmpbuf()->state, expected_target_state);
to->jmpbuf()->state = wasm::JumpBuffer::Active;
@@ -4862,11 +4881,11 @@ Isolate::Isolate(IsolateGroup* isolate_group)
void Isolate::CheckIsolateLayout() {
#ifdef V8_ENABLE_SANDBOX
- static_assert(static_cast<int>(OFFSET_OF(ExternalPointerTable, base_)) ==
+ static_assert(static_cast<int>(ExternalPointerTable::BaseOffset()) ==
Internals::kExternalEntityTableBasePointerOffset);
- static_assert(static_cast<int>(OFFSET_OF(TrustedPointerTable, base_)) ==
+ static_assert(static_cast<int>(TrustedPointerTable::BaseOffset()) ==
Internals::kExternalEntityTableBasePointerOffset);
- static_assert(static_cast<int>(OFFSET_OF(JSDispatchTable, base_)) ==
+ static_assert(static_cast<int>(JSDispatchTable::BaseOffset()) ==
Internals::kExternalEntityTableBasePointerOffset);
static_assert(static_cast<int>(sizeof(ExternalPointerTable)) ==
Internals::kExternalEntityTableSize);
@@ -5046,7 +5065,6 @@ void Isolate::PrintAndClearRegExpSubjectStrings() {
}
#endif // V8_ENABLE_REGEXP_DIAGNOSTICS
-#ifdef V8_CPPGC_MICROTASK_QUEUE
void Isolate::CompactMicrotaskQueues() {
microtask_queues_.erase(
std::remove_if(microtask_queues_.begin(), microtask_queues_.end(),
@@ -5057,7 +5075,6 @@ void Isolate::RegisterMicrotaskQueue(MicrotaskQueue* queue) {
CompactMicrotaskQueues();
microtask_queues_.push_back(queue);
}
-#endif // V8_CPPGC_MICROTASK_QUEUE
void Isolate::Deinit() {
TRACE_ISOLATE(deinit);
@@ -5437,20 +5454,12 @@ Isolate::~Isolate() {
DCHECK_NULL(builtins_effects_analyzer_);
-#ifdef V8_CPPGC_MICROTASK_QUEUE
// Assert that |default_microtask_queue_| is the last MicrotaskQueue instance.
CompactMicrotaskQueues();
if (DEBUG_BOOL && default_microtask_queue_) {
DCHECK_EQ(microtask_queues_.size(), 1);
}
default_microtask_queue_ = nullptr;
-#else
- // Assert that |default_microtask_queue_| is the last MicrotaskQueue instance.
- DCHECK_IMPLIES(default_microtask_queue_,
- default_microtask_queue_ == default_microtask_queue_->next());
- delete default_microtask_queue_;
- default_microtask_queue_ = nullptr;
-#endif // V8_CPPGC_MICROTASK_QUEUE
// isolate_group_ released in caller, to ensure that all member destructors
// run before potentially unmapping the isolate's VirtualMemoryArea.
@@ -6087,6 +6096,10 @@ void Isolate::VerifyStaticRoots() {
// such that the static map range is restored (consult static-roots.h for a
// sorted list of addresses) or remove the offending entry from the list.
for (idx = RootIndex::kFirstRoot; idx <= RootIndex::kLastRoot; ++idx) {
+#if V8_ENABLE_WEBASSEMBLY
+ // WasmNull is entirely inaccessible, we cannot loads its instance type.
+ if (idx == RootIndex::kWasmNull) continue;
+#endif // V8_ENABLE_WEBASSEMBLY
Tagged<Object> obj = roots_table().slot(idx).load(this);
if (obj.ptr() == kNullAddress || !IsMap(obj)) continue;
Tagged<Map> map = Cast<Map>(obj);
@@ -6621,8 +6634,8 @@ bool Isolate::Init(SnapshotData* startup_snapshot_data,
#if V8_STATIC_ROOTS_BOOL
// Protect the payload of wasm null.
if (!page_allocator()->DecommitPages(
- reinterpret_cast<void*>(factory()->wasm_null()->payload()),
- WasmNull::kPayloadSize)) {
+ reinterpret_cast<void*>(factory()->wasm_null()->address()),
+ WasmNull::kSize)) {
V8::FatalProcessOutOfMemory(this, "decommitting WasmNull payload");
}
#endif // V8_STATIC_ROOTS_BOOL
@@ -6833,6 +6846,7 @@ void Isolate::DumpAndResetStats() {
void Isolate::DumpAndResetBuiltinsProfileData() {
if (BasicBlockProfiler::Get()->HasData(this)) {
+#ifndef V8_FUZZILLI
if (v8_flags.turbo_profiling_output) {
FILE* f = std::fopen(v8_flags.turbo_profiling_output, "w");
if (f == nullptr) {
@@ -6845,6 +6859,7 @@ void Isolate::DumpAndResetBuiltinsProfileData() {
StdoutStream out;
BasicBlockProfiler::Get()->Print(this, out);
}
+#endif // !V8_FUZZILLI
BasicBlockProfiler::Get()->ResetCounts(this);
}
}
@@ -7688,10 +7703,17 @@ void Isolate::SetReleaseCppHeapCallback(
void Isolate::RunReleaseCppHeapCallback(std::unique_ptr<v8::CppHeap> cpp_heap) {
if (release_cpp_heap_callback_) {
+ // Invalidate the isolate alive token, as the CppHeap will continue to exist
+ // after the isolate is destroyed.
+ CppHeap::From(cpp_heap.get())->invalidate_isolate_alive_token();
release_cpp_heap_callback_(std::move(cpp_heap));
}
}
+std::shared_ptr<bool> Isolate::cpp_heap_isolate_alive_token() const {
+ return CppHeap::From(heap_.cpp_heap())->isolate_alive_token();
+}
+
void Isolate::SetPromiseHook(PromiseHook hook) {
promise_hook_ = hook;
PromiseHookStateUpdated();
diff --git a/deps/v8/src/execution/isolate.h b/deps/v8/src/execution/isolate.h
index 9c5cc6b63b4..fab13a6a35b 100644
--- a/deps/v8/src/execution/isolate.h
+++ b/deps/v8/src/execution/isolate.h
@@ -759,6 +759,12 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
return &boilerplate_migration_access_;
}
+#if V8_ENABLE_WEBASSEMBLY
+ base::Mutex* wasm_shared_canonical_types_mutex() {
+ return &wasm_shared_canonical_types_mutex_;
+ }
+#endif
+
ReadOnlyArtifacts* read_only_artifacts() const {
ReadOnlyArtifacts* artifacts = isolate_group()->read_only_artifacts();
DCHECK_NOT_NULL(artifacts);
@@ -877,6 +883,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
inline bool is_catchable_by_javascript(Tagged<Object> exception);
inline bool is_catchable_by_wasm(Tagged<Object> exception);
inline bool is_execution_terminating();
+ inline bool is_javascript_execution_allowed() const;
// JS execution stack (see frames.h).
static Address c_entry_fp(ThreadLocalTop* thread) {
@@ -1072,7 +1079,6 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void OnPromiseAfter(DirectHandle<JSPromise> promise);
void OnStackTraceCaptured(DirectHandle<StackTraceInfo> stack_trace);
void OnTerminationDuringRunMicrotasks();
-#ifdef V8_CPPGC_MICROTASK_QUEUE
// Remove dead microtask queues from the list.
void CompactMicrotaskQueues();
void RegisterMicrotaskQueue(MicrotaskQueue* queue);
@@ -1081,7 +1087,6 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
const {
return microtask_queues_;
}
-#endif // V8_CPPGC_MICROTASK_QUEUE
// Re-throw an exception. This involves no error reporting since error
// reporting was handled when the exception was thrown originally.
@@ -1157,6 +1162,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void RegisterTryCatchHandler(v8::TryCatch* that);
void UnregisterTryCatchHandler(v8::TryCatch* that);
+ static void MarkTryCatchInternal(v8::TryCatch* that);
+ static bool IsInternalTryCatch(v8::TryCatch* that);
char* ArchiveThread(char* to);
char* RestoreThread(char* from);
@@ -1935,6 +1942,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
void SetReleaseCppHeapCallback(v8::Isolate::ReleaseCppHeapCallback callback);
void RunReleaseCppHeapCallback(std::unique_ptr<v8::CppHeap> cpp_heap);
+ std::shared_ptr<bool> cpp_heap_isolate_alive_token() const;
void SetPromiseHook(PromiseHook hook);
void RunPromiseHook(PromiseHookType type, DirectHandle<JSPromise> promise,
@@ -2432,7 +2440,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
SimulatorData* simulator_data() { return simulator_data_; }
#endif
-#ifdef V8_ENABLE_WEBASSEMBLY
+#if V8_ENABLE_WEBASSEMBLY
bool IsOnCentralStack();
std::vector<std::unique_ptr<wasm::StackMemory>>& wasm_stacks() {
return wasm_stacks_;
@@ -2833,14 +2841,10 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
#undef ISOLATE_FIELD_OFFSET
#endif
-#ifdef V8_CPPGC_MICROTASK_QUEUE
cppgc::Persistent<MicrotaskQueue> default_microtask_queue_;
// This list is used for visiting Microtask objects within live
// microtask queues during atomic pause.
std::vector<cppgc::WeakPersistent<MicrotaskQueue>> microtask_queues_;
-#else
- MicrotaskQueue* default_microtask_queue_ = nullptr;
-#endif // V8_CPPGC_MICROTASK_QUEUE
bool detailed_source_positions_for_profiling_;
bool preprocessing_exception_ = false;
@@ -3007,7 +3011,8 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
// Stack size set with ResourceConstraints or Isolate::SetStackLimit, in
// bytes. This is initialized with value of --stack-size.
size_t stack_size_;
-#ifdef V8_ENABLE_WEBASSEMBLY
+#if V8_ENABLE_WEBASSEMBLY
+ base::Mutex wasm_shared_canonical_types_mutex_;
wasm::WasmCodeLookupCache* wasm_code_look_up_cache_ = nullptr;
std::vector<std::unique_ptr<wasm::StackMemory>> wasm_stacks_;
#if V8_ENABLE_DRUMBRAKE
@@ -3015,7 +3020,7 @@ class V8_EXPORT_PRIVATE Isolate final : private HiddenFactory {
#endif // V8_ENABLE_DRUMBRAKE
wasm::WasmOrphanedGlobalHandle* wasm_orphaned_handle_ = nullptr;
wasm::StackPool stack_pool_;
-#endif
+#endif // V8_ENABLE_WEBASSEMBLY
// Enables the host application to provide a mechanism for recording a
// predefined set of data as crash keys to be used in postmortem debugging
@@ -3168,9 +3173,14 @@ class StackLimitCheck {
#endif
// Use this to check for interrupt request in C++ code.
- V8_INLINE bool InterruptRequested() {
+ V8_INLINE bool InterruptRequested(
+ StackGuard::InterruptLevel level =
+ StackGuard::InterruptLevel::kAnyEffect) {
StackGuard* stack_guard = isolate_->stack_guard();
- return GetCurrentStackPosition() < stack_guard->climit();
+ if (level == StackGuard::InterruptLevel::kAnyEffect) {
+ return GetCurrentStackPosition() < stack_guard->climit();
+ }
+ return stack_guard->CheckInterrupt(StackGuard::InterruptLevelMask(level));
}
// Precondition: InterruptRequested == true.
diff --git a/deps/v8/src/execution/microtask-queue.cc b/deps/v8/src/execution/microtask-queue.cc
index db261fc8792..10bbafe749d 100644
--- a/deps/v8/src/execution/microtask-queue.cc
+++ b/deps/v8/src/execution/microtask-queue.cc
@@ -4,21 +4,19 @@
#include "src/execution/microtask-queue.h"
-#ifdef V8_CPPGC_MICROTASK_QUEUE
-#include "include/cppgc/allocation.h"
-#include "include/cppgc/visitor.h"
-#include "include/v8-cppgc.h"
-#endif // V8_CPPGC_MICROTASK_QUEUE
-
#include <algorithm>
#include <cstddef>
#include <optional>
+#include "include/cppgc/allocation.h"
+#include "include/cppgc/visitor.h"
+#include "include/v8-cppgc.h"
#include "src/api/api-inl.h"
#include "src/base/logging.h"
-#include "src/execution/isolate.h"
+#include "src/execution/isolate-inl.h"
#include "src/handles/handle-scope-implementer-inl.h"
#include "src/handles/handles-inl.h"
+#include "src/heap/heap-inl.h"
#include "src/objects/microtask-inl.h"
#include "src/objects/visitors.h"
#include "src/roots/roots-inl.h"
@@ -42,22 +40,15 @@ const intptr_t MicrotaskQueue::kMinimumCapacity = 8;
void MicrotaskQueue::SetUpDefaultMicrotaskQueue(Isolate* isolate) {
DCHECK_NULL(isolate->default_microtask_queue());
-#ifdef V8_CPPGC_MICROTASK_QUEUE
cppgc::AllocationHandle& handle =
isolate->heap()->cpp_heap()->GetAllocationHandle();
MicrotaskQueue* microtask_queue =
cppgc::MakeGarbageCollected<MicrotaskQueue>(handle);
isolate->RegisterMicrotaskQueue(microtask_queue);
-#else
- MicrotaskQueue* microtask_queue = new MicrotaskQueue;
- microtask_queue->next_ = microtask_queue;
- microtask_queue->prev_ = microtask_queue;
-#endif // V8_CPPGC_MICROTASK_QUEUE
isolate->set_default_microtask_queue(microtask_queue);
}
// static
-#ifdef V8_CPPGC_MICROTASK_QUEUE
MicrotaskQueue* MicrotaskQueue::New(Isolate* isolate) {
DCHECK_NOT_NULL(isolate->default_microtask_queue());
@@ -70,41 +61,16 @@ MicrotaskQueue* MicrotaskQueue::New(Isolate* isolate) {
return microtask_queue;
}
-#else
-std::unique_ptr<MicrotaskQueue> MicrotaskQueue::New(Isolate* isolate) {
- DCHECK_NOT_NULL(isolate->default_microtask_queue());
-
- std::unique_ptr<MicrotaskQueue> microtask_queue(new MicrotaskQueue);
-
- // Insert the new instance to the next of last MicrotaskQueue instance.
- MicrotaskQueue* last = isolate->default_microtask_queue()->prev_;
- microtask_queue->next_ = last->next_;
- microtask_queue->prev_ = last;
- last->next_->prev_ = microtask_queue.get();
- last->next_ = microtask_queue.get();
-
- return microtask_queue;
-}
-#endif // V8_CPPGC_MICROTASK_QUEUE
MicrotaskQueue::MicrotaskQueue() = default;
MicrotaskQueue::~MicrotaskQueue() {
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- if (next_ != this) {
- DCHECK_NE(prev_, this);
- next_->prev_ = prev_;
- prev_->next_ = next_;
- }
-#endif // V8_CPPGC_MICROTASK_QUEUE
delete[] ring_buffer_;
}
-#ifdef V8_CPPGC_MICROTASK_QUEUE
void MicrotaskQueue::Trace(cppgc::Visitor* visitor) const {
v8::MicrotaskQueue::Trace(visitor);
}
-#endif // V8_CPPGC_MICROTASK_QUEUE
// static
Address MicrotaskQueue::CallEnqueueMicrotask(Isolate* isolate,
@@ -163,8 +129,27 @@ void MicrotaskQueue::EnqueueMicrotask(Tagged<Microtask> microtask) {
++size_;
}
+bool MicrotaskQueue::ShouldPerformCheckpoint(v8::Isolate* v8_isolate) const {
+ Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
+ return !IsRunningMicrotasks() && !GetMicrotasksScopeDepth() &&
+ !HasMicrotasksSuppressions() &&
+ isolate->is_javascript_execution_allowed();
+}
+
void MicrotaskQueue::PerformCheckpointInternal(v8::Isolate* v8_isolate) {
- DCHECK(ShouldPerfomCheckpoint());
+ DCHECK(ShouldPerformCheckpoint(v8_isolate));
+ DCHECK(!microtasks_completed_callbacks_cow_.has_value());
+ Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
+ // Fast path: Checkpoints occur frequently when exiting script or microtask
+ // scopes. If there are no microtasks to drain, no completion callbacks to
+ // notify, and no kept objects from FinalizationRegistry / WeakRefs to clear,
+ // we can bail out immediately and avoid artificial MicrotasksScope setup and
+ // RunMicrotasks overhead.
+ if (size() == 0 && microtasks_completed_callbacks_.empty() &&
+ isolate->heap()->weak_refs_keep_during_job() ==
+ ReadOnlyRoots(isolate).undefined_value()) [[likely]] {
+ return;
+ }
std::optional<MicrotasksScope> microtasks_scope;
if (microtasks_policy_ == v8::MicrotasksPolicy::kScoped) {
// If we're using microtask scopes to schedule microtask execution, V8
@@ -175,7 +160,6 @@ void MicrotaskQueue::PerformCheckpointInternal(v8::Isolate* v8_isolate) {
microtasks_scope.emplace(v8_isolate, this,
v8::MicrotasksScope::kDoNotRunMicrotasks);
}
- Isolate* isolate = reinterpret_cast<Isolate*>(v8_isolate);
RunMicrotasks(isolate);
isolate->ClearKeptObjects();
}
@@ -213,6 +197,7 @@ int MicrotaskQueue::RunMicrotasks(Isolate* isolate) {
// We should not enter V8 if it's marked for termination.
DCHECK_IMPLIES(v8_flags.strict_termination_checks,
!isolate->is_execution_terminating());
+ DCHECK(isolate->is_javascript_execution_allowed());
intptr_t base_count = finished_microtask_count_;
HandleScope handle_scope(isolate);
@@ -347,12 +332,18 @@ void MicrotaskQueue::RemoveMicrotasksCompletedCallback(
}
void MicrotaskQueue::OnCompleted(Isolate* isolate) {
+ DCHECK_IMPLIES(microtasks_completed_callbacks_.empty(),
+ !microtasks_completed_callbacks_cow_.has_value());
+ if (microtasks_completed_callbacks_.empty()) [[likely]] {
+ return;
+ }
+
is_running_completed_callbacks_ = true;
for (auto& callback : microtasks_completed_callbacks_) {
callback.first(reinterpret_cast<v8::Isolate*>(isolate), callback.second);
}
is_running_completed_callbacks_ = false;
- if (V8_UNLIKELY(microtasks_completed_callbacks_cow_.has_value())) {
+ if (microtasks_completed_callbacks_cow_.has_value()) [[unlikely]] {
microtasks_completed_callbacks_ =
std::move(microtasks_completed_callbacks_cow_.value());
microtasks_completed_callbacks_cow_.reset();
diff --git a/deps/v8/src/execution/microtask-queue.h b/deps/v8/src/execution/microtask-queue.h
index ef643a9a3c6..f13c994fc27 100644
--- a/deps/v8/src/execution/microtask-queue.h
+++ b/deps/v8/src/execution/microtask-queue.h
@@ -7,18 +7,15 @@
#include <stdint.h>
-#include <memory>
#include <vector>
#include "include/v8-internal.h" // For Address.
#include "include/v8-microtask-queue.h"
#include "src/base/macros.h"
-#ifdef V8_CPPGC_MICROTASK_QUEUE
namespace cppgc {
class Visitor;
} // namespace cppgc
-#endif // V8_CPPGC_MICROTASK_QUEUE
namespace v8 {
namespace internal {
@@ -33,19 +30,13 @@ class Tagged;
class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
public:
static void SetUpDefaultMicrotaskQueue(Isolate* isolate);
-#ifdef V8_CPPGC_MICROTASK_QUEUE
static MicrotaskQueue* New(Isolate* isolate);
-#else
- static std::unique_ptr<MicrotaskQueue> New(Isolate* isolate);
-#endif // V8_CPPGC_MICROTASK_QUEUE
~MicrotaskQueue() override;
-#ifdef V8_CPPGC_MICROTASK_QUEUE
MicrotaskQueue();
void Trace(cppgc::Visitor* visitor) const override;
const char* GetHumanReadableName() const override { return "MicrotaskQueue"; }
-#endif // V8_CPPGC_MICROTASK_QUEUE
// Uses raw Address values because it's called via ExternalReference.
// {raw_microtask} is a tagged Microtask pointer.
@@ -63,14 +54,11 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
v8::MicrotaskCallbackWithData callback,
v8::Local<v8::Data> data) override;
void PerformCheckpoint(v8::Isolate* isolate) override {
- if (!ShouldPerfomCheckpoint()) return;
+ if (!ShouldPerformCheckpoint(isolate)) return;
PerformCheckpointInternal(isolate);
}
- bool ShouldPerfomCheckpoint() const {
- return !IsRunningMicrotasks() && !GetMicrotasksScopeDepth() &&
- !HasMicrotasksSuppressions();
- }
+ bool ShouldPerformCheckpoint(v8::Isolate* isolate) const;
void EnqueueMicrotask(Tagged<Microtask> microtask);
void AddMicrotasksCompletedCallback(
@@ -126,11 +114,6 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
Tagged<Microtask> get(intptr_t index) const;
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- MicrotaskQueue* next() const { return next_; }
- MicrotaskQueue* prev() const { return prev_; }
-#endif // V8_CPPGC_MICROTASK_QUEUE
-
static const size_t kRingBufferOffset;
static const size_t kCapacityOffset;
static const size_t kSizeOffset;
@@ -144,9 +127,6 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
void OnCompleted(Isolate* isolate);
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- MicrotaskQueue();
-#endif // V8_CPPGC_MICROTASK_QUEUE
void ResizeBuffer(intptr_t new_capacity);
// A ring buffer to hold Microtask instances.
@@ -160,11 +140,6 @@ class V8_EXPORT_PRIVATE MicrotaskQueue final : public v8::MicrotaskQueue {
// The number of finished microtask.
intptr_t finished_microtask_count_ = 0;
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- MicrotaskQueue* next_ = nullptr;
- MicrotaskQueue* prev_ = nullptr;
-#endif // V8_CPPGC_MICROTASK_QUEUE
-
int microtasks_depth_ = 0;
int microtasks_suppressions_ = 0;
#ifdef DEBUG
diff --git a/deps/v8/src/execution/riscv/simulator-riscv.cc b/deps/v8/src/execution/riscv/simulator-riscv.cc
index e4e32b5d524..2604e508b92 100644
--- a/deps/v8/src/execution/riscv/simulator-riscv.cc
+++ b/deps/v8/src/execution/riscv/simulator-riscv.cc
@@ -2814,8 +2814,7 @@ bool Simulator::test_fflags_bits(uint32_t mask) {
template <typename T>
T Simulator::FMaxMinHelper(T a, T b, MaxMinKind kind) {
// set invalid bit for signaling nan
- if ((a == std::numeric_limits<T>::signaling_NaN()) ||
- (b == std::numeric_limits<T>::signaling_NaN())) {
+ if ((std::isnan(a) || std::isnan(b)) && (isSnan(a) || isSnan(b))) {
set_csr_bits(csr_fflags, kInvalidOperation);
}
@@ -4177,9 +4176,9 @@ struct ScopedRoundingMode {
case RTZ:
return FE_TOWARDZERO;
case RDN:
- return FE_UPWARD;
- case RUP:
return FE_DOWNWARD;
+ case RUP:
+ return FE_UPWARD;
case RMM:
return FE_TONEAREST;
default:
@@ -4383,22 +4382,20 @@ bool Simulator::CompareFHelper(T input1, T input2, FPUCondition cc) {
break;
case EQ:
- if (std::numeric_limits<T>::signaling_NaN() == input1 ||
- std::numeric_limits<T>::signaling_NaN() == input2) {
- set_fflags(kInvalidOperation);
- }
if (std::isnan(input1) || std::isnan(input2)) {
+ if (isSnan(input1) || isSnan(input2)) {
+ set_fflags(kInvalidOperation);
+ }
result = false;
} else {
result = (input1 == input2);
}
break;
case NE:
- if (std::numeric_limits<T>::signaling_NaN() == input1 ||
- std::numeric_limits<T>::signaling_NaN() == input2) {
- set_fflags(kInvalidOperation);
- }
if (std::isnan(input1) || std::isnan(input2)) {
+ if (isSnan(input1) || isSnan(input2)) {
+ set_fflags(kInvalidOperation);
+ }
result = true;
} else {
result = (input1 != input2);
@@ -4438,9 +4435,10 @@ static inline bool is_invalid_fsqrt(T src1) {
return (src1 < 0);
}
-template <typename T, typename OP>
+template <typename T, typename OP, typename FormatResult>
void Simulator::AtomicMemoryHelper(sreg_t rs1, T value, OP f,
- Instruction* instr) {
+ Instruction* instr,
+ FormatResult format_result) {
unsigned element_size = sizeof(T);
uintptr_t address = rs1;
DCHECK_EQ(address % element_size, 0);
@@ -4468,10 +4466,11 @@ void Simulator::AtomicMemoryHelper(sreg_t rs1, T value, OP f,
}
WriteMem<T>(address, result, instr);
- set_rd(T(data));
+ set_rd(format_result(data));
}
void Simulator::DecodeRVRAType() {
+ auto format_word_result = [](auto result) { return sext32(result); };
// TODO(riscv): Add macro for RISCV A extension
// Special handling for A extension instructions because it uses func5
// For all A extension instruction, V8 simulator is pure sequential. No
@@ -4518,7 +4517,8 @@ void Simulator::DecodeRVRAType() {
}
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)rs2(),
- [&](uint32_t lhs, uint32_t rhs) { return rhs; }, instr_.instr());
+ [&](uint32_t lhs, uint32_t rhs) { return rhs; }, instr_.instr(),
+ format_word_result);
break;
}
case RO_AMOADD_W: {
@@ -4527,8 +4527,8 @@ void Simulator::DecodeRVRAType() {
}
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)(rs2()),
- [&](uint32_t lhs, uint32_t rhs) { return lhs + rhs; },
- instr_.instr());
+ [&](uint32_t lhs, uint32_t rhs) { return lhs + rhs; }, instr_.instr(),
+ format_word_result);
break;
}
case RO_AMOXOR_W: {
@@ -4537,8 +4537,8 @@ void Simulator::DecodeRVRAType() {
}
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)rs2(),
- [&](uint32_t lhs, uint32_t rhs) { return lhs ^ rhs; },
- instr_.instr());
+ [&](uint32_t lhs, uint32_t rhs) { return lhs ^ rhs; }, instr_.instr(),
+ format_word_result);
break;
}
case RO_AMOAND_W: {
@@ -4547,8 +4547,8 @@ void Simulator::DecodeRVRAType() {
}
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)rs2(),
- [&](uint32_t lhs, uint32_t rhs) { return lhs & rhs; },
- instr_.instr());
+ [&](uint32_t lhs, uint32_t rhs) { return lhs & rhs; }, instr_.instr(),
+ format_word_result);
break;
}
case RO_AMOOR_W: {
@@ -4557,8 +4557,8 @@ void Simulator::DecodeRVRAType() {
}
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)rs2(),
- [&](uint32_t lhs, uint32_t rhs) { return lhs | rhs; },
- instr_.instr());
+ [&](uint32_t lhs, uint32_t rhs) { return lhs | rhs; }, instr_.instr(),
+ format_word_result);
break;
}
case RO_AMOMIN_W: {
@@ -4568,7 +4568,7 @@ void Simulator::DecodeRVRAType() {
AtomicMemoryHelper<int32_t>(
rs1(), (int32_t)rs2(),
[&](int32_t lhs, int32_t rhs) { return std::min(lhs, rhs); },
- instr_.instr());
+ instr_.instr(), format_word_result);
break;
}
case RO_AMOMAX_W: {
@@ -4578,7 +4578,7 @@ void Simulator::DecodeRVRAType() {
AtomicMemoryHelper<int32_t>(
rs1(), (int32_t)rs2(),
[&](int32_t lhs, int32_t rhs) { return std::max(lhs, rhs); },
- instr_.instr());
+ instr_.instr(), format_word_result);
break;
}
case RO_AMOMINU_W: {
@@ -4588,7 +4588,7 @@ void Simulator::DecodeRVRAType() {
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)rs2(),
[&](uint32_t lhs, uint32_t rhs) { return std::min(lhs, rhs); },
- instr_.instr());
+ instr_.instr(), format_word_result);
break;
}
case RO_AMOMAXU_W: {
@@ -4598,7 +4598,7 @@ void Simulator::DecodeRVRAType() {
AtomicMemoryHelper<uint32_t>(
rs1(), (uint32_t)rs2(),
[&](uint32_t lhs, uint32_t rhs) { return std::max(lhs, rhs); },
- instr_.instr());
+ instr_.instr(), format_word_result);
break;
}
#ifdef V8_TARGET_ARCH_RISCV64
@@ -6533,6 +6533,9 @@ void Simulator::DecodeCAType() {
case RO_C_AND:
set_rvc_rs1s(rvc_rs1s() & rvc_rs2s());
break;
+ case RO_C_MUL:
+ set_rvc_rs1s(sext_xlen(rvc_rs1s() * rvc_rs2s()));
+ break;
#if V8_TARGET_ARCH_RISCV64
case RO_C_SUBW:
set_rvc_rs1s(sext32(rvc_rs1s() - rvc_rs2s()));
@@ -6710,6 +6713,35 @@ void Simulator::DecodeCLType() {
break;
}
#endif
+ case RO_C_LBU: { // Zcb loads, all sharing funct3=100.
+ switch (instr_.InstructionBits() & kRvcFunct6Mask) {
+ case RO_C_LHU: {
+ sreg_t addr = rvc_rs1s() + (instr_.Bit(5) << 1);
+ if (!ProbeMemory(addr, sizeof(int16_t))) return;
+ if (instr_.Bit(6)) { // c.lh
+ int16_t val = ReadMem<int16_t>(addr, instr_.instr());
+ set_rvc_rs2s(sext_xlen(val), false);
+ TraceMemRd(addr, val, get_register(rvc_rs2s_reg()));
+ } else { // c.lhu
+ uint16_t val = ReadMem<uint16_t>(addr, instr_.instr());
+ set_rvc_rs2s(zext_xlen(val), false);
+ TraceMemRd(addr, val, get_register(rvc_rs2s_reg()));
+ }
+ break;
+ }
+ case RO_C_LBU: { // c.lbu
+ sreg_t addr = rvc_rs1s() + (instr_.Bit(5) << 1) + instr_.Bit(6);
+ if (!ProbeMemory(addr, sizeof(int8_t))) return;
+ uint8_t val = ReadMem<uint8_t>(addr, instr_.instr());
+ set_rvc_rs2s(zext_xlen(val), false);
+ TraceMemRd(addr, val, get_register(rvc_rs2s_reg()));
+ break;
+ }
+ default:
+ UNSUPPORTED();
+ }
+ break;
+ }
default:
UNSUPPORTED();
}
@@ -6737,6 +6769,28 @@ void Simulator::DecodeCSType() {
WriteMem<double>(addr, static_cast<double>(rvc_drs2s()), instr_.instr());
break;
}
+ case RO_C_LBU: { // Zcb stores, all sharing funct3=100.
+ // c.sb: bits[12:10]=010; c.sh: bits[12:10]=011.
+ switch (instr_.InstructionBits() & kRvcFunct6Mask) {
+ case RO_C_SB: { // c.sb
+ sreg_t addr = rvc_rs1s() + (instr_.Bit(5) << 1) + instr_.Bit(6);
+ if (!ProbeMemory(addr, sizeof(int8_t))) return;
+ WriteMem<uint8_t>(addr, static_cast<uint8_t>(rvc_rs2s()),
+ instr_.instr());
+ break;
+ }
+ case RO_C_SH: { // c.sh
+ sreg_t addr = rvc_rs1s() + (instr_.Bit(5) << 1);
+ if (!ProbeMemory(addr, sizeof(int16_t))) return;
+ WriteMem<uint16_t>(addr, static_cast<uint16_t>(rvc_rs2s()),
+ instr_.instr());
+ break;
+ }
+ default:
+ UNSUPPORTED();
+ }
+ break;
+ }
default:
UNSUPPORTED();
}
@@ -6777,6 +6831,32 @@ void Simulator::DecodeCBType() {
set_rvc_rs1s(sext_xlen(sext_xlen(rvc_rs1s()) >> rvc_shamt6()));
} else if (instr_.RvcFunct2BValue() == 0b10) { // c.andi
set_rvc_rs1s(rvc_imm6() & rvc_rs1s());
+ } else if (instr_.RvcFunct2BValue() == 0b11) {
+ // Zcb unary instructions (CU format), distinguished by nzuimm[5:0].
+ switch (instr_.RvcImm6Value() & 0b111111) {
+ case 0b111000: // c.zext.b
+ set_rvc_rs1s(rvc_rs1s() & 0xff);
+ break;
+ case 0b111001: // c.sext.b
+ set_rvc_rs1s(sext_xlen(static_cast<int8_t>(rvc_rs1s())));
+ break;
+ case 0b111010: // c.zext.h
+ set_rvc_rs1s(rvc_rs1s() & 0xffff);
+ break;
+ case 0b111011: // c.sext.h
+ set_rvc_rs1s(sext_xlen(static_cast<int16_t>(rvc_rs1s())));
+ break;
+#ifdef V8_TARGET_ARCH_RISCV64
+ case 0b111100: // c.zext.w
+ set_rvc_rs1s(rvc_rs1s() & 0xffffffff);
+ break;
+#endif
+ case 0b111101: // c.not
+ set_rvc_rs1s(~rvc_rs1s());
+ break;
+ default:
+ UNSUPPORTED();
+ }
} else {
UNSUPPORTED();
}
diff --git a/deps/v8/src/execution/riscv/simulator-riscv.h b/deps/v8/src/execution/riscv/simulator-riscv.h
index add8f467e41..879b447341f 100644
--- a/deps/v8/src/execution/riscv/simulator-riscv.h
+++ b/deps/v8/src/execution/riscv/simulator-riscv.h
@@ -50,6 +50,8 @@
#define V8_EXECUTION_RISCV_SIMULATOR_RISCV_H_
// globals.h defines USE_SIMULATOR.
+#include <functional>
+
#include "src/base/float16.h"
#include "src/common/globals.h"
@@ -709,8 +711,9 @@ class Simulator : public SimulatorBase {
// WORD_DWORD
};
- template <typename T, typename OP>
- void AtomicMemoryHelper(sreg_t rs1, T value, OP f, Instruction* instr);
+ template <typename T, typename OP, typename FormatResult = std::identity>
+ void AtomicMemoryHelper(sreg_t rs1, T value, OP f, Instruction* instr,
+ FormatResult format_result = {});
void CheckMemoryAccess(uintptr_t address, uintptr_t stack);
// "Probe" if an address range can be read. This is currently implemented
diff --git a/deps/v8/src/execution/tiering-manager.cc b/deps/v8/src/execution/tiering-manager.cc
index 6755cb14137..655895570f9 100644
--- a/deps/v8/src/execution/tiering-manager.cc
+++ b/deps/v8/src/execution/tiering-manager.cc
@@ -181,17 +181,34 @@ int InterruptBudgetFor(Isolate* isolate, std::optional<CodeKind> code_kind,
Tagged<JSFunction> function,
CachedTieringDecision cached_tiering_decision,
int bytecode_length) {
- // Avoid interrupts while we're already tiering.
- if (function->tiering_in_progress()) return INT_MAX / 2;
-
const std::optional<CodeKind> existing_request =
function->GetRequestedOptimizationIfAny(isolate);
- if (existing_request == CodeKind::TURBOFAN_JS ||
- (code_kind.has_value() && code_kind.value() == CodeKind::TURBOFAN_JS)) {
- return v8_flags.invocation_count_for_osr * bytecode_length;
+
+ bool maybe_ml_osr =
+ maglev::IsMaglevOsrEnabled() && existing_request == CodeKind::MAGLEV;
+ bool maybe_tf_osr =
+ v8_flags.use_osr &&
+ (existing_request == CodeKind::TURBOFAN_JS ||
+ (code_kind.has_value() && code_kind.value() == CodeKind::TURBOFAN_JS));
+ bool tiering_in_progress = function->tiering_in_progress();
+ bool osr_tiering_in_progress = function->osr_tiering_in_progress();
+
+ // Avoid interrupts while we're already tiering.
+ if (tiering_in_progress && !osr_tiering_in_progress) {
+ return INT_MAX / 2;
+ }
+
+ // Stretch loop interrupts while tiering is already in progress.
+ double osr_factor =
+ osr_tiering_in_progress
+ ? 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;
}
- if (maglev::IsMaglevOsrEnabled() && existing_request == CodeKind::MAGLEV) {
- return v8_flags.invocation_count_for_maglev_osr * bytecode_length;
+ if (maybe_ml_osr) {
+ return osr_factor * v8_flags.invocation_count_for_maglev_osr *
+ bytecode_length;
}
if (TiersUpToMaglev(code_kind) &&
diff --git a/deps/v8/src/extensions/statistics-extension.cc b/deps/v8/src/extensions/statistics-extension.cc
index b4fa9db47ec..5f3c8c687cb 100644
--- a/deps/v8/src/extensions/statistics-extension.cc
+++ b/deps/v8/src/extensions/statistics-extension.cc
@@ -40,7 +40,7 @@ static void AddCounter(v8::Isolate* isolate,
v8::Local<v8::Number> value =
v8::Number::New(isolate, *counter->GetInternalPointer());
// Ignore failure due to throwing setters.
- std::ignore = object->Set(context, key, value);
+ std::ignore = object->CreateDataProperty(context, key, value);
}
}
@@ -51,7 +51,7 @@ static void AddNumber(v8::Isolate* isolate, v8::Local<v8::Object> object,
v8::String::NewFromUtf8(isolate, name).ToLocalChecked();
v8::Local<v8::Number> val = v8::Number::New(isolate, value);
// Ignore failure due to throwing setters.
- std::ignore = object->Set(context, key, val);
+ std::ignore = object->CreateDataProperty(context, key, val);
}
@@ -65,7 +65,7 @@ static void AddNumber64(v8::Isolate* isolate,
v8::Local<v8::Number> val =
v8::Number::New(isolate, static_cast<double>(value));
// Ignore failure due to throwing setters.
- std::ignore = object->Set(context, key, val);
+ std::ignore = object->CreateDataProperty(context, key, val);
}
void StatisticsExtension::GetCounters(
diff --git a/deps/v8/src/flags/feature-flags.h b/deps/v8/src/flags/feature-flags.h
new file mode 100644
index 00000000000..18de3b8280e
--- /dev/null
+++ b/deps/v8/src/flags/feature-flags.h
@@ -0,0 +1,232 @@
+// 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_FLAGS_FEATURE_FLAGS_H_
+#define V8_FLAGS_FEATURE_FLAGS_H_
+
+// Any V8 feature or large scale change that follows the launch process should
+// be tracked here for transparency. This ensures that the requirements for
+// each step of the process are met, e.g. enabling it for fuzzers, opening it
+// to the VRP, etc.
+
+// For each step of the shipping process, there is a dedicated section below
+// with a macro. The entries for each feature move from one macro to the next
+// as they go through the shipping process.
+
+// Each flag is defined by the following parameters:
+// 1. Type - either JS_FEATURE, WASM_FEATURE, or INTERNAL_FEATURE depending on
+// whether the feature is a TC39 proposal, a Wasm CG proposal or something
+// else (e.g. performance or internal feature).
+// 2. Name - the name of the feature which will be used as the flag name
+// WASM_FEATUREs will be prefixed with wasm_ in their flag name.
+// 3. Description - this serves as the help text for the feature flag.
+
+// Additionally, the feature should be annotated with a comment containing
+// 1. Its internal name (might be the same as above or different)
+// 2. A link to the proposal where applicable
+// 3. V8-side owner
+// 4. Information on Finch or origin trials, their status and links
+
+// Update bootstrapper.cc whenever adding a new JS/harmony feature flag.
+// The "harmony" naming is now outdated and will no longer be used for new JS
+// features.
+// TODO(v8:14214): Remove --harmony flags once transition is complete.
+
+// Features that should only be present when certain build flags are set need to
+// define their own conditional macro for that feature.
+#ifdef V8_INTL_SUPPORT
+#define IF_INTL_ENABLED(then, feature_name, description) \
+ then(feature_name, description)
+#else
+#define IF_INTL_ENABLED(then, feature_name, description)
+#endif
+
+#ifdef V8_ENABLE_WASM_SIMD256_REVEC
+#define IF_REVEC_ENABLED(then, feature_name, description) \
+ then(feature_name, description)
+#else
+#define IF_REVEC_ENABLED(then, feature_name, description)
+#endif // V8_ENABLE_WASM_SIMD256_REVEC
+
+#ifdef V8_ENABLE_SPARKPLUG_PLUS
+#define IF_SPARKPLUG_PLUS_ENABLED(then, feature_name, description) \
+ then(feature_name, description)
+#else
+#define IF_SPARKPLUG_PLUS_ENABLED(then, feature_name, description)
+// If the build flag is not defined, we add a read-only flag in
+// flag-definitions.h instead.
+#endif // V8_ENABLE_SPARKPLUG_PLUS
+
+// #############################################################################
+// Experimental features (disabled by default).
+// These features are still in active development and not stable enough for
+// fuzzing or developer testing yet.
+#define FOREACH_EXPERIMENTAL_FEATURE_FLAG(JS_FEATURE, WASM_FEATURE, \
+ INTERNAL_FEATURE) /* (80 columns) */ \
+ \
+ JS_FEATURE(harmony_shadow_realm, "harmony ShadowRealm") \
+ \
+ JS_FEATURE(harmony_struct, \
+ "harmony structs, shared structs, and shared arrays") \
+ \
+ IF_INTL_ENABLED(JS_FEATURE, harmony_intl_best_fit_matcher, \
+ "Intl BestFitMatcher") \
+ \
+ JS_FEATURE(js_decorators, "decorators") \
+ \
+ JS_FEATURE(js_source_phase_imports, "source phase imports") \
+ \
+ JS_FEATURE(js_regexp_buffer_boundaries, \
+ "RegExp \\A \\z \\Z buffer boundary assertions") \
+ \
+ IF_SPARKPLUG_PLUS_ENABLED(INTERNAL_FEATURE, sparkplug_inline_smi, \
+ "inline the Smi fast path of embedded feedback " \
+ "operations into JS baseline code") \
+ \
+ /* Instruction Tracing tool convention (early prototype, might change) */ \
+ /* Tool convention: https://github.com/WebAssembly/tool-conventions */ \
+ /* V8 side owner: jabraham */ \
+ WASM_FEATURE(instruction_tracing, "instruction tracing section") \
+ \
+ /* Shared-Everything Threads proposal. */ \
+ /* https://github.com/WebAssembly/shared-everything-threads */ \
+ /* V8 side owner: manoskouk */ \
+ WASM_FEATURE(shared, "shared-everything threads") \
+ \
+ /* FP16 proposal. */ \
+ /* https://github.com/WebAssembly/half-precision */ \
+ /* V8 side owner: dahlb */ \
+ WASM_FEATURE(fp16, "fp16") \
+ \
+ /* Memory Control proposal */ \
+ /* https://github.com/WebAssembly/memory-control */ \
+ /* V8 side owner: ahaas */ \
+ WASM_FEATURE(memory_control, "memory control") \
+ \
+ /* Core stack switching, main proposal */ \
+ /* https://github.com/WebAssembly/stack-switching */ \
+ /* V8 side owner: fgm, thibaudm */ \
+ WASM_FEATURE(wasmfx, "core stack switching") \
+ \
+ /* Compilation hints */ \
+ /* https://github.com/WebAssembly/compilation-hints */ \
+ /* V8 side owner: ecmziegler, manoskouk */ \
+ WASM_FEATURE(compilation_hints, "compilation hints") \
+ \
+ /* V8 side owner: thibaudm */ \
+ WASM_FEATURE(growable_stacks, "growable stacks for jspi") \
+ \
+ /* Compact Import Section proposal. */ \
+ /* https://github.com/WebAssembly/compact-import-section */ \
+ /* V8 side owner: ryandiaz */ \
+ WASM_FEATURE(compact_imports, "compact import section")
+
+// #############################################################################
+// Pre-staged features (disabled by default, but enabled via
+// --experimental-fuzzing).
+// Pre-staged features get limited fuzzer coverage, and should come with their
+// own tests. Features typically spend about 2-4 weeks in this stage before
+// being moved to the staging phase.
+#define FOREACH_PRE_STAGED_FEATURE_FLAG(JS_FEATURE, WASM_FEATURE, \
+ INTERNAL_FEATURE) /* (80 columns) */ \
+ \
+ /* Reference-Typed Strings Proposal. */ \
+ /* https://github.com/WebAssembly/stringref */ \
+ /* V8 side owner: jkummerow */ \
+ WASM_FEATURE(stringref, "reference-typed strings") \
+ \
+ /* Imported Strings TextEncoder/TextDecoder post-MVP extension. */ \
+ /* No upstream repo yet. */ \
+ /* 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 */ \
+ /* V8 side owner: rezvan */ \
+ WASM_FEATURE(acquire_release, "acquire_release memory ordering")
+
+// #############################################################################
+// Staged features (disabled by default, but enabled via --js-staging/--harmony,
+// --wasm-staging or --future).
+// Staged features get limited fuzzer coverage, and should come with their own
+// tests.
+// They might be enabled for an origin or Finch trial after some bake time
+// while remaining in this stage before moving to shipped.
+// They are not run through all fuzzers though and don't get much exposure in
+// the wild. Staged features are not necessarily fully stabilized. They should
+// be shipped with enough lead time to the next branch to allow for
+// stabilization.
+// Consider adding a chromium-side use counter if you want to track usage in
+// the wild (also see {V8::UseCounterFeature}).
+#define FOREACH_STAGED_FEATURE_FLAG(JS_FEATURE, WASM_FEATURE, \
+ INTERNAL_FEATURE) /* (80 columns) */ \
+ \
+ JS_FEATURE(js_immutable_arraybuffer, "Immutable ArrayBuffer") \
+ \
+ JS_FEATURE(js_import_bytes, "import bytes") \
+ \
+ JS_FEATURE(js_defer_import_eval, "defer import eval") \
+ \
+ /* Custom Descriptors proposal. */ \
+ /* https://github.com/WebAssembly/custom-descriptors */ \
+ /* Note: the JS Interop part of the proposal is enabled by */ \
+ /* --wasm-js-interop for now. */ \
+ /* V8 side owner: jkummerow */ \
+ /* Staged (without JS Interop) in v14.8 */ \
+ WASM_FEATURE(custom_descriptors, "custom descriptors") \
+ \
+ /* Wasm Re-vectorization (no proposal, engine optimization only). */ \
+ /* V8 side owner: jkummerow */ \
+ /* Staged in 15.4 */ \
+ IF_REVEC_ENABLED(INTERNAL_FEATURE, wasm_revectorize, \
+ "128 to 256 bit SIMD re-vectorization for Wasm")
+
+// #############################################################################
+// Shipped features (enabled by default).
+// The feature flag can be removed after it has been shipped on stable for a
+// sufficiently long time that an emergency deactivation option is not required
+// anymore. In some cases, features might stay on this list for longer if the
+// ability to deactivate them is still useful.
+#define FOREACH_SHIPPED_FEATURE_FLAG(JS_FEATURE, WASM_FEATURE, \
+ INTERNAL_FEATURE) /* (80 columns) */ \
+ \
+ JS_FEATURE(harmony_import_attributes, "harmony import attributes") \
+ \
+ JS_FEATURE(harmony_temporal, "Temporal") \
+ \
+ JS_FEATURE(js_esm_ns_reexport, \
+ "Support diamond-importing re-expored namespaces " \
+ "(https://github.com/tc39/ecma262/pull/3715)") \
+ \
+ JS_FEATURE(js_iterator_join, "Iterator.prototype.join") \
+ \
+ JS_FEATURE(js_iterator_sequencing, "iterator sequencing") \
+ \
+ JS_FEATURE(js_joint_iteration, "joint iteration") \
+ \
+ JS_FEATURE(js_pr_3883, \
+ "Promise.try not wrapping the result in an extra promise in the " \
+ "non-throwing case (https://github.com/tc39/ecma262/pull/3883)") \
+ \
+ JS_FEATURE(js_iterator_includes, "Iterator.prototype.includes") \
+ \
+ JS_FEATURE(js_import_text, "import text") \
+ \
+ /* Legacy exception handling proposal. */ \
+ /* https://github.com/WebAssembly/exception-handling */ \
+ /* V8 side owner: thibaudm */ \
+ /* Staged in v8.9 */ \
+ /* Shipped in v9.5 */ \
+ WASM_FEATURE(legacy_eh, "legacy exception handling opcodes") \
+ \
+ IF_SPARKPLUG_PLUS_ENABLED(INTERNAL_FEATURE, sparkplug_plus, \
+ "dynamic patching on JS baseline code")
+
+#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 8ab3f27af84..a64f1b5e7b3 100644
--- a/deps/v8/src/flags/flag-definitions.h
+++ b/deps/v8/src/flags/flag-definitions.h
@@ -100,6 +100,11 @@
TriggerImplication(v8_flags.flag < min_value, #flag "<" #min_value, \
&v8_flags.flag, #flag, min_value, false);
+#define DEFINE_MAX_VALUE_IMPLICATION(flag, max_value) \
+ changed |= \
+ TriggerImplication(v8_flags.flag > max_value, #max_value "<" #flag, \
+ &v8_flags.flag, #flag, max_value, false);
+
#define DEFINE_DISABLE_FLAG_IMPLICATION(whenflag, thenflag) \
if (whenflag && thenflag) { \
PrintF(stderr, "Warning: disabling flag --" #thenflag \
@@ -165,6 +170,10 @@
#define DEFINE_MIN_VALUE_IMPLICATION(flag, min_value)
#endif
+#ifndef DEFINE_MAX_VALUE_IMPLICATION
+#define DEFINE_MAX_VALUE_IMPLICATION(flag, max_value)
+#endif
+
#ifndef DEFINE_DISABLE_FLAG_IMPLICATION
#define DEFINE_DISABLE_FLAG_IMPLICATION(whenflag, thenflag)
#endif
@@ -312,127 +321,11 @@ DEFINE_BOOL(use_strict, false, "enforce strict mode")
DEFINE_DEVELOPER_FLAG(trace_temporal, "trace temporal code")
-DEFINE_BOOL(harmony, false, "enable all completed harmony features")
-DEFINE_BOOL(harmony_shipping, true, "enable all shipped harmony features")
-
-DEFINE_BOOL(js_staging, false, "enable all completed JavaScript features")
-DEFINE_BOOL(js_shipping, true, "enable all shipped JavaScript features")
-
-// Update bootstrapper.cc whenever adding a new feature flag.
-
-// Features that are still work in progress (behind individual flags).
-//
-// The "harmony" naming is now outdated and will no longer be used for new JS
-// features. Use the JAVASCRIPT macros instead.
-//
-// TODO(v8:14214): Remove --harmony flags once transition is complete.
-#define HARMONY_INPROGRESS_BASE(V) \
- V(harmony_shadow_realm, "harmony ShadowRealm") \
- V(harmony_struct, "harmony structs, shared structs, and shared arrays")
-
-#define JAVASCRIPT_INPROGRESS_FEATURES_BASE(V) \
- V(js_decorators, "decorators") \
- V(js_source_phase_imports, "source phase imports") \
- V(js_regexp_buffer_boundaries, \
- "RegExp \\A \\z \\Z buffer boundary assertions")
-
-#ifdef V8_INTL_SUPPORT
-#define HARMONY_INPROGRESS(V) \
- HARMONY_INPROGRESS_BASE(V) \
- V(harmony_intl_best_fit_matcher, "Intl BestFitMatcher")
-#define JAVASCRIPT_INPROGRESS_FEATURES(V) JAVASCRIPT_INPROGRESS_FEATURES_BASE(V)
-#else
-#define HARMONY_INPROGRESS(V) HARMONY_INPROGRESS_BASE(V)
-#define JAVASCRIPT_INPROGRESS_FEATURES(V) JAVASCRIPT_INPROGRESS_FEATURES_BASE(V)
-#endif
-
-// Features that are complete (but still behind the --harmony flag).
-#define HARMONY_STAGED_BASE(V)
-
-#define JAVASCRIPT_STAGED_FEATURES_BASE(V) \
- V(js_iterator_join, "Iterator.prototype.join") \
- V(js_immutable_arraybuffer, "Immutable ArrayBuffer") \
- V(js_joint_iteration, "joint iteration") \
- V(js_import_text, "import text") \
- V(js_import_bytes, "import bytes") \
- V(js_defer_import_eval, "defer import eval") \
- V(js_iterator_includes, "Iterator.prototype.includes")
-
-#ifdef V8_INTL_SUPPORT
-#define HARMONY_STAGED(V) HARMONY_STAGED_BASE(V)
-#define JAVASCRIPT_STAGED_FEATURES(V) JAVASCRIPT_STAGED_FEATURES_BASE(V)
-#else
-#define HARMONY_STAGED(V) HARMONY_STAGED_BASE(V)
-#define JAVASCRIPT_STAGED_FEATURES(V) JAVASCRIPT_STAGED_FEATURES_BASE(V)
-#endif
-
-// Features that are shipping (turned on by default, but internal flag remains).
-#define HARMONY_SHIPPING_BASE(V) \
- V(harmony_import_attributes, "harmony import attributes") \
- V(harmony_temporal, "Temporal")
-
-#define JAVASCRIPT_SHIPPING_FEATURES_BASE(V) \
- V(js_regexp_duplicate_named_groups, "RegExp duplicate named groups") \
- V(js_regexp_modifiers, "RegExp modifiers") \
- V(js_promise_try, "Promise.try") \
- V(js_atomics_pause, "Atomics.pause") \
- V(js_error_iserror, "Error.isError") \
- V(js_regexp_escape, "RegExp.escape") \
- V(js_explicit_resource_management, "explicit resource management") \
- V(js_base_64, "Uint8Array to/from base64 and hex") \
- V(js_esm_ns_reexport, \
- "Support diamond-importing re-expored namespaces " \
- "(https://github.com/tc39/ecma262/pull/3715)") \
- V(js_upsert, "upsert") \
- V(js_iterator_sequencing, "iterator sequencing") \
- V(js_sum_precise, "Math.sumPrecise")
-
-#ifdef V8_INTL_SUPPORT
-#define HARMONY_SHIPPING(V) HARMONY_SHIPPING_BASE(V)
-#define JAVASCRIPT_SHIPPING_FEATURES(V) \
- JAVASCRIPT_SHIPPING_FEATURES_BASE(V) \
- V(js_intl_locale_variants, "Intl.Locale.prototype.variants")
-#else
-#define HARMONY_SHIPPING(V) HARMONY_SHIPPING_BASE(V)
-#define JAVASCRIPT_SHIPPING_FEATURES(V) JAVASCRIPT_SHIPPING_FEATURES_BASE(V)
-#endif
-
-// Once a shipping feature has proved stable in the wild, it will be dropped
-// from HARMONY_SHIPPING, all occurrences of the FLAG_ variable are removed,
-// and associated tests are moved from the harmony directory to the appropriate
-// esN directory.
-//
-// In-progress features are not code complete and are considered experimental,
-// i.e. not ready for fuzz testing.
-
-#define FLAG_INPROGRESS_FEATURES(id, description) \
- DEFINE_BOOL(id, false, \
- "enable " #description " (in progress / experimental)") \
- DEFINE_IMPLICATION(id, experimental)
-HARMONY_INPROGRESS(FLAG_INPROGRESS_FEATURES)
-JAVASCRIPT_INPROGRESS_FEATURES(FLAG_INPROGRESS_FEATURES)
-#undef FLAG_INPROGRESS_FEATURES
-
-#define FLAG_STAGED_FEATURES(id, description) \
- DEFINE_BOOL(id, false, "enable " #description) \
- DEFINE_IMPLICATION(harmony, id) \
- DEFINE_IMPLICATION(js_staging, id)
-HARMONY_STAGED(FLAG_STAGED_FEATURES)
-JAVASCRIPT_STAGED_FEATURES(FLAG_STAGED_FEATURES)
-DEFINE_IMPLICATION(harmony, js_staging)
-#undef FLAG_STAGED_FEATURES
-
-#define FLAG_SHIPPING_FEATURES(id, description) \
- DEFINE_BOOL(id, true, "enable " #description) \
- DEFINE_NEG_NEG_IMPLICATION(harmony_shipping, id) \
- DEFINE_NEG_NEG_IMPLICATION(js_shipping, id)
-HARMONY_SHIPPING(FLAG_SHIPPING_FEATURES)
-JAVASCRIPT_SHIPPING_FEATURES(FLAG_SHIPPING_FEATURES)
-DEFINE_NEG_NEG_IMPLICATION(harmony_shipping, js_shipping)
-#undef FLAG_SHIPPING_FEATURES
-
DEFINE_IMPLICATION(js_import_bytes, js_immutable_arraybuffer)
+DEFINE_BOOL(js_postmessage_share_immutable_arraybuffer, true,
+ "share immutable array buffers in postMessage instead of copying")
+
DEFINE_BOOL(builtin_subclassing, true,
"subclassing support in built-in methods")
@@ -458,6 +351,9 @@ DEFINE_EXPERIMENTAL_FEATURE(
DEFINE_BOOL(icu_timezone_data, true, "get information about timezones from ICU")
DEFINE_STRING(icu_datetime_compat_lang, "*",
"limits ICU date time compat changes to the given language")
+DEFINE_BOOL(
+ intl_date_time_pattern_generator_cache_eviction, false,
+ "enable 9-entry cache eviction in DateTimePatternGeneratorCache")
#endif
#ifdef V8_ENABLE_DOUBLE_CONST_STORE_CHECK
@@ -619,24 +515,6 @@ DEFINE_BOOL_READONLY(local_off_stack_check,
V8_ENABLE_LOCAL_OFF_STACK_CHECK_BOOL,
"check for off-stack allocation of v8::Local")
-// This flag implies experimental features for our fuzzers without needing to
-// stage them yet. Once sufficiently stable, they should be moved to
-// --future, --wasm-staging or a similar flag that indicates its readiness
-// for staging.
-DEFINE_EXPERIMENTAL_FEATURE(
- experimental_fuzzing,
- "Implies all experimental pre-staged features that can already be "
- "fuzzed but are not ready for staging yet.")
-
-#ifdef V8_ENABLE_FUTURE
-#define FUTURE_BOOL true
-#else
-#define FUTURE_BOOL false
-#endif
-DEFINE_BOOL(future, FUTURE_BOOL,
- "Implies all staged features that we want to ship in the "
- "not-too-far future")
-
DEFINE_BOOL(force_emit_interrupt_budget_checks, false,
"force emit tier-up logic from all non-turbofan code, even if it "
"is the top enabled tier")
@@ -683,6 +561,9 @@ DEFINE_NEG_IMPLICATION(maglev_as_top_tier, turbolev)
DEFINE_BOOL(maglev_inlining, true,
"enable inlining in the maglev optimizing compiler")
+DEFINE_BOOL(
+ maglev_disable_builtin_reducers, false,
+ "disable eager builtin reducers in the maglev graph builder (for testing)")
DEFINE_BOOL(maglev_loop_peeling, true,
"enable loop peeling in the maglev optimizing compiler")
DEFINE_BOOL(maglev_optimistic_peeled_loops, true,
@@ -885,20 +766,26 @@ DEFINE_WEAK_IMPLICATION(future, flush_baseline_code)
#ifdef V8_TARGET_ARCH_64_BIT
-DEFINE_BOOL(additive_safe_int_feedback, false,
- "Enable the use of AdditiveSafeInteger feedback")
+DEFINE_BOOL(additive_safe_int_feedback, true,
+ "Record AdditiveSafeInteger feedback")
DEFINE_BOOL(turbolev_additive_safe_int_feedback, true,
"Enable the use of AdditiveSafeInteger feedback for Turbolev")
+DEFINE_BOOL_READONLY(
+ turbofan_additive_safe_int_feedback, false,
+ "Enable the use of AdditiveSafeInteger feedback for TurboFan")
// Additive safe ints are only used by TurboFan or Turbolev.
DEFINE_NEG_IMPLICATION(jitless, additive_safe_int_feedback)
DEFINE_NEG_IMPLICATION(disable_optimizing_compilers, additive_safe_int_feedback)
#else
DEFINE_BOOL_READONLY(additive_safe_int_feedback, false,
- "Enable the use of AdditiveSafeInteger feedback")
+ "Record AdditiveSafeInteger feedback")
DEFINE_BOOL_READONLY(
turbolev_additive_safe_int_feedback, false,
"Enable the use of AdditiveSafeInteger feedback for Turbolev")
+DEFINE_BOOL_READONLY(
+ turbofan_additive_safe_int_feedback, false,
+ "Enable the use of AdditiveSafeInteger feedback for TurboFan")
#endif // V8_TARGET_ARCH_64_BIT
DEFINE_BOOL(
@@ -1172,20 +1059,23 @@ DEFINE_INT(invocation_count_for_maglev, 400,
#endif // ANDROID
DEFINE_INT(invocation_count_for_maglev_osr, 100,
"invocation count required for maglev OSR")
-DEFINE_BOOL(osr_from_maglev, false,
- "whether we try to OSR to Turbofan from OSR'd Maglev")
+DEFINE_INT(osr_from_maglev, 3,
+ "bitset mode for OSR from Maglev to Turbofan (0=off, 1=on OSR "
+ "compile, 2=if loop was OSR'd, 4=always)")
DEFINE_FLOAT(
osr_from_maglev_interrupt_scale_factor, 0.8,
"Scale interrupt budget reduction for OSR from Maglev vs. OSR to Maglev")
DEFINE_BOOL(always_osr_from_maglev, false,
- "whether we try to OSR to Turbofan from any Maglev")
-DEFINE_WEAK_IMPLICATION(turbolev, always_osr_from_maglev)
-DEFINE_WEAK_IMPLICATION(always_osr_from_maglev, osr_from_maglev)
+ "whether we try to OSR to Turbofan from any Maglev (alias for "
+ "--osr-from-maglev=4)")
+DEFINE_VALUE_IMPLICATION(always_osr_from_maglev, osr_from_maglev, 4)
// Tiering: Turbofan.
DEFINE_INT(invocation_count_for_turbofan, 3000,
"invocation count required for optimizing with TurboFan")
DEFINE_INT(invocation_count_for_osr, 500, "invocation count required for OSR")
+DEFINE_FLOAT(invocation_count_for_osr_factor_while_tiering_in_progress, 3.0,
+ "invocation count factor while waiting for code to compile")
DEFINE_UINT(osr_to_tierup, 1,
"number to decrease the invocation budget by when we follow OSR")
DEFINE_INT(minimum_invocations_after_ic_update, 500,
@@ -1218,8 +1108,10 @@ DEFINE_VALUE_IMPLICATION(jit_fuzzing, minimum_invocations_after_ic_update, 5)
#if V8_ENABLE_WEBASSEMBLY
// Wasm tiering thresholds.
-DEFINE_VALUE_IMPLICATION(jit_fuzzing, wasm_wrapper_tiering_budget, 1)
-DEFINE_VALUE_IMPLICATION(jit_fuzzing, wasm_tiering_budget, 1)
+DEFINE_VALUE_IMPLICATION(jit_fuzzing,
+ wasm_wrapper_tiering_budget, 1)
+DEFINE_VALUE_IMPLICATION(jit_fuzzing,
+ wasm_tiering_budget, 1)
DEFINE_IMPLICATION(jit_fuzzing, wasm_inlining_ignore_call_counts)
#endif // V8_ENABLE_WEBASSEMBLY
@@ -1370,6 +1262,8 @@ DEFINE_NEG_IMPLICATION(shared_heap, always_use_string_forwarding_table)
DEFINE_BOOL(transition_strings_during_gc_with_stack, false,
"Transition strings during a full GC with stack")
+DEFINE_NEG_IMPLICATION(shared_string_table,
+ transition_strings_during_gc_with_stack)
DEFINE_SIZE_T(initial_shared_heap_size, 0,
"initial size of the shared heap (in Mbytes); "
@@ -1435,6 +1329,8 @@ DEFINE_INT(stress_runs, 0, "number of stress runs")
DEFINE_INT(deopt_every_n_times, 0,
"deoptimize every n times a deopt point is passed")
DEFINE_BOOL(print_deopt_stress, false, "print number of possible deopt points")
+DEFINE_BOOL(disable_loop_stack_checks, false,
+ "disable loop stack checks (for testing/fuzzing only)")
// Flags for TurboFan.
#ifdef V8_ENABLE_TURBOFAN
@@ -1609,6 +1505,8 @@ DEFINE_INT(max_optimized_bytecode_size, 60 * KB,
"maximum bytecode size to "
"be considered for turbofan optimization; too high values may cause "
"the compiler to hit (release) assertions")
+DEFINE_INT(max_maglev_optimized_bytecode_size, 512 * KB,
+ "maximum bytecode size to be considered for maglev optimization")
DEFINE_FLOAT(min_inlining_frequency, 0.15, "minimum frequency for inlining")
DEFINE_WEAK_VALUE_IMPLICATION(maglev, min_inlining_frequency, 0.05)
DEFINE_BOOL(stress_inline, false,
@@ -1634,9 +1532,10 @@ DEFINE_INT(max_turbolev_eager_inlined_bytecode_size, 30,
"maximum size of bytecode considered for eager inlining")
// When using maglev as OSR target allow us to tier up further
-DEFINE_WEAK_VALUE_IMPLICATION(maglev_osr, osr_from_maglev, true)
+DEFINE_WEAK_VALUE_IMPLICATION(maglev_osr, osr_from_maglev, 2)
DEFINE_VALUE_IMPLICATION(!use_osr, maglev_osr, false)
-DEFINE_VALUE_IMPLICATION(!turbofan, osr_from_maglev, false)
+DEFINE_VALUE_IMPLICATION(!turbofan, osr_from_maglev, 0)
+DEFINE_VALUE_IMPLICATION(!turbofan, always_osr_from_maglev, false)
DEFINE_BOOL(concurrent_osr, true, "enable concurrent OSR")
DEFINE_INT(maglev_allocation_folding, 2, "maglev allocation folding level")
@@ -1744,14 +1643,6 @@ DEFINE_BOOL(fast_api_allow_float_in_sim, false,
// for other tests, which would just lead to errors or crashes.
DEFINE_NEG_IMPLICATION(fuzzing, fast_api_allow_float_in_sim)
-#ifdef V8_USE_ZLIB
-DEFINE_BOOL(turbo_compress_frame_translations, false,
- "compress deoptimization frame translations (experimental)")
-#else
-DEFINE_BOOL_READONLY(
- turbo_compress_frame_translations, false,
- "compress deoptimization frame translations (experimental)")
-#endif // V8_USE_ZLIB
DEFINE_BOOL(
turbo_inline_js_wasm_calls, true,
"inline JS->Wasm calls (specifically: inline JS-to-Wasm wrappers and then "
@@ -1817,8 +1708,8 @@ DEFINE_BOOL(turboshaft_string_concat_escape_analysis, true,
DEFINE_BOOL(turboshaft_trusted_load_elimination, true,
"enable Turboshaft's low level load elimination for trusted loads "
"(JS and Wasm)")
-DEFINE_IMPLICATION(turboshaft_trusted_load_elimination,
- turboshaft_load_elimination)
+DEFINE_WEAK_IMPLICATION(turboshaft_trusted_load_elimination,
+ turboshaft_load_elimination)
DEFINE_EXPERIMENTAL_FEATURE(turboshaft_typed_optimizations,
"enable an additional Turboshaft phase that "
@@ -1954,6 +1845,7 @@ DEFINE_BOOL(profile_guided_optimization_for_empty_feedback_vector, true,
"profile guided optimization for empty feedback vector")
DEFINE_INT(invocation_count_for_early_optimization, 30,
"invocation count threshold for early optimization")
+DEFINE_MAX_VALUE_IMPLICATION(invocation_count_for_early_optimization, 254)
DEFINE_INT(invocation_count_for_maglev_with_delay, 600,
"invocation count for maglev for functions which according to "
"profile_guided_optimization are likely to deoptimize before "
@@ -1975,7 +1867,126 @@ DEFINE_BOOL(verify_get_js_builtin_state, false,
"Enable verification of Builtins::GetJSBuiltinState().")
DEFINE_IMPLICATION(enable_slow_asserts, verify_get_js_builtin_state)
-// Flags for WebAssembly.
+// Declare command-line flags for V8 features.
+#include "src/flags/feature-flags.h"
+
+// This flag implies experimental features for our fuzzers without needing to
+// stage them yet. Once sufficiently stable, they should be moved to
+// --future, --wasm-staging or a similar flag that indicates its readiness
+// for staging.
+DEFINE_EXPERIMENTAL_FEATURE(
+ experimental_fuzzing,
+ "Implies all experimental pre-staged features that can already be "
+ "fuzzed but are not ready for staging yet.")
+
+#ifdef V8_ENABLE_FUTURE
+#define FUTURE_BOOL true
+#else
+#define FUTURE_BOOL false
+#endif
+DEFINE_BOOL(future, FUTURE_BOOL,
+ "Implies all staged features that we want to ship in the "
+ "not-too-far future")
+
+DEFINE_BOOL(harmony, false, "enable all completed harmony features")
+DEFINE_BOOL(js_staging, false, "enable all completed JavaScript features")
+DEFINE_BOOL(wasm_staging, false, "enable staged wasm features")
+
+DEFINE_BOOL(js_shipping, true, "enable all shipped JavaScript features")
+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)
+#else
+#define DECL_EXPERIMENTAL_WASM_FLAG(feature_name, description)
+#endif // V8_ENABLE_WEBASSEMBLY
+#define DECL_EXPERIMENTAL_INTERNAL_FLAG(feature_name, description) \
+ DEFINE_EXPERIMENTAL_FEATURE(feature_name, "enable " description)
+FOREACH_EXPERIMENTAL_FEATURE_FLAG(DECL_EXPERIMENTAL_JS_FLAG,
+ DECL_EXPERIMENTAL_WASM_FLAG,
+ DECL_EXPERIMENTAL_INTERNAL_FLAG)
+#undef DECL_EXPERIMENTAL_JS_FLAG
+#undef DECL_EXPERIMENTAL_WASM_FLAG
+#undef DECL_EXPERIMENTAL_INTERNAL_FLAG
+
+#define DECL_PRE_STAGED_JS_FLAG(feature_name, description) \
+ DEFINE_EXPERIMENTAL_FEATURE(feature_name, "enable " description " for JS") \
+ DEFINE_IMPLICATION(experimental_fuzzing, feature_name)
+#ifdef V8_ENABLE_WEBASSEMBLY
+#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)
+#endif // V8_ENABLE_WEBASSEMBLY
+#define DECL_PRE_STAGED_INTERNAL_FLAG(feature_name, description) \
+ DEFINE_EXPERIMENTAL_FEATURE(feature_name, "enable " description) \
+ DEFINE_WEAK_IMPLICATION(experimental_fuzzing, feature_name)
+FOREACH_PRE_STAGED_FEATURE_FLAG(DECL_PRE_STAGED_JS_FLAG,
+ DECL_PRE_STAGED_WASM_FLAG,
+ DECL_PRE_STAGED_INTERNAL_FLAG)
+#undef DECL_PRE_STAGED_JS_FLAG
+#undef DECL_PRE_STAGED_WASM_FLAG
+#undef DECL_PRE_STAGED_INTERNAL_FLAG
+
+#define DECL_STAGED_JS_FLAG(feature_name, description) \
+ DEFINE_BOOL(feature_name, false, "enable " description " for JS") \
+ DEFINE_WEAK_IMPLICATION(js_staging, feature_name) \
+ DEFINE_WEAK_IMPLICATION(harmony, feature_name)
+#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)
+#endif // V8_ENABLE_WEBASSEMBLY
+#define DECL_STAGED_INTERNAL_FLAG(feature_name, description) \
+ DEFINE_BOOL(feature_name, false, "enable " description) \
+ DEFINE_WEAK_IMPLICATION(future, feature_name)
+FOREACH_STAGED_FEATURE_FLAG(DECL_STAGED_JS_FLAG, DECL_STAGED_WASM_FLAG,
+ DECL_STAGED_INTERNAL_FLAG)
+DEFINE_IMPLICATION(harmony, js_staging)
+#undef DECL_STAGED_JS_FLAG
+#undef DECL_STAGED_WASM_FLAG
+#undef DECL_STAGED_INTERNAL_FLAG
+
+#define DECL_SHIPPED_JS_FLAG(feature_name, description) \
+ DEFINE_BOOL(feature_name, true, "enable " description " for JS") \
+ 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)
+#else
+#define DECL_SHIPPED_WASM_FLAG(feature_name, description)
+#endif // V8_ENABLE_WEBASSEMBLY
+#define DECL_SHIPPED_INTERNAL_FLAG(feature_name, description) \
+ DEFINE_BOOL(feature_name, true, "enable " description)
+FOREACH_SHIPPED_FEATURE_FLAG(DECL_SHIPPED_JS_FLAG, DECL_SHIPPED_WASM_FLAG,
+ DECL_SHIPPED_INTERNAL_FLAG)
+DEFINE_NEG_NEG_IMPLICATION(harmony_shipping, js_shipping)
+#undef DECL_SHIPPED_JS_FLAG
+#undef DECL_SHIPPED_WASM_FLAG
+#undef DECL_SHIPPED_INTERNAL_FLAG
+
+// Non-feature flags for WebAssembly.
#if V8_ENABLE_WEBASSEMBLY
DEFINE_BOOL(wasm_generic_wrapper, true,
@@ -2051,6 +2062,8 @@ DEFINE_BOOL(stress_wasm_stack_switching, false,
"with a regular (non-JSPI) export")
DEFINE_INT(wasm_stack_switching_stack_size, V8_DEFAULT_STACK_SIZE_KB,
"default size of stacks for wasm stack-switching (in kB)")
+DEFINE_INT(wasm_stack_pool_capacity_mb, 500,
+ "default capacity for the wasm stack pool in MB, -1 for unlimited")
// 1 will be rounded up to the smallest possible initial stack size, which
// depends on the stack limit margin and the platform's page size.
DEFINE_VALUE_IMPLICATION(wasm_growable_stacks,
@@ -2067,8 +2080,9 @@ DEFINE_DEBUG_BOOL(
"enables a testing opcode in wasm that is only implemented in TurboFan")
DEFINE_NEG_IMPLICATION(liftoff_only, enable_testing_opcode_in_wasm)
// Do synchronous tier up (instead of in-background tierup) in single threaded
-// mode.
+// and predictable mode.
DEFINE_IMPLICATION(single_threaded, wasm_sync_tier_up)
+DEFINE_IMPLICATION(predictable, wasm_sync_tier_up)
DEFINE_DEBUG_BOOL(trace_liftoff, false,
"trace Liftoff, the baseline compiler for WebAssembly")
DEFINE_DEVELOPER_FLAG(trace_wasm_memory,
@@ -2132,29 +2146,6 @@ DEFINE_SIZE_T(wasm_deopts_per_function_limit, 10,
"limit of wasm deopts for a single function after which no "
"further deopt points are emitted in Turbofan")
-// Declare command-line flags for Wasm features. Warning: avoid using these
-// flags directly in the implementation. Instead accept
-// wasm::WasmEnabledFeatures for configurability.
-#include "src/wasm/wasm-feature-flags.h"
-
-#define DECL_WASM_FLAG(feat, desc, val) \
- DEFINE_BOOL(wasm_##feat, val, "enable " desc " for Wasm") \
- DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_##feat, wasm_##feat, \
- TEMPORARY_WASM_ALIAS_COMMENT)
-#define DECL_EXPERIMENTAL_WASM_FLAG(feat, desc, val) \
- DEFINE_EXPERIMENTAL_FEATURE(wasm_##feat, "enable " desc " for Wasm") \
- DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_##feat, wasm_##feat, \
- TEMPORARY_WASM_ALIAS_COMMENT)
-// Experimental wasm features imply --experimental and get the " (experimental)"
-// suffix.
-FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(DECL_EXPERIMENTAL_WASM_FLAG)
-FOREACH_WASM_PRE_STAGING_FEATURE_FLAG(DECL_EXPERIMENTAL_WASM_FLAG)
-// Staging and shipped features do not imply --experimental.
-FOREACH_WASM_STAGING_FEATURE_FLAG(DECL_WASM_FLAG)
-FOREACH_WASM_SHIPPED_FEATURE_FLAG(DECL_WASM_FLAG)
-#undef DECL_WASM_FLAG
-#undef DECL_EXPERIMENTAL_WASM_FLAG
-
// Unsafe additions to the GC proposal for performance experiments.
DEFINE_TEST_ONLY_FLAG(
wasm_assume_ref_cast_succeeds,
@@ -2185,18 +2176,9 @@ DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_js_interop, wasm_js_interop,
DEFINE_IMPLICATION(wasm_js_interop, wasm_custom_descriptors)
DEFINE_BOOL(wasm_custom_descriptors_permitted, true,
"Emergency off-switch for Custom Descriptors Origin Trial")
-
-#define WASM_PRE_STAGING_IMPLICATION(feat, desc, val) \
- DEFINE_IMPLICATION(experimental_fuzzing, wasm_##feat)
-FOREACH_WASM_PRE_STAGING_FEATURE_FLAG(WASM_PRE_STAGING_IMPLICATION)
-#undef WASM_PRE_STAGING_IMPLICATION
-
-DEFINE_BOOL(wasm_staging, false, "enable staged wasm features")
-
-#define WASM_STAGING_IMPLICATION(feat, desc, val) \
- DEFINE_IMPLICATION(wasm_staging, wasm_##feat)
-FOREACH_WASM_STAGING_FEATURE_FLAG(WASM_STAGING_IMPLICATION)
-#undef WASM_STAGING_IMPLICATION
+DEFINE_EXPERIMENTAL_FEATURE(wasm_merged_descriptors,
+ "merge Custom Descriptor into v8::internal::Map")
+DEFINE_IMPLICATION(wasm_merged_descriptors, wasm_custom_descriptors)
DEFINE_DEBUG_BOOL(
wasm_opt, true,
@@ -2212,6 +2194,23 @@ DEFINE_BOOL(
"enforce explicit bounds check even if the trap handler is available")
// "no bounds checks" implies "no enforced bounds checks".
DEFINE_NEG_NEG_IMPLICATION(wasm_bounds_checks, wasm_enforce_bounds_checks)
+
+// The Arm architecture does not specify the results in memory of
+// partially-in-bound writes, which does not align with the wasm spec. This
+// affects when trap handlers can be used for OOB detection; however, Mac
+// systems with Apple silicon currently do provide trapping behaviour for
+// partially-out-of-bound writes, so we assume we can rely on that on MacOS,
+// since doing so provides better performance for writes.
+DEFINE_BOOL(
+#if V8_TARGET_ARCH_RISCV64 || (V8_TARGET_ARCH_ARM64 && !V8_OS_MACOS)
+ wasm_partial_oob_writes_are_noops, false,
+#else
+ wasm_partial_oob_writes_are_noops, true,
+#endif
+ "assume partially out-of-bounds writes are no-ops and can use the trap "
+ "handler. Note that explicitly enabling this flag (if not enabled by "
+ "default) can affect the spec-compliance of V8.")
+
DEFINE_BOOL(wasm_math_intrinsics, true,
"intrinsify some Math imports into wasm")
@@ -2313,12 +2312,8 @@ DEFINE_DEBUG_BOOL(trace_wasm_instances, false,
// Flags for WASM SIMD256 revectorize
#ifdef V8_ENABLE_WASM_SIMD256_REVEC
-DEFINE_EXPERIMENTAL_FEATURE(
- wasm_revectorize,
- "enable 128 to 256 bit revectorization for WebAssembly SIMD")
DEFINE_ALIAS_BOOL_WITH_COMMENT(experimental_wasm_revectorize, wasm_revectorize,
TEMPORARY_WASM_ALIAS_COMMENT)
-DEFINE_WEAK_IMPLICATION(experimental_fuzzing, wasm_revectorize)
DEFINE_DEVELOPER_FLAG(trace_wasm_revectorize, "trace wasm revectorize")
#endif // V8_ENABLE_WASM_SIMD256_REVEC
@@ -2722,6 +2717,7 @@ DEFINE_BOOL(memory_reducer_for_small_heaps, true,
"use memory reducer for small heaps")
DEFINE_INT(memory_reducer_gc_count, 2,
"Maximum number of memory reducer GCs scheduled")
+DEFINE_REQUIREMENT(v8_flags.memory_reducer_gc_count > 0)
DEFINE_INT(memory_reducer_delay_ms, 8'000, "Delay before memory reducer start")
DEFINE_REQUIREMENT(v8_flags.memory_reducer_delay_ms > 0)
DEFINE_INT(gc_memory_reducer_start_delay_ms, 30'000,
@@ -2748,6 +2744,9 @@ DEFINE_INT(
sqrt_allocation_limits_minimal_factor, 20,
"When the sqrt heap limit is enabled, multiplier on the heap growth for "
"HeapGrowingMode::kMinimal.")
+DEFINE_FLOAT(
+ sqrt_allocation_limits_min_growing_factor, 1.1,
+ "This is the lower bound for growing factor when using sqrt heap limit.")
DEFINE_FLOAT(
sqrt_allocation_limits_max_growing_factor, 4.0,
"This is the upper bound for growing factor when using sqrt heap limit.")
@@ -2797,6 +2796,7 @@ DEFINE_BOOL(flush_baseline_code, false,
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)
@@ -2960,8 +2960,15 @@ DEFINE_BOOL(enable_apx_f_setzucc, false,
"enable use of APX setzucc for x64 zero-extending setcc patterns")
DEFINE_BOOL(enable_apx_f_cmovcc, false,
"enable use of APX cmovcc for x64 conditional move patterns")
+DEFINE_BOOL(enable_apx_f_ccmp, false,
+ "enable use of APX ccmp/ctest for x64 conditional compare patterns")
DEFINE_IMPLICATION(enable_apx_f_setzucc, enable_apx_f)
DEFINE_IMPLICATION(enable_apx_f_cmovcc, enable_apx_f)
+DEFINE_IMPLICATION(enable_apx_f_ccmp, enable_apx_f)
+#endif
+#ifdef V8_ENABLE_AVX10_1
+DEFINE_BOOL(enable_avx10_1, false,
+ "enable use of AVX10.1 instructions if available")
#endif
DEFINE_STRING(arm_arch, ARM_ARCH_DEFAULT,
"generate instructions for the selected ARM architecture if "
@@ -3035,11 +3042,6 @@ DEFINE_BOOL(
"an existing Script if one is found in the Isolate compilation cache")
DEFINE_BOOL(verify_code_merge, false, "Verify scope infos after merge")
-// Fix https://issues.chromium.org/u/1/issues/366783806 before enabling.
-DEFINE_BOOL(
- experimental_embedder_instance_types, false,
- "enable type checks based on instance types provided by the embedder")
-DEFINE_IMPLICATION(experimental_embedder_instance_types, experimental)
// bootstrapper.cc
DEFINE_BOOL(expose_gc, false, "expose gc extension")
@@ -3081,6 +3083,7 @@ DEFINE_BOOL(test_small_max_function_context_stub_size, false,
"by making the maximum size smaller")
DEFINE_WEAK_IMPLICATION(future, fast_api_indexof)
DEFINE_BOOL(fast_api_indexof, false, "enable using indexOf Api callbacks")
+DEFINE_WEAK_IMPLICATION(future, fast_api_iterable_to_list)
DEFINE_BOOL(fast_api_iterable_to_list, false,
"enable fast path for IterableToList for indexed interceptors")
@@ -3098,13 +3101,13 @@ DEFINE_INT(switch_table_min_cases, 6,
DEFINE_REQUIREMENT(v8_flags.switch_table_min_cases > 0)
// Note that enabling this stress mode might result in a failure to compile
// even a top-level code.
-DEFINE_INT(stress_lazy_compilation, 0,
- "stress lazy compilation by simulating stack overflow during "
- "unoptimized bytecode generation with 1/n-th probability, "
- "do nothing on 0")
+DEFINE_UINT(stress_lazy_compilation, 0,
+ "stress lazy compilation by simulating stack overflow during "
+ "unoptimized bytecode generation with 1/n-th probability, "
+ "do nothing on 0")
// Correctness fuzzing treats stack overflows as crashes.
DEFINE_VALUE_IMPLICATION(correctness_fuzzer_suppressions,
- stress_lazy_compilation, 0)
+ stress_lazy_compilation, 0u)
// codegen-ia32.cc / codegen-arm.cc
DEFINE_BOOL(trace, false, "trace javascript function calls")
@@ -3213,9 +3216,6 @@ DEFINE_BOOL(log_colour, ENABLE_LOG_COLOUR,
// inspector
DEFINE_BOOL(expose_inspector_scripts, false,
"expose injected-script-source.js for debugging")
-DEFINE_BOOL(inspector_live_edit, false,
- "Enable the Debugger.setScriptSource CDP command, otherwise it'll "
- "always fail with an error")
// execution.cc
//
@@ -3283,7 +3283,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 4
+#define DEFAULT_MAX_POLYMORPHIC_MAP_COUNT 10
DEFINE_INT(max_valid_polymorphic_map_count, DEFAULT_MAX_POLYMORPHIC_MAP_COUNT,
"maximum number of valid maps to track in POLYMORPHIC state")
DEFINE_BOOL(
@@ -3295,19 +3295,18 @@ DEFINE_WEAK_IMPLICATION(future, clone_object_sidestep_transitions)
DEFINE_INT(fast_properties_soft_limit, 12,
"limits the number of properties that can be added to an object "
"using keyed store before transitioning to dictionary mode")
-DEFINE_INT(max_fast_properties, 128,
- "limits the number of mutable properties that can be added to an "
- "object before transitioning to dictionary mode")
DEFINE_BOOL(native_code_counters, DEBUG_BOOL,
"generate extra code for manipulating stats counters")
-#ifdef V8_ENABLE_SPARKPLUG_PLUS
-DEFINE_BOOL(sparkplug_plus, false, "enable dynamic patching on baseline code")
-DEFINE_WEAK_IMPLICATION(future, sparkplug_plus)
-#else
+#ifndef V8_ENABLE_SPARKPLUG_PLUS
+// If the Sparkplug+ build flag is enabled, we define the flag in
+// feature-flags.h instead of here to follow the regular launch process format.
DEFINE_BOOL_READONLY(sparkplug_plus, false,
- "enable dynamic patching on baseline code")
+ "enable dynamic patching on JS baseline code")
+DEFINE_BOOL_READONLY(sparkplug_inline_smi, false,
+ "inline the Smi fast path of embedded feedback "
+ "operations into baseline code")
#endif
DEFINE_IMPLICATION(sparkplug_plus, short_builtin_calls)
@@ -3340,17 +3339,6 @@ DEFINE_IMPLICATION(allow_natives_for_differential_fuzzing, allow_natives_syntax)
DEFINE_IMPLICATION(allow_natives_for_differential_fuzzing, fuzzing)
DEFINE_BOOL(parse_only, false, "only parse the sources")
-DEFINE_BOOL(enable_parser_ablation, false, "Enable parser ablation")
-DEFINE_BOOL(enable_preparser_ablation, false, "Enable preparser ablation")
-DEFINE_BOOL(enable_bytecode_compiler_ablation, false,
- "Enable bytecode compiler ablation")
-DEFINE_FLOAT(parser_ablation_amount, 0.8,
- "Increase parse time by x for ablation studies")
-DEFINE_FLOAT(preparser_ablation_amount, 0.8,
- "Increase parse time by x for ablation studies")
-DEFINE_FLOAT(bytecode_compiler_ablation_amount, 0.8,
- "Increase BC compile time by x for ablation studies")
-
// simulator-arm.cc and simulator-arm64.cc.
#ifdef USE_SIMULATOR
DEFINE_DEVELOPER_FLAG(trace_sim, "Trace simulator execution")
@@ -3701,6 +3689,13 @@ DEFINE_EXPERIMENTAL_FEATURE(validate_generated_code,
DEFINE_BOOL_READONLY(validate_generated_code, false,
"Enable generated code verifier")
#endif
+DEFINE_DEVELOPER_FLAG(validate_generated_code_include_code,
+ "Print the disassembled code as part of the generated "
+ "code validator's output in case of violations.")
+DEFINE_DEVELOPER_FLAG(
+ validate_generated_code_non_fatal,
+ "Treat generated code validator violations as non-fatal. Can be "
+ "used to find all issues rather than exiting after the first one.")
#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
// Sandbox fuzzing mode requires the memory corruption API.
@@ -4231,7 +4226,12 @@ DEFINE_NEG_IMPLICATION(predictable, parallel_compile_tasks_for_lazy)
#ifdef V8_ENABLE_MAGLEV
DEFINE_NEG_IMPLICATION(predictable, maglev_deopt_data_on_background)
DEFINE_NEG_IMPLICATION(predictable, maglev_build_code_on_background)
+DEFINE_NEG_IMPLICATION(predictable, maglev_destroy_on_background)
#endif // V8_ENABLE_MAGLEV
+DEFINE_NEG_IMPLICATION(predictable, concurrent_cache_deserialization)
+#if V8_ENABLE_WEBASSEMBLY
+DEFINE_NEG_IMPLICATION(predictable, wasm_test_streaming)
+#endif // V8_ENABLE_WEBASSEMBLY
// Avoid random seeds in predictable mode.
DEFINE_VALUE_IMPLICATION(predictable && random_seed == 0, random_seed, 12347)
@@ -4424,6 +4424,10 @@ DEFINE_NEG_IMPLICATION(disallow_unsafe_flags, maglev_break_on_entry)
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags, stop_sim_at)
#endif
DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags, gc_fake_mmap)
+// Non-standard stack sizes can lead to stack overflows (signaled as segfaults)
+// and produce spurious bug reports. V8 should handle stack overflows gracefully
+// in default configurations.
+DEFINE_NOT_EXPLICITLY_SET_IMPLICATION(disallow_unsafe_flags, stack_size)
// Runs a program as security POC. This mode is used to determine whether a bug
// in a program is a security problem. V8 supports many different configurations
@@ -4537,6 +4541,7 @@ DEFINE_IMPLICATION(gdbjit, log)
#undef DEFINE_NEG_VALUE_VALUE_IMPLICATION
#undef DEFINE_VALUE_IMPLICATION
#undef DEFINE_MIN_VALUE_IMPLICATION
+#undef DEFINE_MAX_VALUE_IMPLICATION
#undef DEFINE_DISABLE_FLAG_IMPLICATION
#undef DEFINE_WEAK_VALUE_IMPLICATION
#undef DEFINE_GENERIC_IMPLICATION
diff --git a/deps/v8/src/flags/flags.cc b/deps/v8/src/flags/flags.cc
index 4d2efe32613..3a87e4c7e61 100644
--- a/deps/v8/src/flags/flags.cc
+++ b/deps/v8/src/flags/flags.cc
@@ -358,7 +358,12 @@ constexpr auto kFlagsMetadata = []() {
const char* comment;
};
constexpr RawMetadata raw[] = {
-#define FLAG_MODE_APPLY(ctype, nam, primary, cmt) {#nam, #primary, cmt},
+#define FLAG_MODE_APPLY(ctype, nam, primary, cmt) \
+ [] { \
+ static_assert(#nam[0] != 'n' || #nam[1] != 'o', \
+ "Flags must not start with 'no'"); \
+ return RawMetadata{#nam, #primary, cmt}; \
+ }(),
#define FLAG_MODE_INCLUDE_READONLY
#define FLAG_MODE_INCLUDE_ALIASES
#include "src/flags/flag-definitions.h" // NOLINT(build/include)
@@ -629,10 +634,16 @@ uint32_t ComputeFlagListHash() {
// The following flags are implied by --predictable (some negated).
if (flag.PointsTo(&v8_flags.concurrent_sparkplug) ||
flag.PointsTo(&v8_flags.concurrent_recompilation) ||
+ flag.PointsTo(&v8_flags.concurrent_cache_deserialization) ||
flag.PointsTo(&v8_flags.lazy_feedback_allocation) ||
#ifdef V8_ENABLE_MAGLEV
flag.PointsTo(&v8_flags.maglev_deopt_data_on_background) ||
flag.PointsTo(&v8_flags.maglev_build_code_on_background) ||
+ flag.PointsTo(&v8_flags.maglev_destroy_on_background) ||
+#endif
+#if V8_ENABLE_WEBASSEMBLY
+ flag.PointsTo(&v8_flags.wasm_sync_tier_up) ||
+ flag.PointsTo(&v8_flags.wasm_test_streaming) ||
#endif
flag.PointsTo(&v8_flags.parallel_scavenge) ||
flag.PointsTo(&v8_flags.concurrent_marking) ||
@@ -1086,35 +1097,50 @@ void FlagList::PrintFeatureFlagsJSON() {
{
std::vector<const char*> inprogress_flags;
+ std::vector<const char*> inprogress_harmony_flags;
std::vector<const char*> staged_flags;
+ std::vector<const char*> staged_harmony_flags;
std::vector<const char*> shipping_flags;
+ std::vector<const char*> shipping_harmony_flags;
+
+#define IGNORE_FEATURE(name, desc)
-#define ADD_JS_INPROGRESS_FLAG(name, desc) inprogress_flags.push_back(#name);
-#define ADD_JS_STAGED_FLAG(name, desc) staged_flags.push_back(#name);
-#define ADD_JS_SHIPPING_FLAG(name, desc) shipping_flags.push_back(#name);
+#define ADD_JS_INPROGRESS_FLAG(name, desc) \
+ if (strncmp("harmony_", #name, 8) == 0) { \
+ inprogress_harmony_flags.push_back(#name); \
+ } else { \
+ inprogress_flags.push_back(#name); \
+ }
+#define ADD_JS_STAGED_FLAG(name, desc) \
+ if (strncmp("harmony_", #name, 8) == 0) { \
+ staged_harmony_flags.push_back(#name); \
+ } else { \
+ staged_flags.push_back(#name); \
+ }
+#define ADD_JS_SHIPPING_FLAG(name, desc) \
+ if (strncmp("harmony_", #name, 8) == 0) { \
+ shipping_harmony_flags.push_back(#name); \
+ } else { \
+ shipping_flags.push_back(#name); \
+ }
- JAVASCRIPT_INPROGRESS_FEATURES(ADD_JS_INPROGRESS_FLAG)
- JAVASCRIPT_STAGED_FEATURES(ADD_JS_STAGED_FLAG)
- JAVASCRIPT_SHIPPING_FEATURES(ADD_JS_SHIPPING_FLAG)
+ FOREACH_EXPERIMENTAL_FEATURE_FLAG(ADD_JS_INPROGRESS_FLAG, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_PRE_STAGED_FEATURE_FLAG(ADD_JS_INPROGRESS_FLAG, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_STAGED_FEATURE_FLAG(ADD_JS_STAGED_FLAG, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_SHIPPED_FEATURE_FLAG(ADD_JS_SHIPPING_FLAG, IGNORE_FEATURE,
+ IGNORE_FEATURE)
os << " \"js\": ";
PrintFeatureFlagsJSONObject(os, inprogress_flags, staged_flags,
shipping_flags);
os << ",\n";
- }
-
- {
- std::vector<const char*> inprogress_flags;
- std::vector<const char*> staged_flags;
- std::vector<const char*> shipping_flags;
-
- HARMONY_INPROGRESS(ADD_JS_INPROGRESS_FLAG)
- HARMONY_STAGED(ADD_JS_STAGED_FLAG)
- HARMONY_SHIPPING(ADD_JS_SHIPPING_FLAG)
os << " \"harmony\": ";
- PrintFeatureFlagsJSONObject(os, inprogress_flags, staged_flags,
- shipping_flags);
+ PrintFeatureFlagsJSONObject(os, inprogress_harmony_flags,
+ staged_harmony_flags, shipping_harmony_flags);
os << ",\n";
}
@@ -1124,16 +1150,20 @@ void FlagList::PrintFeatureFlagsJSON() {
std::vector<const char*> staged_flags;
std::vector<const char*> shipping_flags;
-#define ADD_WASM_INPROGRESS_FLAG(name, desc, val) \
+#define ADD_WASM_INPROGRESS_FLAG(name, desc) \
inprogress_flags.push_back("wasm_" #name);
-#define ADD_WASM_STAGED_FLAG(name, desc, val) \
- staged_flags.push_back("wasm_" #name);
-#define ADD_WASM_SHIPPED_FLAG(name, desc, val) \
+#define ADD_WASM_STAGED_FLAG(name, desc) staged_flags.push_back("wasm_" #name);
+#define ADD_WASM_SHIPPED_FLAG(name, desc) \
shipping_flags.push_back("wasm_" #name);
- FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(ADD_WASM_INPROGRESS_FLAG)
- FOREACH_WASM_STAGING_FEATURE_FLAG(ADD_WASM_STAGED_FLAG)
- FOREACH_WASM_SHIPPED_FEATURE_FLAG(ADD_WASM_SHIPPED_FLAG)
+ FOREACH_EXPERIMENTAL_FEATURE_FLAG(IGNORE_FEATURE, ADD_WASM_INPROGRESS_FLAG,
+ IGNORE_FEATURE)
+ FOREACH_PRE_STAGED_FEATURE_FLAG(IGNORE_FEATURE, ADD_WASM_INPROGRESS_FLAG,
+ IGNORE_FEATURE)
+ FOREACH_STAGED_FEATURE_FLAG(IGNORE_FEATURE, ADD_WASM_STAGED_FLAG,
+ IGNORE_FEATURE)
+ FOREACH_SHIPPED_FEATURE_FLAG(IGNORE_FEATURE, ADD_WASM_SHIPPED_FLAG,
+ IGNORE_FEATURE)
os << " \"wasm\": ";
PrintFeatureFlagsJSONObject(os, inprogress_flags, staged_flags,
@@ -1151,6 +1181,7 @@ void FlagList::PrintFeatureFlagsJSON() {
#undef ADD_WASM_INPROGRESS_FLAG
#undef ADD_WASM_STAGED_FLAG
#undef ADD_WASM_SHIPPED_FLAG
+#undef IGNORE_FEATURE
}
namespace {
@@ -1341,6 +1372,11 @@ void FlagList::ResolveContradictionsWhenFuzzing() {
CONTRADICTION(always_osr_from_maglev, lite_mode);
CONTRADICTION(always_osr_from_maglev, turbofan);
CONTRADICTION(always_osr_from_maglev, turboshaft);
+ CONTRADICTION(osr_from_maglev, disable_optimizing_compilers);
+ CONTRADICTION(osr_from_maglev, jitless);
+ CONTRADICTION(osr_from_maglev, lite_mode);
+ CONTRADICTION(osr_from_maglev, turbofan);
+ CONTRADICTION(osr_from_maglev, turboshaft);
CONTRADICTION(assert_types, stress_concurrent_inlining);
CONTRADICTION(assert_types, stress_concurrent_inlining_attach_code);
CONTRADICTION(disable_optimizing_compilers, maglev_future);
@@ -1390,6 +1426,7 @@ void FlagList::ResolveContradictionsWhenFuzzing() {
CONTRADICTION(predictable_gc_schedule, stress_compaction);
CONTRADICTION(single_threaded, stress_concurrent_inlining_attach_code);
#if V8_ENABLE_WEBASSEMBLY
+ CONTRADICTION(wasm_test_streaming, predictable);
CONTRADICTION(single_threaded, wasm_pgo_to_file);
CONTRADICTION(single_threaded, wasm_generate_compilation_hints);
CONTRADICTION(single_threaded, trace_wasm_generate_compilation_hints);
@@ -1441,6 +1478,11 @@ void FlagList::ResolveContradictionsWhenFuzzing() {
// Not useful for differential fuzzing: https://crbug.com/496356383
RESET_WHEN_CORRECTNESS_FUZZING(heap_snapshot_on_gc);
+ // https://crbug.com/550629905
+#if V8_ENABLE_WEBASSEMBLY
+ RESET_WHEN_CORRECTNESS_FUZZING(wasm_pgo_to_file);
+#endif // V8_ENABLE_WEBASSEMBLY
+
// https://crbug.com/369974230
RESET_WHEN_FUZZING(expose_async_hooks);
@@ -1457,6 +1499,21 @@ void FlagList::ResolveContradictionsWhenFuzzing() {
RESET_WHEN_FUZZING(array_destructure_bytecode);
}
+#if V8_ENABLE_WEBASSEMBLY
+ if (v8_flags.wasm_max_code_space_size_mb > kDefaultMaxWasmCodeSpaceSizeMb) {
+ // Skip the warning on correctness (differential) fuzzing to prevent false
+ // positives.
+ if (!v8_flags.correctness_fuzzer_suppressions) {
+ std::cerr << "Warning: lowering flag --wasm-max-code-space-size-mb="
+ << v8_flags.wasm_max_code_space_size_mb
+ << " to --wasm-max-code-space-size-mb="
+ << kDefaultMaxWasmCodeSpaceSizeMb
+ << ", larger values are unsupported";
+ }
+ v8_flags.wasm_max_code_space_size_mb = kDefaultMaxWasmCodeSpaceSizeMb;
+ }
+#endif
+
for (auto [flag1, flag2] : contradictions) {
if (!flag1 || !flag2) continue;
if (flag1->IsDefault() || flag2->IsDefault()) continue;
diff --git a/deps/v8/src/fuzzilli/OWNERS b/deps/v8/src/fuzzilli/OWNERS
index d64e372d757..251231a879a 100644
--- a/deps/v8/src/fuzzilli/OWNERS
+++ b/deps/v8/src/fuzzilli/OWNERS
@@ -1,4 +1,7 @@
+bettscheider@chromium.org
cffsmith@chromium.org
machenbach@chromium.org
+marja@chromium.org
mliedtke@chromium.org
+rherouart@chromium.org
saelo@chromium.org
diff --git a/deps/v8/src/fuzzilli/cov.cc b/deps/v8/src/fuzzilli/cov.cc
index e263268d59e..1dc9ba72d25 100644
--- a/deps/v8/src/fuzzilli/cov.cc
+++ b/deps/v8/src/fuzzilli/cov.cc
@@ -183,10 +183,7 @@ __attribute__((visibility("default"))) uint32_t
sanitizer_cov_count_discovered_edges() {
uint32_t on_edges_counter = 0;
for (uint32_t i = 1; i < builtins_start; ++i) {
- const uint32_t byteIndex = i >> 3; // Divide by 8 using a shift operation
- const uint32_t bitIndex = i & 7; // Modulo 8 using a bitwise AND operation
-
- if (shmem->edges[byteIndex] & (1 << bitIndex)) {
+ if (cov_is_edge_set(shmem->edges, i)) {
++on_edges_counter;
}
}
@@ -214,7 +211,7 @@ __sanitizer_cov_trace_pc_guard(uint32_t* guard) {
uint32_t old_pkru = GrantDefaultPkeyAccessIfNecessary();
#endif // V8_ENABLE_SANDBOX_HARDWARE_SUPPORT
- shmem->edges[index / 8] |= 1 << (index % 8);
+ cov_set_edge(shmem->edges, index);
#ifndef USE_CHROMIUM_FUZZILLI
// This is a hot path, so use a macro instead of an if statement.
@@ -244,21 +241,10 @@ void cov_init_builtins_edges(uint32_t num_edges) {
num_edges);
}
-// This function is ran once per REPRL loop. In case of crash the coverage of
-// crash will not be stored in shared memory. Therefore, it would be useful, if
-// we could store these coverage information into shared memory in real time.
-void cov_update_builtins_basic_block_coverage(
- const std::vector<bool>& cov_map) {
- if (cov_map.size() != builtins_edge_count) {
- fprintf(stderr, "[COV] Error: Size of builtins cov map changed.\n");
- exit(-1);
- }
- for (uint32_t i = 0; i < cov_map.size(); ++i) {
- if (cov_map[i]) {
- const uint32_t byteIndex = (i + builtins_start) >> 3;
- const uint32_t bitIndex = (i + builtins_start) & 7;
+bool cov_has_builtins_edges() {
+ return builtins_edge_count > 0 && shmem != nullptr;
+}
- shmem->edges[byteIndex] |= (1 << bitIndex);
- }
- }
+void cov_set_builtin_edge(uint32_t block_index) {
+ cov_set_edge(shmem->edges, builtins_start + block_index);
}
diff --git a/deps/v8/src/fuzzilli/cov.h b/deps/v8/src/fuzzilli/cov.h
index 2bca96a654a..74a59ceb3f0 100644
--- a/deps/v8/src/fuzzilli/cov.h
+++ b/deps/v8/src/fuzzilli/cov.h
@@ -13,10 +13,23 @@
#include <cstdint>
#include <vector>
+inline void cov_set_edge(uint8_t* edges, uint32_t index) {
+ const uint32_t byte_index = index >> 3;
+ const uint32_t bit_index = index & 7;
+ edges[byte_index] |= static_cast<uint8_t>(1 << bit_index);
+}
+
+inline bool cov_is_edge_set(const uint8_t* edges, uint32_t index) {
+ const uint32_t byte_index = index >> 3;
+ const uint32_t bit_index = index & 7;
+ return (edges[byte_index] & (1 << bit_index)) != 0;
+}
+
void fuzzilli_cov_enable();
void sanitizer_cov_reset_edgeguards();
uint32_t sanitizer_cov_count_discovered_edges();
void cov_init_builtins_edges(uint32_t num_edges);
-void cov_update_builtins_basic_block_coverage(const std::vector<bool>& cov_map);
+bool cov_has_builtins_edges();
+void cov_set_builtin_edge(uint32_t block_index);
#endif // V8_FUZZILLI_COV_H_
diff --git a/deps/v8/src/handles/global-handles.cc b/deps/v8/src/handles/global-handles.cc
index e03603371cd..fa3079d554f 100644
--- a/deps/v8/src/handles/global-handles.cc
+++ b/deps/v8/src/handles/global-handles.cc
@@ -410,12 +410,11 @@ namespace {
void ExtractInternalFields(Tagged<JSObject> jsobject, void** embedder_fields,
int len) {
int field_count = jsobject->GetEmbedderFieldCount();
- IsolateForSandbox isolate = GetCurrentIsolateForSandbox();
for (int i = 0; i < len; ++i) {
if (field_count == i) break;
void* pointer;
if (EmbedderDataSlot(jsobject, i)
- .DeprecatedToAlignedPointer(isolate, &pointer)) {
+ .DeprecatedToAlignedPointer(Isolate::Current(), &pointer)) {
embedder_fields[i] = pointer;
}
}
diff --git a/deps/v8/src/handles/handles.h b/deps/v8/src/handles/handles.h
index 9269281671c..0bbe40f806b 100644
--- a/deps/v8/src/handles/handles.h
+++ b/deps/v8/src/handles/handles.h
@@ -312,7 +312,7 @@ class V8_NODISCARD HandleScope {
// Limit for number of handles with --check-handle-count. This is
// large enough to compile natives and pass unit tests with some
// slack for future changes to natives.
- static const int kCheckHandleThreshold = 32 * 1024;
+ static const int kCheckHandleThreshold = 48 * 1024;
private:
Isolate* isolate_;
diff --git a/deps/v8/src/heap/concurrent-marking.cc b/deps/v8/src/heap/concurrent-marking.cc
index 2339116faac..1648ad6d95e 100644
--- a/deps/v8/src/heap/concurrent-marking.cc
+++ b/deps/v8/src/heap/concurrent-marking.cc
@@ -506,16 +506,16 @@ V8_INLINE size_t ConcurrentMarking::RunMinorImpl(JobDelegate* delegate,
size_t marked_bytes = 0;
size_t current_marked_bytes = 0;
int objects_processed = 0;
+ YoungPendingAllocations* const young_pending_allocations =
+ heap_->young_pending_allocations();
+ YoungPendingAllocations::Snapshot young_pending_snapshot;
YoungGenerationMarkingVisitor<marking_mode> visitor(
- heap_, &task_state->local_pretenuring_feedback);
+ heap_, &task_state->local_pretenuring_feedback, &young_pending_snapshot);
YoungGenerationRememberedSetsMarkingWorklist::Local remembered_sets(
heap_->minor_mark_sweep_collector()->remembered_sets_marking_handler());
auto& marking_worklists_local = visitor.marking_worklists_local();
Isolate* isolate = heap_->isolate();
minor_marking_state_->MarkerStarted();
- YoungPendingAllocations* const young_pending_allocations =
- heap_->young_pending_allocations();
- YoungPendingAllocations::Snapshot young_pending_snapshot;
do {
if (delegate->IsJoiningThread()) {
diff --git a/deps/v8/src/heap/cppgc-internal/explicit-management.cc b/deps/v8/src/heap/cppgc-internal/explicit-management.cc
index 040258df19a..8f9b5efb04c 100644
--- a/deps/v8/src/heap/cppgc-internal/explicit-management.cc
+++ b/deps/v8/src/heap/cppgc-internal/explicit-management.cc
@@ -92,6 +92,7 @@ bool Grow(HeapObjectHeader& header, BasePage& base_page, size_t new_size,
size_t size_delta) {
DCHECK_GE(new_size, header.AllocatedSize() + kAllocationGranularity);
DCHECK_GE(size_delta, kAllocationGranularity);
+ DCHECK_LT(new_size, kLargeObjectSizeThreshold);
DCHECK(!base_page.is_large());
auto& normal_space = *static_cast<NormalPageSpace*>(&base_page.space());
@@ -120,6 +121,7 @@ bool Shrink(HeapObjectHeader& header, BasePage& base_page, size_t new_size,
size_t size_delta) {
DCHECK_GE(header.AllocatedSize(), new_size + kAllocationGranularity);
DCHECK_GE(size_delta, kAllocationGranularity);
+ DCHECK_GE(new_size, sizeof(HeapObjectHeader));
DCHECK(!base_page.is_large());
auto& normal_space = *static_cast<NormalPageSpace*>(&base_page.space());
@@ -176,9 +178,14 @@ bool ExplicitManagementImpl::Resize(void* object, size_t new_object_size) {
const size_t new_size = RoundUp<kAllocationGranularity>(
sizeof(HeapObjectHeader) + new_object_size);
+
+ if (new_size < sizeof(HeapObjectHeader) ||
+ new_size >= kLargeObjectSizeThreshold) {
+ return false;
+ }
+
auto& header = HeapObjectHeader::FromObject(object);
const size_t old_size = header.AllocatedSize();
-
if (new_size > old_size) {
return Grow(header, *base_page, new_size, new_size - old_size);
} else if (old_size > new_size) {
diff --git a/deps/v8/src/heap/cppgc-internal/heap-object-header.h b/deps/v8/src/heap/cppgc-internal/heap-object-header.h
index 0155cd6b559..33e26d1ef8f 100644
--- a/deps/v8/src/heap/cppgc-internal/heap-object-header.h
+++ b/deps/v8/src/heap/cppgc-internal/heap-object-header.h
@@ -189,6 +189,19 @@ HeapObjectHeader::HeapObjectHeader(size_t size, GCInfoIndex gc_info_index) {
DCHECK_LT(gc_info_index, kMaxGCInfoIndex);
DCHECK_EQ(0u, size & (sizeof(HeapObjectHeader) - 1));
DCHECK_GE(kMaxSize, size);
+#if defined(V8_HOST_ARCH_64_BIT)
+#if defined(V8_TARGET_BIG_ENDIAN)
+ const uint64_t header_word =
+ (static_cast<uint64_t>(GCInfoIndexField::encode(gc_info_index)) << 16) |
+ static_cast<uint64_t>(EncodeSize(size));
+#else // !defined(V8_TARGET_BIG_ENDIAN)
+ const uint64_t header_word =
+ (static_cast<uint64_t>(GCInfoIndexField::encode(gc_info_index)) << 32) |
+ (static_cast<uint64_t>(EncodeSize(size)) << 48);
+#endif // !defined(V8_TARGET_BIG_ENDIAN)
+ std::atomic_ref<uint64_t>(*reinterpret_cast<uint64_t*>(this))
+ .store(header_word, std::memory_order_relaxed);
+#else // !defined(V8_HOST_ARCH_64_BIT)
encoded_low_ = EncodeSize(size);
// Objects may get published to the marker without any other synchronization
// (e.g., write barrier) in which case the in-construction bit is read
@@ -199,6 +212,7 @@ HeapObjectHeader::HeapObjectHeader(size_t size, GCInfoIndex gc_info_index) {
std::atomic_ref<uint16_t>(encoded_high_)
.store(GCInfoIndexField::encode(gc_info_index),
std::memory_order_relaxed);
+#endif // !defined(V8_HOST_ARCH_64_BIT)
DCHECK(IsInConstruction());
#ifdef DEBUG
CheckApiConstants();
diff --git a/deps/v8/src/heap/cppgc-internal/heap-page.h b/deps/v8/src/heap/cppgc-internal/heap-page.h
index ba57e680926..ad9c77d9ab6 100644
--- a/deps/v8/src/heap/cppgc-internal/heap-page.h
+++ b/deps/v8/src/heap/cppgc-internal/heap-page.h
@@ -237,6 +237,10 @@ class V8_EXPORT_PRIVATE NormalPage final : public BasePage {
Address PayloadEnd();
ConstAddress PayloadEnd() const;
+ static constexpr size_t PageHeaderSize() {
+ return RoundUp(sizeof(NormalPage), kAllocationGranularity);
+ }
+
static constexpr size_t PayloadSize();
bool PayloadContains(ConstAddress address) const {
diff --git a/deps/v8/src/heap/cppgc-internal/heap-space.h b/deps/v8/src/heap/cppgc-internal/heap-space.h
index 1adc14a7844..f6be1feae2e 100644
--- a/deps/v8/src/heap/cppgc-internal/heap-space.h
+++ b/deps/v8/src/heap/cppgc-internal/heap-space.h
@@ -70,24 +70,24 @@ class V8_EXPORT_PRIVATE NormalPageSpace final : public BaseSpace {
class LinearAllocationBuffer {
public:
Address Allocate(size_t alloc_size) {
- DCHECK_GE(size_, alloc_size);
+ DCHECK_GE(size(), alloc_size);
Address result = start_;
start_ += alloc_size;
- size_ -= alloc_size;
return result;
}
void Set(Address ptr, size_t size) {
start_ = ptr;
- size_ = size;
+ limit_ = ptr + size;
}
Address start() const { return start_; }
- size_t size() const { return size_; }
+ Address limit() const { return limit_; }
+ size_t size() const { return static_cast<size_t>(limit_ - start_); }
private:
Address start_ = nullptr;
- size_t size_ = 0;
+ Address limit_ = nullptr;
};
static NormalPageSpace& From(BaseSpace& space) {
diff --git a/deps/v8/src/heap/cppgc-internal/marking-state.h b/deps/v8/src/heap/cppgc-internal/marking-state.h
index 99aef45b9b8..9d729f4ee42 100644
--- a/deps/v8/src/heap/cppgc-internal/marking-state.h
+++ b/deps/v8/src/heap/cppgc-internal/marking-state.h
@@ -48,8 +48,6 @@ class MarkingStateBase {
}
protected:
- inline void MarkAndPush(HeapObjectHeader&, TraceDescriptor);
-
inline bool MarkNoPush(HeapObjectHeader&);
HeapBase& heap_;
@@ -68,13 +66,9 @@ MarkingStateBase::MarkingStateBase(HeapBase& heap,
void MarkingStateBase::MarkAndPush(const void* object, TraceDescriptor desc) {
DCHECK_NOT_NULL(object);
- MarkAndPush(
- HeapObjectHeader::FromObject(const_cast<void*>(desc.base_object_payload)),
- desc);
-}
+ HeapObjectHeader& header =
+ HeapObjectHeader::FromObject(const_cast<void*>(desc.base_object_payload));
-void MarkingStateBase::MarkAndPush(HeapObjectHeader& header,
- TraceDescriptor desc) {
DCHECK_NOT_NULL(desc.callback);
if (header.IsInConstruction<AccessMode::kAtomic>()) {
@@ -94,10 +88,14 @@ bool MarkingStateBase::MarkNoPush(HeapObjectHeader& header) {
}
void MarkingStateBase::MarkAndPush(HeapObjectHeader& header) {
- MarkAndPush(
- header,
- {header.ObjectStart(),
- GlobalGCInfoTable::GCInfoFromIndex(header.GetGCInfoIndex()).trace});
+ if (header.IsInConstruction<AccessMode::kAtomic>()) {
+ not_fully_constructed_worklist_.Push<AccessMode::kAtomic>(&header);
+ } else if (MarkNoPush(header)) {
+ PushMarked(
+ header,
+ {header.ObjectStart(),
+ GlobalGCInfoTable::GCInfoFromIndex(header.GetGCInfoIndex()).trace});
+ }
}
void MarkingStateBase::PushMarked(HeapObjectHeader& header,
diff --git a/deps/v8/src/heap/cppgc-internal/memory.h b/deps/v8/src/heap/cppgc-internal/memory.h
index 412e8365dea..8f60737c32a 100644
--- a/deps/v8/src/heap/cppgc-internal/memory.h
+++ b/deps/v8/src/heap/cppgc-internal/memory.h
@@ -40,11 +40,17 @@ V8_INLINE void CheckMemoryIsZero(const void* address, size_t size) {
}
}
+#if defined(V8_USE_MEMORY_SANITIZER) || defined(V8_USE_ADDRESS_SANITIZER) || \
+ DEBUG
+#define CPPGC_SHOULD_ZAP_MEMORY 1
+#else
+#define CPPGC_SHOULD_ZAP_MEMORY 0
+#endif
+
// Together `SetMemoryAccessible()` and `SetMemoryInaccessible()` form the
// memory access model for allocation and free.
-#if defined(V8_USE_MEMORY_SANITIZER) || defined(V8_USE_ADDRESS_SANITIZER) || \
- DEBUG
+#if CPPGC_SHOULD_ZAP_MEMORY
void SetMemoryAccessible(void* address, size_t size);
void SetMemoryInaccessible(void* address, size_t size);
diff --git a/deps/v8/src/heap/cppgc-internal/page-memory.cc b/deps/v8/src/heap/cppgc-internal/page-memory.cc
index c4016160dec..60afa7100bd 100644
--- a/deps/v8/src/heap/cppgc-internal/page-memory.cc
+++ b/deps/v8/src/heap/cppgc-internal/page-memory.cc
@@ -11,6 +11,7 @@
#include "include/v8config.h"
#include "src/base/macros.h"
#include "src/base/sanitizer/asan.h"
+#include "src/heap/cppgc-internal/heap-page.h"
#include "src/heap/cppgc-internal/memory.h"
#include "src/heap/cppgc-internal/platform.h"
@@ -110,7 +111,13 @@ void NormalPageMemoryPool::Add(PageMemoryRegion* pmr) {
// Oilpan requires the pages to be zero-initialized.
{
void* base = pmr->region().base();
+#if CPPGC_SHOULD_ZAP_MEMORY
const size_t size = pmr->region().size();
+#else
+ // In release builds, swept page payloads are already zero-initialized by
+ // SetMemoryInaccessible(). Only the page header needs to be zeroed.
+ const size_t size = NormalPage::PageHeaderSize();
+#endif
AsanUnpoisonScope unpoison_for_memset(base, size);
std::memset(base, 0, size);
}
diff --git a/deps/v8/src/heap/cppgc-js/cpp-heap.cc b/deps/v8/src/heap/cppgc-js/cpp-heap.cc
index b897df95238..120bcce5a11 100644
--- a/deps/v8/src/heap/cppgc-js/cpp-heap.cc
+++ b/deps/v8/src/heap/cppgc-js/cpp-heap.cc
@@ -49,6 +49,7 @@
#include "src/heap/gc-tracer.h"
#include "src/heap/heap-controller.h"
#include "src/heap/heap.h"
+#include "src/heap/incremental-marking.h"
#include "src/heap/marking-worklist.h"
#include "src/heap/minor-mark-sweep.h"
#include "src/heap/traced-handles-marking-visitor.h"
@@ -116,8 +117,6 @@ cppgc::HeapHandle& CppHeap::GetHeapHandle() {
return *internal::CppHeap::From(this);
}
-void CppHeap::Terminate() { internal::CppHeap::From(this)->Terminate(); }
-
cppgc::HeapStatistics CppHeap::CollectStatistics(
cppgc::HeapStatistics::DetailLevel detail_level) {
return internal::CppHeap::From(this)->AsBase().CollectStatistics(
@@ -147,6 +146,15 @@ void CppHeap::CollectGarbageInYoungGenerationForTesting(
internal::CppHeap::CollectionType::kMinor, stack_state);
}
+void CppHeap::SetForceIncrementalSweepingForTesting(bool value) {
+ return internal::CppHeap::From(this)->SetForceIncrementalSweepingForTesting(
+ value);
+}
+
+void CppHeap::FinishSweepingForTesting() {
+ return internal::CppHeap::From(this)->FinishSweepingIfRunning();
+}
+
namespace internal {
namespace {
@@ -538,14 +546,6 @@ CppHeap::CppHeap(
}
CppHeap::~CppHeap() {
- Terminate();
-}
-
-void CppHeap::Terminate() {
- // TODO(ahaas): Remove `already_terminated_` once the V8 API
- // CppHeap::Terminate has been removed.
- if (already_terminated_) return;
- already_terminated_ = true;
// Must not be attached to a heap when invoking termination GCs.
CHECK(!isolate_);
// Gracefully terminate the C++ heap invoking destructors.
@@ -630,6 +630,7 @@ void CppHeap::AttachIsolate(Isolate* isolate) {
CHECK_NULL(isolate_);
isolate_ = isolate;
heap_ = isolate->heap();
+ isolate_alive_token_ = std::make_shared<bool>(true);
stack_->SetScanSimulatorCallback(
Isolate::IterateRegistersAndStackOfSimulator);
static_cast<CppgcPlatformAdapter*>(platform())
@@ -745,7 +746,15 @@ CppHeap::MarkingType CppHeap::SelectMarkingType() const {
}
CppHeap::SweepingType CppHeap::SelectSweepingType() const {
- if (IsForceGC(current_gc_flags_)) return SweepingType::kAtomic;
+ // A forced GC normally sweeps atomically, which runs finalizers before the
+ // collection returns. Tests that need to observe an object after it has been
+ // found unreachable but before it is finalized opt out via
+ // SetForceIncrementalSweepingForTesting(), which leaves sweeping deferred as
+ // it would be in a natural GC.
+ if (IsForceGC(current_gc_flags_) &&
+ !force_incremental_sweeping_for_testing_) {
+ return SweepingType::kAtomic;
+ }
return sweeping_support();
}
@@ -1087,9 +1096,9 @@ void CppHeap::ReportBufferedAllocationSizeIfPossible() {
std::memory_order_relaxed);
allocated_size_ += bytes_to_report;
- if (v8_flags.incremental_marking) {
- if (allocated_size_ > allocated_size_limit_for_check_) {
- Heap* heap = isolate_->heap();
+ Heap* heap = isolate_->heap();
+ if (allocated_size_ > allocated_size_limit_for_check_) {
+ if (v8_flags.incremental_marking) {
heap->StartIncrementalMarkingIfAllocationLimitIsReached(
heap->main_thread_local_heap(),
heap->GCFlagsForIncrementalMarking(),
@@ -1102,9 +1111,17 @@ void CppHeap::ReportBufferedAllocationSizeIfPossible() {
heap->incremental_marking()->AdvanceOnAllocation();
}
}
- allocated_size_limit_for_check_ =
- allocated_size_ + kIncrementalMarkingCheckInterval;
+ } else if (heap->deserialization_complete()) {
+ if (heap->GlobalSpaceAvailable() == 0 ||
+ heap->OldGenerationSpaceAvailable() == 0) {
+ heap->CollectGarbage(
+ OLD_SPACE, heap->OldGenerationSpaceAvailable() == 0
+ ? GarbageCollectionReason::kAllocationLimit
+ : GarbageCollectionReason::kGlobalAllocationLimit);
+ }
}
+ allocated_size_limit_for_check_ =
+ allocated_size_ + kIncrementalMarkingCheckInterval;
}
}
}
diff --git a/deps/v8/src/heap/cppgc-js/cpp-heap.h b/deps/v8/src/heap/cppgc-js/cpp-heap.h
index c8618c0aae2..106894d8a74 100644
--- a/deps/v8/src/heap/cppgc-js/cpp-heap.h
+++ b/deps/v8/src/heap/cppgc-js/cpp-heap.h
@@ -124,8 +124,6 @@ class V8_EXPORT_PRIVATE CppHeap final
void StartDetachingIsolate();
void DetachIsolate();
- void Terminate();
-
void CollectCustomSpaceStatisticsAtLastGC(
std::vector<cppgc::CustomSpaceIndex>,
std::unique_ptr<CustomSpaceStatisticsReceiver>);
@@ -169,6 +167,13 @@ class V8_EXPORT_PRIVATE CppHeap final
MetricRecorderAdapter* GetMetricRecorder() const;
Isolate* isolate() const { return isolate_; }
+ std::shared_ptr<bool> isolate_alive_token() const {
+ return isolate_alive_token_;
+ }
+ void invalidate_isolate_alive_token() {
+ *isolate_alive_token_ = false;
+ isolate_alive_token_.reset();
+ }
size_t used_size() const {
return used_size_.load(std::memory_order_relaxed);
@@ -206,6 +211,12 @@ class V8_EXPORT_PRIVATE CppHeap final
void EnableDetachedGarbageCollectionsForTesting();
void CollectGarbageForTesting(CollectionType, StackState);
void UpdateGCCapabilitiesFromFlagsForTesting();
+ // Only meaningful for a heap attached to an isolate: CompactAndSweep()
+ // requires atomic sweeping when there is no isolate.
+ void SetForceIncrementalSweepingForTesting(bool value) {
+ DCHECK_IMPLIES(value, isolate_ != nullptr);
+ force_incremental_sweeping_for_testing_ = value;
+ }
bool CurrentThreadIsHeapThread() const final;
@@ -238,6 +249,11 @@ class V8_EXPORT_PRIVATE CppHeap final
Isolate* isolate_ = nullptr;
Heap* heap_ = nullptr;
+ // Token to indicate that the isolate is alive. The token is only reset to
+ // false when the CppHeap gets released from the isolate. Otherwise, the
+ // CppHeap dies together with the isolate, and therefore the token never has
+ // to be set to false.
+ std::shared_ptr<bool> isolate_alive_token_;
bool marking_done_ = true;
// |collection_type_| is initialized when marking is in progress.
std::optional<CollectionType> collection_type_;
@@ -256,6 +272,7 @@ class V8_EXPORT_PRIVATE CppHeap final
bool in_detached_testing_mode_ = false;
bool force_incremental_marking_for_testing_ = false;
+ bool force_incremental_sweeping_for_testing_ = false;
bool is_in_v8_marking_step_ = false;
// Used size of objects. Reported to V8's regular heap growing strategy.
@@ -275,7 +292,6 @@ class V8_EXPORT_PRIVATE CppHeap final
std::optional<v8::base::RandomNumberGenerator> allocation_timeout_rng_;
#endif // V8_ENABLE_ALLOCATION_TIMEOUT
- bool already_terminated_ = false;
bool is_detached_ = true;
friend class MetricRecorderAdapter;
diff --git a/deps/v8/src/heap/factory-base.h b/deps/v8/src/heap/factory-base.h
index ead2434a776..8ee1f9b9cc7 100644
--- a/deps/v8/src/heap/factory-base.h
+++ b/deps/v8/src/heap/factory-base.h
@@ -16,7 +16,12 @@
#include "src/objects/function-kind.h"
#include "src/objects/instance-type.h"
#include "src/roots/roots.h"
+#ifndef V8_METAGEN_GENERATION_PASS
+// Forward declarations only, and generated after the metagen harvest
+// parses this header. The harvest reads class definitions, so nothing
+// it collects comes from here.
#include "torque-generated/class-forward-declarations.h"
+#endif
namespace v8 {
namespace internal {
@@ -32,12 +37,14 @@ template <typename T, typename Base>
class FixedIntegerArrayBase;
class FreshlyAllocatedBigInt;
class FunctionLiteral;
+class FunctionTemplateRareData;
class HeapObject;
class ObjectBoilerplateDescription;
template <typename T>
class PodArray;
class PreparseData;
class RegExpBoilerplateDescription;
+class RegExpDataWrapper;
class SeqOneByteString;
class SeqTwoByteString;
class SharedFunctionInfo;
diff --git a/deps/v8/src/heap/factory.cc b/deps/v8/src/heap/factory.cc
index 682d303ab7d..6390e956594 100644
--- a/deps/v8/src/heap/factory.cc
+++ b/deps/v8/src/heap/factory.cc
@@ -41,7 +41,6 @@
#include "src/numbers/conversions.h"
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/allocation-site-inl.h"
-#include "src/objects/allocation-site-scopes.h"
#include "src/objects/api-callbacks.h"
#include "src/objects/arguments-inl.h"
#include "src/objects/bigint.h"
@@ -969,91 +968,92 @@ MaybeHandle<String> NewStringFromUtf8Variant(Isolate* isolate,
UNREACHABLE();
}
+inline base::OwnedVector<uint8_t> CopyBytes(const base::Atomic8* src,
+ size_t length) {
+ auto copy = base::OwnedVector<uint8_t>::NewForOverwrite(length);
+ base::Relaxed_Memcpy(reinterpret_cast<base::Atomic8*>(copy.data()), src,
+ length);
+ return copy;
+}
+
+#if V8_ENABLE_WEBASSEMBLY
+inline base::OwnedVector<uint16_t> CopyCodeUnits(const base::Atomic16* src,
+ size_t length) {
+ auto copy = base::OwnedVector<uint16_t>::NewForOverwrite(length);
+ for (size_t i = 0; i < length; i++) {
+ auto dest = reinterpret_cast<base::Atomic16*>(copy.data() + i);
+ base::Relaxed_Store(dest, base::Relaxed_Load(src + i));
+ }
+ return copy;
+}
+#endif // V8_ENABLE_WEBASSEMBLY
+
} // namespace
MaybeHandle<String> Factory::NewStringFromUtf8(
- base::Vector<const uint8_t> string, unibrow::Utf8Variant utf8_variant,
+ base::Vector<const uint8_t> string, UnicodeConfig config,
AllocationType allocation) {
if (string.size() > kMaxInt) {
// The Utf8Decode can't handle longer inputs, and we couldn't create
// strings from them anyway.
THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError());
}
- auto peek_bytes = [&]() -> base::Vector<const uint8_t> { return string; };
- return NewStringFromUtf8Variant(isolate(), peek_bytes, utf8_variant,
+ base::OwnedVector<uint8_t> private_copy;
+ if (config.source_shared()) {
+ private_copy = CopyBytes(
+ reinterpret_cast<const base::Atomic8*>(string.data()), string.size());
+ }
+ auto peek_bytes = [&]() -> base::Vector<const uint8_t> {
+ return config.source_shared() ? private_copy.as_vector() : string;
+ };
+ if (config.dest_shared()) {
+ return NewStringFromUtf8Variant(isolate(), peek_bytes, config.variant(),
+ SharedStringBuilder{},
+ AllocationType::kSharedOld);
+ }
+ return NewStringFromUtf8Variant(isolate(), peek_bytes, config.variant(),
StringBuilder{}, allocation);
}
MaybeHandle<String> Factory::NewStringFromUtf8(base::Vector<const char> string,
AllocationType allocation) {
return NewStringFromUtf8(base::Vector<const uint8_t>::cast(string),
- unibrow::Utf8Variant::kLossyUtf8, allocation);
-}
-
-MaybeHandle<String> Factory::NewSharedStringFromUtf8(
- base::Vector<const uint8_t> string, unibrow::Utf8Variant utf8_variant) {
- if (string.size() > kMaxInt) {
- // The Utf8Decode can't handle longer inputs, and we couldn't create
- // strings from them anyway.
- THROW_NEW_ERROR(isolate(), NewInvalidStringLengthError());
- }
- auto peek_bytes = [&]() -> base::Vector<const uint8_t> { return string; };
- return NewStringFromUtf8Variant(isolate(), peek_bytes, utf8_variant,
- SharedStringBuilder{},
- AllocationType::kSharedOld);
-}
-
-MaybeHandle<String> Factory::NewSharedStringFromUtf8(
- base::Vector<const char> string) {
- return NewSharedStringFromUtf8(base::Vector<const uint8_t>::cast(string),
- unibrow::Utf8Variant::kLossyUtf8);
+ UnicodeConfig(unibrow::Utf8Variant::kLossyUtf8),
+ allocation);
}
#if V8_ENABLE_WEBASSEMBLY
MaybeDirectHandle<String> Factory::NewStringFromUtf8(
DirectHandle<WasmArray> array, uint32_t start, uint32_t end,
- unibrow::Utf8Variant utf8_variant, AllocationType allocation) {
- DCHECK_EQ(sizeof(uint8_t), WasmArray::DecodeElementSizeFromMap(array->map()));
- DCHECK_LE(start, end);
- DCHECK_LE(end, array->length());
- // {end - start} can never be more than what the Utf8Decoder can handle.
- static_assert(WasmArray::MaxLength(sizeof(uint8_t)) <= kMaxInt);
- auto peek_bytes = [&]() -> base::Vector<const uint8_t> {
- const uint8_t* contents =
- reinterpret_cast<const uint8_t*>(array->ElementAddress(0));
- return {contents + start, end - start};
- };
- return NewStringFromUtf8Variant(isolate(), peek_bytes, utf8_variant,
- StringBuilder{}, allocation);
-}
-
-MaybeDirectHandle<String> Factory::NewSharedStringFromUtf8(
- DirectHandle<WasmArray> array, uint32_t start, uint32_t end,
- unibrow::Utf8Variant utf8_variant) {
+ UnicodeConfig config) {
DCHECK_EQ(sizeof(uint8_t), WasmArray::DecodeElementSizeFromMap(array->map()));
DCHECK_LE(start, end);
DCHECK_LE(end, array->length());
// {end - start} can never be more than what the Utf8Decoder can handle.
static_assert(WasmArray::MaxLength(sizeof(uint8_t)) <= kMaxInt);
- // We need a private copy of the array's contents. We have a pass that
- // validates utf8/computes the string's length and one that copies the bytes,
- // and we cannot afford to have concurrent modifications to the array between
- // those.
-
uint32_t length = end - start;
- const base::Atomic8* contents =
- reinterpret_cast<base::Atomic8*>(array->ElementAddress(start));
- auto private_copy = base::OwnedVector<uint8_t>::NewForOverwrite(length);
- base::Relaxed_Memcpy(reinterpret_cast<base::Atomic8*>(private_copy.data()),
- contents, length);
-
+ base::OwnedVector<uint8_t> private_copy;
+ if (config.source_shared()) {
+ private_copy = CopyBytes(
+ reinterpret_cast<const base::Atomic8*>(array->ElementAddress(start)),
+ length);
+ }
auto peek_bytes = [&]() -> base::Vector<const uint8_t> {
- return private_copy.as_vector();
+ if (config.source_shared()) {
+ return private_copy.as_vector();
+ }
+ const uint8_t* contents =
+ reinterpret_cast<const uint8_t*>(array->ElementAddress(0));
+ return {contents + start, length};
};
- return NewStringFromUtf8Variant(isolate(), peek_bytes, utf8_variant,
- SharedStringBuilder{},
- AllocationType::kSharedOld);
+ if (config.dest_shared()) {
+ return NewStringFromUtf8Variant(isolate(), peek_bytes, config.variant(),
+ SharedStringBuilder{},
+ AllocationType::kSharedOld);
+ }
+ return NewStringFromUtf8Variant(isolate(), peek_bytes, config.variant(),
+ StringBuilder{}, AllocationType::kYoung);
}
MaybeHandle<String> Factory::NewStringFromUtf8(
@@ -1090,54 +1090,38 @@ struct Wtf16Decoder {
MaybeDirectHandle<String> Factory::NewStringFromUtf16(
DirectHandle<WasmArray> array, uint32_t start, uint32_t end,
- AllocationType allocation) {
+ UnicodeConfig config) {
DCHECK_EQ(sizeof(uint16_t),
WasmArray::DecodeElementSizeFromMap(array->map()));
DCHECK_LE(start, end);
DCHECK_LE(end, array->length());
// {end - start} can never be more than what the Utf8Decoder can handle.
static_assert(WasmArray::MaxLength(sizeof(uint16_t)) <= kMaxInt);
- auto peek_bytes = [&]() -> base::Vector<const uint16_t> {
- const uint16_t* contents =
- reinterpret_cast<const uint16_t*>(array->ElementAddress(0));
- return {contents + start, end - start};
- };
- return NewStringFromBytes<Wtf16Decoder, decltype(peek_bytes),
- NonSharedStringPolicy>(
- isolate(), peek_bytes, allocation, MessageTemplate::kNone);
-}
-
-MaybeDirectHandle<String> Factory::NewSharedStringFromUtf16(
- DirectHandle<WasmArray> array, uint32_t start, uint32_t end) {
- DCHECK_EQ(sizeof(uint16_t),
- WasmArray::DecodeElementSizeFromMap(array->map()));
- DCHECK_LE(start, end);
- DCHECK_LE(end, array->length());
- // {end - start} can never be more than what the Utf8Decoder can handle.
- static_assert(WasmArray::MaxLength(sizeof(uint16_t)) <= kMaxInt);
-
- // We need a private copy of the array's contents. We have a pass that
- // checks whether the string is one-byte and one that copies the bytes,
- // and we cannot afford to have concurrent modifications to the array between
- // those.
uint32_t length = end - start;
- const base::Atomic16* contents =
- reinterpret_cast<base::Atomic16*>(array->ElementAddress(start));
- auto private_copy = base::OwnedVector<uint16_t>::NewForOverwrite(length);
-
- for (uint32_t i = 0; i < length; i++) {
- auto dest = reinterpret_cast<base::Atomic16*>(private_copy.data() + i);
- base::Relaxed_Store(dest, base::Relaxed_Load(contents + i));
+ base::OwnedVector<uint16_t> private_copy;
+ if (config.source_shared()) {
+ private_copy = CopyCodeUnits(
+ reinterpret_cast<const base::Atomic16*>(array->ElementAddress(start)),
+ length);
}
-
auto peek_bytes = [&]() -> base::Vector<const uint16_t> {
- return private_copy.as_vector();
+ if (config.source_shared()) {
+ return private_copy.as_vector();
+ }
+ const uint16_t* contents =
+ reinterpret_cast<const uint16_t*>(array->ElementAddress(0));
+ return {contents + start, length};
};
+ if (config.dest_shared()) {
+ return NewStringFromBytes<Wtf16Decoder, decltype(peek_bytes),
+ SharedStringPolicy>(isolate(), peek_bytes,
+ AllocationType::kSharedOld,
+ MessageTemplate::kNone);
+ }
return NewStringFromBytes<Wtf16Decoder, decltype(peek_bytes),
- SharedStringPolicy>(isolate(), peek_bytes,
- AllocationType::kSharedOld,
- MessageTemplate::kNone);
+ NonSharedStringPolicy>(
+ isolate(), peek_bytes, AllocationType::kYoung, MessageTemplate::kNone);
}
MaybeDirectHandle<String> Factory::WasmStringAddShared(
@@ -1224,9 +1208,26 @@ MaybeDirectHandle<String> Factory::NewStringFromTwoByte(
#if V8_ENABLE_WEBASSEMBLY
MaybeDirectHandle<String> Factory::NewStringFromTwoByteLittleEndian(
- base::Vector<const base::uc16> str, AllocationType allocation) {
+ base::Vector<const base::uc16> str, UnicodeConfig config) {
#if defined(V8_TARGET_LITTLE_ENDIAN)
- return NewStringFromTwoByte(str, allocation);
+ uint32_t length = static_cast<uint32_t>(str.length());
+ base::OwnedVector<uint16_t> private_copy;
+ if (config.source_shared()) {
+ private_copy = CopyCodeUnits(
+ reinterpret_cast<const base::Atomic16*>(str.data()), length);
+ }
+ auto peek_bytes = [&]() -> base::Vector<const uint16_t> {
+ return config.source_shared() ? private_copy.as_vector() : str;
+ };
+ if (config.dest_shared()) {
+ return NewStringFromBytes<Wtf16Decoder, decltype(peek_bytes),
+ SharedStringPolicy>(isolate(), peek_bytes,
+ AllocationType::kSharedOld,
+ MessageTemplate::kNone);
+ }
+ return NewStringFromBytes<Wtf16Decoder, decltype(peek_bytes),
+ NonSharedStringPolicy>(
+ isolate(), peek_bytes, AllocationType::kYoung, MessageTemplate::kNone);
#elif defined(V8_TARGET_BIG_ENDIAN)
// TODO(12868): Duplicate the guts of NewStringFromTwoByte, so that
// copying and transcoding the data can be done in a single pass.
@@ -2352,7 +2353,7 @@ DirectHandle<WasmExportedFunctionData> Factory::NewWasmExportedFunctionData(
}
DirectHandle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
- Address call_target, DirectHandle<Foreign> embedder_data,
+ Address call_target, DirectHandle<CppGCManagedBase> embedder_data,
DirectHandle<Code> wrapper_code, DirectHandle<Map> rtt,
const wasm::CanonicalSig* sig) {
DirectHandle<WasmImportData> import_data =
@@ -2384,6 +2385,8 @@ DirectHandle<WasmCapiFunctionData> Factory::NewWasmCapiFunctionData(
Tagged<WasmArray> Factory::NewWasmArrayUninitialized(
uint32_t length, DirectHandle<Map> map, AllocationType allocation) {
+ DCHECK_LE(length, static_cast<uint32_t>(WasmArray::MaxLength(
+ WasmArray::DecodeElementSizeFromMap(*map))));
const bool is_shared = allocation == AllocationType::kSharedOld;
DCHECK_EQ(is_shared, HeapLayout::InAnySharedSpace(*map));
Tagged<HeapObject> raw =
@@ -2515,6 +2518,45 @@ Handle<WasmStruct> Factory::NewWasmStructUninitialized(
return handle(result, isolate());
}
+Handle<WasmCustomMap> Factory::NewWasmCustomMapUninitialized(
+ const wasm::StructType* descriptor,
+ wasm::CanonicalTypeIndex described_index, int described_size,
+ InstanceType described_instance_type, DirectHandle<Map> rtt_parent,
+ int num_supertypes, DirectHandle<Map> map) {
+ const SharedFlag shared = descriptor->is_shared();
+
+ const wasm::CanonicalValueType no_array_element = wasm::kWasmBottom;
+ // If we had a CanonicalHeapType, we could use that here.
+ wasm::CanonicalValueType heaptype = wasm::CanonicalValueType::Ref(
+ described_index, shared, wasm::RefTypeKind::kStruct);
+ DirectHandle<WasmTypeInfo> type_info = NewWasmTypeInfo(
+ heaptype, no_array_element, rtt_parent, num_supertypes, shared);
+
+ AllocationType allocation =
+ shared ? AllocationType::kSharedMap : AllocationType::kMap;
+ AllocationAlignment alignment = shared ? kDoubleAligned : kTaggedAligned;
+ const int descriptor_size = WasmCustomMap::Size(descriptor);
+ DCHECK_EQ(descriptor_size, WasmStruct::DecodeInstanceSizeFromMap(*map));
+ Tagged<HeapObject> raw = AllocateRaw(descriptor_size, allocation, alignment);
+ raw->set_map_after_allocation(isolate(), *map);
+ Tagged<WasmCustomMap> result = Cast<WasmCustomMap>(raw);
+ const int inobject_properties = 0;
+ // If NO_ELEMENTS were supported, we could use that here.
+ const ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
+ ReadOnlyRoots roots(isolate());
+ InitializeMap(result, described_instance_type, kVariableSizeSentinel,
+ elements_kind, inobject_properties, roots);
+ result->set_native_context_for_wrapper(isolate()->raw_native_context());
+ result->set_wasm_type_info(*type_info);
+ result->set_is_extensible(false);
+ result->set_immediate_supertype_map(*rtt_parent);
+ result->set_js_wrapper(*null_value());
+ WasmStruct::EncodeInstanceSizeInMap(described_size, result);
+ isolate()->counters()->maps_created()->Increment();
+ return handle(result, isolate());
+}
+
+// TODO(jkummerow): Replace with ...Uninitialized variant.
DirectHandle<WasmStruct> Factory::NewWasmStruct(const wasm::StructType* type,
wasm::WasmValue* args,
DirectHandle<Map> map) {
@@ -2866,6 +2908,7 @@ DirectHandle<Map> Factory::NewContextfulMap(
DCHECK(InstanceTypeChecker::IsNativeContextSpecific(type) ||
#if V8_ENABLE_WEBASSEMBLY
InstanceTypeChecker::IsWasmStruct(type) ||
+ InstanceTypeChecker::IsWasmCustomMap(type) ||
#endif // V8_ENABLE_WEBASSEMBLY
InstanceTypeChecker::IsMap(type));
auto meta_map_provider = [native_context] {
@@ -3393,6 +3436,16 @@ Handle<CppHeapExternalObject> Factory::NewCppHeapExternal(
return handle(external, isolate());
}
+Handle<CppGCManagedBase> Factory::NewCppGCManagedBase(
+ AllocationType allocation_type) {
+ Tagged<CppGCManagedBase> managed = Cast<CppGCManagedBase>(
+ AllocateRawWithAllocationSite(cpp_gc_managed_base_map(), allocation_type,
+ DirectHandle<AllocationSite>::null()));
+ managed->SetupLazilyInitializedCppHeapPointerField(
+ offsetof(CppGCManagedBase, cpp_gc_wrapper_));
+ return handle(managed, isolate());
+}
+
DirectHandle<Code> Factory::NewCodeObjectForEmbeddedBuiltin(
DirectHandle<Code> code, Address off_heap_entry) {
CHECK_NOT_NULL(isolate()->embedded_blob_code());
@@ -4594,15 +4647,28 @@ Handle<StackTraceInfo> Factory::NewStackTraceInfo(
return handle(info, isolate());
}
+Handle<DebugScriptScopeInfo> Factory::NewDebugScriptScopeInfo(
+ DirectHandle<ByteArray> numeric_data,
+ DirectHandle<FixedArray> string_table) {
+ Tagged<DebugScriptScopeInfo> info = NewStructInternal<DebugScriptScopeInfo>(
+ DEBUG_SCRIPT_SCOPE_INFO_TYPE, AllocationType::kOld);
+ DisallowGarbageCollection no_gc;
+ info->set_numeric_data(*numeric_data);
+ info->set_string_table(*string_table);
+ return handle(info, isolate());
+}
+
Handle<JSObject> Factory::NewArgumentsObject(DirectHandle<JSFunction> callee,
int length) {
bool strict_mode_callee = is_strict(callee->shared()->language_mode()) ||
!callee->shared()->has_simple_parameters();
- DirectHandle<Map> map = strict_mode_callee
- ? isolate()->strict_arguments_map()
- : isolate()->sloppy_arguments_map();
- AllocationSiteUsageContext context(isolate(), Handle<AllocationSite>(),
- false);
+ return strict_mode_callee ? NewStrictArgumentsObject(callee, length)
+ : NewSloppyArgumentsObject(callee, length);
+}
+
+Handle<JSObject> Factory::NewStrictArgumentsObject(
+ DirectHandle<JSFunction> callee, int length) {
+ DirectHandle<Map> map = isolate()->strict_arguments_map();
DCHECK(!isolate()->has_exception());
Handle<JSObject> result = NewJSObjectFromMap(map);
DirectHandle<Smi> value(Smi::FromInt(length), isolate());
@@ -4610,12 +4676,23 @@ Handle<JSObject> Factory::NewArgumentsObject(DirectHandle<JSFunction> callee,
StoreOrigin::kMaybeKeyed,
Just(ShouldThrow::kThrowOnError))
.Assert();
- if (!strict_mode_callee) {
- Object::SetProperty(isolate(), result, callee_string(), callee,
- StoreOrigin::kMaybeKeyed,
- Just(ShouldThrow::kThrowOnError))
- .Assert();
- }
+ return result;
+}
+
+Handle<JSObject> Factory::NewSloppyArgumentsObject(
+ DirectHandle<JSFunction> callee, int length) {
+ DirectHandle<Map> map = isolate()->sloppy_arguments_map();
+ DCHECK(!isolate()->has_exception());
+ Handle<JSObject> result = NewJSObjectFromMap(map);
+ DirectHandle<Smi> value(Smi::FromInt(length), isolate());
+ Object::SetProperty(isolate(), result, length_string(), value,
+ StoreOrigin::kMaybeKeyed,
+ Just(ShouldThrow::kThrowOnError))
+ .Assert();
+ Object::SetProperty(isolate(), result, callee_string(), callee,
+ StoreOrigin::kMaybeKeyed,
+ Just(ShouldThrow::kThrowOnError))
+ .Assert();
return result;
}
@@ -4750,8 +4827,7 @@ DirectHandle<RegExpData> Factory::NewAtomRegExpData(
instance->set_escaped_source(*escaped_source);
instance->set_flags(flags);
instance->set_pattern(*pattern);
- instance->set_quick_check_mask(0);
- instance->set_quick_check_value(0);
+ instance->clear_quick_check();
Tagged<RegExpDataWrapper> raw_wrapper = *wrapper;
instance->set_wrapper(raw_wrapper);
instance->InitAndPublish(isolate());
@@ -4786,8 +4862,7 @@ DirectHandle<RegExpData> Factory::NewIrRegExpData(
instance->set_ticks_until_tier_up(ticks_until_tier_up);
instance->set_backtrack_limit(backtrack_limit);
instance->set_bit_field(bit_field);
- instance->set_quick_check_mask(0);
- instance->set_quick_check_value(0);
+ instance->clear_quick_check();
Tagged<RegExpDataWrapper> raw_wrapper = *wrapper;
instance->set_wrapper(raw_wrapper);
instance->InitAndPublish(isolate());
@@ -4825,8 +4900,7 @@ DirectHandle<RegExpData> Factory::NewExperimentalRegExpData(
instance->set_ticks_until_tier_up(JSRegExp::kUninitializedValue);
instance->set_backtrack_limit(JSRegExp::kUninitializedValue);
instance->set_bit_field(0);
- instance->set_quick_check_mask(0);
- instance->set_quick_check_value(0);
+ instance->clear_quick_check();
Tagged<RegExpDataWrapper> raw_wrapper = *wrapper;
instance->set_wrapper(raw_wrapper);
instance->InitAndPublish(isolate());
@@ -5451,7 +5525,8 @@ Handle<JSFunction> Factory::JSFunctionBuilder::BuildRaw(
// needed and maybe find some alternative to initialize it correctly
// from the beginning.
if (old_code->is_builtin()) {
- jdt.SetCodeNoWriteBarrier(dispatch_handle, *code, isolate);
+ jdt.SetCodeKeepTieringRequest(dispatch_handle, *code, function, isolate,
+ mode);
function->set_dispatch_handle(dispatch_handle, mode);
} else {
// On a transition of a feedback cell from one closure to many, make
@@ -5459,7 +5534,8 @@ Handle<JSFunction> Factory::JSFunctionBuilder::BuildRaw(
// specialized, and if it was, eagerly re-optimize.
if (cell_transition == FeedbackCell::kOneToMany &&
old_code->is_context_specialized()) {
- jdt.SetCodeNoWriteBarrier(dispatch_handle, *code, isolate);
+ jdt.SetCodeKeepTieringRequest(dispatch_handle, *code, function,
+ isolate, mode);
function->set_dispatch_handle(dispatch_handle, mode);
DCHECK(old_code->kind() == CodeKind::MAGLEV ||
old_code->kind() == CodeKind::TURBOFAN_JS);
diff --git a/deps/v8/src/heap/factory.h b/deps/v8/src/heap/factory.h
index 67d4a1e6821..ed01e3e68a0 100644
--- a/deps/v8/src/heap/factory.h
+++ b/deps/v8/src/heap/factory.h
@@ -24,10 +24,6 @@
// TODO(leszeks): Remove this by forward declaring JSRegExp::Flags.
#include "src/objects/js-regexp.h"
-namespace unibrow {
-enum class Utf8Variant : uint8_t;
-}
-
namespace v8 {
namespace internal {
@@ -41,12 +37,15 @@ class CallableTask;
class CallbackTask;
class CallSiteInfo;
class CoverageInfo;
+class CppGCManagedBase;
class DebugInfo;
+class DebugScriptScopeInfo;
class DeoptimizationData;
class DeoptimizationLiteralArray;
class DictionaryTemplateInfo;
class EmbedderDataArray;
class EnumCache;
+class ErrorStackData;
class Expression;
class FreshlyAllocatedBigInt;
class FunctionTemplateInfo;
@@ -69,6 +68,7 @@ class JSWeakMap;
class LoadHandler;
class NativeContext;
class ObjectBoilerplateDescription;
+class PromiseCapability;
class PromiseResolveThenableJobTask;
class RegExpMatchInfo;
class ScriptContextTable;
@@ -83,6 +83,7 @@ class SyntheticModule;
class TemplateObjectDescription;
template <typename T>
class TrustedManaged;
+class UnicodeConfig;
class WasmCapiFunctionData;
class WasmExportedFunctionData;
@@ -335,6 +336,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8(
base::Vector<const char> str,
AllocationType allocation = AllocationType::kYoung);
+
V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8(
std::string_view str,
AllocationType allocation = AllocationType::kYoung) {
@@ -342,27 +344,20 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
}
V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8(
- base::Vector<const uint8_t> str, unibrow::Utf8Variant utf8_variant,
+ base::Vector<const uint8_t> str, UnicodeConfig config,
AllocationType allocation = AllocationType::kYoung);
- V8_WARN_UNUSED_RESULT MaybeHandle<String> NewSharedStringFromUtf8(
- base::Vector<const char> str);
- V8_WARN_UNUSED_RESULT MaybeHandle<String> NewSharedStringFromUtf8(
- std::string_view str) {
- return NewSharedStringFromUtf8(base::StrVector(str));
+ V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8(
+ base::Vector<const uint8_t> str,
+ unibrow::Utf8Variant utf8_variant = unibrow::Utf8Variant::kLossyUtf8,
+ AllocationType allocation = AllocationType::kYoung) {
+ return NewStringFromUtf8(str, UnicodeConfig(utf8_variant), allocation);
}
- V8_WARN_UNUSED_RESULT MaybeHandle<String> NewSharedStringFromUtf8(
- base::Vector<const uint8_t> str, unibrow::Utf8Variant utf8_variant);
#if V8_ENABLE_WEBASSEMBLY
V8_WARN_UNUSED_RESULT MaybeDirectHandle<String> NewStringFromUtf8(
DirectHandle<WasmArray> array, uint32_t begin, uint32_t end,
- unibrow::Utf8Variant utf8_variant,
- AllocationType allocation = AllocationType::kYoung);
-
- V8_WARN_UNUSED_RESULT MaybeDirectHandle<String> NewSharedStringFromUtf8(
- DirectHandle<WasmArray> array, uint32_t begin, uint32_t end,
- unibrow::Utf8Variant utf8_variant);
+ UnicodeConfig config);
V8_WARN_UNUSED_RESULT MaybeHandle<String> NewStringFromUtf8(
DirectHandle<ByteArray> array, uint32_t start, uint32_t end,
@@ -371,10 +366,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
V8_WARN_UNUSED_RESULT MaybeDirectHandle<String> NewStringFromUtf16(
DirectHandle<WasmArray> array, uint32_t start, uint32_t end,
- AllocationType allocation = AllocationType::kYoung);
-
- V8_WARN_UNUSED_RESULT MaybeDirectHandle<String> NewSharedStringFromUtf16(
- DirectHandle<WasmArray> array, uint32_t start, uint32_t end);
+ UnicodeConfig config);
V8_WARN_UNUSED_RESULT MaybeDirectHandle<String> WasmStringAddShared(
DirectHandle<String> left, DirectHandle<String> right);
@@ -392,9 +384,8 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
// Usually the two-byte encodings are in the native endianness, but for
// WebAssembly linear memory, they are explicitly little-endian.
V8_WARN_UNUSED_RESULT MaybeDirectHandle<String>
- NewStringFromTwoByteLittleEndian(
- base::Vector<const base::uc16> str,
- AllocationType allocation = AllocationType::kYoung);
+ NewStringFromTwoByteLittleEndian(base::Vector<const base::uc16> str,
+ UnicodeConfig config);
#endif // V8_ENABLE_WEBASSEMBLY
DirectHandle<JSStringIterator> NewJSStringIterator(Handle<String> string);
@@ -562,6 +553,9 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
int bytecode_offset_or_source_position,
DirectHandle<String> function_name, bool is_constructor);
Handle<StackTraceInfo> NewStackTraceInfo(DirectHandle<FixedArray> frames);
+ Handle<DebugScriptScopeInfo> NewDebugScriptScopeInfo(
+ DirectHandle<ByteArray> numeric_data,
+ DirectHandle<FixedArray> string_table);
// Allocate various microtasks.
DirectHandle<CallableTask> NewCallableTask(
@@ -737,6 +731,12 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<JSObject> NewArgumentsObject(DirectHandle<JSFunction> callee,
int length);
+ Handle<JSObject> NewStrictArgumentsObject(DirectHandle<JSFunction> callee,
+ int length);
+
+ Handle<JSObject> NewSloppyArgumentsObject(DirectHandle<JSFunction> callee,
+ int length);
+
// Allocates and initializes a new JavaScript object based on a
// constructor.
// JS objects are pretenured when allocated by the bootstrapper and
@@ -868,7 +868,7 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
DirectHandle<WasmInternalFunction> internal_function,
DirectHandle<Map> rtt);
DirectHandle<WasmCapiFunctionData> NewWasmCapiFunctionData(
- Address call_target, DirectHandle<Foreign> embedder_data,
+ Address call_target, DirectHandle<CppGCManagedBase> embedder_data,
DirectHandle<Code> wrapper_code, DirectHandle<Map> rtt,
const wasm::CanonicalSig* sig);
DirectHandle<WasmExportedFunctionData> NewWasmExportedFunctionData(
@@ -903,6 +903,11 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<WasmStruct> NewWasmStructUninitialized(const wasm::StructType* type,
DirectHandle<Map> map,
AllocationType allocation);
+ Handle<WasmCustomMap> NewWasmCustomMapUninitialized(
+ const wasm::StructType* descriptor,
+ wasm::CanonicalTypeIndex described_index, int described_size,
+ InstanceType described_instance_type, DirectHandle<Map> rtt_parent,
+ int num_supertypes, DirectHandle<Map> map);
DirectHandle<WasmArray> NewWasmArray(wasm::ValueType element_type,
uint32_t length,
@@ -1016,6 +1021,9 @@ class V8_EXPORT_PRIVATE Factory : public FactoryBase<Factory> {
Handle<CppHeapExternalObject> NewCppHeapExternal(
AllocationType allocation = AllocationType::kYoung);
+ Handle<CppGCManagedBase> NewCppGCManagedBase(
+ AllocationType allocation = AllocationType::kYoung);
+
// Allocates a new code object and initializes it to point to the given
// off-heap entry point.
//
diff --git a/deps/v8/src/heap/gc-tracer.cc b/deps/v8/src/heap/gc-tracer.cc
index 9ef93130942..a58125730eb 100644
--- a/deps/v8/src/heap/gc-tracer.cc
+++ b/deps/v8/src/heap/gc-tracer.cc
@@ -394,6 +394,9 @@ void GCTracer::StartInSafepoint(base::TimeTicks time) {
current_.start_object_size = heap_->SizeOfObjects();
current_.start_memory_size = heap_->memory_allocator()->Size();
current_.start_holes_size = CountTotalHolesSize(heap_);
+ current_.start_old_generation_consumed_size =
+ heap_->OldGenerationConsumedBytes();
+ current_.start_global_consumed_size = heap_->GlobalConsumedBytes();
size_t new_space_size = (heap_->new_space() ? heap_->new_space()->Size() : 0);
size_t new_lo_space_size =
(heap_->new_lo_space() ? heap_->new_lo_space()->SizeOfObjects() : 0);
@@ -405,6 +408,9 @@ void GCTracer::StopInSafepoint(base::TimeTicks time) {
current_.end_object_size = heap_->SizeOfObjects();
current_.end_memory_size = heap_->memory_allocator()->Size();
current_.end_holes_size = CountTotalHolesSize(heap_);
+ current_.end_old_generation_consumed_size =
+ heap_->OldGenerationConsumedBytes();
+ current_.end_global_consumed_size = heap_->GlobalConsumedBytes();
current_.survived_young_object_size = heap_->SurvivedYoungObjectSize();
current_.end_atomic_pause_time = time;
@@ -972,6 +978,11 @@ void GCTracer::PrintNVP() const {
.p("end_memory_size", current_.end_memory_size)
.p("start_holes_size", current_.start_holes_size)
.p("end_holes_size", current_.end_holes_size)
+ .p("start_old_gen_consumed_size",
+ current_.start_old_generation_consumed_size)
+ .p("end_old_gen_consumed_size", current_.end_old_generation_consumed_size)
+ .p("start_global_consumed_size", current_.start_global_consumed_size)
+ .p("end_global_consumed_size", current_.end_global_consumed_size)
.p("pool_local_chunks", heap_->memory_allocator()->GetPooledChunksCount())
.p("pool_shared_chunks",
heap_->memory_allocator()->GetSharedPooledChunksCount())
diff --git a/deps/v8/src/heap/gc-tracer.h b/deps/v8/src/heap/gc-tracer.h
index 39916e95941..453ab94e4b1 100644
--- a/deps/v8/src/heap/gc-tracer.h
+++ b/deps/v8/src/heap/gc-tracer.h
@@ -259,6 +259,18 @@ class V8_EXPORT_PRIVATE GCTracer {
// after the current GC.
size_t end_holes_size = 0;
+ // Consumed bytes in old generation before the current GC.
+ size_t start_old_generation_consumed_size = 0;
+
+ // Consumed bytes in old generation after the current GC.
+ size_t end_old_generation_consumed_size = 0;
+
+ // Consumed bytes globally before the current GC.
+ size_t start_global_consumed_size = 0;
+
+ // Consumed bytes globally after the current GC.
+ size_t end_global_consumed_size = 0;
+
// Size of young objects in constructor.
size_t young_object_size = 0;
diff --git a/deps/v8/src/heap/heap-controller.cc b/deps/v8/src/heap/heap-controller.cc
index cd8e8d2abc5..12b4139eca1 100644
--- a/deps/v8/src/heap/heap-controller.cc
+++ b/deps/v8/src/heap/heap-controller.cc
@@ -51,11 +51,14 @@ uint64_t MemoryController<Trait>::ComputeSqrtLimit(
// by `limit_factor`. We also assume that GC cost (L/s) is proportional to
// `total_size_excluding_external_at_last_gc_`, which includes young
// objects and excludes external memory, for both old gen or global limit.
- return std::min<uint64_t>(
+ const double computed_limit =
heap_size_at_last_gc +
- limit_factor * sqrt(allocation_speed * total_size_of_objects),
- v8_flags.sqrt_allocation_limits_max_growing_factor *
- heap_size_at_last_gc);
+ limit_factor * sqrt(allocation_speed * total_size_of_objects);
+ const double min_limit =
+ v8_flags.sqrt_allocation_limits_min_growing_factor * heap_size_at_last_gc;
+ const double max_limit =
+ v8_flags.sqrt_allocation_limits_max_growing_factor * heap_size_at_last_gc;
+ return std::clamp(computed_limit, min_limit, max_limit);
}
template <typename Trait>
diff --git a/deps/v8/src/heap/heap-inl.h b/deps/v8/src/heap/heap-inl.h
index ffe18c4acad..335a96f3c70 100644
--- a/deps/v8/src/heap/heap-inl.h
+++ b/deps/v8/src/heap/heap-inl.h
@@ -156,10 +156,17 @@ void Heap::SetNextCachedBigIntDivisor(Tagged<BigInt> divisor) {
set_next_cached_bigint_divisor(divisor);
}
+void Heap::SetRegExpSplitCache(Tagged<FixedArray> cache) {
+ set_regexp_split_cache(cache);
+}
+
#if V8_ENABLE_WEBASSEMBLY
void Heap::SetWasmCanonicalRtts(Tagged<WeakFixedArray> rtts) {
set_wasm_canonical_rtts(rtts);
}
+void Heap::SetWasmSharedCanonicalRtts(Tagged<WeakFixedArray> rtts) {
+ set_wasm_shared_canonical_rtts(rtts);
+}
void Heap::SetJSToWasmWrappers(Tagged<WeakFixedArray> js_to_wasm_wrappers) {
set_js_to_wasm_wrappers(js_to_wasm_wrappers);
}
diff --git a/deps/v8/src/heap/heap-verifier.cc b/deps/v8/src/heap/heap-verifier.cc
index d410242372e..14fedc7a194 100644
--- a/deps/v8/src/heap/heap-verifier.cc
+++ b/deps/v8/src/heap/heap-verifier.cc
@@ -146,6 +146,7 @@ void VerifyPointersVisitor::VisitMapPointer(Tagged<HeapObject> host) {
void VerifyPointersVisitor::VerifyHeapObjectImpl(
Tagged<HeapObject> heap_object) {
CHECK(IsValidHeapObject(heap_, heap_object));
+ if (IsInaccessible(heap_object)) return;
CHECK(IsMap(heap_object->map()));
// Heap::InToPage() is not available with sticky mark-bits.
CHECK_IMPLIES(
diff --git a/deps/v8/src/heap/heap-visitor.h b/deps/v8/src/heap/heap-visitor.h
index 035d3ce5b88..9830a6b8b22 100644
--- a/deps/v8/src/heap/heap-visitor.h
+++ b/deps/v8/src/heap/heap-visitor.h
@@ -47,83 +47,85 @@ class MaybeObjectSize final {
// Visitation in here will refer to BodyDescriptors with the regular instance
// size.
-#define TYPED_VISITOR_ID_LIST(V) \
- V(AccessorInfo) \
- V(AllocationSite) \
- V(BigInt) \
- V(BytecodeWrapper) \
- V(CallSiteInfo) \
- V(Cell) \
- V(CodeWrapper) \
- V(ConsString) \
- V(Context) \
- V(ContextCell) \
- V(CoverageInfo) \
- V(DataHandler) \
- V(DescriptorArray) \
- V(DoubleStringCache) \
- V(EmbedderDataArray) \
- V(EphemeronHashTable) \
- V(ExternalString) \
- V(FeedbackCell) \
- V(FeedbackMetadata) \
- V(FeedbackVector) \
- V(Foreign) \
- V(FunctionTemplateInfo) \
- V(HeapNumber) \
- V(HashSeedWrapper) \
- V(InterceptorInfo) \
- V(Hole) \
- V(Map) \
- V(MegaDomHandler) \
- V(NativeContext) \
- V(Oddball) \
- V(OnHeapBasicBlockProfilerData) \
- V(PreparseData) \
- V(PropertyArray) \
- V(PropertyCell) \
- V(JSProxy) \
- V(PrototypeInfo) \
- V(PrototypeSharedClosureInfo) \
- V(RegExpBoilerplateDescription) \
- V(RegExpDataWrapper) \
- V(ScopeInfo) \
- V(SeqOneByteString) \
- V(SeqTwoByteString) \
- V(SharedFunctionInfo) \
- V(SlicedString) \
- V(SmallOrderedHashMap) \
- V(SmallOrderedHashSet) \
- V(SmallOrderedNameDictionary) \
- V(SortState) \
- V(SourceTextModule) \
- V(SwissNameDictionary) \
- V(Symbol) \
- V(SyntheticModule) \
- V(ThinString) \
- V(TransitionArray) \
- V(WeakCell) \
- IF_WASM(V, WasmArray) \
- IF_WASM(V, WasmFastApiCallData) \
- IF_WASM(V, WasmFuncRef) \
- IF_WASM(V, WasmNull) \
- IF_WASM(V, WasmResumeData) \
- IF_WASM(V, WasmStringViewIter) \
- IF_WASM(V, WasmStruct) \
- IF_WASM(V, WasmContinuationObject) \
- IF_WASM(V, WasmStackObject) \
- IF_WASM(V, WasmTypeInfo) \
- V(TurbofanBitsetType) \
- V(TurbofanHeapConstantType) \
- V(TurbofanOtherNumberConstantType) \
- V(TurbofanRangeType) \
- V(TurbofanUnionType) \
- V(TurboshaftFloat64RangeType) \
- V(TurboshaftFloat64SetType) \
- V(TurboshaftWord32RangeType) \
- V(TurboshaftWord32SetType) \
- V(TurboshaftWord64RangeType) \
- V(TurboshaftWord64SetType) \
+#define TYPED_VISITOR_ID_LIST(V) /* force 80 cols */ \
+ V(AccessorInfo) \
+ V(AllocationSite) \
+ V(BigInt) \
+ V(BytecodeWrapper) \
+ V(CallSiteInfo) \
+ V(Cell) \
+ V(CodeWrapper) \
+ V(ConsString) \
+ V(Context) \
+ V(ContextCell) \
+ V(CoverageInfo) \
+ V(CppGCManagedBase) \
+ V(DataHandler) \
+ V(DescriptorArray) \
+ V(DoubleStringCache) \
+ V(EmbedderDataArray) \
+ V(EphemeronHashTable) \
+ V(ExternalString) \
+ V(FeedbackCell) \
+ V(FeedbackMetadata) \
+ V(FeedbackVector) \
+ V(Foreign) \
+ V(FunctionTemplateInfo) \
+ V(HeapNumber) \
+ V(HashSeedWrapper) \
+ V(InterceptorInfo) \
+ V(Hole) \
+ V(Map) \
+ V(MegaDomHandler) \
+ V(NativeContext) \
+ V(Oddball) \
+ V(OnHeapBasicBlockProfilerData) \
+ V(PreparseData) \
+ V(PropertyArray) \
+ V(PropertyCell) \
+ V(JSProxy) \
+ V(PrototypeInfo) \
+ V(PrototypeSharedClosureInfo) \
+ V(RegExpBoilerplateDescription) \
+ V(RegExpDataWrapper) \
+ V(ScopeInfo) \
+ V(SeqOneByteString) \
+ V(SeqTwoByteString) \
+ V(SharedFunctionInfo) \
+ V(SlicedString) \
+ V(SmallOrderedHashMap) \
+ V(SmallOrderedHashSet) \
+ V(SmallOrderedNameDictionary) \
+ V(SortState) \
+ V(SourceTextModule) \
+ V(SwissNameDictionary) \
+ V(Symbol) \
+ V(SyntheticModule) \
+ V(ThinString) \
+ V(TransitionArray) \
+ V(WeakCell) \
+ IF_WASM(V, WasmArray) \
+ IF_WASM(V, WasmCustomMap) \
+ IF_WASM(V, WasmFastApiCallData) \
+ IF_WASM(V, WasmFuncRef) \
+ IF_WASM(V, WasmNull) \
+ IF_WASM(V, WasmResumeData) \
+ IF_WASM(V, WasmStringViewIter) \
+ IF_WASM(V, WasmStruct) \
+ IF_WASM(V, WasmContinuationObject) \
+ IF_WASM(V, WasmStackObject) \
+ IF_WASM(V, WasmTypeInfo) \
+ V(TurbofanBitsetType) \
+ V(TurbofanHeapConstantType) \
+ V(TurbofanOtherNumberConstantType) \
+ V(TurbofanRangeType) \
+ V(TurbofanUnionType) \
+ V(TurboshaftFloat64RangeType) \
+ V(TurboshaftFloat64SetType) \
+ V(TurboshaftWord32RangeType) \
+ V(TurboshaftWord32SetType) \
+ V(TurboshaftWord64RangeType) \
+ V(TurboshaftWord64SetType) \
SIMPLE_HEAP_OBJECT_LIST1(V)
// Visitation in here will refer to BodyDescriptors with the used size of the
diff --git a/deps/v8/src/heap/heap-write-barrier.cc b/deps/v8/src/heap/heap-write-barrier.cc
index 378b75bdafb..f40c7c22abc 100644
--- a/deps/v8/src/heap/heap-write-barrier.cc
+++ b/deps/v8/src/heap/heap-write-barrier.cc
@@ -153,7 +153,7 @@ void WriteBarrier::MarkingSlow(Tagged<HeapObject> host,
DCHECK(!space->is_internal_read_only_space());
ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
- table.Mark(space, handle, slot.address());
+ table.Mark(space, handle, slot.address(), slot.tag_range());
if (marking_barrier->is_minor() && HeapLayout::InYoungGeneration(host)) {
MutablePage* host_page =
diff --git a/deps/v8/src/heap/heap.cc b/deps/v8/src/heap/heap.cc
index e9423f6d42e..d67b6933c72 100644
--- a/deps/v8/src/heap/heap.cc
+++ b/deps/v8/src/heap/heap.cc
@@ -1023,9 +1023,6 @@ void Heap::PublishMainThreadPendingAllocations() {
}
void Heap::DeoptMarkedAllocationSites() {
- // TODO(hpayer): If iterating over the allocation sites list becomes a
- // performance issue, use a cache data structure in heap instead.
-
ForeachAllocationSite(
allocation_sites_list(), [this](Tagged<AllocationSite> site) {
if (site->deopt_dependent_code()) {
@@ -2608,6 +2605,7 @@ void Heap::MarkCompactPrologue() {
TRACE_GC(tracer(), GCTracer::Scope::MC_PROLOGUE);
isolate_->descriptor_lookup_cache()->Clear();
regexp::ResultsCache::Clear(string_split_cache());
+ regexp::ResultsCache::Clear(regexp_split_cache());
regexp::ResultsCache::Clear(regexp_multiple_cache());
regexp::ResultsCache_MatchGlobalAtom::Clear(this);
@@ -4502,6 +4500,7 @@ bool IsInterestingObjectStart(MapWord map_word) {
bool ClearStaleLeftTrimmedPointerVisitor::IsLeftTrimmed(FullObjectSlot p) {
Tagged<HeapObject> current;
if (!TryCast<HeapObject>(*p, ¤t)) return false;
+ if (IsInaccessible(current)) return false;
// Using MapWord instead of `current` directly defends against concurrent
// Scavenge tasks installing forward pointers on `current`.
MapWord map_word = current->map_word(kRelaxedLoad);
@@ -4665,23 +4664,11 @@ void Heap::IterateRoots(RootVisitor* v, base::EnumSet<SkipRoot> options,
v->Synchronize(VisitorSynchronization::kEternalHandles);
// Iterate over pending Microtasks stored in MicrotaskQueues.
-#ifdef V8_CPPGC_MICROTASK_QUEUE
for (const auto& weak_ptr : isolate_->microtask_queues()) {
if (weak_ptr) {
weak_ptr->IterateMicrotasks(v);
}
}
-#else
- MicrotaskQueue* default_microtask_queue =
- isolate_->default_microtask_queue();
- if (default_microtask_queue) {
- MicrotaskQueue* microtask_queue = default_microtask_queue;
- do {
- microtask_queue->IterateMicrotasks(v);
- microtask_queue = microtask_queue->next();
- } while (microtask_queue != default_microtask_queue);
- }
-#endif // V8_CPPGC_MICROTASK_QUEUE
v->Synchronize(VisitorSynchronization::kMicroTasks);
// Iterate over other strong roots (currently only identity maps and
diff --git a/deps/v8/src/heap/heap.h b/deps/v8/src/heap/heap.h
index 676319f2b17..810449851fe 100644
--- a/deps/v8/src/heap/heap.h
+++ b/deps/v8/src/heap/heap.h
@@ -909,9 +909,11 @@ class Heap final {
V8_INLINE void SetDoubleStringCache(Tagged<DoubleStringCache> cache);
V8_INLINE void SetCachedBigIntDivisor(Tagged<BigInt> divisor);
V8_INLINE void SetNextCachedBigIntDivisor(Tagged<BigInt> divisor);
+ V8_INLINE void SetRegExpSplitCache(Tagged<FixedArray> cache);
#if V8_ENABLE_WEBASSEMBLY
V8_INLINE void SetWasmCanonicalRtts(Tagged<WeakFixedArray> rtts);
+ V8_INLINE void SetWasmSharedCanonicalRtts(Tagged<WeakFixedArray> rtts);
V8_INLINE void SetJSToWasmWrappers(
Tagged<WeakFixedArray> js_to_wasm_wrappers);
#endif
@@ -2520,11 +2522,12 @@ class Heap final {
// The Isolate constructs us.
friend class Isolate;
- // Used in cctest.
+ // Used in cctest and unittests.
friend class heap::HeapTester;
FRIEND_TEST(SpacesTest, InlineAllocationObserverCadence);
FRIEND_TEST(SpacesTest, AllocationObserver);
FRIEND_TEST(MinimalStackTest, MinimalStackInTurbofanAllocate);
+ FRIEND_TEST(HeapTest, Regress10560);
friend class HeapInternalsBase;
};
@@ -2851,6 +2854,8 @@ class ClearStaleLeftTrimmedPointerVisitor : public RootVisitor {
visitor_->Synchronize(tag);
}
+ GarbageCollector collector() const override { return visitor_->collector(); }
+
// The pointer compression cage base value used for decompression of all
// tagged values except references to InstructionStream objects.
PtrComprCageBase cage_base() const {
diff --git a/deps/v8/src/heap/mark-compact.cc b/deps/v8/src/heap/mark-compact.cc
index 5cb959c244c..caa1192d2fc 100644
--- a/deps/v8/src/heap/mark-compact.cc
+++ b/deps/v8/src/heap/mark-compact.cc
@@ -1227,7 +1227,7 @@ class MarkExternalPointerFromExternalStringTable : public RootVisitor {
DCHECK(!slot.tag_range().IsEmpty());
DCHECK(IsSharedExternalPointerType(slot.tag_range()));
ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
- table_->Mark(space_, handle, slot.address());
+ table_->Mark(space_, handle, slot.address(), slot.tag_range());
}
void VisitPointers(Tagged<HeapObject> host, ObjectSlot start,
ObjectSlot end) override {
@@ -2953,7 +2953,9 @@ class FullStringForwardingTableCleaner final
}
TryExternalize(original_string, record);
TryInternalize(original_string, record);
- original_string->set_raw_hash_field(record->raw_hash(isolate_));
+ if (!HeapLayout::InReadOnlySpace(original_string)) {
+ original_string->set_raw_hash_field(record->raw_hash(isolate_));
+ }
} else {
DisposeExternalResource(record);
}
@@ -2973,11 +2975,27 @@ class FullStringForwardingTableCleaner final
if (external_resource == nullptr) return;
if (is_one_byte) {
+ // The string could have been internalized in the meantime and converted
+ // to a ThinString, with the actual string pointing to a
+ // non-externalizable string (e.g. in RO space).
+ if (V8_UNLIKELY(!original_string->SupportsExternalization(
+ v8::String::Encoding::ONE_BYTE_ENCODING))) {
+ DisposeExternalResource(record);
+ return;
+ }
original_string->MakeExternalDuringGC(
isolate_,
reinterpret_cast<v8::String::ExternalOneByteStringResource*>(
external_resource));
} else {
+ // The string could have been internalized in the meantime and converted
+ // to a ThinString, with the actual string pointing to a
+ // non-externalizable string (e.g. in RO space).
+ if (V8_UNLIKELY(!original_string->SupportsExternalization(
+ v8::String::Encoding::TWO_BYTE_ENCODING))) {
+ DisposeExternalResource(record);
+ return;
+ }
original_string->MakeExternalDuringGC(
isolate_, reinterpret_cast<v8::String::ExternalStringResource*>(
external_resource));
@@ -3262,6 +3280,8 @@ void MarkCompactCollector::ClearNonLiveReferences() {
JSDispatchTable& jdt = isolate->js_dispatch_table();
Tagged<Code> compile_lazy =
heap_->isolate()->builtins()->code(Builtin::kCompileLazy);
+ Tagged<Code> mark_flushed =
+ heap_->isolate()->builtins()->code(Builtin::kMarkFlushed);
jdt.Sweep(heap_->js_dispatch_table_space(),
heap_->isolate()->counters(), [&](JSDispatchEntry& entry) {
Tagged<Code> code = entry.GetCode();
@@ -3286,7 +3306,7 @@ void MarkCompactCollector::ClearNonLiveReferences() {
code->kind() == CodeKind::TURBOFAN_JS ||
code->is_interpreter_trampoline_builtin());
entry.SetCodeAndEntrypointPointer(
- compile_lazy.ptr(), compile_lazy->instruction_start(),
+ compile_lazy.ptr(), mark_flushed->instruction_start(),
isolate);
}
});
@@ -3642,6 +3662,13 @@ void MarkCompactCollector::FlushBytecodeFromSFI(
Tagged<BytecodeArray> bytecode_array =
shared_info->GetBytecodeArrayForGC(heap_->isolate());
+ // With in-sandbox corruption, the SFI::trusted_function_data_ handle could be
+ // swapped before getting flushed. The SBXCHECK ensures that we haven't marked
+ // this bytecode as live, so we don't flush out functions that are currently
+ // executing on the stack.
+ SBXCHECK(!MarkingHelper::IsMarkedOrAlwaysLive(
+ heap_, non_atomic_marking_state_, bytecode_array));
+
#ifdef V8_ENABLE_SANDBOX
DCHECK(!HeapLayout::InWritableSharedSpace(shared_info));
// Make the old handle unusable. We don't zap it eagerly since other SFI might
diff --git a/deps/v8/src/heap/marking-barrier.cc b/deps/v8/src/heap/marking-barrier.cc
index 9e5a838dd4a..9ecfabd6af2 100644
--- a/deps/v8/src/heap/marking-barrier.cc
+++ b/deps/v8/src/heap/marking-barrier.cc
@@ -50,7 +50,10 @@ void MarkingBarrier::Write(Tagged<HeapObject> host, IndirectPointerSlot slot) {
// An indirect pointer slot can only contain a Smi if it is uninitialized (in
// which case the vaue will be Smi::zero()). However, at this point the slot
// must have been initialized because it was just written to.
- Tagged<HeapObject> value = Cast<HeapObject>(slot.load(isolate()));
+ // During deserialization, the referenced object may not yet have been
+ // published. We can still mark it here.
+ Tagged<HeapObject> value =
+ Cast<HeapObject>(slot.Relaxed_Load_AllowUnpublished(isolate()));
// If the host is in shared space, the target must be in the shared trusted
// space. No other edges indirect pointers are currently possible in shared
diff --git a/deps/v8/src/heap/marking-visitor-inl.h b/deps/v8/src/heap/marking-visitor-inl.h
index 492dadebe7a..39b5b653247 100644
--- a/deps/v8/src/heap/marking-visitor-inl.h
+++ b/deps/v8/src/heap/marking-visitor-inl.h
@@ -30,6 +30,7 @@
#include "src/objects/slots.h"
#include "src/objects/smi.h"
#include "src/objects/string.h"
+#include "src/sandbox/check.h"
#include "src/sandbox/external-pointer-inl.h"
#include "src/sandbox/indirect-pointer-tag.h"
#include "src/sandbox/js-dispatch-table-inl.h"
@@ -264,7 +265,7 @@ void MarkingVisitorBase<ConcreteVisitor>::VisitExternalPointer(
: heap_->old_external_pointer_space();
}
}
- table->Mark(space, handle, slot.address());
+ table->Mark(space, handle, slot.address(), slot.tag_range());
if (slot.tag_range() != kArrayBufferExtensionTag) {
return;
}
@@ -279,6 +280,12 @@ void MarkingVisitorBase<ConcreteVisitor>::VisitExternalPointer(
ArrayBufferExtension* extension =
reinterpret_cast<ArrayBufferExtension*>(maybe_extension);
extension->InitializationBarrier();
+#ifdef V8_COMPRESS_POINTERS
+ SBXCHECK_EQ(space == heap_->young_external_pointer_space()
+ ? ArrayBufferExtension::Age::kYoung
+ : ArrayBufferExtension::Age::kOld,
+ extension->age());
+#endif // V8_COMPRESS_POINTERS
extension->Mark();
}
}
diff --git a/deps/v8/src/heap/memory-chunk-inl.h b/deps/v8/src/heap/memory-chunk-inl.h
index 21a792225af..7722d84fcac 100644
--- a/deps/v8/src/heap/memory-chunk-inl.h
+++ b/deps/v8/src/heap/memory-chunk-inl.h
@@ -14,10 +14,9 @@
namespace v8::internal {
+// LINT.IfChange(BasePageFromMemoryChunk)
template <bool check_isolate>
BasePage* MemoryChunk::MetadataImpl(const Isolate* isolate) {
- // If this changes, we also need to update
- // `CodeStubAssembler::BasePageFromMemoryChunk()`
#ifdef V8_ENABLE_SANDBOX
DCHECK_LT(metadata_index_,
MemoryChunkConstants::kMetadataPointerTableSizeMask);
@@ -40,6 +39,7 @@ BasePage* MemoryChunk::MetadataImpl(const Isolate* isolate) {
return metadata_;
#endif
}
+// LINT.ThenChange(/src/codegen/code-stub-assembler.cc:BasePageFromMemoryChunk)
template <bool check_isolate>
const BasePage* MemoryChunk::MetadataImpl(const Isolate* isolate) const {
diff --git a/deps/v8/src/heap/minor-mark-sweep.cc b/deps/v8/src/heap/minor-mark-sweep.cc
index 89ff1bae09b..ea2805d9edf 100644
--- a/deps/v8/src/heap/minor-mark-sweep.cc
+++ b/deps/v8/src/heap/minor-mark-sweep.cc
@@ -898,7 +898,7 @@ bool ShouldMovePage(NormalPage* p, intptr_t live_bytes, intptr_t wasted_bytes) {
} // namespace
-void MinorMarkSweepCollector::EvacuateExternalPointerReferences(
+void MinorMarkSweepCollector::EvacuateExternalPointerReferencesDuringSweeping(
MutablePage* p) {
#ifdef V8_COMPRESS_POINTERS
using BasicSlotSet = ::heap::base::BasicSlotSet<kTaggedSize>;
@@ -911,7 +911,8 @@ void MinorMarkSweepCollector::EvacuateExternalPointerReferences(
ExternalPointerHandle handle =
*reinterpret_cast<ExternalPointerHandle*>(handle_location);
table.Evacuate(young, old, handle, handle_location,
- ExternalPointerTable::EvacuateMarkMode::kClearMark);
+ ExternalPointerTable::EvacuateMarkMode::kClearMark,
+ kAnyExternalPointerTagRange);
return KEEP_SLOT;
};
auto slot_count = slots->Iterate<BasicSlotSet::AccessMode::NON_ATOMIC>(
@@ -949,7 +950,7 @@ bool MinorMarkSweepCollector::StartSweepNewSpace() {
}
if (ShouldMovePage(p, live_bytes_on_page, p->wasted_memory())) {
- EvacuateExternalPointerReferences(p);
+ EvacuateExternalPointerReferencesDuringSweeping(p);
// free list categories will be relinked by the sweeper after sweeping is
// done.
p->set_will_be_promoted(true);
@@ -1029,7 +1030,7 @@ bool MinorMarkSweepCollector::SweepNewLargeSpace() {
current->ClearFlagNonExecutable(MemoryChunk::TO_PAGE);
current->SetFlagNonExecutable(MemoryChunk::FROM_PAGE);
current->marking_progress_tracker().ResetIfEnabled();
- EvacuateExternalPointerReferences(current);
+ EvacuateExternalPointerReferencesDuringSweeping(current);
old_lo_space->PromoteNewLargeObject(current);
has_promoted_pages = true;
sweeper()->AddPromotedPage(current);
diff --git a/deps/v8/src/heap/minor-mark-sweep.h b/deps/v8/src/heap/minor-mark-sweep.h
index dbb9cad1d95..93f7f048ff4 100644
--- a/deps/v8/src/heap/minor-mark-sweep.h
+++ b/deps/v8/src/heap/minor-mark-sweep.h
@@ -207,7 +207,7 @@ class MinorMarkSweepCollector final {
YoungGenerationRootMarkingVisitor& root_visitor);
void MarkRootsFromConservativeStack(
YoungGenerationRootMarkingVisitor& root_visitor);
- void EvacuateExternalPointerReferences(MutablePage* p);
+ void EvacuateExternalPointerReferencesDuringSweeping(MutablePage* p);
void TraceFragmentation();
void ClearNonLiveReferences();
diff --git a/deps/v8/src/heap/mutable-page.cc b/deps/v8/src/heap/mutable-page.cc
index 9d7f6401a2b..a63309718da 100644
--- a/deps/v8/src/heap/mutable-page.cc
+++ b/deps/v8/src/heap/mutable-page.cc
@@ -42,8 +42,6 @@ MutablePage::MutablePage(Heap* heap, BaseSpace* space, size_t chunk_size,
// aligning the metadata on x64 (before, the metadata started at offset 0x10).
// After reordering, the impact is still 0.1%/0.2% on jetstream2/speedometer3,
// so there should be some more optimization potential here.
- // TODO(mlippautz): Replace 64 below with
- // `hardware_destructive_interference_size` once supported.
static constexpr auto kOffsetOfFirstFastField = offsetof(MutablePage, heap_);
static constexpr auto kOffsetOfLastFastField =
offsetof(MutablePage, slot_set_) +
@@ -51,7 +49,9 @@ MutablePage::MutablePage(Heap* heap, BaseSpace* space, size_t chunk_size,
// This assert is merely necessary but not sufficient to guarantee that the
// fields sit on the same cacheline as the metadata object itself is
// dynamically allocated without alignment restrictions.
- static_assert(kOffsetOfFirstFastField / 64 == kOffsetOfLastFastField / 64);
+ static_assert(
+ kOffsetOfFirstFastField / std::hardware_destructive_interference_size ==
+ kOffsetOfLastFastField / std::hardware_destructive_interference_size);
}
// static
diff --git a/deps/v8/src/heap/object-stats.cc b/deps/v8/src/heap/object-stats.cc
index e5661267454..7a4e6a12540 100644
--- a/deps/v8/src/heap/object-stats.cc
+++ b/deps/v8/src/heap/object-stats.cc
@@ -25,6 +25,8 @@
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/literal-objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
+#include "src/objects/oddball-predicates-inl.h"
#include "src/objects/prototype-info.h"
#include "src/objects/slots.h"
#include "src/objects/templates.h"
@@ -955,6 +957,8 @@ void ObjectStatsCollectorImpl::CollectGlobalStatistics() {
StatsEnum::NUMBER_STRING_CACHE_TYPE);
RecordSimpleVirtualObjectStats({}, heap_->string_split_cache(),
StatsEnum::STRING_SPLIT_CACHE_TYPE);
+ RecordSimpleVirtualObjectStats({}, heap_->regexp_split_cache(),
+ StatsEnum::STRING_SPLIT_CACHE_TYPE);
RecordSimpleVirtualObjectStats({}, heap_->regexp_multiple_cache(),
StatsEnum::REGEXP_MULTIPLE_CACHE_TYPE);
@@ -1131,6 +1135,7 @@ void ObjectStatsCollectorImpl::
RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
Tagged<HeapObject> parent, Tagged<HeapObject> object,
ObjectStats::VirtualInstanceType type) {
+ if (IsInaccessible(object)) return;
if (!RecordSimpleVirtualObjectStats(parent, object, type)) return;
if (IsFixedArrayExact(object)) {
Tagged<FixedArray> array = Cast<FixedArray>(object);
@@ -1210,7 +1215,8 @@ void ObjectStatsCollectorImpl::RecordVirtualCodeDetails(
int const mode_mask = RelocInfo::EmbeddedObjectModeMask();
for (RelocIterator it(code, mode_mask); !it.done(); it.next()) {
DCHECK(RelocInfo::IsEmbeddedObjectMode(it.rinfo()->rmode()));
- Tagged<Object> target = it.rinfo()->target_object();
+ Tagged<HeapObject> target = it.rinfo()->target_object();
+ if (IsInaccessible(target)) continue;
if (IsFixedArrayExact(target)) {
RecordVirtualObjectsForConstantPoolOrEmbeddedObjects(
istream, Cast<HeapObject>(target), StatsEnum::EMBEDDED_OBJECT_TYPE);
@@ -1272,6 +1278,7 @@ void IterateHeap(Heap* heap, ObjectStatsVisitor* visitor) {
CombinedHeapObjectIterator iterator(heap);
for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
+ if (IsInaccessible(obj)) continue;
visitor->Visit(obj);
}
}
diff --git a/deps/v8/src/heap/pretenuring-handler-inl.h b/deps/v8/src/heap/pretenuring-handler-inl.h
index 33bc72d3a9e..78a25635d90 100644
--- a/deps/v8/src/heap/pretenuring-handler-inl.h
+++ b/deps/v8/src/heap/pretenuring-handler-inl.h
@@ -21,7 +21,9 @@ namespace v8::internal {
// static
void PretenuringHandler::UpdateAllocationSite(
Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size,
- PretenuringFeedbackMap* pretenuring_feedback) {
+ PretenuringFeedbackMap* pretenuring_feedback,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot) {
DCHECK_NE(pretenuring_feedback,
&heap->pretenuring_handler()->global_pretenuring_feedback_);
#ifdef DEBUG
@@ -36,8 +38,8 @@ void PretenuringHandler::UpdateAllocationSite(
!AllocationSite::CanTrack(map->instance_type())) {
return;
}
- Tagged<AllocationMemento> memento_candidate =
- FindAllocationMemento<kForGC>(heap, map, object, object_size);
+ Tagged<AllocationMemento> memento_candidate = FindAllocationMemento<kForGC>(
+ heap, map, object, object_size, young_pending_allocations_snapshot);
if (memento_candidate.is_null()) {
return;
}
@@ -54,25 +56,33 @@ void PretenuringHandler::UpdateAllocationSite(
void PretenuringHandler::UpdateAllocationSite(
Heap* heap, Tagged<Map> map, Tagged<HeapObject> object,
SafeHeapObjectSize object_size,
- PretenuringFeedbackMap* pretenuring_feedback) {
+ PretenuringFeedbackMap* pretenuring_feedback,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot) {
// TODO(425150995): We should have uint versions for allocation to avoid
// introducing OOBs via sign-extended ints along the way.
UpdateAllocationSite(heap, map, object, object_size.value(),
- pretenuring_feedback);
+ pretenuring_feedback,
+ young_pending_allocations_snapshot);
}
// static
template <PretenuringHandler::FindMementoMode mode>
Tagged<AllocationMemento> PretenuringHandler::FindAllocationMemento(
- Heap* heap, Tagged<Map> map, Tagged<HeapObject> object) {
+ Heap* heap, Tagged<Map> map, Tagged<HeapObject> object,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot) {
return FindAllocationMemento<mode>(heap, map, object,
- object->SizeFromMap(map));
+ object->SizeFromMap(map),
+ young_pending_allocations_snapshot);
}
// static
template <PretenuringHandler::FindMementoMode mode>
Tagged<AllocationMemento> PretenuringHandler::FindAllocationMemento(
- Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size) {
+ Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot) {
// For uses from within the GC, the size here may actually change when e.g.
// updating mementos during marking in the young generation collector. This is
// not an issue with Scavenger that stops the mutator.
@@ -93,12 +103,28 @@ Tagged<AllocationMemento> PretenuringHandler::FindAllocationMemento(
// If the page is being swept, treat it as if the memento was already swept
// and bail out.
- if constexpr (mode != FindMementoMode::kForGC) {
+ if constexpr (mode == FindMementoMode::kForRuntime) {
MemoryChunk* object_chunk = MemoryChunk::FromAddress(object_address);
NormalPage* object_page = SbxCast<NormalPage>(object_chunk->Metadata());
if (!object_page->SweepingDone()) {
return {};
}
+ } else {
+ DCHECK_EQ(mode, FindMementoMode::kForGC);
+ DCHECK_IMPLIES(!v8_flags.minor_ms,
+ young_pending_allocations_snapshot == nullptr);
+ if (young_pending_allocations_snapshot &&
+ young_pending_allocations_snapshot->Contains(memento_address)) {
+ return {};
+ }
+ }
+
+ // Bailout if memento is below the age mark. This is only possible for pinned
+ // pages in the scavenger. Full GC has page promotion but clears the
+ // NEW_SPACE_BELOW_AGE_MARK page flags before checking mementos.
+ if (!v8_flags.minor_ms &&
+ heap->semi_space_new_space()->IsAddressBelowAgeMark(object_address)) {
+ return {};
}
Tagged<HeapObject> candidate = HeapObject::FromAddress(memento_address);
@@ -112,14 +138,6 @@ Tagged<AllocationMemento> PretenuringHandler::FindAllocationMemento(
return {};
}
- // Bailout if memento is below the age mark. This is only possible for pinned
- // pages in the scavenger. Full GC has page promotion but clears the
- // NEW_SPACE_BELOW_AGE_MARK page flags before checking mementos.
- if (!v8_flags.minor_ms &&
- heap->semi_space_new_space()->IsAddressBelowAgeMark(object_address)) {
- return {};
- }
-
Tagged<AllocationMemento> memento_candidate =
Cast<AllocationMemento>(candidate);
diff --git a/deps/v8/src/heap/pretenuring-handler.h b/deps/v8/src/heap/pretenuring-handler.h
index c54910e0762..b1cf15762fb 100644
--- a/deps/v8/src/heap/pretenuring-handler.h
+++ b/deps/v8/src/heap/pretenuring-handler.h
@@ -8,6 +8,7 @@
#include <memory>
#include <unordered_map>
+#include "src/heap/pending-allocations.h"
#include "src/objects/allocation-site.h"
#include "src/objects/heap-object.h"
#include "src/objects/map.h"
@@ -36,10 +37,14 @@ class PretenuringHandler final {
// return a null AllocationMemento.
template <FindMementoMode mode>
static inline Tagged<AllocationMemento> FindAllocationMemento(
- Heap* heap, Tagged<Map> map, Tagged<HeapObject> object);
+ Heap* heap, Tagged<Map> map, Tagged<HeapObject> object,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot = nullptr);
template <FindMementoMode mode>
static inline Tagged<AllocationMemento> FindAllocationMemento(
- Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size);
+ Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot = nullptr);
// ===========================================================================
// Allocation site tracking. =================================================
@@ -49,11 +54,15 @@ class PretenuringHandler final {
// count) is cached on the local pretenuring feedback.
static inline void UpdateAllocationSite(
Heap* heap, Tagged<Map> map, Tagged<HeapObject> object, int object_size,
- PretenuringFeedbackMap* pretenuring_feedback);
+ PretenuringFeedbackMap* pretenuring_feedback,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot = nullptr);
static inline void UpdateAllocationSite(
Heap* heap, Tagged<Map> map, Tagged<HeapObject> object,
SafeHeapObjectSize object_size,
- PretenuringFeedbackMap* pretenuring_feedback);
+ PretenuringFeedbackMap* pretenuring_feedback,
+ const YoungPendingAllocations::Snapshot*
+ young_pending_allocations_snapshot = nullptr);
// Merges local pretenuring feedback into the global one. Note that this
// method needs to be called after evacuation, as allocation sites may be
diff --git a/deps/v8/src/heap/read-only-heap.cc b/deps/v8/src/heap/read-only-heap.cc
index 8fae16bc6a3..73ec378499e 100644
--- a/deps/v8/src/heap/read-only-heap.cc
+++ b/deps/v8/src/heap/read-only-heap.cc
@@ -31,9 +31,8 @@ namespace internal {
ReadOnlyHeap::~ReadOnlyHeap() {
#if V8_ENABLE_WEBASSEMBLY && V8_STATIC_ROOTS_BOOL
- if (wasm_null_payload_ != kNullAddress) {
- trap_handler::UnregisterCoveredMemory(wasm_null_payload_,
- WasmNull::kPayloadSize);
+ if (wasm_null_ != kNullAddress) {
+ trap_handler::UnregisterCoveredMemory(wasm_null_, WasmNull::kSize);
}
#endif // V8_ENABLE_WEBASSEMBLY && V8_STATIC_ROOTS_BOOL
}
@@ -166,10 +165,9 @@ void ReadOnlyHeap::InitFromIsolate(Isolate* isolate) {
#if V8_ENABLE_WEBASSEMBLY && V8_STATIC_ROOTS_BOOL
if (trap_handler::IsTrapHandlerEnabled()) {
- CHECK_EQ(wasm_null_payload_, kNullAddress);
- wasm_null_payload_ = isolate->factory()->wasm_null()->payload();
- CHECK(trap_handler::RegisterCoveredMemory(wasm_null_payload_,
- WasmNull::kPayloadSize));
+ CHECK_EQ(wasm_null_, kNullAddress);
+ wasm_null_ = isolate->factory()->wasm_null()->address();
+ CHECK(trap_handler::RegisterCoveredMemory(wasm_null_, WasmNull::kSize));
}
#endif // V8_ENABLE_WEBASSEMBLY && V8_STATIC_ROOTS_BOOL
@@ -276,6 +274,12 @@ Tagged<HeapObject> ReadOnlyPageObjectIterator::Next() {
if (current_addr_ == end) return {};
Tagged<HeapObject> object = HeapObject::FromAddress(current_addr_);
+#if V8_ENABLE_WEBASSEMBLY
+ if (IsWasmNull(object)) {
+ current_addr_ += ALIGN_TO_ALLOCATION_ALIGNMENT(WasmNull::kSize);
+ return object;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
const uint32_t object_size = object->SafeSize().value();
current_addr_ += ALIGN_TO_ALLOCATION_ALIGNMENT(object_size);
diff --git a/deps/v8/src/heap/read-only-heap.h b/deps/v8/src/heap/read-only-heap.h
index f4a9f39ffdf..329d0abeecb 100644
--- a/deps/v8/src/heap/read-only-heap.h
+++ b/deps/v8/src/heap/read-only-heap.h
@@ -105,7 +105,7 @@ class ReadOnlyHeap final {
ReadOnlySpace* read_only_space_ = nullptr;
#if V8_ENABLE_WEBASSEMBLY
- Address wasm_null_payload_ = kNullAddress;
+ Address wasm_null_ = kNullAddress;
#endif
private:
diff --git a/deps/v8/src/heap/read-only-promotion.cc b/deps/v8/src/heap/read-only-promotion.cc
index de6cad221e6..35164f892ce 100644
--- a/deps/v8/src/heap/read-only-promotion.cc
+++ b/deps/v8/src/heap/read-only-promotion.cc
@@ -475,7 +475,7 @@ class ReadOnlyPromotionImpl final : public AllStatic {
const HeapObjectMap& moves) {
Heap* heap = isolate->heap();
#ifdef V8_COMPRESS_POINTERS
- ExternalPointerTable::UnsealReadOnlySegmentScope unseal_scope(
+ SegmentedTableBase::UnsealReadOnlySegmentScope unseal_scope(
&isolate->external_pointer_table());
#endif // V8_COMPRESS_POINTERS
UpdatePointersVisitor v(isolate, &moves);
@@ -763,7 +763,7 @@ class ReadOnlyPromotionImpl final : public AllStatic {
DisallowJavascriptExecution no_js(isolate_);
TrustedPointerPublishingScope scope(isolate_, no_js);
- TrustedPointerTable::UnsealReadOnlySegmentScope unseal_scope(tpt);
+ SegmentedTableBase::UnsealReadOnlySegmentScope unseal_scope(tpt);
IndirectPointerHandle new_handle =
tpt->AllocateAndInitializeEntry(space, obj.ptr(), tag, &scope);
scope.MarkSuccess();
diff --git a/deps/v8/src/heap/read-only-spaces.cc b/deps/v8/src/heap/read-only-spaces.cc
index 54d3f1a1657..b302fd3f4b3 100644
--- a/deps/v8/src/heap/read-only-spaces.cc
+++ b/deps/v8/src/heap/read-only-spaces.cc
@@ -252,6 +252,16 @@ class ReadOnlySpaceObjectIterator : public ObjectIterator {
continue;
}
Tagged<HeapObject> obj = HeapObject::FromAddress(cur_addr_);
+#if V8_ENABLE_WEBASSEMBLY && \
+ (V8_STATIC_ROOTS_BOOL || V8_STATIC_ROOTS_GENERATION_BOOL)
+ if (IsWasmNull(obj)) {
+ cur_addr_ += ALIGN_TO_ALLOCATION_ALIGNMENT(WasmNull::kSize);
+ DCHECK_LE(cur_addr_, cur_end_);
+ // For the few specific callers of this function, skipping WasmNull
+ // here makes things simpler.
+ continue;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY && ...
const uint32_t obj_size = obj->SafeSize().value();
cur_addr_ += ALIGN_TO_ALLOCATION_ALIGNMENT(obj_size);
DCHECK_LE(cur_addr_, cur_end_);
diff --git a/deps/v8/src/heap/scavenger.cc b/deps/v8/src/heap/scavenger.cc
index 29a3f617a27..64d996f2b25 100644
--- a/deps/v8/src/heap/scavenger.cc
+++ b/deps/v8/src/heap/scavenger.cc
@@ -513,26 +513,30 @@ class ScavengerObjectVisitorBase : public NewSpaceVisitor<ConcreteVisitor> {
ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
Heap* heap = scavenger_->heap();
ExternalPointerTable& table = heap->isolate()->external_pointer_table();
- ArrayBufferExtension* array_buffer_extension =
- slot.tag_range() == kArrayBufferExtensionTag
- ? reinterpret_cast<ArrayBufferExtension*>(
- table.Get(handle, kArrayBufferExtensionTag))
- : nullptr;
if constexpr (kExpectedObjectAge == ObjectAge::kYoung) {
// For survivor objects, mark their EPT entries when they are
// copied. Scavenger then sweeps the young EPT space at the end of
// collection, reclaiming unmarked EPT entries.
- table.Mark(heap->young_external_pointer_space(), handle, slot.address());
+ table.Mark(heap->young_external_pointer_space(), handle, slot.address(),
+ slot.tag_range());
} else {
// When promoting, we just evacuate the entry from new to old space.
// Usually the entry will be unmarked, unless the slot was initialized
// since the last GC (external pointer tags have the mark bit set), in
// which case it may be marked already. In any case, transfer the color
// from new to old EPT space.
- table.Evacuate(heap->young_external_pointer_space(),
- heap->old_external_pointer_space(), handle, slot.address(),
- ExternalPointerTable::EvacuateMarkMode::kTransferMark);
+ handle = table.Evacuate(
+ heap->young_external_pointer_space(),
+ heap->old_external_pointer_space(), handle, slot.address(),
+ ExternalPointerTable::EvacuateMarkMode::kTransferMark,
+ slot.tag_range());
}
+
+ ArrayBufferExtension* array_buffer_extension =
+ slot.tag_range() == kArrayBufferExtensionTag
+ ? reinterpret_cast<ArrayBufferExtension*>(
+ table.Get(handle, kArrayBufferExtensionTag))
+ : nullptr;
#else // !V8_COMPRESS_POINTERS
ArrayBufferExtension* array_buffer_extension =
slot.tag_range() == kArrayBufferExtensionTag
@@ -1456,6 +1460,10 @@ class RootScavengeVisitor final : public RootVisitor {
void VisitRootPointers(Root root, const char* description,
FullObjectSlot start, FullObjectSlot end) final;
+ GarbageCollector collector() const final {
+ return GarbageCollector::SCAVENGER;
+ }
+
private:
void ScavengePointer(FullObjectSlot p);
@@ -1833,7 +1841,6 @@ void ScavengerCollector::CollectGarbage() {
// Since we promote all surviving large objects immediately, all remaining
// large objects must be dead.
- // TODO(hpayer): Don't free all as soon as we have an intermediate generation.
heap_->new_lo_space()->FreeDeadObjects(
[](Tagged<HeapObject>) { return true; });
diff --git a/deps/v8/src/heap/setup-heap-internal.cc b/deps/v8/src/heap/setup-heap-internal.cc
index 7e3add2ab88..4448bd8400e 100644
--- a/deps/v8/src/heap/setup-heap-internal.cc
+++ b/deps/v8/src/heap/setup-heap-internal.cc
@@ -39,6 +39,7 @@
#include "src/objects/map.h"
#include "src/objects/megadom-handler.h"
#include "src/objects/microtask.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/ordered-hash-table.h"
@@ -87,8 +88,9 @@ bool IsMutableMap(InstanceType instance_type, ElementsKind elements_kind) {
InstanceTypeChecker::IsAlwaysSharedSpaceJSObject(instance_type);
bool is_wasm_object = false;
#if V8_ENABLE_WEBASSEMBLY
- is_wasm_object =
- instance_type == WASM_STRUCT_TYPE || instance_type == WASM_ARRAY_TYPE;
+ is_wasm_object = instance_type == WASM_STRUCT_TYPE ||
+ instance_type == WASM_CUSTOM_MAP_TYPE ||
+ instance_type == WASM_ARRAY_TYPE;
#endif // V8_ENABLE_WEBASSEMBLY
DCHECK_IMPLIES(is_js_object &&
!Map::CanHaveFastTransitionableElementsKind(instance_type),
@@ -904,6 +906,8 @@ bool Heap::CreateLateReadOnlyJSReceiverMaps() {
ALLOCATE_MAP(CPP_HEAP_EXTERNAL_OBJECT_TYPE,
CppHeapExternalObject::kHeaderSize, cpp_heap_external)
+ ALLOCATE_MAP(CPP_GCMANAGED_BASE_TYPE, CppGCManagedBase::kHeaderSize,
+ cpp_gc_managed_base)
}
// Shared space object maps are immutable and can be in RO space.
@@ -1360,11 +1364,9 @@ bool Heap::CreateReadOnlyObjects() {
#ifdef V8_ENABLE_WEBASSEMBLY
// Allocate the wasm-null object. It is a regular V8 heap object contained in
// a V8 page.
- // In static-roots builds, it is large enough so that its payload (other than
- // its map word) can be mprotected on OS page granularity. We adjust the
- // layout such that we have a filler object in the current OS page, and the
- // wasm-null map word at the end of the current OS page. The payload then is
- // contained on a separate OS page which can be protected.
+ // In static-roots builds, it is large enough so that it can be mprotected on
+ // OS page granularity, so we fill up the rest of the current OS page with
+ // a filler.
// In non-static-roots builds, it is a regular object of size {kTaggedSize}
// and does not need padding.
#define V8_UNMAP_WASM_NULL_PAYLOAD \
@@ -1373,17 +1375,10 @@ bool Heap::CreateReadOnlyObjects() {
#if V8_UNMAP_WASM_NULL_PAYLOAD
// Allocate an unmappable WasmNull.
{
- static_assert(WasmNull::kSize ==
- WasmNull::kHeaderSize + WasmNull::kPayloadSize);
Tagged<HeapObject> wasm_null_obj =
- read_only_space_
- ->AllocateRawUnmappableAllocation(WasmNull::kHeaderSize,
- WasmNull::kPayloadSize)
+ read_only_space_->AllocateRawUnmappableAllocation(0, WasmNull::kSize)
.ToObjectChecked();
- wasm_null_obj->set_map_after_allocation(isolate(), roots.wasm_null_map(),
- SKIP_WRITE_BARRIER);
- // No need to initialize the payload since it's either empty or unmapped.
- set_wasm_null(Cast<WasmNull>(wasm_null_obj));
+ set_wasm_null(UncheckedCast<WasmNull>(wasm_null_obj));
}
#else
// Allocate the WasmNull.
@@ -1487,6 +1482,8 @@ void Heap::CreateInitialMutableObjects() {
// Allocate regexp caches.
set_string_split_cache(*factory->NewFixedArray(
regexp::ResultsCache::kRegExpResultsCacheSize, AllocationType::kOld));
+ // Allocated on first use, see EnsureRegExpSplitCache.
+ set_regexp_split_cache(roots.empty_fixed_array());
set_regexp_multiple_cache(*factory->NewFixedArray(
regexp::ResultsCache::kRegExpResultsCacheSize, AllocationType::kOld));
set_regexp_match_global_atom_cache(*factory->NewFixedArray(
@@ -1501,6 +1498,7 @@ void Heap::CreateInitialMutableObjects() {
#ifdef V8_ENABLE_WEBASSEMBLY
set_js_to_wasm_wrappers(roots.empty_weak_fixed_array());
set_wasm_canonical_rtts(roots.empty_weak_fixed_array());
+ set_wasm_shared_canonical_rtts(roots.empty_weak_fixed_array());
#endif // V8_ENABLE_WEBASSEMBLY
set_script_list(roots.empty_weak_array_list());
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 897d667ad7d..14c6c693722 100644
--- a/deps/v8/src/heap/young-generation-marking-visitor-inl.h
+++ b/deps/v8/src/heap/young-generation-marking-visitor-inl.h
@@ -24,7 +24,8 @@ namespace internal {
template <YoungGenerationMarkingVisitationMode marking_mode>
YoungGenerationMarkingVisitor<marking_mode>::YoungGenerationMarkingVisitor(
Heap* heap,
- PretenuringHandler::PretenuringFeedbackMap* local_pretenuring_feedback)
+ PretenuringHandler::PretenuringFeedbackMap* local_pretenuring_feedback,
+ YoungPendingAllocations::Snapshot* young_pending_allocations_snapshot)
: Base(heap->isolate()),
isolate_(heap->isolate()),
marking_worklists_local_(
@@ -36,6 +37,7 @@ YoungGenerationMarkingVisitor<marking_mode>::YoungGenerationMarkingVisitor(
*heap->minor_mark_sweep_collector()->ephemeron_table_list()),
pretenuring_handler_(heap->pretenuring_handler()),
local_pretenuring_feedback_(local_pretenuring_feedback),
+ young_pending_allocations_snapshot_(young_pending_allocations_snapshot),
shortcut_strings_(heap->CanShortcutStringsDuringGC(
GarbageCollector::MINOR_MARK_SWEEPER)) {}
@@ -84,8 +86,12 @@ size_t YoungGenerationMarkingVisitor<marking_mode>::VisitJSObjectSubclass(
const int object_size =
static_cast<int>(Base::template VisitJSObjectSubclass<T, TBodyDescriptor>(
map, object, maybe_object_size));
+ DCHECK_IMPLIES(
+ marking_mode == YoungGenerationMarkingVisitationMode::kConcurrent,
+ young_pending_allocations_snapshot_ != nullptr);
PretenuringHandler::UpdateAllocationSite(
- isolate_->heap(), map, object, object_size, local_pretenuring_feedback_);
+ isolate_->heap(), map, object, object_size, local_pretenuring_feedback_,
+ young_pending_allocations_snapshot_);
return object_size;
}
@@ -122,7 +128,7 @@ void YoungGenerationMarkingVisitor<marking_mode>::VisitExternalPointer(
if (handle != kNullExternalPointerHandle) {
ExternalPointerTable& table = isolate_->external_pointer_table();
auto* space = isolate_->heap()->young_external_pointer_space();
- table.Mark(space, handle, slot.address());
+ table.Mark(space, handle, slot.address(), slot.tag_range());
if (slot.tag_range() == kArrayBufferExtensionTag) {
maybe_extension = table.Get(handle, kArrayBufferExtensionTag);
}
diff --git a/deps/v8/src/heap/young-generation-marking-visitor.h b/deps/v8/src/heap/young-generation-marking-visitor.h
index 52e4be30d6c..9b355544957 100644
--- a/deps/v8/src/heap/young-generation-marking-visitor.h
+++ b/deps/v8/src/heap/young-generation-marking-visitor.h
@@ -11,6 +11,7 @@
#include "src/heap/heap-visitor.h"
#include "src/heap/heap.h"
#include "src/heap/marking-worklist.h"
+#include "src/heap/pending-allocations.h"
#include "src/heap/pretenuring-handler.h"
namespace v8 {
@@ -36,7 +37,9 @@ class YoungGenerationMarkingVisitor final
YoungGenerationMarkingVisitor(
Heap* heap,
- PretenuringHandler::PretenuringFeedbackMap* local_pretenuring_feedback);
+ PretenuringHandler::PretenuringFeedbackMap* local_pretenuring_feedback,
+ YoungPendingAllocations::Snapshot* young_pending_allocations_snapshot =
+ nullptr);
~YoungGenerationMarkingVisitor() override;
@@ -125,6 +128,8 @@ class YoungGenerationMarkingVisitor final
EphemeronRememberedSet::TableList::Local ephemeron_table_list_local_;
PretenuringHandler* const pretenuring_handler_;
PretenuringHandler::PretenuringFeedbackMap* const local_pretenuring_feedback_;
+ const YoungPendingAllocations::Snapshot* const
+ young_pending_allocations_snapshot_;
const bool shortcut_strings_;
};
diff --git a/deps/v8/src/ic/accessor-assembler.cc b/deps/v8/src/ic/accessor-assembler.cc
index 52aec124a61..c5f4df6edfb 100644
--- a/deps/v8/src/ic/accessor-assembler.cc
+++ b/deps/v8/src/ic/accessor-assembler.cc
@@ -212,6 +212,14 @@ void AccessorAssembler::TryHomomorphicCase(TNode<Object> lookup_start_object,
CSA_DCHECK(this,
Word32BitwiseNot(IsDictionaryMap(lookup_start_object_map)));
+ // Reject special receivers. Access checks and named interceptors imply
+ // special receiver.
+ GotoIf(IsSpecialReceiverMap(lookup_start_object_map), miss);
+ CSA_DCHECK(this, Word32BinaryNot(IsSetWord32(
+ LoadMapBitField(lookup_start_object_map),
+ Map::Bits1::HasNamedInterceptorBit::kMask |
+ Map::Bits1::IsAccessCheckNeededBit::kMask)));
+
// Load the descriptor at the index and verify that the key matches the
// loaded name.
TNode<DescriptorArray> descriptors =
diff --git a/deps/v8/src/ic/handler-configuration.h b/deps/v8/src/ic/handler-configuration.h
index df9e366332e..6e85b8f06f6 100644
--- a/deps/v8/src/ic/handler-configuration.h
+++ b/deps/v8/src/ic/handler-configuration.h
@@ -26,6 +26,8 @@ class JSProxy;
// that represents load handlers that can't be encoded in a Smi.
// TODO(ishell): move to load-handler.h
V8_OBJECT class LoadHandler final : public DataHandler {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
DECL_PRINTER(LoadHandler)
DECL_VERIFIER(LoadHandler)
@@ -255,6 +257,8 @@ V8_OBJECT class LoadHandler final : public DataHandler {
// that represents store handlers that can't be encoded in a Smi.
// TODO(ishell): move to store-handler.h
V8_OBJECT class StoreHandler final : public DataHandler {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
DECL_PRINTER(StoreHandler)
DECL_VERIFIER(StoreHandler)
diff --git a/deps/v8/src/ic/ic.cc b/deps/v8/src/ic/ic.cc
index 2c6612178d7..ad7852b0ba3 100644
--- a/deps/v8/src/ic/ic.cc
+++ b/deps/v8/src/ic/ic.cc
@@ -38,6 +38,7 @@
#include "src/objects/js-array-inl.h"
#include "src/objects/js-proxy-inl.h"
#include "src/objects/megadom-handler.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/objects/prototype.h"
#include "src/runtime/runtime.h"
@@ -84,6 +85,17 @@ char IC::TransitionMarkFromState(IC::State state) {
namespace {
+bool MayHaveTypedArrayInPrototypeChain(Isolate* isolate,
+ DirectHandle<JSObject> object) {
+ for (PrototypeIterator iter(isolate, *object); !iter.IsAtEnd();
+ iter.Advance()) {
+ // Be conservative, don't walk into proxies.
+ if (IsJSProxy(iter.GetCurrent())) return true;
+ if (IsJSTypedArray(iter.GetCurrent())) return true;
+ }
+ return false;
+}
+
const char* GetModifier(KeyedAccessLoadMode mode) {
switch (mode) {
case KeyedAccessLoadMode::kHandleOOB:
@@ -234,6 +246,7 @@ static void LookupForRead(LookupIterator* it, bool is_has_property) {
if (JSDeferredModuleNamespace::TriggersEvaluation(it)) {
return;
}
+ JSModuleNamespace::MaybeCountMissingDefaultWithStarExport(it);
// Once a deferred module is evaluated, we will fallback to perform IC
// as an ordinary module namespace. This way it can be either ACCESSOR
// or NOT_FOUND state.
@@ -2304,6 +2317,11 @@ MaybeDirectHandle<Object> StoreIC::Store(Handle<JSAny> object,
if (!can_store.FromJust()) {
return isolate()->factory()->undefined_value();
}
+ // Restart the lookup iterator updated by CheckPrivateNameStore() for
+ // UpdateCaches() to handle access checks.
+ if (use_ic && IsAccessCheckNeeded(*object)) {
+ it.Restart();
+ }
}
// IC handling of private fields/symbols stores on JSProxy is not
@@ -2372,7 +2390,17 @@ MaybeDirectHandle<Object> StoreIC::Store(Handle<JSAny> object,
void StoreIC::UpdateCaches(LookupIterator* lookup, DirectHandle<Object> value,
StoreOrigin store_origin) {
MaybeObjectHandle handler;
- if (LookupForWrite(lookup, value, store_origin)) {
+ if (lookup->IsElement() && !IsAnyDefineOwn() &&
+ IsJSObject(*lookup->GetReceiver()) &&
+ MayHaveTypedArrayInPrototypeChain(
+ isolate(), Cast<JSObject>(lookup->GetReceiver()))) {
+ // Make sure we don't handle this in IC if there's any JSTypedArray in
+ // the {receiver}'s prototype chain, since that prototype is going to
+ // swallow all stores that are out-of-bounds for said prototype, and we
+ // just let the runtime deal with the complexity of this.
+ set_slow_stub_reason("typed array in the prototype chain");
+ handler = MaybeObjectHandle(StoreHandler::StoreSlow(isolate()));
+ } else if (LookupForWrite(lookup, value, store_origin)) {
if (IsStoreGlobalIC()) {
if (lookup->state() == LookupIterator::DATA &&
lookup->GetReceiver().is_identical_to(lookup->GetHolder<Object>())) {
@@ -2988,17 +3016,6 @@ void KeyedStoreIC::StoreElementPolymorphicHandlers(
namespace {
-bool MayHaveTypedArrayInPrototypeChain(Isolate* isolate,
- DirectHandle<JSObject> object) {
- for (PrototypeIterator iter(isolate, *object); !iter.IsAtEnd();
- iter.Advance()) {
- // Be conservative, don't walk into proxies.
- if (IsJSProxy(iter.GetCurrent())) return true;
- if (IsJSTypedArray(iter.GetCurrent())) return true;
- }
- return false;
-}
-
KeyedAccessStoreMode GetStoreMode(DirectHandle<JSObject> receiver,
size_t index) {
bool oob_access = IsOutOfBoundsAccess(receiver, index);
@@ -3164,16 +3181,14 @@ MaybeDirectHandle<Object> KeyedStoreIC::Store(Handle<JSAny> object,
}
namespace {
-Maybe<bool> StoreOwnElement(Isolate* isolate, DirectHandle<JSArray> array,
- Handle<Object> index, DirectHandle<Object> value) {
+V8_WARN_UNUSED_RESULT MaybeDirectHandle<Object> StoreOwnElement(
+ Isolate* isolate, DirectHandle<JSArray> array, Handle<Object> index,
+ DirectHandle<Object> value) {
DCHECK(IsNumber(*index));
PropertyKey key(isolate, index);
LookupIterator it(isolate, array, key, LookupIterator::OWN);
- MAYBE_RETURN(JSObject::DefineOwnPropertyIgnoreAttributes(
- &it, value, NONE, Just(ShouldThrow::kThrowOnError)),
- Nothing<bool>());
- return Just(true);
+ return JSObject::DefineOwnPropertyIgnoreAttributes(&it, value, NONE);
}
} // namespace
@@ -3185,7 +3200,8 @@ MaybeDirectHandle<Object> StoreInArrayLiteralIC::Store(
if (!v8_flags.use_ic || state() == NO_FEEDBACK ||
MigrateDeprecated(isolate(), array)) {
- MAYBE_RETURN_NULL(StoreOwnElement(isolate(), array, index, value));
+ RETURN_ON_EXCEPTION(isolate(),
+ StoreOwnElement(isolate(), array, index, value));
TraceIC("StoreInArrayLiteralIC", index);
return value;
}
@@ -3200,7 +3216,8 @@ MaybeDirectHandle<Object> StoreInArrayLiteralIC::Store(
}
Handle<Map> old_array_map(array->map(), isolate());
- MAYBE_RETURN_NULL(StoreOwnElement(isolate(), array, index, value));
+ RETURN_ON_EXCEPTION(isolate(),
+ StoreOwnElement(isolate(), array, index, value));
if (IsSmi(*index)) {
DCHECK(!old_array_map->is_abandoned_prototype_map());
@@ -3752,8 +3769,8 @@ RUNTIME_FUNCTION(Runtime_StoreInArrayLiteralIC_Slow) {
DirectHandle<Object> value = args.at(0);
DirectHandle<Object> array = args.at(1);
Handle<Object> index = args.at(2);
- StoreOwnElement(isolate, Cast<JSArray>(array), index, value);
- return *value;
+ RETURN_RESULT_OR_FAILURE(
+ isolate, StoreOwnElement(isolate, Cast<JSArray>(array), index, value));
}
RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
@@ -3775,8 +3792,8 @@ RUNTIME_FUNCTION(Runtime_ElementsTransitionAndStoreIC_Miss) {
}
if (IsStoreInArrayLiteralICKind(kind)) {
- StoreOwnElement(isolate, Cast<JSArray>(object), key, value);
- return *value;
+ RETURN_RESULT_OR_FAILURE(
+ isolate, StoreOwnElement(isolate, Cast<JSArray>(object), key, value));
} else {
DCHECK(IsKeyedStoreICKind(kind) || IsSetNamedICKind(kind) ||
IsDefineKeyedOwnICKind(kind));
diff --git a/deps/v8/src/ic/unary-op-assembler.cc b/deps/v8/src/ic/unary-op-assembler.cc
index 61d3a72575d..7d43c7ce2b0 100644
--- a/deps/v8/src/ic/unary-op-assembler.cc
+++ b/deps/v8/src/ic/unary-op-assembler.cc
@@ -20,9 +20,7 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
: CodeStubAssembler(state) {}
TNode<Object> BitwiseNot(TNode<Context> context, TNode<Object> value,
- TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
+ const FeedbackUpdater& feedback_updater) {
// TODO(jgruber): Make this implementation more consistent with other unary
// ops (i.e. have them all use UnaryOpWithFeedback or some other common
// mechanism).
@@ -31,9 +29,9 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
TVARIABLE(BigInt, var_bigint);
TVARIABLE(Object, var_result);
Label if_number(this), if_bigint(this, Label::kDeferred), out(this);
- LazyNode<HeapObject> get_vector = [&]() { return maybe_feedback_vector; };
- FeedbackValues feedback = {&var_feedback, &get_vector, &slot,
- update_feedback_mode};
+ FeedbackValues feedback = {&var_feedback, nullptr, nullptr,
+ UpdateFeedbackMode::kNoFeedback,
+ &feedback_updater};
TaggedToWord32OrBigIntWithFeedback(context, value, &if_number, &var_word32,
&if_bigint, nullptr, &var_bigint,
feedback);
@@ -45,14 +43,12 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
TNode<Smi> result_type = SelectSmiConstant(
TaggedIsSmi(var_result.value()), BinaryOperationFeedback::kSignedSmall,
BinaryOperationFeedback::kNumber);
- UpdateFeedback(SmiOr(result_type, var_feedback.value()),
- maybe_feedback_vector, slot, update_feedback_mode);
+ feedback_updater(SmiOr(result_type, var_feedback.value()));
Goto(&out);
// BigInt case.
BIND(&if_bigint);
- UpdateFeedback(SmiConstant(BinaryOperationFeedback::kBigInt),
- maybe_feedback_vector, slot, update_feedback_mode);
+ feedback_updater(SmiConstant(BinaryOperationFeedback::kBigInt));
var_result =
CallRuntime(Runtime::kBigIntUnaryOp, context, var_bigint.value(),
SmiConstant(Operation::kBitwiseNot));
@@ -63,25 +59,19 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
}
TNode<Object> Decrement(TNode<Context> context, TNode<Object> value,
- TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
- return IncrementOrDecrement<Operation::kDecrement>(
- context, value, slot, maybe_feedback_vector, update_feedback_mode);
+ const FeedbackUpdater& feedback_updater) {
+ return IncrementOrDecrement<Operation::kDecrement>(context, value,
+ feedback_updater);
}
TNode<Object> Increment(TNode<Context> context, TNode<Object> value,
- TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
- return IncrementOrDecrement<Operation::kIncrement>(
- context, value, slot, maybe_feedback_vector, update_feedback_mode);
+ const FeedbackUpdater& feedback_updater) {
+ return IncrementOrDecrement<Operation::kIncrement>(context, value,
+ feedback_updater);
}
TNode<Object> Negate(TNode<Context> context, TNode<Object> value,
- TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
+ const FeedbackUpdater& feedback_updater) {
SmiOperation smi_op =
[=, this](TNode<Smi> smi_value, TVariable<Smi>* var_feedback,
Label* do_float_op, TVariable<Float64T>* var_float) {
@@ -118,9 +108,8 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
return CAST(CallRuntime(Runtime::kBigIntUnaryOp, context, bigint_value,
SmiConstant(Operation::kNegate)));
};
- return UnaryOpWithFeedback(context, value, slot, maybe_feedback_vector,
- smi_op, float_op, bigint_op,
- update_feedback_mode);
+ return UnaryOpWithFeedback(context, value, smi_op, float_op, bigint_op,
+ feedback_updater);
}
private:
@@ -133,12 +122,10 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
TNode<Context> /* context */, TNode<HeapObject> /* bigint_value */)>;
TNode<Object> UnaryOpWithFeedback(TNode<Context> context, TNode<Object> value,
- TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
const SmiOperation& smi_op,
const FloatOperation& float_op,
const BigIntOperation& bigint_op,
- UpdateFeedbackMode update_feedback_mode) {
+ const FeedbackUpdater& feedback_updater) {
TVARIABLE(Object, var_value, value);
TVARIABLE(Object, var_result);
TVARIABLE(Float64T, var_float_value);
@@ -217,8 +204,7 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
BIND(&if_exception);
{
- UpdateFeedback(var_feedback.value(), maybe_feedback_vector, slot,
- update_feedback_mode);
+ feedback_updater(var_feedback.value());
CallRuntime(Runtime::kReThrow, context, var_exception.value());
Unreachable();
}
@@ -232,16 +218,14 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
}
BIND(&end);
- UpdateFeedback(var_feedback.value(), maybe_feedback_vector, slot,
- update_feedback_mode);
+ feedback_updater(var_feedback.value());
return var_result.value();
}
template <Operation kOperation>
TNode<Object> IncrementOrDecrement(TNode<Context> context,
- TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
+ TNode<Object> value,
+ const FeedbackUpdater& feedback_updater) {
static_assert(kOperation == Operation::kIncrement ||
kOperation == Operation::kDecrement);
static constexpr int kAddValue =
@@ -272,48 +256,39 @@ class UnaryOpAssemblerImpl final : public CodeStubAssembler {
return CAST(CallRuntime(Runtime::kBigIntUnaryOp, context, bigint_value,
SmiConstant(kOperation)));
};
- return UnaryOpWithFeedback(context, value, slot, maybe_feedback_vector,
- smi_op, float_op, bigint_op,
- update_feedback_mode);
+ return UnaryOpWithFeedback(context, value, smi_op, float_op, bigint_op,
+ feedback_updater);
}
};
} // namespace
TNode<Object> UnaryOpAssembler::Generate_BitwiseNotWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
- UnaryOpAssemblerImpl a(state_);
- return a.BitwiseNot(context, value, slot, maybe_feedback_vector,
- update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater) {
+ UnaryOpAssemblerImpl a(state());
+ return a.BitwiseNot(context, value, feedback_updater);
}
TNode<Object> UnaryOpAssembler::Generate_DecrementWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
- UnaryOpAssemblerImpl a(state_);
- return a.Decrement(context, value, slot, maybe_feedback_vector,
- update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater) {
+ UnaryOpAssemblerImpl a(state());
+ return a.Decrement(context, value, feedback_updater);
}
TNode<Object> UnaryOpAssembler::Generate_IncrementWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
- UnaryOpAssemblerImpl a(state_);
- return a.Increment(context, value, slot, maybe_feedback_vector,
- update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater) {
+ UnaryOpAssemblerImpl a(state());
+ return a.Increment(context, value, feedback_updater);
}
TNode<Object> UnaryOpAssembler::Generate_NegateWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode) {
- UnaryOpAssemblerImpl a(state_);
- return a.Negate(context, value, slot, maybe_feedback_vector,
- update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater) {
+ UnaryOpAssemblerImpl a(state());
+ return a.Negate(context, value, feedback_updater);
}
#include "src/codegen/undef-code-stub-assembler-macros.inc"
diff --git a/deps/v8/src/ic/unary-op-assembler.h b/deps/v8/src/ic/unary-op-assembler.h
index 7dc6079fc4c..71ac7570607 100644
--- a/deps/v8/src/ic/unary-op-assembler.h
+++ b/deps/v8/src/ic/unary-op-assembler.h
@@ -14,33 +14,34 @@ namespace compiler {
class CodeAssemblerState;
} // namespace compiler
-class UnaryOpAssembler final {
+class UnaryOpAssembler final : public CodeStubAssembler {
public:
explicit UnaryOpAssembler(compiler::CodeAssemblerState* state)
- : state_(state) {}
+ : CodeStubAssembler(state) {}
+
+ FeedbackUpdater MakeEmbeddedFeedbackUpdater(
+ TNode<BytecodeArray> bytecode_array, TNode<IntPtrT> feedback_offset) {
+ return [=, this](TNode<Smi> feedback) {
+ UpdateEmbeddedFeedback<BinaryOperationFeedback>(feedback, bytecode_array,
+ feedback_offset);
+ };
+ }
TNode<Object> Generate_BitwiseNotWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater);
TNode<Object> Generate_DecrementWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater);
TNode<Object> Generate_IncrementWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode);
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater);
TNode<Object> Generate_NegateWithFeedback(
- TNode<Context> context, TNode<Object> value, TNode<UintPtrT> slot,
- TNode<HeapObject> maybe_feedback_vector,
- UpdateFeedbackMode update_feedback_mode);
-
- private:
- compiler::CodeAssemblerState* const state_;
+ TNode<Context> context, TNode<Object> value,
+ const FeedbackUpdater& feedback_updater);
};
} // namespace internal
diff --git a/deps/v8/src/init/bootstrapper.cc b/deps/v8/src/init/bootstrapper.cc
index cee7e90d34f..7299c9561a9 100644
--- a/deps/v8/src/init/bootstrapper.cc
+++ b/deps/v8/src/init/bootstrapper.cc
@@ -254,14 +254,17 @@ class Genesis {
void InitializeConsole(DirectHandle<JSObject> extras_binding);
#define DECLARE_FEATURE_INITIALIZATION(id, descr) void InitializeGlobal_##id();
-
- HARMONY_INPROGRESS(DECLARE_FEATURE_INITIALIZATION)
- JAVASCRIPT_INPROGRESS_FEATURES(DECLARE_FEATURE_INITIALIZATION)
- HARMONY_STAGED(DECLARE_FEATURE_INITIALIZATION)
- JAVASCRIPT_STAGED_FEATURES(DECLARE_FEATURE_INITIALIZATION)
- HARMONY_SHIPPING(DECLARE_FEATURE_INITIALIZATION)
- JAVASCRIPT_SHIPPING_FEATURES(DECLARE_FEATURE_INITIALIZATION)
+#define IGNORE_FEATURE(id, descr)
+ FOREACH_EXPERIMENTAL_FEATURE_FLAG(DECLARE_FEATURE_INITIALIZATION,
+ IGNORE_FEATURE, IGNORE_FEATURE)
+ FOREACH_PRE_STAGED_FEATURE_FLAG(DECLARE_FEATURE_INITIALIZATION,
+ IGNORE_FEATURE, IGNORE_FEATURE)
+ FOREACH_STAGED_FEATURE_FLAG(DECLARE_FEATURE_INITIALIZATION, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_SHIPPED_FEATURE_FLAG(DECLARE_FEATURE_INITIALIZATION, IGNORE_FEATURE,
+ IGNORE_FEATURE)
#undef DECLARE_FEATURE_INITIALIZATION
+#undef IGNORE_FEATURE
void InitializeGlobal_regexp_linear_flag();
void InitializeGlobal_sharedarraybuffer();
#if V8_ENABLE_WEBASSEMBLY
@@ -1524,6 +1527,8 @@ void InstallError(Isolate* isolate, DirectHandle<JSObject> global,
if (context_index == Context::ERROR_FUNCTION_INDEX) {
SimpleInstallFunction(isolate, error_fun, "captureStackTrace",
Builtin::kErrorCaptureStackTrace, 2, kDontAdapt);
+ SimpleInstallFunction(isolate, error_fun, "isError", Builtin::kErrorIsError,
+ 1, kAdapt);
}
InstallWithIntrinsicDefaultProto(isolate, error_fun, context_index);
@@ -3149,6 +3154,8 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
native_context()->set_promise_withresolvers_result_map(*result_map);
InstallFunctionWithBuiltinId(isolate_, promise_fun, "withResolvers",
Builtin::kPromiseWithResolvers, 0, kAdapt);
+ InstallFunctionWithBuiltinId(isolate_, promise_fun, "try",
+ Builtin::kPromiseTry, 1, kDontAdapt);
SetConstructorInstanceType(isolate_, promise_fun,
JS_PROMISE_CONSTRUCTOR_TYPE);
@@ -3351,6 +3358,9 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
INSTALL_CAPTURE_GETTER(8);
INSTALL_CAPTURE_GETTER(9);
#undef INSTALL_CAPTURE_GETTER
+
+ SimpleInstallFunction(isolate_, regexp_fun, "escape",
+ Builtin::kRegExpEscape, 1, kAdapt);
}
SetConstructorInstanceType(isolate_, regexp_fun,
JS_REG_EXP_CONSTRUCTOR_TYPE);
@@ -3437,6 +3447,11 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
InstallError(isolate_, global, factory->URIError_string(),
Context::URI_ERROR_FUNCTION_INDEX);
+ // -- S u p p r e s s e d E r r o r
+ InstallError(isolate_, global, factory->SuppressedError_string(),
+ Context::SUPPRESSED_ERROR_FUNCTION_INDEX,
+ Builtin::kSuppressedErrorConstructor, 3);
+
// Initialize the embedder data slot.
// TODO(ishell): microtask queue pointer will be moved from native context
// to the embedder data array so we don't need an empty embedder data array.
@@ -3545,6 +3560,8 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
kAdapt);
SimpleInstallFunction(isolate_, math, "sqrt", Builtin::kMathSqrt, 1,
kAdapt);
+ SimpleInstallFunction(isolate_, math, "sumPrecise",
+ Builtin::kMathSumPrecise, 1, kAdapt);
SimpleInstallFunction(isolate_, math, "tan", Builtin::kMathTan, 1, kAdapt);
SimpleInstallFunction(isolate_, math, "tanh", Builtin::kMathTanh, 1,
kAdapt);
@@ -3842,6 +3859,8 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
Builtin::kLocalePrototypeScript, kAdapt);
SimpleInstallGetter(isolate(), prototype, factory->region_string(),
Builtin::kLocalePrototypeRegion, kAdapt);
+ SimpleInstallGetter(isolate(), prototype, factory->variants_string(),
+ Builtin::kLocalePrototypeVariants, kAdapt);
SimpleInstallGetter(isolate(), prototype, factory->baseName_string(),
Builtin::kLocalePrototypeBaseName, kAdapt);
// Unicode extension getters.
@@ -4190,6 +4209,8 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
Builtin::kAtomicsWaitAsync, 4, kAdapt);
SimpleInstallFunction(isolate_, atomics_object, "notify",
Builtin::kAtomicsNotify, 3, kAdapt);
+ SimpleInstallFunction(isolate_, atomics_object, "pause",
+ Builtin::kAtomicsPause, 0, kDontAdapt);
}
{ // -- T y p e d A r r a y
@@ -4317,6 +4338,34 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
}
TYPED_ARRAYS_BASE(INSTALL_TYPED_ARRAY)
#undef INSTALL_TYPED_ARRAY
+
+ std::array<DirectHandle<Name>, 2> fields{factory->read_string(),
+ factory->written_string()};
+ DirectHandle<Map> map = CreateLiteralObjectMapFromCache(isolate(), fields);
+ native_context()->set_set_unit8_array_result_map(*map);
+
+ DirectHandle<JSObject> uint8_array_function =
+ Cast<JSObject>(JSReceiver::GetProperty(isolate(), global, "Uint8Array")
+ .ToHandleChecked());
+ SimpleInstallFunction(isolate(), uint8_array_function, "fromBase64",
+ Builtin::kUint8ArrayFromBase64, 1, kDontAdapt);
+ SimpleInstallFunction(isolate(), uint8_array_function, "fromHex",
+ Builtin::kUint8ArrayFromHex, 1, kDontAdapt);
+
+ DirectHandle<JSObject> uint8_array_prototype(
+ Cast<JSObject>(
+ Cast<JSFunction>(uint8_array_function)->instance_prototype()),
+ isolate());
+ SimpleInstallFunction(isolate(), uint8_array_prototype, "toBase64",
+ Builtin::kUint8ArrayPrototypeToBase64, 0, kDontAdapt);
+ SimpleInstallFunction(isolate(), uint8_array_prototype, "setFromBase64",
+ Builtin::kUint8ArrayPrototypeSetFromBase64, 1,
+ kDontAdapt);
+ SimpleInstallFunction(isolate(), uint8_array_prototype, "toHex",
+ Builtin::kUint8ArrayPrototypeToHex, 0, kDontAdapt);
+ SimpleInstallFunction(isolate(), uint8_array_prototype, "setFromHex",
+ Builtin::kUint8ArrayPrototypeSetFromHex, 1,
+ kDontAdapt);
}
{ // -- D a t a V i e w
@@ -4453,10 +4502,10 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
SimpleInstallFunction(isolate_, prototype, "values",
Builtin::kMapPrototypeValues, 0, kAdapt);
- // TODO(olivf, 434977728): Remove initial_map_prototype once --js-upsert
- // flag is removed.
- USE(v8_flags.js_upsert);
- native_context()->set_initial_map_prototype(*prototype);
+ SimpleInstallFunction(isolate_, prototype, "getOrInsert",
+ Builtin::kMapPrototypeGetOrInsert, 2, kAdapt);
+ SimpleInstallFunction(isolate_, prototype, "getOrInsertComputed",
+ Builtin::kMapPrototypeGetOrInsertComputed, 2, kAdapt);
native_context()->set_initial_map_prototype_map(prototype->map());
InstallSpeciesGetter(isolate_, js_map_fun);
@@ -4778,10 +4827,11 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
InstallToStringTag(isolate_, prototype, "WeakMap");
- // TODO(olivf, 434977728): Remove initial_weakmap_prototype once --js-upsert
- // flag is removed.
- USE(v8_flags.js_upsert);
- native_context()->set_initial_weakmap_prototype(*prototype);
+ SimpleInstallFunction(isolate_, prototype, "getOrInsert",
+ Builtin::kWeakMapPrototypeGetOrInsert, 2, kAdapt);
+ SimpleInstallFunction(isolate_, prototype, "getOrInsertComputed",
+ Builtin::kWeakMapPrototypeGetOrInsertComputed, 2,
+ kAdapt);
native_context()->set_initial_weakmap_prototype_map(prototype->map());
}
@@ -5080,6 +5130,100 @@ void Genesis::InitializeGlobal(DirectHandle<JSGlobalObject> global_object,
Builtin::kHandleApiCallAsConstructorDelegate, 0, kDontAdapt);
native_context()->set_call_as_constructor_delegate(*delegate);
}
+
+ { // -- D i s p o s a b l e S t a c k
+ DirectHandle<Map> js_disposable_stack_map =
+ factory->NewContextfulMapForCurrentContext(
+ JS_DISPOSABLE_STACK_BASE_TYPE, sizeof(JSDisposableStackBase));
+ js_disposable_stack_map->SetConstructor(
+ native_context()->object_function());
+ native_context()->set_js_disposable_stack_map(*js_disposable_stack_map);
+ LOG(isolate(), MapDetails(*js_disposable_stack_map));
+
+ // SyncDisposableStack
+ DirectHandle<JSFunction> disposable_stack_function = InstallFunction(
+ isolate(), global, "DisposableStack", JS_SYNC_DISPOSABLE_STACK_TYPE,
+ sizeof(JSSyncDisposableStack), 0, factory->the_hole_value(),
+ Builtin::kDisposableStackConstructor, 0, kDontAdapt);
+ DirectHandle<JSObject> sync_disposable_stack_prototype(
+ Cast<JSObject>(disposable_stack_function->instance_prototype()),
+ isolate());
+ InstallWithIntrinsicDefaultProto(
+ isolate(), disposable_stack_function,
+ Context::JS_DISPOSABLE_STACK_FUNCTION_INDEX);
+
+ SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "use",
+ Builtin::kDisposableStackPrototypeUse, 1, kAdapt);
+ DirectHandle<JSFunction> dispose = SimpleInstallFunction(
+ isolate(), sync_disposable_stack_prototype, "dispose",
+ Builtin::kDisposableStackPrototypeDispose, 0, kAdapt);
+ JSObject::AddProperty(isolate(), sync_disposable_stack_prototype,
+ factory->dispose_symbol(), dispose, DONT_ENUM);
+ SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "adopt",
+ Builtin::kDisposableStackPrototypeAdopt, 2, kAdapt);
+ SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "defer",
+ Builtin::kDisposableStackPrototypeDefer, 1, kAdapt);
+ SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "move",
+ Builtin::kDisposableStackPrototypeMove, 0, kAdapt);
+
+ InstallToStringTag(isolate(), sync_disposable_stack_prototype,
+ "DisposableStack");
+ SimpleInstallGetter(isolate(), sync_disposable_stack_prototype,
+ factory->disposed_string(),
+ Builtin::kDisposableStackPrototypeGetDisposed, kAdapt);
+
+ // AsyncDisposableStack
+ DirectHandle<JSFunction> async_disposable_stack_function = InstallFunction(
+ isolate(), global, "AsyncDisposableStack",
+ JS_ASYNC_DISPOSABLE_STACK_TYPE, sizeof(JSAsyncDisposableStack), 0,
+ factory->the_hole_value(), Builtin::kAsyncDisposableStackConstructor, 0,
+ kDontAdapt);
+ DirectHandle<JSObject> async_disposable_stack_prototype(
+ Cast<JSObject>(async_disposable_stack_function->instance_prototype()),
+ isolate());
+ InstallWithIntrinsicDefaultProto(
+ isolate(), async_disposable_stack_function,
+ Context::JS_ASYNC_DISPOSABLE_STACK_FUNCTION_INDEX);
+
+ SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "use",
+ Builtin::kAsyncDisposableStackPrototypeUse, 1,
+ kAdapt);
+ DirectHandle<JSFunction> dispose_async = SimpleInstallFunction(
+ isolate(), async_disposable_stack_prototype, "disposeAsync",
+ Builtin::kAsyncDisposableStackPrototypeDisposeAsync, 0, kAdapt);
+ JSObject::AddProperty(isolate(), async_disposable_stack_prototype,
+ factory->async_dispose_symbol(), dispose_async,
+ DONT_ENUM);
+ SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "adopt",
+ Builtin::kAsyncDisposableStackPrototypeAdopt, 2,
+ kAdapt);
+ SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "defer",
+ Builtin::kAsyncDisposableStackPrototypeDefer, 1,
+ kAdapt);
+ SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "move",
+ Builtin::kAsyncDisposableStackPrototypeMove, 0,
+ kAdapt);
+
+ InstallToStringTag(isolate(), async_disposable_stack_prototype,
+ "AsyncDisposableStack");
+ SimpleInstallGetter(
+ isolate(), async_disposable_stack_prototype, factory->disposed_string(),
+ Builtin::kAsyncDisposableStackPrototypeGetDisposed, kAdapt);
+
+ // Add symbols to iterator prototypes
+ DirectHandle<JSObject> iterator_prototype(
+ native_context()->initial_iterator_prototype(), isolate());
+ InstallFunctionAtSymbol(isolate(), iterator_prototype,
+ factory->dispose_symbol(), "[Symbol.dispose]",
+ Builtin::kIteratorPrototypeDispose, 0, kAdapt);
+
+ DirectHandle<JSObject> async_iterator_prototype(
+ native_context()->initial_async_iterator_prototype(), isolate());
+ InstallFunctionAtSymbol(
+ isolate(), async_iterator_prototype, factory->async_dispose_symbol(),
+ "[Symbol.asyncDispose]", Builtin::kAsyncIteratorPrototypeAsyncDispose,
+ 0, kAdapt);
+ }
}
DirectHandle<JSFunction> Genesis::InstallTypedArray(
@@ -5144,17 +5288,21 @@ DirectHandle<JSFunction> Genesis::InstallTypedArray(
void Genesis::InitializeExperimentalGlobal() {
#define FEATURE_INITIALIZE_GLOBAL(id, descr) InitializeGlobal_##id();
+#define IGNORE_FEATURE(id, descr)
// Initialize features from more mature to less mature, because less mature
// features may depend on more mature features having been initialized
// already.
- HARMONY_SHIPPING(FEATURE_INITIALIZE_GLOBAL)
- JAVASCRIPT_SHIPPING_FEATURES(FEATURE_INITIALIZE_GLOBAL)
- HARMONY_STAGED(FEATURE_INITIALIZE_GLOBAL)
- JAVASCRIPT_STAGED_FEATURES(FEATURE_INITIALIZE_GLOBAL)
- HARMONY_INPROGRESS(FEATURE_INITIALIZE_GLOBAL)
- JAVASCRIPT_INPROGRESS_FEATURES(FEATURE_INITIALIZE_GLOBAL)
+ FOREACH_SHIPPED_FEATURE_FLAG(FEATURE_INITIALIZE_GLOBAL, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_STAGED_FEATURE_FLAG(FEATURE_INITIALIZE_GLOBAL, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_PRE_STAGED_FEATURE_FLAG(FEATURE_INITIALIZE_GLOBAL, IGNORE_FEATURE,
+ IGNORE_FEATURE)
+ FOREACH_EXPERIMENTAL_FEATURE_FLAG(FEATURE_INITIALIZE_GLOBAL, IGNORE_FEATURE,
+ IGNORE_FEATURE)
#undef FEATURE_INITIALIZE_GLOBAL
+#undef IGNORE_FEATURE
InitializeGlobal_regexp_linear_flag();
InitializeGlobal_sharedarraybuffer();
@@ -5549,8 +5697,6 @@ void Genesis::InitializeConsole(DirectHandle<JSObject> extras_binding) {
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_import_attributes)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(js_import_text)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(js_regexp_buffer_boundaries)
-EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(js_regexp_modifiers)
-EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(js_regexp_duplicate_named_groups)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(js_decorators)
EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(js_import_bytes)
@@ -5561,32 +5707,9 @@ EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE(harmony_intl_best_fit_matcher)
#undef EMPTY_INITIALIZE_GLOBAL_FOR_FEATURE
void Genesis::InitializeGlobal_js_esm_ns_reexport() {}
+void Genesis::InitializeGlobal_js_pr_3883() {}
-void Genesis::InitializeGlobal_js_atomics_pause() {
- if (!v8_flags.js_atomics_pause) return;
- DirectHandle<JSGlobalObject> global(native_context()->global_object(),
- isolate());
- DirectHandle<JSObject> atomics_object = Cast<JSObject>(
- JSReceiver::GetProperty(isolate(), global, "Atomics").ToHandleChecked());
- InstallFunctionWithBuiltinId(isolate(), atomics_object, "pause",
- Builtin::kAtomicsPause, 0, kDontAdapt);
-}
-
-void Genesis::InitializeGlobal_js_promise_try() {
- if (!v8_flags.js_promise_try) return;
- DirectHandle<JSFunction> promise_fun(native_context()->promise_function(),
- isolate());
- InstallFunctionWithBuiltinId(isolate(), promise_fun, "try",
- Builtin::kPromiseTry, 1, kDontAdapt);
-}
-void Genesis::InitializeGlobal_js_error_iserror() {
- if (!v8_flags.js_error_iserror) return;
- DirectHandle<JSFunction> error_fun(native_context()->error_function(),
- isolate());
- InstallFunctionWithBuiltinId(isolate(), error_fun, "isError",
- Builtin::kErrorIsError, 1, kAdapt);
-}
void Genesis::InitializeGlobal_js_immutable_arraybuffer() {
if (!v8_flags.js_immutable_arraybuffer) return;
@@ -5657,30 +5780,6 @@ void Genesis::InitializeGlobal_js_joint_iteration() {
}
}
-void Genesis::InitializeGlobal_js_upsert() {
- if (!v8_flags.js_upsert) return;
-
- {
- auto prototype =
- handle(native_context()->initial_map_prototype(), isolate_);
- SimpleInstallFunction(isolate_, prototype, "getOrInsert",
- Builtin::kMapPrototypeGetOrInsert, 2, kAdapt);
- SimpleInstallFunction(isolate_, prototype, "getOrInsertComputed",
- Builtin::kMapPrototypeGetOrInsertComputed, 2, kAdapt);
- native_context()->set_initial_map_prototype_map(prototype->map());
- }
- {
- auto prototype =
- handle(native_context()->initial_weakmap_prototype(), isolate_);
- SimpleInstallFunction(isolate_, prototype, "getOrInsert",
- Builtin::kWeakMapPrototypeGetOrInsert, 2, kAdapt);
- SimpleInstallFunction(isolate_, prototype, "getOrInsertComputed",
- Builtin::kWeakMapPrototypeGetOrInsertComputed, 2,
- kAdapt);
- native_context()->set_initial_weakmap_prototype_map(prototype->map());
- }
-}
-
void Genesis::InitializeGlobal_js_iterator_join() {
if (!v8_flags.js_iterator_join) return;
@@ -5870,115 +5969,9 @@ void Genesis::InitializeGlobal_sharedarraybuffer() {
isolate()->shared_array_buffer_fun(), DONT_ENUM);
}
-void Genesis::InitializeGlobal_js_explicit_resource_management() {
- if (!v8_flags.js_explicit_resource_management) return;
-
- Factory* factory = isolate()->factory();
- DirectHandle<JSGlobalObject> global(native_context()->global_object(),
- isolate());
-
- // -- S u p p r e s s e d E r r o r
- InstallError(isolate(), global, factory->SuppressedError_string(),
- Context::SUPPRESSED_ERROR_FUNCTION_INDEX,
- Builtin::kSuppressedErrorConstructor, 3);
-
- // -- D i s p o s a b l e S t a c k
- DirectHandle<Map> js_disposable_stack_map =
- factory->NewContextfulMapForCurrentContext(JS_DISPOSABLE_STACK_BASE_TYPE,
- sizeof(JSDisposableStackBase));
- js_disposable_stack_map->SetConstructor(native_context()->object_function());
- native_context()->set_js_disposable_stack_map(*js_disposable_stack_map);
- LOG(isolate(), MapDetails(*js_disposable_stack_map));
-
- // SyncDisposableStack
- DirectHandle<JSFunction> disposable_stack_function = InstallFunction(
- isolate(), global, "DisposableStack", JS_SYNC_DISPOSABLE_STACK_TYPE,
- sizeof(JSSyncDisposableStack), 0, factory->the_hole_value(),
- Builtin::kDisposableStackConstructor, 0, kDontAdapt);
- DirectHandle<JSObject> sync_disposable_stack_prototype(
- Cast<JSObject>(disposable_stack_function->instance_prototype()),
- isolate());
- InstallWithIntrinsicDefaultProto(isolate(), disposable_stack_function,
- Context::JS_DISPOSABLE_STACK_FUNCTION_INDEX);
-
- SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "use",
- Builtin::kDisposableStackPrototypeUse, 1, kAdapt);
- DirectHandle<JSFunction> dispose = SimpleInstallFunction(
- isolate(), sync_disposable_stack_prototype, "dispose",
- Builtin::kDisposableStackPrototypeDispose, 0, kAdapt);
- JSObject::AddProperty(isolate(), sync_disposable_stack_prototype,
- factory->dispose_symbol(), dispose, DONT_ENUM);
- SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "adopt",
- Builtin::kDisposableStackPrototypeAdopt, 2, kAdapt);
- SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "defer",
- Builtin::kDisposableStackPrototypeDefer, 1, kAdapt);
- SimpleInstallFunction(isolate(), sync_disposable_stack_prototype, "move",
- Builtin::kDisposableStackPrototypeMove, 0, kAdapt);
-
- InstallToStringTag(isolate(), sync_disposable_stack_prototype,
- "DisposableStack");
- SimpleInstallGetter(isolate(), sync_disposable_stack_prototype,
- factory->disposed_string(),
- Builtin::kDisposableStackPrototypeGetDisposed, kAdapt);
-
- // AsyncDisposableStack
- DirectHandle<JSFunction> async_disposable_stack_function = InstallFunction(
- isolate(), global, "AsyncDisposableStack", JS_ASYNC_DISPOSABLE_STACK_TYPE,
- sizeof(JSAsyncDisposableStack), 0, factory->the_hole_value(),
- Builtin::kAsyncDisposableStackConstructor, 0, kDontAdapt);
- DirectHandle<JSObject> async_disposable_stack_prototype(
- Cast<JSObject>(async_disposable_stack_function->instance_prototype()),
- isolate());
- InstallWithIntrinsicDefaultProto(
- isolate(), async_disposable_stack_function,
- Context::JS_ASYNC_DISPOSABLE_STACK_FUNCTION_INDEX);
-
- SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "use",
- Builtin::kAsyncDisposableStackPrototypeUse, 1, kAdapt);
- DirectHandle<JSFunction> dispose_async = SimpleInstallFunction(
- isolate(), async_disposable_stack_prototype, "disposeAsync",
- Builtin::kAsyncDisposableStackPrototypeDisposeAsync, 0, kAdapt);
- JSObject::AddProperty(isolate(), async_disposable_stack_prototype,
- factory->async_dispose_symbol(), dispose_async,
- DONT_ENUM);
- SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "adopt",
- Builtin::kAsyncDisposableStackPrototypeAdopt, 2,
- kAdapt);
- SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "defer",
- Builtin::kAsyncDisposableStackPrototypeDefer, 1,
- kAdapt);
- SimpleInstallFunction(isolate(), async_disposable_stack_prototype, "move",
- Builtin::kAsyncDisposableStackPrototypeMove, 0, kAdapt);
-
- InstallToStringTag(isolate(), async_disposable_stack_prototype,
- "AsyncDisposableStack");
- SimpleInstallGetter(
- isolate(), async_disposable_stack_prototype, factory->disposed_string(),
- Builtin::kAsyncDisposableStackPrototypeGetDisposed, kAdapt);
- // Add symbols to iterator prototypes
- DirectHandle<JSObject> iterator_prototype(
- native_context()->initial_iterator_prototype(), isolate());
- InstallFunctionAtSymbol(isolate(), iterator_prototype,
- factory->dispose_symbol(), "[Symbol.dispose]",
- Builtin::kIteratorPrototypeDispose, 0, kAdapt);
- DirectHandle<JSObject> async_iterator_prototype(
- native_context()->initial_async_iterator_prototype(), isolate());
- InstallFunctionAtSymbol(
- isolate(), async_iterator_prototype, factory->async_dispose_symbol(),
- "[Symbol.asyncDispose]", Builtin::kAsyncIteratorPrototypeAsyncDispose, 0,
- kAdapt);
-}
-
-void Genesis::InitializeGlobal_js_regexp_escape() {
- if (!v8_flags.js_regexp_escape) return;
- DirectHandle<JSFunction> regexp_fun(native_context()->regexp_function(),
- isolate());
- SimpleInstallFunction(isolate(), regexp_fun, "escape", Builtin::kRegExpEscape,
- 1, kAdapt);
-}
void Genesis::InitializeGlobal_js_defer_import_eval() {}
@@ -6008,40 +6001,6 @@ void Genesis::InitializeGlobal_js_source_phase_imports() {
Builtin::kAbstractModuleSourceToStringTag, kAdapt);
}
-void Genesis::InitializeGlobal_js_base_64() {
- if (!v8_flags.js_base_64) return;
-
- std::array<DirectHandle<Name>, 2> fields{
- isolate()->factory()->read_string(),
- isolate()->factory()->written_string()};
- DirectHandle<Map> map = CreateLiteralObjectMapFromCache(isolate(), fields);
- native_context()->set_set_unit8_array_result_map(*map);
-
- DirectHandle<JSGlobalObject> global(native_context()->global_object(),
- isolate());
- DirectHandle<JSObject> uint8_array_function =
- Cast<JSObject>(JSReceiver::GetProperty(isolate(), global, "Uint8Array")
- .ToHandleChecked());
- SimpleInstallFunction(isolate(), uint8_array_function, "fromBase64",
- Builtin::kUint8ArrayFromBase64, 1, kDontAdapt);
- SimpleInstallFunction(isolate(), uint8_array_function, "fromHex",
- Builtin::kUint8ArrayFromHex, 1, kDontAdapt);
-
- DirectHandle<JSObject> uint8_array_prototype(
- Cast<JSObject>(
- Cast<JSFunction>(uint8_array_function)->instance_prototype()),
- isolate());
- SimpleInstallFunction(isolate(), uint8_array_prototype, "toBase64",
- Builtin::kUint8ArrayPrototypeToBase64, 0, kDontAdapt);
- SimpleInstallFunction(isolate(), uint8_array_prototype, "setFromBase64",
- Builtin::kUint8ArrayPrototypeSetFromBase64, 1,
- kDontAdapt);
- SimpleInstallFunction(isolate(), uint8_array_prototype, "toHex",
- Builtin::kUint8ArrayPrototypeToHex, 0, kDontAdapt);
- SimpleInstallFunction(isolate(), uint8_array_prototype, "setFromHex",
- Builtin::kUint8ArrayPrototypeSetFromHex, 1, kDontAdapt);
-}
-
void Genesis::InitializeGlobal_regexp_linear_flag() {
if (!v8_flags.enable_experimental_regexp_engine) return;
@@ -6057,17 +6016,6 @@ void Genesis::InitializeGlobal_regexp_linear_flag() {
native_context()->set_regexp_prototype_map(regexp_prototype->map());
}
-#ifdef V8_INTL_SUPPORT
-void Genesis::InitializeGlobal_js_intl_locale_variants() {
- if (!v8_flags.js_intl_locale_variants) return;
- DirectHandle<JSObject> prototype(
- Cast<JSObject>(isolate()->intl_locale_function()->prototype()),
- isolate());
- SimpleInstallGetter(isolate(), prototype, factory()->variants_string(),
- Builtin::kLocalePrototypeVariants, kAdapt);
-}
-#endif // V8_INTL_SUPPORT
-
void Genesis::InitializeGlobal_harmony_temporal() {
#ifdef V8_TEMPORAL_SUPPORT
if (!v8_flags.harmony_temporal) return;
@@ -6099,17 +6047,6 @@ void Genesis::InitializeGlobal_harmony_temporal() {
#endif // V8_TEMPORAL_SUPPORT
}
-void Genesis::InitializeGlobal_js_sum_precise() {
- if (!v8_flags.js_sum_precise) return;
- DirectHandle<JSGlobalObject> global(native_context()->global_object(),
- isolate());
- DirectHandle<JSObject> math = Cast<JSObject>(
- JSReceiver::GetProperty(isolate(), global, "Math").ToHandleChecked());
-
- SimpleInstallFunction(isolate_, math, "sumPrecise", Builtin::kMathSumPrecise,
- 1, kAdapt);
-}
-
void Genesis::InitializeGlobal_queueMicrotask() {
if (!v8_flags.enable_queue_microtask) return;
diff --git a/deps/v8/src/init/isolate-group.h b/deps/v8/src/init/isolate-group.h
index 22594ded9d2..c92cebdaff4 100644
--- a/deps/v8/src/init/isolate-group.h
+++ b/deps/v8/src/init/isolate-group.h
@@ -74,6 +74,10 @@ class V8_EXPORT_PRIVATE IsolateGroup final {
#ifdef V8_ENABLE_SANDBOX
class BasePageTableEntry {
public:
+ // This indicates that the metadata entry can be read from any isolates
+ // (in essence, for the read-only or shared pages).
+ static constexpr uintptr_t kReadOnlyOrSharedEntryIsolateSentinel = -1;
+
void CheckIfMetadataAccessibleFromIsolate(const Isolate* isolate) const {
if (isolate_ ==
reinterpret_cast<Isolate*>(kReadOnlyOrSharedEntryIsolateSentinel)) {
@@ -94,9 +98,7 @@ class V8_EXPORT_PRIVATE IsolateGroup final {
BasePage** metadata_slot() { return &metadata_; }
private:
- // This indicates that the metadata entry can be read from any isolates
- // (in essence, for the read-only or shared pages).
- static constexpr uintptr_t kReadOnlyOrSharedEntryIsolateSentinel = -1;
+ friend class CodeStubAssembler;
BasePage* metadata_ = nullptr;
Isolate* isolate_ = nullptr;
diff --git a/deps/v8/src/inspector/custom-preview.cc b/deps/v8/src/inspector/custom-preview.cc
index 3f7938e3155..469705c11f1 100644
--- a/deps/v8/src/inspector/custom-preview.cc
+++ b/deps/v8/src/inspector/custom-preview.cc
@@ -54,17 +54,6 @@ void reportError(v8::Local<v8::Context> context, const v8::TryCatch& tryCatch,
reportError(context, tryCatch);
}
-InjectedScript* getInjectedScript(v8::Local<v8::Context> context,
- int sessionId) {
- v8::Isolate* isolate = v8::Isolate::GetCurrent();
- V8InspectorImpl* inspector =
- static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
- std::shared_ptr<InspectedContext> inspectedContext =
- inspector->getContext(InspectedContext::contextId(context));
- if (!inspectedContext) return nullptr;
- return inspectedContext->getInjectedScript(sessionId);
-}
-
bool substituteObjectTags(int sessionId, const String16& groupName,
v8::Local<v8::Context> context,
v8::Local<v8::Array> jsonML, int maxDepth) {
@@ -95,6 +84,10 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
reportError(context, tryCatch, "attributes should be an Object");
return false;
}
+ if (attributesValue->IsProxy()) {
+ reportError(context, tryCatch, "Proxy values are not allowed in JSONML");
+ return false;
+ }
v8::Local<v8::Object> attributes = attributesValue.As<v8::Object>();
v8::Local<v8::Value> originValue;
if (!attributes->Get(context, objectLiteral).ToLocal(&originValue)) {
@@ -114,7 +107,16 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
return false;
}
- InjectedScript* injectedScript = getInjectedScript(context, sessionId);
+ V8InspectorImpl* inspector =
+ static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
+ std::shared_ptr<InspectedContext> inspectedContext =
+ inspector->getContext(InspectedContext::contextId(context));
+ if (!inspectedContext) {
+ reportError(context, tryCatch, "cannot find context with specified id");
+ return false;
+ }
+ std::shared_ptr<InjectedScript> injectedScript =
+ inspectedContext->getInjectedScript(sessionId);
if (!injectedScript) {
reportError(context, tryCatch, "cannot find context with specified id");
return false;
@@ -148,6 +150,11 @@ bool substituteObjectTags(int sessionId, const String16& groupName,
reportError(context, tryCatch);
return false;
}
+ if (value->IsProxy()) {
+ reportError(context, tryCatch,
+ "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)) {
@@ -393,7 +400,16 @@ void generateCustomPreview(v8::Isolate* isolate, int sessionId,
.setHeader(toProtocolString(isolate, header))
.build();
if (!bodyFunction.IsEmpty()) {
- InjectedScript* injectedScript = getInjectedScript(context, sessionId);
+ V8InspectorImpl* inspector =
+ static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
+ std::shared_ptr<InspectedContext> inspectedContext =
+ inspector->getContext(InspectedContext::contextId(context));
+ if (!inspectedContext) {
+ reportError(context, tryCatch, "cannot find context with specified id");
+ return;
+ }
+ std::shared_ptr<InjectedScript> injectedScript =
+ inspectedContext->getInjectedScript(sessionId);
if (!injectedScript) {
reportError(context, tryCatch, "cannot find context with specified id");
return;
diff --git a/deps/v8/src/inspector/injected-script.cc b/deps/v8/src/inspector/injected-script.cc
index dd346bb7f36..0d14be4660b 100644
--- a/deps/v8/src/inspector/injected-script.cc
+++ b/deps/v8/src/inspector/injected-script.cc
@@ -1136,7 +1136,7 @@ Response InjectedScript::ObjectScope::findInjectedScript(
std::unique_ptr<RemoteObjectId> remoteId;
Response response = RemoteObjectId::parse(m_remoteObjectId, &remoteId);
if (!response.IsSuccess()) return response;
- InjectedScript* injectedScript = nullptr;
+ std::shared_ptr<InjectedScript> injectedScript;
response = session->findInjectedScript(remoteId.get(), injectedScript,
&m_inspectedContext);
if (!response.IsSuccess()) return response;
@@ -1190,7 +1190,7 @@ Response InjectedScript::bindRemoteObjectIfNeeded(
static_cast<V8InspectorImpl*>(v8::debug::GetInspector(isolate));
std::shared_ptr<InspectedContext> inspectedContext =
inspector->getContext(InspectedContext::contextId(context));
- InjectedScript* injectedScript =
+ std::shared_ptr<InjectedScript> injectedScript =
inspectedContext ? inspectedContext->getInjectedScript(sessionId)
: nullptr;
if (!injectedScript) {
diff --git a/deps/v8/src/inspector/injected-script.h b/deps/v8/src/inspector/injected-script.h
index 0d14c235a77..d72d77daaca 100644
--- a/deps/v8/src/inspector/injected-script.h
+++ b/deps/v8/src/inspector/injected-script.h
@@ -162,7 +162,7 @@ class InjectedScript final {
void allowCodeGenerationFromStrings();
void setTryCatchVerbose();
v8::Local<v8::Context> context() const { return m_context; }
- InjectedScript* injectedScript() const { return m_injectedScript; }
+ InjectedScript* injectedScript() const { return m_injectedScript.get(); }
const v8::TryCatch& tryCatch() const { return m_tryCatch; }
V8InspectorImpl* inspector() const { return m_inspector; }
@@ -172,7 +172,7 @@ class InjectedScript final {
virtual Response findInjectedScript(V8InspectorSessionImpl*) = 0;
V8InspectorImpl* m_inspector;
- InjectedScript* m_injectedScript;
+ std::shared_ptr<InjectedScript> m_injectedScript;
std::shared_ptr<InspectedContext> m_inspectedContext;
private:
diff --git a/deps/v8/src/inspector/inspected-context.cc b/deps/v8/src/inspector/inspected-context.cc
index 6f1e5207a6a..d77db2fc078 100644
--- a/deps/v8/src/inspector/inspected-context.cc
+++ b/deps/v8/src/inspector/inspected-context.cc
@@ -133,17 +133,19 @@ void InspectedContext::setReported(int sessionId, bool reported) {
}
}
-InjectedScript* InspectedContext::getInjectedScript(int sessionId) {
+std::shared_ptr<InjectedScript> InspectedContext::getInjectedScript(
+ int sessionId) {
auto it = m_injectedScripts.find(sessionId);
- return it == m_injectedScripts.end() ? nullptr : it->second.get();
+ return it == m_injectedScripts.end() ? nullptr : it->second;
}
-InjectedScript* InspectedContext::createInjectedScript(int sessionId) {
- std::unique_ptr<InjectedScript> injectedScript =
- std::make_unique<InjectedScript>(this, sessionId);
+std::shared_ptr<InjectedScript> InspectedContext::createInjectedScript(
+ int sessionId) {
+ std::shared_ptr<InjectedScript> injectedScript =
+ std::make_shared<InjectedScript>(this, sessionId);
CHECK(m_injectedScripts.find(sessionId) == m_injectedScripts.end());
- m_injectedScripts[sessionId] = std::move(injectedScript);
- return getInjectedScript(sessionId);
+ m_injectedScripts[sessionId] = injectedScript;
+ return injectedScript;
}
void InspectedContext::discardInjectedScript(int sessionId) {
diff --git a/deps/v8/src/inspector/inspected-context.h b/deps/v8/src/inspector/inspected-context.h
index 3fa47104ca1..e0e96af0d76 100644
--- a/deps/v8/src/inspector/inspected-context.h
+++ b/deps/v8/src/inspector/inspected-context.h
@@ -59,8 +59,8 @@ class InspectedContext {
v8::Isolate* isolate() const;
V8InspectorImpl* inspector() const { return m_inspector; }
- InjectedScript* getInjectedScript(int sessionId);
- InjectedScript* createInjectedScript(int sessionId);
+ std::shared_ptr<InjectedScript> getInjectedScript(int sessionId);
+ std::shared_ptr<InjectedScript> createInjectedScript(int sessionId);
void discardInjectedScript(int sessionId);
bool addInternalObject(v8::Local<v8::Object> object,
@@ -83,7 +83,7 @@ class InspectedContext {
const String16 m_auxData;
const internal::V8DebuggerId m_uniqueId;
std::unordered_set<int> m_reportedSessionIds;
- std::unordered_map<int, std::unique_ptr<InjectedScript>> m_injectedScripts;
+ std::unordered_map<int, std::shared_ptr<InjectedScript>> m_injectedScripts;
WeakCallbackData* m_weakCallbackData;
v8::Global<v8::debug::EphemeronTable> m_internalObjects;
};
diff --git a/deps/v8/src/inspector/v8-console.cc b/deps/v8/src/inspector/v8-console.cc
index 88d0da1c5dc..b65149e7d0d 100644
--- a/deps/v8/src/inspector/v8-console.cc
+++ b/deps/v8/src/inspector/v8-console.cc
@@ -66,11 +66,10 @@ class ConsoleHelper {
int contextId() const { return InspectedContext::contextId(context()); }
int groupId() const { return m_inspector->contextGroupId(contextId()); }
- InjectedScript* injectedScript(int sessionId) {
- std::shared_ptr<InspectedContext> context =
- m_inspector->getContext(groupId(), contextId());
- if (!context) return nullptr;
- return context->getInjectedScript(sessionId);
+ std::shared_ptr<InjectedScript> injectedScript(int sessionId) {
+ m_inspectedContext = m_inspector->getContext(groupId(), contextId());
+ if (!m_inspectedContext) return nullptr;
+ return m_inspectedContext->getInjectedScript(sessionId);
}
V8InspectorSessionImpl* session(int sessionId) {
@@ -210,6 +209,7 @@ class ConsoleHelper {
const v8::debug::ConsoleCallArguments& m_info;
const v8::debug::ConsoleContext& m_consoleContext;
V8InspectorImpl* m_inspector;
+ std::shared_ptr<InspectedContext> m_inspectedContext;
};
void createBoundFunctionProperty(
@@ -389,7 +389,9 @@ void V8Console::Profile(const v8::debug::ConsoleCallArguments& info,
String16 title =
toProtocolString(m_inspector->isolate(), helper.firstArgToString());
helper.forEachSession([&title](V8InspectorSessionImpl* session) {
- session->profilerAgent()->consoleProfile(title);
+ if (session->profilerAgent()) {
+ session->profilerAgent()->consoleProfile(title);
+ }
});
TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "title",
title.utf8().c_str());
@@ -403,7 +405,9 @@ void V8Console::ProfileEnd(const v8::debug::ConsoleCallArguments& info,
String16 title =
toProtocolString(m_inspector->isolate(), helper.firstArgToString());
helper.forEachSession([&title](V8InspectorSessionImpl* session) {
- session->profilerAgent()->consoleProfileEnd(title);
+ if (session->profilerAgent()) {
+ session->profilerAgent()->consoleProfileEnd(title);
+ }
});
TRACE_EVENT_END(TRACE_DISABLED_BY_DEFAULT("v8.inspector"), "title",
title.utf8().c_str());
@@ -761,7 +765,8 @@ void V8Console::lastEvaluationResultCallback(
const v8::FunctionCallbackInfo<v8::Value>& info, int sessionId) {
v8::debug::ConsoleCallArguments args(info);
ConsoleHelper helper(args, v8::debug::ConsoleContext(), m_inspector);
- InjectedScript* injectedScript = helper.injectedScript(sessionId);
+ std::shared_ptr<InjectedScript> injectedScript =
+ helper.injectedScript(sessionId);
if (!injectedScript) return;
info.GetReturnValue().Set(injectedScript->lastEvaluationResult());
}
@@ -774,7 +779,8 @@ static void inspectImpl(const v8::FunctionCallbackInfo<v8::Value>& info,
v8::debug::ConsoleCallArguments args(info);
ConsoleHelper helper(args, v8::debug::ConsoleContext(), inspector);
- InjectedScript* injectedScript = helper.injectedScript(sessionId);
+ std::shared_ptr<InjectedScript> injectedScript =
+ helper.injectedScript(sessionId);
if (!injectedScript) return;
std::unique_ptr<protocol::Runtime::RemoteObject> wrappedObject;
protocol::Response response = injectedScript->wrapObject(
@@ -1042,9 +1048,27 @@ DEFINE_LAZY_LEAKY_OBJECT_GETTER(std::set<std::string_view>,
"debug", "undebug", "monitor", "unmonitor",
"inspect", "copy", "queryObjects"})
-bool IsUnsafeCommandLineAPIFn(v8::Local<v8::Value> name, v8::Isolate* isolate) {
+bool IsUnsafeCommandLineAPIFn(v8::Local<v8::Context> context,
+ v8::Local<v8::Object> commandLineAPI,
+ v8::Local<v8::Name> name, v8::Isolate* isolate) {
std::string nameStr = toProtocolStringWithTypeCheck(isolate, name).utf8();
- return UnsafeCommandLineAPIFns()->count(nameStr) > 0;
+ if (UnsafeCommandLineAPIFns()->count(nameStr) > 0) return true;
+
+ v8::Local<v8::Value> descriptor_val;
+ if (!commandLineAPI->GetOwnPropertyDescriptor(context, name)
+ .ToLocal(&descriptor_val) ||
+ !descriptor_val->IsObject()) {
+ return false;
+ }
+ v8::Local<v8::Object> descriptor = descriptor_val.As<v8::Object>();
+ v8::Local<v8::Value> value;
+ if (!descriptor
+ ->Get(context, v8::String::NewFromUtf8Literal(isolate, "value"))
+ .ToLocal(&value)) {
+ return false;
+ }
+
+ return v8::debug::IsAPIFunctionWithSideEffects(value);
}
} // namespace
@@ -1070,7 +1094,8 @@ V8Console::CommandLineAPIScope::CommandLineAPIScope(
if (global->Has(context, name).FromMaybe(true)) continue;
const v8::SideEffectType get_accessor_side_effect_type =
- IsUnsafeCommandLineAPIFn(name, isolate())
+ IsUnsafeCommandLineAPIFn(context, commandLineAPI, name.As<v8::Name>(),
+ isolate())
? v8::SideEffectType::kHasSideEffect
: v8::SideEffectType::kHasNoSideEffect;
if (!global
diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.cc b/deps/v8/src/inspector/v8-debugger-agent-impl.cc
index a1dad4e89ab..2438b05cfdb 100644
--- a/deps/v8/src/inspector/v8-debugger-agent-impl.cc
+++ b/deps/v8/src/inspector/v8-debugger-agent-impl.cc
@@ -1219,29 +1219,6 @@ Response V8DebuggerAgentImpl::searchInContent(
return Response::Success();
}
-namespace {
-const char* buildStatus(v8::debug::LiveEditResult::Status status) {
- switch (status) {
- case v8::debug::LiveEditResult::OK:
- return protocol::Debugger::SetScriptSource::StatusEnum::Ok;
- case v8::debug::LiveEditResult::COMPILE_ERROR:
- return protocol::Debugger::SetScriptSource::StatusEnum::CompileError;
- case v8::debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION:
- return protocol::Debugger::SetScriptSource::StatusEnum::
- BlockedByActiveFunction;
- case v8::debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR:
- return protocol::Debugger::SetScriptSource::StatusEnum::
- BlockedByActiveGenerator;
- case v8::debug::LiveEditResult::BLOCKED_BY_TOP_LEVEL_ES_MODULE_CHANGE:
- return protocol::Debugger::SetScriptSource::StatusEnum::
- BlockedByTopLevelEsModuleChange;
- case v8::debug::LiveEditResult::FEATURE_DISABLED:
- UNREACHABLE();
- }
- UNREACHABLE();
-}
-} // namespace
-
Response V8DebuggerAgentImpl::setScriptSource(
const String16& scriptId, const String16& newContent,
std::optional<bool> dryRun, std::optional<bool> allowTopFrameEditing,
@@ -1253,59 +1230,8 @@ Response V8DebuggerAgentImpl::setScriptSource(
String16* status,
std::unique_ptr<protocol::Runtime::ExceptionDetails>* optOutCompileError) {
if (!enabled()) return Response::ServerError(kDebuggerNotEnabled);
-
- std::shared_ptr<V8DebuggerScript> script;
- {
- v8::debug::DisallowGarbageCollectionScope no_gc;
- if (getScriptById(scriptId, no_gc)) {
- script = m_scripts.at(scriptId);
- }
- }
- if (!script) {
- return Response::ServerError("No script with given id found");
- }
- int contextId = script->executionContextId();
- std::shared_ptr<InspectedContext> inspected =
- m_inspector->getContext(contextId);
- if (!inspected) {
- return Response::InternalError();
- }
- v8::HandleScope handleScope(m_isolate);
- v8::Local<v8::Context> context = inspected->context();
- v8::Context::Scope contextScope(context);
- const bool allowTopFrameLiveEditing = allowTopFrameEditing.value_or(false);
-
- v8::debug::LiveEditResult result;
- script->setSource(newContent, dryRun.value_or(false),
- allowTopFrameLiveEditing, &result);
- if (result.status == v8::debug::LiveEditResult::FEATURE_DISABLED) {
- return Response::ServerError(
- "setScriptSource functionality no longer available");
- }
- *status = buildStatus(result.status);
- if (result.status == v8::debug::LiveEditResult::COMPILE_ERROR) {
- *optOutCompileError =
- protocol::Runtime::ExceptionDetails::create()
- .setExceptionId(m_inspector->nextExceptionId())
- .setText(toProtocolString(m_isolate, result.message))
- .setLineNumber(result.line_number != -1 ? result.line_number - 1
- : 0)
- .setColumnNumber(result.column_number != -1 ? result.column_number
- : 0)
- .build();
- return Response::Success();
- }
-
- if (result.restart_top_frame_required) {
- CHECK(allowTopFrameLiveEditing);
- // Nothing could have happened to the JS stack since the live edit so
- // restarting the top frame is guaranteed to be successful.
- CHECK(m_debugger->restartFrame(m_session->contextGroupId(),
- /* callFrameOrdinal */ 0));
- m_session->releaseObjectGroup(kBacktraceObjectGroup);
- }
-
- return Response::Success();
+ return Response::ServerError(
+ "setScriptSource functionality no longer available");
}
Response V8DebuggerAgentImpl::restartFrame(
@@ -1705,7 +1631,7 @@ Response V8DebuggerAgentImpl::evaluateOnCallFrame(
std::optional<bool> includeCommandLineAPI, std::optional<bool> silent,
std::optional<bool> returnByValue, std::optional<bool> generatePreview,
std::optional<bool> throwOnSideEffect, std::optional<double> timeout,
- std::unique_ptr<RemoteObject>* result,
+ std::optional<int> scopeNumber, std::unique_ptr<RemoteObject>* result,
std::unique_ptr<protocol::Runtime::ExceptionDetails>* exceptionDetails) {
if (!isPaused()) return Response::ServerError(kDebuggerNotPaused);
InjectedScript::CallFrameScope scope(m_session, callFrameId);
@@ -1726,6 +1652,18 @@ Response V8DebuggerAgentImpl::evaluateOnCallFrame(
return Response::ServerError("Could not find call frame with given id");
}
+ if (scopeNumber.has_value()) {
+ auto scopeIterator = it->GetScopeIterator();
+ int number = scopeNumber.value();
+ while (!scopeIterator->Done() && number > 0) {
+ --number;
+ scopeIterator->Advance();
+ }
+ if (number != 0 || scopeIterator->Done()) {
+ return Response::ServerError("Could not find scope with given number");
+ }
+ }
+
v8::MaybeLocal<v8::Value> maybeResultValue;
{
V8InspectorImpl::EvaluateScope evaluateScope(scope);
@@ -1734,7 +1672,8 @@ Response V8DebuggerAgentImpl::evaluateOnCallFrame(
if (!response.IsSuccess()) return response;
}
maybeResultValue = it->Evaluate(toV8String(m_isolate, expression),
- throwOnSideEffect.value_or(false));
+ throwOnSideEffect.value_or(false),
+ scopeNumber.value_or(0));
}
// Re-initialize after running client's code, as it could have destroyed
// context or session.
@@ -1926,7 +1865,7 @@ Response V8DebuggerAgentImpl::currentCallFrames(
int frameOrdinal = 0;
for (; !iterator->Done(); iterator->Advance(), frameOrdinal++) {
int contextId = iterator->GetContextId();
- InjectedScript* injectedScript = nullptr;
+ std::shared_ptr<InjectedScript> injectedScript;
std::shared_ptr<InspectedContext> inspectedContext;
if (contextId) {
m_session->findInjectedScript(contextId, injectedScript,
@@ -1939,8 +1878,8 @@ Response V8DebuggerAgentImpl::currentCallFrames(
std::unique_ptr<Array<Scope>> scopes;
auto scopeIterator = iterator->GetScopeIterator();
- Response res =
- buildScopes(m_isolate, scopeIterator.get(), injectedScript, &scopes);
+ Response res = buildScopes(m_isolate, scopeIterator.get(),
+ injectedScript.get(), &scopes);
if (!res.IsSuccess()) return res;
std::unique_ptr<RemoteObject> protocolReceiver;
@@ -2117,7 +2056,6 @@ void V8DebuggerAgentImpl::didParseSource(
executionContextAuxData = protocol::DictionaryValue::cast(
protocol::Value::parseBinary(cbor.data(), cbor.size()));
}
- bool isLiveEdit = script->isLiveEdit();
bool hasSourceURLComment = script->hasSourceURLComment();
bool isModule = script->isModule();
String16 scriptId = script->scriptId();
@@ -2151,7 +2089,6 @@ void V8DebuggerAgentImpl::didParseSource(
scriptRef->resetBlackboxedStateCache();
std::optional<String16> sourceMapURLParam = scriptRef->sourceMappingURL();
- const bool* isLiveEditParam = isLiveEdit ? &isLiveEdit : nullptr;
const bool* hasSourceURLParam =
hasSourceURLComment ? &hasSourceURLComment : nullptr;
const bool* isModuleParam = isModule ? &isModule : nullptr;
@@ -2216,7 +2153,7 @@ void V8DebuggerAgentImpl::didParseSource(
scriptId, scriptURL, scriptRef->startLine(), scriptRef->startColumn(),
scriptRef->endLine(), scriptRef->endColumn(), contextId,
scriptRef->hash(), scriptRef->buildId(),
- std::move(executionContextAuxData), isLiveEditParam,
+ std::move(executionContextAuxData), /* isLiveEdit */ false,
std::move(sourceMapURLParam), hasSourceURLParam, isModuleParam,
scriptRef->length(), std::move(stackTrace), std::move(codeOffset),
std::move(scriptLanguage), std::move(debugSymbols), embedderName,
@@ -2309,7 +2246,7 @@ void V8DebuggerAgentImpl::didPause(
hitReasons.push_back(std::make_pair(
protocol::Debugger::Paused::ReasonEnum::Assert, nullptr));
} else if (breakReasons.contains(v8::debug::BreakReason::kException)) {
- InjectedScript* injectedScript = nullptr;
+ std::shared_ptr<InjectedScript> injectedScript;
std::shared_ptr<InspectedContext> inspectedContext;
m_session->findInjectedScript(contextId, injectedScript, &inspectedContext);
if (injectedScript) {
diff --git a/deps/v8/src/inspector/v8-debugger-agent-impl.h b/deps/v8/src/inspector/v8-debugger-agent-impl.h
index e922633bf42..09c85bd7deb 100644
--- a/deps/v8/src/inspector/v8-debugger-agent-impl.h
+++ b/deps/v8/src/inspector/v8-debugger-agent-impl.h
@@ -154,6 +154,7 @@ class V8DebuggerAgentImpl : public protocol::Debugger::Backend {
std::optional<bool> includeCommandLineAPI, std::optional<bool> silent,
std::optional<bool> returnByValue, std::optional<bool> generatePreview,
std::optional<bool> throwOnSideEffect, std::optional<double> timeout,
+ std::optional<int> scopeNumber,
std::unique_ptr<protocol::Runtime::RemoteObject>* result,
std::unique_ptr<protocol::Runtime::ExceptionDetails>*) override;
Response setVariableValue(
diff --git a/deps/v8/src/inspector/v8-debugger-script.cc b/deps/v8/src/inspector/v8-debugger-script.cc
index 3055f1fa6f9..bce79a73796 100644
--- a/deps/v8/src/inspector/v8-debugger-script.cc
+++ b/deps/v8/src/inspector/v8-debugger-script.cc
@@ -47,7 +47,7 @@ String16 calculateHash(v8::Isolate* isolate, v8::Local<v8::String> source) {
V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate,
v8::Local<v8::debug::Script> script,
- bool hadCompileError, bool isLiveEdit,
+ bool hadCompileError,
V8DebuggerAgentImpl* agent,
V8InspectorClient* client)
: m_id(String16::fromInteger(script->Id())),
@@ -55,8 +55,7 @@ V8DebuggerScript::V8DebuggerScript(v8::Isolate* isolate,
m_isolate(isolate),
m_embedderName(GetScriptName(isolate, script, client)),
m_agent(agent),
- m_hadCompileError(hadCompileError),
- m_isLiveEdit(isLiveEdit) {
+ m_hadCompileError(hadCompileError) {
Initialize(script);
}
@@ -119,23 +118,6 @@ void V8DebuggerScript::setSourceMappingURL(const String16& sourceMappingURL) {
m_sourceMappingURL = sourceMappingURL;
}
-void V8DebuggerScript::setSource(const String16& newSource, bool preview,
- bool allowTopFrameLiveEditing,
- v8::debug::LiveEditResult* result) {
- v8::EscapableHandleScope scope(m_isolate);
- v8::Local<v8::String> v8Source = toV8String(m_isolate, newSource);
- if (!m_script.Get(m_isolate)->SetScriptSource(
- v8Source, preview, allowTopFrameLiveEditing, result)) {
- result->message = scope.Escape(result->message);
- return;
- }
- // NOP if preview or unchanged source (diffs.empty() in PatchScript)
- if (preview || result->script.IsEmpty()) return;
-
- m_hash = String16();
- Initialize(scope.Escape(result->script));
-}
-
bool V8DebuggerScript::getPossibleBreakpoints(
const v8::debug::Location& start, const v8::debug::Location& end,
bool restrictToFunction, std::vector<v8::debug::BreakLocation>* locations) {
diff --git a/deps/v8/src/inspector/v8-debugger-script.h b/deps/v8/src/inspector/v8-debugger-script.h
index daed719d432..52584e84028 100644
--- a/deps/v8/src/inspector/v8-debugger-script.h
+++ b/deps/v8/src/inspector/v8-debugger-script.h
@@ -56,8 +56,8 @@ class V8DebuggerScript {
enum class Language { JavaScript, WebAssembly };
V8DebuggerScript(v8::Isolate* isolate, v8::Local<v8::debug::Script> script,
- bool hadCompileError, bool isLiveEdit,
- V8DebuggerAgentImpl* agent, V8InspectorClient* client);
+ bool hadCompileError, V8DebuggerAgentImpl* agent,
+ V8InspectorClient* client);
~V8DebuggerScript() = default;
V8DebuggerScript(const V8DebuggerScript&) = delete;
V8DebuggerScript& operator=(const V8DebuggerScript&) = delete;
@@ -80,16 +80,12 @@ class V8DebuggerScript {
int codeOffset() const;
int executionContextId() const { return m_executionContextId; }
bool hadCompileError() const { return m_hadCompileError; }
- bool isLiveEdit() const { return m_isLiveEdit; }
bool isModule() const { return m_isModule; }
int length() const;
void setSourceURL(const String16&);
void setSourceMappingURL(const String16&);
void setBuildId(const String16&);
- void setSource(const String16& source, bool preview,
- bool allowTopFrameLiveEditing,
- v8::debug::LiveEditResult* result);
bool getPossibleBreakpoints(const v8::debug::Location& start,
const v8::debug::Location& end,
@@ -137,7 +133,6 @@ class V8DebuggerScript {
mutable String16 m_buildId;
Language m_language;
bool m_hadCompileError = false;
- bool m_isLiveEdit = false;
bool m_isModule = false;
mutable String16 m_hash;
int m_startLine = 0;
diff --git a/deps/v8/src/inspector/v8-debugger.cc b/deps/v8/src/inspector/v8-debugger.cc
index d80a2acddd6..346c6c94a6d 100644
--- a/deps/v8/src/inspector/v8-debugger.cc
+++ b/deps/v8/src/inspector/v8-debugger.cc
@@ -170,7 +170,7 @@ std::vector<std::unique_ptr<V8DebuggerScript>> V8Debugger::getCompiledScripts(
if (m_inspector->contextGroupId(contextId) != contextGroupId) continue;
}
result.push_back(std::make_unique<V8DebuggerScript>(
- m_isolate, script, false, false, agent, m_inspector->client()));
+ m_isolate, script, false, agent, m_inspector->client()));
}
return result;
}
@@ -501,15 +501,14 @@ void V8Debugger::handleProgramBreak(
m_externalAsyncTaskPauseRequested = false;
m_taskWithScheduledBreakPauseRequested = false;
- bool scheduledOOMBreak = m_scheduledOOMBreak;
- DCHECK(scheduledOOMBreak ==
- breakReasons.contains(v8::debug::BreakReason::kOOM));
+ bool isOOMBreak = breakReasons.contains(v8::debug::BreakReason::kOOM);
+ DCHECK(!isOOMBreak || m_scheduledOOMBreak);
bool hasAgents = false;
m_inspector->forEachSession(
contextGroupId,
- [&scheduledOOMBreak, &hasAgents](V8InspectorSessionImpl* session) {
- if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) {
+ [isOOMBreak, &hasAgents](V8InspectorSessionImpl* session) {
+ if (session->debuggerAgent()->acceptsPause(isOOMBreak)) {
hasAgents = true;
}
});
@@ -528,14 +527,15 @@ void V8Debugger::handleProgramBreak(
m_inspector->forEachSession(
contextGroupId,
[&pausedContext, &exception, &breakpointIds, &exceptionType, &isUncaught,
- &scheduledOOMBreak, &breakReasons](V8InspectorSessionImpl* session) {
- if (session->debuggerAgent()->acceptsPause(scheduledOOMBreak)) {
+ isOOMBreak, &breakReasons](V8InspectorSessionImpl* session) {
+ if (session->debuggerAgent()->acceptsPause(isOOMBreak)) {
session->debuggerAgent()->didPause(
InspectedContext::contextId(pausedContext), exception,
breakpointIds, exceptionType, isUncaught, breakReasons);
}
});
{
+ v8::Isolate::AllowJavascriptExecutionScope allow_script(m_isolate);
v8::Context::Scope scope(pausedContext);
m_inspector->forEachSession(
@@ -556,8 +556,10 @@ void V8Debugger::handleProgramBreak(
}
});
- if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit();
- m_scheduledOOMBreak = false;
+ if (isOOMBreak) {
+ if (m_scheduledOOMBreak) m_isolate->RestoreOriginalHeapLimit();
+ m_scheduledOOMBreak = false;
+ }
}
namespace {
@@ -598,7 +600,7 @@ size_t V8Debugger::nearHeapLimitCallback(void* data, size_t current_heap_limit,
}
void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
- bool is_live_edited, bool has_compile_error) {
+ bool has_compile_error) {
if (m_ignoreScriptParsedEventsCounter != 0) return;
int contextId;
@@ -609,12 +611,12 @@ void V8Debugger::ScriptCompiled(v8::Local<v8::debug::Script> script,
m_inspector->forEachSession(
m_inspector->contextGroupId(contextId),
- [isolate, &script, has_compile_error, is_live_edited,
+ [isolate, &script, has_compile_error,
client](V8InspectorSessionImpl* session) {
auto agent = session->debuggerAgent();
if (!agent->enabled()) return;
agent->didParseSource(std::make_unique<V8DebuggerScript>(
- isolate, script, has_compile_error, is_live_edited, agent, client));
+ isolate, script, has_compile_error, agent, client));
});
}
diff --git a/deps/v8/src/inspector/v8-debugger.h b/deps/v8/src/inspector/v8-debugger.h
index f6fb175fe85..0172067e82a 100644
--- a/deps/v8/src/inspector/v8-debugger.h
+++ b/deps/v8/src/inspector/v8-debugger.h
@@ -204,7 +204,7 @@ class V8Debugger : public v8::debug::DebugDelegate,
// v8::debug::DebugEventListener implementation.
void AsyncEventOccurred(v8::debug::DebugAsyncActionType type, int id,
bool isBlackboxed, int skipFrameCount = 0) override;
- void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited,
+ void ScriptCompiled(v8::Local<v8::debug::Script> script,
bool has_compile_error) override;
void BreakProgramRequested(
v8::Local<v8::Context> paused_context,
diff --git a/deps/v8/src/inspector/v8-deep-serializer.cc b/deps/v8/src/inspector/v8-deep-serializer.cc
index cf83fb941f3..6ed8bb84c4d 100644
--- a/deps/v8/src/inspector/v8-deep-serializer.cc
+++ b/deps/v8/src/inspector/v8-deep-serializer.cc
@@ -94,9 +94,9 @@ Response SerializeArrayValue(v8::Local<v8::Array> value,
serializedValue->reserve(length);
for (uint32_t i = 0; i < length; i++) {
v8::Local<v8::Value> elementValue;
- bool success = value->Get(context, i).ToLocal(&elementValue);
- CHECK(success);
- USE(success);
+ if (!value->Get(context, i).ToLocal(&elementValue)) {
+ return Response::ServerError("exception during deep serialization");
+ }
std::unique_ptr<protocol::DictionaryValue> elementProtocolValue;
Response response = ValueMirror::create(context, elementValue)
@@ -151,12 +151,10 @@ Response SerializeMap(v8::Local<v8::Map> value, v8::Local<v8::Context> context,
std::unique_ptr<protocol::Value> keyProtocolValue;
std::unique_ptr<protocol::DictionaryValue> propertyProtocolValue;
- bool success = propertiesAndValues->Get(context, i).ToLocal(&keyV8Value);
- CHECK(success);
- success =
- propertiesAndValues->Get(context, i + 1).ToLocal(&propertyV8Value);
- CHECK(success);
- USE(success);
+ if (!propertiesAndValues->Get(context, i).ToLocal(&keyV8Value) ||
+ !propertiesAndValues->Get(context, i + 1).ToLocal(&propertyV8Value)) {
+ return Response::ServerError("exception during deep serialization");
+ }
if (keyV8Value->IsString()) {
keyProtocolValue = protocol::StringValue::create(toProtocolString(
@@ -220,15 +218,15 @@ Response SerializeObjectValue(v8::Local<v8::Object> value,
protocol::ListValue::create();
// Iterate through object's enumerable properties ignoring symbols.
v8::Local<v8::Array> propertyNames;
- bool success =
- value
- ->GetOwnPropertyNames(context,
- static_cast<v8::PropertyFilter>(
- v8::PropertyFilter::ONLY_ENUMERABLE |
- v8::PropertyFilter::SKIP_SYMBOLS),
- v8::KeyConversionMode::kConvertToString)
- .ToLocal(&propertyNames);
- CHECK(success);
+ if (!value
+ ->GetOwnPropertyNames(context,
+ static_cast<v8::PropertyFilter>(
+ v8::PropertyFilter::ONLY_ENUMERABLE |
+ v8::PropertyFilter::SKIP_SYMBOLS),
+ v8::KeyConversionMode::kConvertToString)
+ .ToLocal(&propertyNames)) {
+ return Response::ServerError("exception during deep serialization");
+ }
uint32_t length = propertyNames->Length();
serializedValue->reserve(length);
@@ -237,22 +235,28 @@ Response SerializeObjectValue(v8::Local<v8::Object> value,
std::unique_ptr<protocol::Value> keyProtocolValue;
std::unique_ptr<protocol::DictionaryValue> propertyProtocolValue;
- success = propertyNames->Get(context, i).ToLocal(&keyV8Value);
- CHECK(success);
- CHECK(keyV8Value->IsString());
+ if (!propertyNames->Get(context, i).ToLocal(&keyV8Value)) {
+ return Response::ServerError("exception during deep serialization");
+ }
+ if (!keyV8Value->IsString()) {
+ continue;
+ }
v8::Maybe<bool> hasRealNamedProperty =
value->HasRealNamedProperty(context, keyV8Value.As<v8::String>());
+ if (hasRealNamedProperty.IsNothing()) {
+ return Response::ServerError("exception during deep serialization");
+ }
// Don't access properties with interceptors.
- if (hasRealNamedProperty.IsNothing() || !hasRealNamedProperty.FromJust()) {
+ if (!hasRealNamedProperty.FromJust()) {
continue;
}
keyProtocolValue = protocol::StringValue::create(toProtocolString(
v8::Isolate::GetCurrent(), keyV8Value.As<v8::String>()));
- success = value->Get(context, keyV8Value).ToLocal(&propertyV8Value);
- CHECK(success);
- USE(success);
+ if (!value->Get(context, keyV8Value).ToLocal(&propertyV8Value)) {
+ return Response::ServerError("exception during deep serialization");
+ }
Response response = ValueMirror::create(context, propertyV8Value)
->buildDeepSerializedValue(
diff --git a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc
index a2f2ed22df1..6473b38fa16 100644
--- a/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc
+++ b/deps/v8/src/inspector/v8-heap-profiler-agent-impl.cc
@@ -562,14 +562,14 @@ Response V8HeapProfilerAgentImpl::startSampling(
const unsigned defaultSamplingInterval = 1 << 15;
double samplingIntervalValue =
samplingInterval.value_or(defaultSamplingInterval);
- if (samplingIntervalValue <= 0.0) {
+ if (samplingIntervalValue < 1.0) {
return Response::ServerError("Invalid sampling interval");
}
m_state->setDouble(HeapProfilerAgentState::samplingHeapProfilerInterval,
samplingIntervalValue);
const unsigned defaultStackDepth = 128;
double stackDepthValue = stackDepth.value_or(defaultStackDepth);
- if (stackDepthValue <= 0.0) {
+ if (stackDepthValue < 1.0) {
return Response::ServerError("Invalid stack depth");
}
m_state->setDouble(HeapProfilerAgentState::samplingHeapProfilerStackDepth,
diff --git a/deps/v8/src/inspector/v8-inspector-impl.cc b/deps/v8/src/inspector/v8-inspector-impl.cc
index acea5a50b99..e4bd1415e26 100644
--- a/deps/v8/src/inspector/v8-inspector-impl.cc
+++ b/deps/v8/src/inspector/v8-inspector-impl.cc
@@ -99,6 +99,7 @@ int V8InspectorImpl::resolveUniqueContextId(
v8::MaybeLocal<v8::Value> V8InspectorImpl::compileAndRunInternalScript(
v8::Local<v8::Context> context, v8::Local<v8::String> source) {
+ v8::Isolate::AllowJavascriptExecutionScope allow_script(m_isolate);
v8::Local<v8::UnboundScript> unboundScript;
if (!v8::debug::CompileInspectorScript(m_isolate, source)
.ToLocal(&unboundScript)) {
diff --git a/deps/v8/src/inspector/v8-inspector-session-impl.cc b/deps/v8/src/inspector/v8-inspector-session-impl.cc
index e7d788dd923..92b96d44847 100644
--- a/deps/v8/src/inspector/v8-inspector-session-impl.cc
+++ b/deps/v8/src/inspector/v8-inspector-session-impl.cc
@@ -138,11 +138,11 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(
this, this, agentState(protocol::Console::Metainfo::domainName)));
protocol::Console::Dispatcher::wire(&m_dispatcher, m_consoleAgent.get());
- m_profilerAgent.reset(new V8ProfilerAgentImpl(
- this, this, agentState(protocol::Profiler::Metainfo::domainName)));
- protocol::Profiler::Dispatcher::wire(&m_dispatcher, m_profilerAgent.get());
-
if (m_clientTrustLevel == V8Inspector::kFullyTrusted) {
+ m_profilerAgent.reset(new V8ProfilerAgentImpl(
+ this, this, agentState(protocol::Profiler::Metainfo::domainName)));
+ protocol::Profiler::Dispatcher::wire(&m_dispatcher, m_profilerAgent.get());
+
m_heapProfilerAgent.reset(new V8HeapProfilerAgentImpl(
this, this, agentState(protocol::HeapProfiler::Metainfo::domainName)));
protocol::HeapProfiler::Dispatcher::wire(&m_dispatcher,
@@ -156,7 +156,7 @@ V8InspectorSessionImpl::V8InspectorSessionImpl(
m_runtimeAgent->restore();
m_debuggerAgent->restore();
if (m_heapProfilerAgent) m_heapProfilerAgent->restore();
- m_profilerAgent->restore();
+ if (m_profilerAgent) m_profilerAgent->restore();
m_consoleAgent->restore();
}
}
@@ -165,7 +165,7 @@ V8InspectorSessionImpl::~V8InspectorSessionImpl() {
v8::Isolate::Scope scope(m_inspector->isolate());
discardInjectedScripts();
m_consoleAgent->disable();
- m_profilerAgent->disable();
+ if (m_profilerAgent) m_profilerAgent->disable();
if (m_heapProfilerAgent) m_heapProfilerAgent->disable();
m_debuggerAgent->disable();
m_runtimeAgent->disable();
@@ -225,7 +225,7 @@ void V8InspectorSessionImpl::discardInjectedScripts() {
}
Response V8InspectorSessionImpl::findInjectedScript(
- int contextId, InjectedScript*& injectedScript,
+ int contextId, std::shared_ptr<InjectedScript>& injectedScript,
std::shared_ptr<InspectedContext>* inspectedContext) {
injectedScript = nullptr;
std::shared_ptr<InspectedContext> context =
@@ -245,7 +245,8 @@ Response V8InspectorSessionImpl::findInjectedScript(
}
Response V8InspectorSessionImpl::findInjectedScript(
- RemoteObjectIdBase* objectId, InjectedScript*& injectedScript,
+ RemoteObjectIdBase* objectId,
+ std::shared_ptr<InjectedScript>& injectedScript,
std::shared_ptr<InspectedContext>* inspectedContext) {
if (objectId->isolateId() != m_inspector->isolateId()) {
return Response::ServerError("Cannot find context with specified id");
@@ -262,7 +263,8 @@ void V8InspectorSessionImpl::releaseObjectGroup(const String16& objectGroup) {
int sessionId = m_sessionId;
m_inspector->forEachContext(
m_contextGroupId, [&objectGroup, &sessionId](InspectedContext* context) {
- InjectedScript* injectedScript = context->getInjectedScript(sessionId);
+ std::shared_ptr<InjectedScript> injectedScript =
+ context->getInjectedScript(sessionId);
if (injectedScript) injectedScript->releaseObjectGroup(objectGroup);
});
if (!objectGroup.isEmpty()) {
@@ -298,9 +300,10 @@ Response V8InspectorSessionImpl::unwrapObject(const String16& objectId,
std::unique_ptr<RemoteObjectId> remoteId;
Response response = RemoteObjectId::parse(objectId, &remoteId);
if (!response.IsSuccess()) return response;
- InjectedScript* injectedScript = nullptr;
+ std::shared_ptr<InjectedScript> injectedScript;
std::shared_ptr<InspectedContext> inspectedContext;
- response = findInjectedScript(remoteId.get(), injectedScript, &inspectedContext);
+ response =
+ findInjectedScript(remoteId.get(), injectedScript, &inspectedContext);
if (!response.IsSuccess()) return response;
response = injectedScript->findObject(*remoteId, object);
if (!response.IsSuccess()) return response;
@@ -321,7 +324,7 @@ V8InspectorSessionImpl::wrapObject(v8::Local<v8::Context> context,
v8::Local<v8::Value> value,
const String16& groupName,
bool generatePreview) {
- InjectedScript* injectedScript = nullptr;
+ std::shared_ptr<InjectedScript> injectedScript;
std::shared_ptr<InspectedContext> inspectedContext;
findInjectedScript(InspectedContext::contextId(context), injectedScript,
&inspectedContext);
@@ -338,7 +341,7 @@ std::unique_ptr<protocol::Runtime::RemoteObject>
V8InspectorSessionImpl::wrapTable(v8::Local<v8::Context> context,
v8::Local<v8::Object> table,
v8::MaybeLocal<v8::Array> columns) {
- InjectedScript* injectedScript = nullptr;
+ std::shared_ptr<InjectedScript> injectedScript;
std::shared_ptr<InspectedContext> inspectedContext;
findInjectedScript(InspectedContext::contextId(context), injectedScript,
&inspectedContext);
@@ -351,7 +354,8 @@ void V8InspectorSessionImpl::setCustomObjectFormatterEnabled(bool enabled) {
int sessionId = m_sessionId;
m_inspector->forEachContext(
m_contextGroupId, [&enabled, &sessionId](InspectedContext* context) {
- InjectedScript* injectedScript = context->getInjectedScript(sessionId);
+ std::shared_ptr<InjectedScript> injectedScript =
+ context->getInjectedScript(sessionId);
if (injectedScript) {
injectedScript->setCustomObjectFormatterEnabled(enabled);
}
@@ -367,6 +371,8 @@ void V8InspectorSessionImpl::reportAllContexts(V8RuntimeAgentImpl* agent) {
void V8InspectorSessionImpl::dispatchProtocolMessage(
StringView message, StringView associated_data) {
+ v8::Isolate::AllowJavascriptExecutionScope allow_script(
+ m_inspector->isolate());
KeepSessionAliveScope keepAlive(*this);
using v8_crdtp::span;
@@ -442,18 +448,20 @@ V8InspectorSessionImpl::supportedDomainsImpl() {
.setName(protocol::Debugger::Metainfo::domainName)
.setVersion(protocol::Debugger::Metainfo::version)
.build());
- result.push_back(protocol::Schema::Domain::create()
- .setName(protocol::Profiler::Metainfo::domainName)
- .setVersion(protocol::Profiler::Metainfo::version)
- .build());
- result.push_back(protocol::Schema::Domain::create()
- .setName(protocol::HeapProfiler::Metainfo::domainName)
- .setVersion(protocol::HeapProfiler::Metainfo::version)
- .build());
- result.push_back(protocol::Schema::Domain::create()
- .setName(protocol::Schema::Metainfo::domainName)
- .setVersion(protocol::Schema::Metainfo::version)
- .build());
+ if (m_clientTrustLevel == V8Inspector::kFullyTrusted) {
+ result.push_back(protocol::Schema::Domain::create()
+ .setName(protocol::Profiler::Metainfo::domainName)
+ .setVersion(protocol::Profiler::Metainfo::version)
+ .build());
+ result.push_back(protocol::Schema::Domain::create()
+ .setName(protocol::HeapProfiler::Metainfo::domainName)
+ .setVersion(protocol::HeapProfiler::Metainfo::version)
+ .build());
+ result.push_back(protocol::Schema::Domain::create()
+ .setName(protocol::Schema::Metainfo::domainName)
+ .setVersion(protocol::Schema::Metainfo::version)
+ .build());
+ }
return result;
}
@@ -521,7 +529,9 @@ V8InspectorSessionImpl::searchInTextByLines(StringView text, StringView query,
void V8InspectorSessionImpl::triggerPreciseCoverageDeltaUpdate(
StringView occasion) {
- m_profilerAgent->triggerPreciseCoverageDeltaUpdate(toString16(occasion));
+ if (m_profilerAgent) {
+ m_profilerAgent->triggerPreciseCoverageDeltaUpdate(toString16(occasion));
+ }
}
V8InspectorSession::EvaluateResult V8InspectorSessionImpl::evaluate(
diff --git a/deps/v8/src/inspector/v8-inspector-session-impl.h b/deps/v8/src/inspector/v8-inspector-session-impl.h
index 15bf4208f70..f7701e48af8 100644
--- a/deps/v8/src/inspector/v8-inspector-session-impl.h
+++ b/deps/v8/src/inspector/v8-inspector-session-impl.h
@@ -57,10 +57,10 @@ class V8InspectorSessionImpl : public V8InspectorSession,
int sessionId() const { return m_sessionId; }
Response findInjectedScript(
- int contextId, InjectedScript*&,
+ int contextId, std::shared_ptr<InjectedScript>&,
std::shared_ptr<InspectedContext>* inspectedContext = nullptr);
Response findInjectedScript(
- RemoteObjectIdBase*, InjectedScript*&,
+ RemoteObjectIdBase*, std::shared_ptr<InjectedScript>&,
std::shared_ptr<InspectedContext>* inspectedContext = nullptr);
void reset();
void discardInjectedScripts();
diff --git a/deps/v8/src/inspector/v8-regex.cc b/deps/v8/src/inspector/v8-regex.cc
index 461606f4d44..aa8dda05f81 100644
--- a/deps/v8/src/inspector/v8-regex.cc
+++ b/deps/v8/src/inspector/v8-regex.cc
@@ -38,6 +38,7 @@ V8Regex::V8Regex(V8InspectorImpl* inspector, const String16& pattern,
v8::Local<v8::RegExp> regex;
// Protect against reentrant debugger calls via interrupts.
v8::debug::PostponeInterruptsScope no_interrupts(m_inspector->isolate());
+ v8::Isolate::AllowJavascriptExecutionScope allow_js(m_inspector->isolate());
if (v8::RegExp::New(context, toV8String(isolate, pattern),
static_cast<v8::RegExp::Flags>(flags))
.ToLocal(®ex)) {
@@ -70,6 +71,7 @@ int V8Regex::match(const String16& string, int startFrom,
v8::MicrotasksScope::kDoNotRunMicrotasks);
// Protect against reentrant debugger calls via interrupts.
v8::debug::PostponeInterruptsScope no_interrupts(m_inspector->isolate());
+ v8::Isolate::AllowJavascriptExecutionScope allow_js(m_inspector->isolate());
v8::TryCatch tryCatch(isolate);
v8::Local<v8::RegExp> regex = m_regex.Get(isolate);
diff --git a/deps/v8/src/inspector/value-mirror.cc b/deps/v8/src/inspector/value-mirror.cc
index 2face8f490d..357c9a65712 100644
--- a/deps/v8/src/inspector/value-mirror.cc
+++ b/deps/v8/src/inspector/value-mirror.cc
@@ -260,6 +260,7 @@ String16 descriptionForRegExp(v8::Isolate* isolate,
}
bool isBuiltinGetter(v8::Local<v8::Function> function) {
+ if (function->IsProxy()) return false;
// A bound function may forward to user code via its bound receiver or
// bound arguments even when the underlying target is a builtin, so it is
// never treated as a plain builtin getter.
@@ -1138,6 +1139,10 @@ void getInternalPropertiesForPreview(
allowlist.emplace_back("[[GeneratorState]]");
} else if (object->IsWeakRef()) {
allowlist.emplace_back("[[WeakRefTarget]]");
+ } else if (object->IsModuleNamespaceObject()) {
+ // Having it in the preview lets the front-end tell an unevaluated namespace
+ // from an evaluated one without a second round trip.
+ allowlist.emplace_back("[[ModuleStatus]]");
}
for (auto& mirror : mirrors) {
if (std::find(allowlist.begin(), allowlist.end(), mirror.name) ==
@@ -1850,6 +1855,11 @@ std::unique_ptr<ValueMirror> ValueMirror::create(v8::Local<v8::Context> context,
String16 subtype = toString16(clientSubtype->string());
return clientMirror(context, object, subtype);
}
+ if (object->IsDeferredModuleNamespaceObject()) {
+ return std::make_unique<ObjectMirror>(
+ object, RemoteObject::SubtypeEnum::Deferredmodule,
+ descriptionForObject(isolate, object));
+ }
if (object->IsRegExp()) {
v8::Local<v8::RegExp> regexp = object.As<v8::RegExp>();
return std::make_unique<ObjectMirror>(
diff --git a/deps/v8/src/interpreter/bytecode-array-builder.cc b/deps/v8/src/interpreter/bytecode-array-builder.cc
index 53bb41f3d23..cf500b4831f 100644
--- a/deps/v8/src/interpreter/bytecode-array-builder.cc
+++ b/deps/v8/src/interpreter/bytecode-array-builder.cc
@@ -53,7 +53,7 @@ BytecodeArrayBuilder::BytecodeArrayBuilder(
bytecode_generated_(false),
constant_array_builder_(zone),
handler_table_builder_(zone),
- parameter_count_(parameter_count),
+ parameter_count_(base::checked_cast<uint16_t>(parameter_count)),
max_arguments_(0),
local_register_count_(locals_count),
register_allocator_(fixed_register_count()),
@@ -530,19 +530,23 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::UnaryOperation(Token::Value op,
int feedback_slot) {
switch (op) {
case Token::kInc:
- OutputInc(feedback_slot);
+ DCHECK_EQ(feedback_slot, kFeedbackIsEmbedded);
+ OutputInc(kUninitializedEmbeddedFeedback);
break;
case Token::kDec:
- OutputDec(feedback_slot);
+ DCHECK_EQ(feedback_slot, kFeedbackIsEmbedded);
+ OutputDec(kUninitializedEmbeddedFeedback);
break;
case Token::kAdd:
OutputToNumber(feedback_slot);
break;
case Token::kSub:
- OutputNegate(feedback_slot);
+ DCHECK_EQ(feedback_slot, kFeedbackIsEmbedded);
+ OutputNegate(kUninitializedEmbeddedFeedback);
break;
case Token::kBitNot:
- OutputBitwiseNot(feedback_slot);
+ DCHECK_EQ(feedback_slot, kFeedbackIsEmbedded);
+ OutputBitwiseNot(kUninitializedEmbeddedFeedback);
break;
default:
UNREACHABLE();
diff --git a/deps/v8/src/interpreter/bytecode-array-iterator.cc b/deps/v8/src/interpreter/bytecode-array-iterator.cc
index 49bbd280320..0d2edcbf8c3 100644
--- a/deps/v8/src/interpreter/bytecode-array-iterator.cc
+++ b/deps/v8/src/interpreter/bytecode-array-iterator.cc
@@ -443,8 +443,13 @@ typename EmbeddedFeedbackHintTraits<Feedback>::Hint
BytecodeArrayIterator::GetEmbeddedOperationHint() {
using Traits = EmbeddedFeedbackHintTraits<Feedback>;
DCHECK(Traits::IsWithEmbeddedFeedbackOp(current_bytecode()));
- uint32_t type_feedback = Feedback::DecodeTypeIndex(
- static_cast<typename Feedback::TypeIndex>(GetEmbeddedFeedback(1)));
+ int operand_index =
+ Bytecodes::IsUnaryOpWithEmbeddedFeedback(current_bytecode())
+ ? kUnaryEmbeddedFeedbackOperandIndex
+ : kEmbeddedFeedbackOperandIndex;
+ uint32_t type_feedback =
+ Feedback::DecodeTypeIndex(static_cast<typename Feedback::TypeIndex>(
+ GetEmbeddedFeedback(operand_index)));
return Traits::FromFeedback(type_feedback);
}
diff --git a/deps/v8/src/interpreter/bytecode-array-iterator.h b/deps/v8/src/interpreter/bytecode-array-iterator.h
index f724c725e97..9825ed7ffdb 100644
--- a/deps/v8/src/interpreter/bytecode-array-iterator.h
+++ b/deps/v8/src/interpreter/bytecode-array-iterator.h
@@ -86,7 +86,8 @@ struct EmbeddedFeedbackHintTraits<BinaryOperationFeedback> {
using Hint = BinaryOperationHint;
static Hint FromFeedback(uint32_t feedback_value);
static bool IsWithEmbeddedFeedbackOp(Bytecode bc) {
- return Bytecodes::IsBinaryOpWithEmbeddedFeedback(bc);
+ return Bytecodes::IsBinaryOpWithEmbeddedFeedback(bc) ||
+ Bytecodes::IsUnaryOpWithEmbeddedFeedback(bc);
}
};
diff --git a/deps/v8/src/interpreter/bytecode-array-writer.cc b/deps/v8/src/interpreter/bytecode-array-writer.cc
index d5823b899af..e9b93787ad7 100644
--- a/deps/v8/src/interpreter/bytecode-array-writer.cc
+++ b/deps/v8/src/interpreter/bytecode-array-writer.cc
@@ -100,9 +100,15 @@ int BytecodeArrayWriter::CheckBytecodeMatches(Handle<BytecodeArray> bytecode) {
int bytes_need_to_check = it.current_bytecode_size();
// skip embedded feedback value.
if (Bytecodes::IsEmbeddedFeedbackBytecode(it.current_bytecode())) {
- bytes_need_to_check -= static_cast<int>(
- Bytecodes::GetOperandSize(it.current_bytecode(), /*operand_idx=*/1,
- it.current_operand_scale()));
+ // Unary bytecodes only have a single operand (the embedded feedback
+ // itself), while binary/compare bytecodes have the embedded feedback
+ // as their second operand.
+ int operand_idx =
+ Bytecodes::IsUnaryOpWithEmbeddedFeedback(it.current_bytecode())
+ ? kUnaryEmbeddedFeedbackOperandIndex
+ : kEmbeddedFeedbackOperandIndex;
+ bytes_need_to_check -= static_cast<int>(Bytecodes::GetOperandSize(
+ it.current_bytecode(), operand_idx, it.current_operand_scale()));
}
int start_idx = it.current_offset();
diff --git a/deps/v8/src/interpreter/bytecode-decoder.cc b/deps/v8/src/interpreter/bytecode-decoder.cc
index 93043ec02ac..194a14b47b8 100644
--- a/deps/v8/src/interpreter/bytecode-decoder.cc
+++ b/deps/v8/src/interpreter/bytecode-decoder.cc
@@ -180,11 +180,22 @@ std::ostream& BytecodeDecoder::Decode(std::ostream& os,
<< DecodeUnsignedOperand(operand_start, op_type, operand_scale)
<< "]";
break;
- case interpreter::OperandType::kEmbeddedFeedback:
- os << "EmbeddedFeedback["
- << static_cast<uint32_t>(RacyDecodeEmbeddedFeedback(operand_start))
- << "]";
+ case interpreter::OperandType::kEmbeddedFeedback: {
+ uint8_t feedback = RacyDecodeEmbeddedFeedback(operand_start);
+ os << "EmbeddedFeedback[";
+ if (Bytecodes::IsBinaryOpWithEmbeddedFeedback(bytecode) ||
+ Bytecodes::IsUnaryOpWithEmbeddedFeedback(bytecode)) {
+ os << BinaryOperationFeedback::TypeIndexToString(
+ static_cast<BinaryOperationFeedback::TypeIndex>(feedback));
+ } else if (Bytecodes::IsCompareWithEmbeddedFeedback(bytecode)) {
+ os << CompareOperationFeedback::TypeIndexToString(
+ static_cast<CompareOperationFeedback::TypeIndex>(feedback));
+ } else {
+ os << static_cast<uint32_t>(feedback);
+ }
+ os << "]";
break;
+ }
case interpreter::OperandType::kContextSlot:
// TODO(leszeks): If we had the Context here we could print the context
// contents.
diff --git a/deps/v8/src/interpreter/bytecode-generator.cc b/deps/v8/src/interpreter/bytecode-generator.cc
index 1e892ea9b42..ae6d376a8ad 100644
--- a/deps/v8/src/interpreter/bytecode-generator.cc
+++ b/deps/v8/src/interpreter/bytecode-generator.cc
@@ -1697,14 +1697,15 @@ bool NeedsContextInitialization(DeclarationScope* scope) {
void BytecodeGenerator::GenerateBytecode(uintptr_t stack_limit) {
InitializeAstVisitor(stack_limit);
- if (v8_flags.stress_lazy_compilation && local_isolate_->is_main_thread() &&
+ if (V8_UNLIKELY(v8_flags.stress_lazy_compilation) &&
+ local_isolate_->is_main_thread() &&
!local_isolate_->AsIsolate()->bootstrapper()->IsActive()) {
// Trigger stack overflow with 1/stress_lazy_compilation probability.
// Do this only for the main thread compilations because querying random
// numbers from background threads will make the random values dependent
// on the thread scheduling and thus non-deterministic.
- stack_overflow_ = local_isolate_->fuzzer_rng()->NextInt(
- v8_flags.stress_lazy_compilation) == 0;
+ stack_overflow_ = local_isolate_->fuzzer_rng()->NextDouble() <
+ (1.0 / v8_flags.stress_lazy_compilation);
}
// Initialize the incoming context.
@@ -2040,7 +2041,7 @@ void BytecodeGenerator::GenerateBodyStatements(int start) {
void BytecodeGenerator::GenerateBodyStatementsWithoutImplicitFinalReturn(
int start) {
ZonePtrList<Statement>* body = info()->literal()->body();
- if (v8_flags.js_explicit_resource_management && closure_scope() != nullptr &&
+ if (closure_scope() != nullptr &&
(closure_scope()->has_using_declaration() ||
closure_scope()->has_await_using_declaration())) {
BuildDisposeScope([&]() { VisitStatements(body, start); },
@@ -2106,7 +2107,7 @@ void BytecodeGenerator::VisitBlock(Block* stmt) {
}
void BytecodeGenerator::VisitBlockMaybeDispose(Block* stmt) {
- if (v8_flags.js_explicit_resource_management && stmt->scope() != nullptr &&
+ if (stmt->scope() != nullptr &&
(stmt->scope()->has_using_declaration() ||
stmt->scope()->has_await_using_declaration())) {
BuildDisposeScope([&]() { VisitBlockDeclarationsAndStatements(stmt); },
@@ -4481,7 +4482,7 @@ void BytecodeGenerator::VisitObjectLiteral(ObjectLiteral* expr) {
void BytecodeGenerator::BuildFillArrayWithIterator(
IteratorRecord iterator, Register array, Register index, Register value,
FeedbackSlot next_value_slot, FeedbackSlot next_done_slot,
- FeedbackSlot index_slot, FeedbackSlot element_slot) {
+ FeedbackSlot element_slot) {
DCHECK(array.is_valid());
DCHECK(index.is_valid());
DCHECK(value.is_valid());
@@ -4507,7 +4508,7 @@ void BytecodeGenerator::BuildFillArrayWithIterator(
.StoreInArrayLiteral(array, index, feedback_index(element_slot))
// index++
.LoadAccumulatorWithRegister(index)
- .UnaryOperation(Token::kInc, feedback_index(index_slot))
+ .UnaryOperation(Token::kInc, kFeedbackIsEmbedded)
.StoreAccumulatorInRegister(index);
loop_builder.BindContinueTarget();
}
@@ -4623,7 +4624,6 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
}
// Now build insertions for the remaining elements from current to end.
- SharedFeedbackSlot index_slot(feedback_spec(), FeedbackSlotKind::kBinaryOp);
SharedFeedbackSlot length_slot(
feedback_spec(), feedback_spec()->GetStoreICSlot(LanguageMode::kStrict));
for (; current != end; ++current) {
@@ -4638,11 +4638,10 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
Register value = register_allocator()->NewRegister();
FeedbackSlot next_value_load_slot = feedback_spec()->AddLoadICSlot();
FeedbackSlot next_done_load_slot = feedback_spec()->AddLoadICSlot();
- FeedbackSlot real_index_slot = index_slot.Get();
FeedbackSlot real_element_slot = element_slot.Get();
BuildFillArrayWithIterator(iterator, array, index, value,
next_value_load_slot, next_done_load_slot,
- real_index_slot, real_element_slot);
+ real_element_slot);
} else if (!subexpr->IsTheHoleLiteral()) {
// literal[index++] = subexpr
VisitForAccumulatorValue(subexpr);
@@ -4653,7 +4652,7 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
// Only increase the index if we are not the last element.
if (current + 1 != end) {
builder()
- ->UnaryOperation(Token::kInc, feedback_index(index_slot.Get()))
+ ->UnaryOperation(Token::kInc, kFeedbackIsEmbedded)
.StoreAccumulatorInRegister(index);
}
} else {
@@ -4662,7 +4661,7 @@ void BytecodeGenerator::BuildCreateArrayLiteral(
auto length = ast_string_constants()->length_string();
builder()
->LoadAccumulatorWithRegister(index)
- .UnaryOperation(Token::kInc, feedback_index(index_slot.Get()))
+ .UnaryOperation(Token::kInc, kFeedbackIsEmbedded)
.StoreAccumulatorInRegister(index)
.SetNamedProperty(array, length, feedback_index(length_slot.Get()),
LanguageMode::kStrict);
@@ -5665,10 +5664,9 @@ void BytecodeGenerator::BuildDestructuringArrayAssignment(
// Fill the array with the iterator.
FeedbackSlot element_slot =
feedback_spec()->AddStoreInArrayLiteralICSlot();
- FeedbackSlot index_slot = feedback_spec()->AddBinaryOpICSlot();
BuildFillArrayWithIterator(iterator, array, index, next_result,
next_value_load_slot, next_done_load_slot,
- index_slot, element_slot);
+ element_slot);
builder()->Bind(&is_done);
// Assign the array to the LHS.
@@ -5730,14 +5728,23 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment(
//
// Since the first property access on null/undefined will also trigger a
// TypeError, we can elide this check. The exception is when there are no
- // properties and no rest property (this is an empty literal), or when the
- // first property is a computed name and accessing it can have side effects.
+ // properties and no rest property (this is an empty literal), or when there
+ // is only a rest property (as it uses CloneObject, which does not throw on
+ // null/undefined), or when the first property is a computed name and
+ // accessing it can have side effects.
//
// TODO(leszeks): Also eliminate this check if the value is known to be
// non-null (e.g. an object literal).
- if (pattern->properties()->is_empty() ||
- (pattern->properties()->at(0)->is_computed_name() &&
- pattern->properties()->at(0)->kind() != ObjectLiteralProperty::SPREAD)) {
+ bool is_empty_pattern = pattern->properties()->is_empty();
+ bool is_only_rest_property =
+ pattern->properties()->length() == 1 &&
+ pattern->properties()->at(0)->kind() == ObjectLiteralProperty::SPREAD;
+ bool is_first_property_computed_name =
+ !is_empty_pattern && pattern->properties()->at(0)->is_computed_name() &&
+ pattern->properties()->at(0)->kind() != ObjectLiteralProperty::SPREAD;
+
+ if (is_empty_pattern || is_only_rest_property ||
+ is_first_property_computed_name) {
BytecodeLabel is_null_or_undefined, not_null_or_undefined;
builder()
->JumpIfUndefinedOrNull(&is_null_or_undefined)
@@ -5810,9 +5817,20 @@ void BytecodeGenerator::BuildDestructuringObjectAssignment(
DCHECK_EQ(i, pattern->properties()->length() - 1);
DCHECK(!value_key.is_valid());
DCHECK_NULL(value_name);
- builder()->CallRuntime(
- Runtime::kInlineCopyDataPropertiesWithExcludedPropertiesOnStack,
- rest_runtime_callargs);
+ if (pattern->properties()->length() == 1) {
+ // If there is only the rest property, we have no excluded properties.
+ // We can use the CloneObject bytecode instead of the more expensive
+ // CopyDataPropertiesWithExcludedPropertiesOnStack runtime call.
+ // E.g. for `let { ...rest } = obj;`.
+ DCHECK(pattern->builder()->has_rest_property());
+ int flags = CreateObjectLiteralFlags::Encode(0, false);
+ int clone_index = feedback_index(feedback_spec()->AddCloneObjectSlot());
+ builder()->CloneObject(value, flags, clone_index);
+ } else {
+ builder()->CallRuntime(
+ Runtime::kInlineCopyDataPropertiesWithExcludedPropertiesOnStack,
+ rest_runtime_callargs);
+ }
} else if (value_name) {
builder()->LoadNamedProperty(
value, value_name, feedback_index(feedback_spec()->AddLoadICSlot()));
@@ -7410,13 +7428,17 @@ void BytecodeGenerator::VisitUnaryOperation(UnaryOperation* expr) {
VisitDelete(expr);
break;
case Token::kAdd:
- case Token::kSub:
- case Token::kBitNot:
VisitForAccumulatorValue(expr->expression());
builder()->SetExpressionPosition(expr);
builder()->UnaryOperation(
expr->op(), feedback_index(feedback_spec()->AddBinaryOpICSlot()));
break;
+ case Token::kSub:
+ case Token::kBitNot:
+ VisitForAccumulatorValue(expr->expression());
+ builder()->SetExpressionPosition(expr);
+ builder()->UnaryOperation(expr->op(), kFeedbackIsEmbedded);
+ break;
default:
UNREACHABLE();
}
@@ -7628,9 +7650,9 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
}
}
- // Save result for postfix expressions.
- FeedbackSlot count_slot = feedback_spec()->AddBinaryOpICSlot();
if (is_postfix) {
+ // Save result for postfix expressions.
+ FeedbackSlot count_slot = feedback_spec()->AddBinaryOpICSlot();
old_value = register_allocator()->NewRegister();
// Convert old value into a number before saving it.
// TODO(ignition): Think about adding proper PostInc/PostDec bytecodes
@@ -7641,7 +7663,7 @@ void BytecodeGenerator::VisitCountOperation(CountOperation* expr) {
}
// Perform +1/-1 operation.
- builder()->UnaryOperation(expr->op(), feedback_index(count_slot));
+ builder()->UnaryOperation(expr->op(), kFeedbackIsEmbedded);
// Store the value.
builder()->SetExpressionPosition(expr);
diff --git a/deps/v8/src/interpreter/bytecode-generator.h b/deps/v8/src/interpreter/bytecode-generator.h
index 621183fcefd..66154184028 100644
--- a/deps/v8/src/interpreter/bytecode-generator.h
+++ b/deps/v8/src/interpreter/bytecode-generator.h
@@ -397,7 +397,6 @@ class BytecodeGenerator final : public AstVisitor<BytecodeGenerator> {
Register index, Register value,
FeedbackSlot next_value_slot,
FeedbackSlot next_done_slot,
- FeedbackSlot index_slot,
FeedbackSlot element_slot);
// Create Array literals. |expr| can be nullptr, but if provided,
// a boilerplate will be used to create an initial array for elements
diff --git a/deps/v8/src/interpreter/bytecodes.h b/deps/v8/src/interpreter/bytecodes.h
index d426822afe8..c37a4c662d0 100644
--- a/deps/v8/src/interpreter/bytecodes.h
+++ b/deps/v8/src/interpreter/bytecodes.h
@@ -269,13 +269,13 @@ namespace interpreter {
\
/* Unary Operators */ \
V(Inc, ImplicitRegisterUse::kReadWriteAccumulator, \
- OperandType::kFeedbackSlot) \
+ OperandType::kEmbeddedFeedback) \
V(Dec, ImplicitRegisterUse::kReadWriteAccumulator, \
- OperandType::kFeedbackSlot) \
+ OperandType::kEmbeddedFeedback) \
V(Negate, ImplicitRegisterUse::kReadWriteAccumulator, \
- OperandType::kFeedbackSlot) \
+ OperandType::kEmbeddedFeedback) \
V_TSA(BitwiseNot, ImplicitRegisterUse::kReadWriteAccumulator, \
- OperandType::kFeedbackSlot) \
+ OperandType::kEmbeddedFeedback) \
V(ToBooleanLogicalNot, ImplicitRegisterUse::kReadWriteAccumulator) \
V(LogicalNot, ImplicitRegisterUse::kReadWriteAccumulator) \
V(TypeOf, ImplicitRegisterUse::kReadWriteAccumulator, \
@@ -956,10 +956,23 @@ class V8_EXPORT_PRIVATE Bytecodes final : public AllStatic {
}
}
+ static constexpr bool IsUnaryOpWithEmbeddedFeedback(Bytecode bytecode) {
+ switch (bytecode) {
+ case Bytecode::kInc:
+ case Bytecode::kDec:
+ case Bytecode::kNegate:
+ case Bytecode::kBitwiseNot:
+ return true;
+ default:
+ return false;
+ }
+ }
+
// Returns true if the bytecode has a embedded feedback slot
static constexpr bool IsEmbeddedFeedbackBytecode(Bytecode bytecode) {
return IsCompareWithEmbeddedFeedback(bytecode) ||
- IsBinaryOpWithEmbeddedFeedback(bytecode);
+ IsBinaryOpWithEmbeddedFeedback(bytecode) ||
+ IsUnaryOpWithEmbeddedFeedback(bytecode);
}
// Returns true if the bytecode returns.
diff --git a/deps/v8/src/interpreter/handler-table-builder.cc b/deps/v8/src/interpreter/handler-table-builder.cc
index ac2342df5c3..5bcd681138b 100644
--- a/deps/v8/src/interpreter/handler-table-builder.cc
+++ b/deps/v8/src/interpreter/handler-table-builder.cc
@@ -33,20 +33,19 @@ DirectHandle<TrustedByteArray> HandlerTableBuilder::ToHandlerTable(
Entry& entry = entries_[i];
if (entry.dropped) continue;
HandlerTable::CatchPrediction pred = entry.catch_prediction_;
- table.SetRangeStart(table_index, static_cast<int>(entry.offset_start));
- table.SetRangeEnd(table_index, static_cast<int>(entry.offset_end));
- table.SetRangeHandler(table_index, static_cast<int>(entry.offset_target),
- pred);
+ table.SetRangeStart(table_index, entry.offset_start);
+ table.SetRangeEnd(table_index, entry.offset_end);
+ table.SetRangeHandler(table_index, entry.offset_target, pred);
table.SetRangeData(table_index, entry.context.index());
table_index++;
}
return table_byte_array;
}
-template DirectHandle<TrustedByteArray> HandlerTableBuilder::ToHandlerTable(
- Isolate* isolate);
-template DirectHandle<TrustedByteArray> HandlerTableBuilder::ToHandlerTable(
- LocalIsolate* isolate);
+template V8_EXPORT_PRIVATE DirectHandle<TrustedByteArray>
+HandlerTableBuilder::ToHandlerTable(Isolate* isolate);
+template V8_EXPORT_PRIVATE DirectHandle<TrustedByteArray>
+HandlerTableBuilder::ToHandlerTable(LocalIsolate* isolate);
int HandlerTableBuilder::NewHandlerEntry() {
int handler_id = static_cast<int>(entries_.size());
@@ -58,22 +57,19 @@ int HandlerTableBuilder::NewHandlerEntry() {
return handler_id;
}
-
void HandlerTableBuilder::SetTryRegionStart(int handler_id, size_t offset) {
- DCHECK(Smi::IsValid(offset)); // Encoding of handler table requires this.
- entries_[handler_id].offset_start = offset;
+ DCHECK(base::IsValueInRangeForNumericType<int>(offset));
+ entries_[handler_id].offset_start = static_cast<int>(offset);
}
-
void HandlerTableBuilder::SetTryRegionEnd(int handler_id, size_t offset) {
- DCHECK(Smi::IsValid(offset)); // Encoding of handler table requires this.
- entries_[handler_id].offset_end = offset;
+ DCHECK(base::IsValueInRangeForNumericType<int>(offset));
+ entries_[handler_id].offset_end = static_cast<int>(offset);
}
-
void HandlerTableBuilder::SetHandlerTarget(int handler_id, size_t offset) {
- DCHECK(Smi::IsValid(offset)); // Encoding of handler table requires this.
- entries_[handler_id].offset_target = offset;
+ DCHECK(base::IsValueInRangeForNumericType<int>(offset));
+ entries_[handler_id].offset_target = static_cast<int>(offset);
}
void HandlerTableBuilder::SetPrediction(
diff --git a/deps/v8/src/interpreter/handler-table-builder.h b/deps/v8/src/interpreter/handler-table-builder.h
index ad99a8f33b6..6ec58b86a23 100644
--- a/deps/v8/src/interpreter/handler-table-builder.h
+++ b/deps/v8/src/interpreter/handler-table-builder.h
@@ -45,11 +45,11 @@ class V8_EXPORT_PRIVATE HandlerTableBuilder final {
private:
struct Entry {
- size_t offset_start; // Bytecode offset starting try-region.
- size_t offset_end; // Bytecode offset ending try-region.
- size_t offset_target; // Bytecode offset of handler target.
- Register context; // Register holding context for handler.
- // Optimistic prediction for handler.
+ int offset_start; // Bytecode offset starting try-region.
+ int offset_end; // Bytecode offset ending try-region.
+ int offset_target; // Bytecode offset of handler target.
+ Register context; // Register holding context for handler.
+ // Optimistic prediction for handler.
HandlerTable::CatchPrediction catch_prediction_;
bool dropped;
};
diff --git a/deps/v8/src/interpreter/interpreter-assembler.cc b/deps/v8/src/interpreter/interpreter-assembler.cc
index 074f82763ea..b8fbf96e0b9 100644
--- a/deps/v8/src/interpreter/interpreter-assembler.cc
+++ b/deps/v8/src/interpreter/interpreter-assembler.cc
@@ -1599,12 +1599,40 @@ void InterpreterAssembler::OnStackReplacement(
BIND(&osr_to_sparkplug);
{
+ Label skip_osr_to_sparkplug(this);
+ // InterpreterEntryTrampoline only checks BytecodeArray::frame_size_,
+ // whereas baseline code requires BytecodeArray::max_frame_size()
+ // (frame_size_ + max_arguments_) so it can push outgoing call arguments
+ // without a stack check. Since frame_size_ is already allocated in the
+ // current interpreter frame, verify that there is enough remaining stack
+ // space for max_arguments_ before OSRing into baseline code.
+ //
+ // If there isn't enough space, we skip OSR and stay in the interpreter
+ // rather than throwing a StackOverflow here: exception handler lookup in
+ // the interpreter is keyed by bytecode offset, so throwing at JumpLoop
+ // could be caught by an inner try-catch wrapping the loop (and the call
+ // requiring max_arguments_ might not even be reached). Skipping means we
+ // will re-check on subsequent backedge interrupts while near the stack
+ // limit, which is an acceptable cost for this edge case.
+ TNode<Uint16T> max_arguments = LoadObjectField<Uint16T>(
+ BytecodeArrayTaggedPointer(), offsetof(BytecodeArray, max_arguments_));
+ TNode<UintPtrT> max_arguments_bytes =
+ TimesSystemPointerSize(ChangeUint32ToWord(max_arguments));
+ TNode<UintPtrT> stack_limit =
+ Load<UintPtrT>(IsolateField(IsolateFieldId::kRealJsLimit));
+ GotoIfNot(
+ StackPointerGreaterThan(IntPtrAdd(stack_limit, max_arguments_bytes)),
+ &skip_osr_to_sparkplug);
+
// We already compiled the baseline code, so we don't need to handle failed
// compilation as in the Ignition -> Turbofan case. Therefore we can just
// tailcall to the OSR builtin.
SaveBytecodeOffset();
TailCallBuiltin(Builtin::kInterpreterOnStackReplacement_ToBaseline,
context);
+
+ BIND(&skip_osr_to_sparkplug);
+ JumpBackward(relative_jump);
}
}
diff --git a/deps/v8/src/interpreter/interpreter-generator-tsa.cc b/deps/v8/src/interpreter/interpreter-generator-tsa.cc
index 15917f34d86..dfdc601f928 100644
--- a/deps/v8/src/interpreter/interpreter-generator-tsa.cc
+++ b/deps/v8/src/interpreter/interpreter-generator-tsa.cc
@@ -330,10 +330,10 @@ IGNITION_HANDLER_TS(BitwiseNot, NumberBuiltinsBytecodeHandlerAssembler) {
V<Object> value = GetAccumulator();
V<Context> context = GetContext();
- constexpr int kSlotIndex = 0;
- SetFeedbackSlot(__ ChangeUint32ToUintPtr(
- __ BytecodeOperandFeedbackSlotInt32(kSlotIndex)));
- LoadFeedbackVectorOrUndefinedIfJitless();
+ SetEmbeddedFeedback(
+ BytecodeArrayTaggedPointer(),
+ __ WordPtrAdd(BytecodeOffset(),
+ OperandOffset(kUnaryEmbeddedFeedbackOperandIndex)));
V<Object> result = BitwiseNot(context, value);
SetAccumulator(result);
diff --git a/deps/v8/src/interpreter/interpreter-generator.cc b/deps/v8/src/interpreter/interpreter-generator.cc
index 4f8da14f9f1..40e7050d023 100644
--- a/deps/v8/src/interpreter/interpreter-generator.cc
+++ b/deps/v8/src/interpreter/interpreter-generator.cc
@@ -1276,20 +1276,21 @@ IGNITION_HANDLER(BitwiseAndSmi, InterpreterBitwiseBinaryOpAssembler) {
#ifndef V8_ENABLE_EXPERIMENTAL_TSA_BUILTINS
-// BitwiseNot <feedback_slot>
+// BitwiseNot <feedback_index>
//
// Perform bitwise-not on the accumulator.
IGNITION_HANDLER(BitwiseNot, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
TNode<Context> context = GetContext();
- TNode<UintPtrT> slot_index = BytecodeOperandFeedbackSlot(0);
- TNode<Union<FeedbackVector, Undefined>> maybe_feedback_vector =
- LoadFeedbackVectorOrUndefinedIfJitless();
- static constexpr UpdateFeedbackMode mode = DefaultUpdateFeedbackMode();
+ TNode<BytecodeArray> bytecode_array = BytecodeArrayTaggedPointer();
+ TNode<IntPtrT> feedback_offset =
+ BytecodeOperandOffset(kUnaryEmbeddedFeedbackOperandIndex);
UnaryOpAssembler unary_op_asm(state());
TNode<Object> result = unary_op_asm.Generate_BitwiseNotWithFeedback(
- context, value, slot_index, maybe_feedback_vector, mode);
+ context, value,
+ unary_op_asm.MakeEmbeddedFeedbackUpdater(bytecode_array,
+ feedback_offset));
SetAccumulator(result);
Dispatch();
@@ -1324,20 +1325,21 @@ IGNITION_HANDLER(ShiftRightLogicalSmi, InterpreterBitwiseBinaryOpAssembler) {
BitwiseBinarySmiOpWithEmbeddedFeedback(Operation::kShiftRightLogical);
}
-// Negate <feedback_slot>
+// Negate <feedback_index>
//
// Perform arithmetic negation on the accumulator.
IGNITION_HANDLER(Negate, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
TNode<Context> context = GetContext();
- TNode<UintPtrT> slot_index = BytecodeOperandFeedbackSlot(0);
- TNode<Union<FeedbackVector, Undefined>> maybe_feedback_vector =
- LoadFeedbackVectorOrUndefinedIfJitless();
- static constexpr UpdateFeedbackMode mode = DefaultUpdateFeedbackMode();
+ TNode<BytecodeArray> bytecode_array = BytecodeArrayTaggedPointer();
+ TNode<IntPtrT> feedback_offset =
+ BytecodeOperandOffset(kUnaryEmbeddedFeedbackOperandIndex);
UnaryOpAssembler unary_op_asm(state());
TNode<Object> result = unary_op_asm.Generate_NegateWithFeedback(
- context, value, slot_index, maybe_feedback_vector, mode);
+ context, value,
+ unary_op_asm.MakeEmbeddedFeedbackUpdater(bytecode_array,
+ feedback_offset));
SetAccumulator(result);
Dispatch();
@@ -1410,39 +1412,41 @@ IGNITION_HANDLER(ToBoolean, InterpreterAssembler) {
Dispatch();
}
-// Inc
+// Inc <feedback_index>
//
// Increments value in the accumulator by one.
IGNITION_HANDLER(Inc, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
TNode<Context> context = GetContext();
- TNode<UintPtrT> slot_index = BytecodeOperandFeedbackSlot(0);
- TNode<Union<FeedbackVector, Undefined>> maybe_feedback_vector =
- LoadFeedbackVectorOrUndefinedIfJitless();
- static constexpr UpdateFeedbackMode mode = DefaultUpdateFeedbackMode();
+ TNode<BytecodeArray> bytecode_array = BytecodeArrayTaggedPointer();
+ TNode<IntPtrT> feedback_offset =
+ BytecodeOperandOffset(kUnaryEmbeddedFeedbackOperandIndex);
UnaryOpAssembler unary_op_asm(state());
TNode<Object> result = unary_op_asm.Generate_IncrementWithFeedback(
- context, value, slot_index, maybe_feedback_vector, mode);
+ context, value,
+ unary_op_asm.MakeEmbeddedFeedbackUpdater(bytecode_array,
+ feedback_offset));
SetAccumulator(result);
Dispatch();
}
-// Dec
+// Dec <feedback_index>
//
// Decrements value in the accumulator by one.
IGNITION_HANDLER(Dec, InterpreterAssembler) {
TNode<Object> value = GetAccumulator();
TNode<Context> context = GetContext();
- TNode<UintPtrT> slot_index = BytecodeOperandFeedbackSlot(0);
- TNode<Union<FeedbackVector, Undefined>> maybe_feedback_vector =
- LoadFeedbackVectorOrUndefinedIfJitless();
- static constexpr UpdateFeedbackMode mode = DefaultUpdateFeedbackMode();
+ TNode<BytecodeArray> bytecode_array = BytecodeArrayTaggedPointer();
+ TNode<IntPtrT> feedback_offset =
+ BytecodeOperandOffset(kUnaryEmbeddedFeedbackOperandIndex);
UnaryOpAssembler unary_op_asm(state());
TNode<Object> result = unary_op_asm.Generate_DecrementWithFeedback(
- context, value, slot_index, maybe_feedback_vector, mode);
+ context, value,
+ unary_op_asm.MakeEmbeddedFeedbackUpdater(bytecode_array,
+ feedback_offset));
SetAccumulator(result);
Dispatch();
diff --git a/deps/v8/src/interpreter/interpreter.cc b/deps/v8/src/interpreter/interpreter.cc
index 0278e8f05d6..3c3bcbaacad 100644
--- a/deps/v8/src/interpreter/interpreter.cc
+++ b/deps/v8/src/interpreter/interpreter.cc
@@ -176,13 +176,6 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() {
// TODO(lpy): add support for background compilation RCS trace.
TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("v8.compile"), "V8.CompileIgnition");
- std::optional<base::ElapsedTimer> timer;
- if (v8_flags.enable_bytecode_compiler_ablation &&
- base::TimeTicks::IsHighResolution()) {
- timer.emplace();
- timer->Start();
- }
-
// Print AST if flag is enabled. Note, if compiling on a background thread
// then ASTs from different functions may be intersperse when printed.
{
@@ -197,16 +190,6 @@ InterpreterCompilationJob::Status InterpreterCompilationJob::ExecuteJobImpl() {
return FAILED;
}
- if (timer && timer->Elapsed().InNanoseconds() > 0) {
- auto end = timer->Elapsed();
- end += std::min(base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromMicroseconds(
- static_cast<double>(end.InMicroseconds()) *
- v8_flags.bytecode_compiler_ablation_amount));
- while (timer->Elapsed() < end) {
- }
- }
-
return SUCCEEDED;
}
diff --git a/deps/v8/src/json/json-parser.cc b/deps/v8/src/json/json-parser.cc
index e1fcb293dd7..9fb474514c5 100644
--- a/deps/v8/src/json/json-parser.cc
+++ b/deps/v8/src/json/json-parser.cc
@@ -26,6 +26,7 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/heap-object.h"
#include "src/objects/js-data-object-builder-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/objects/property-details.h"
diff --git a/deps/v8/src/json/json-stringifier.cc b/deps/v8/src/json/json-stringifier.cc
index 73f136df023..c7f692aed1f 100644
--- a/deps/v8/src/json/json-stringifier.cc
+++ b/deps/v8/src/json/json-stringifier.cc
@@ -20,6 +20,7 @@
#include "src/objects/js-raw-json-inl.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/lookup.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/ordered-hash-table.h"
@@ -1063,6 +1064,7 @@ JsonStringifier::Result JsonStringifier::Serialize_(Handle<JSAny> object,
UNREACHABLE();
#if V8_ENABLE_WEBASSEMBLY
case WASM_STRUCT_TYPE:
+ case WASM_CUSTOM_MAP_TYPE:
case WASM_ARRAY_TYPE:
return UNCHANGED;
#endif
@@ -2650,7 +2652,7 @@ Builtin GetBuiltin(Isolate* isolate, Tagged<JSObject> obj,
if (it.state() != LookupIterator::DATA) {
return Builtin::kNoBuiltinId;
}
- DirectHandle<Object> fun = Object::GetProperty(&it).ToHandleChecked();
+ DirectHandle<Object> fun = it.GetDataValue(AllowAllocation{false});
if (!IsJSFunction(*fun)) {
return Builtin::kNoBuiltinId;
}
diff --git a/deps/v8/src/logging/counters-definitions.h b/deps/v8/src/logging/counters-definitions.h
index d4bf90b496e..3f9098146b2 100644
--- a/deps/v8/src/logging/counters-definitions.h
+++ b/deps/v8/src/logging/counters-definitions.h
@@ -68,6 +68,9 @@ namespace internal {
/* Number of deopts triggered in webassembly code. */ \
HR(wasm_deopts_executed, V8.WasmDeoptsExecutedCount, 0, 10000, 51) \
HR(wasm_deopts_per_function, V8.WasmDeoptsPerFunction, 0, 500, 21) \
+ /* Percentage of a function's SIMD128 operations that the revectorizer */ \
+ /* combined into SIMD256 operations, per revectorized function. */ \
+ HR(wasm_revec_conversion_percent, V8.WasmRevecConversionPercent, 0, 101, 32) \
/* Number of live modules per isolate. */ \
HR(wasm_modules_per_isolate, V8.WasmModulesPerIsolate, 1, 1024, 30) \
/* Number of live modules per engine (i.e. whole process). */ \
diff --git a/deps/v8/src/logging/log.cc b/deps/v8/src/logging/log.cc
index 9858c5404b6..773c24fa956 100644
--- a/deps/v8/src/logging/log.cc
+++ b/deps/v8/src/logging/log.cc
@@ -41,6 +41,7 @@
#include "src/objects/api-callbacks.h"
#include "src/objects/code-kind.h"
#include "src/objects/code.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/profiler/tick-sample.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/strings/unicode-inl.h"
@@ -2320,6 +2321,7 @@ void V8FileLogger::LogAllMaps() {
CombinedHeapObjectIterator iterator(heap);
for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
+ if (IsInaccessible(obj)) continue;
if (!IsMap(obj)) continue;
Tagged<Map> map = Cast<Map>(obj);
MapCreate(map);
@@ -2650,6 +2652,7 @@ void ExistingCodeLogger::LogCodeObjects() {
DisallowGarbageCollection no_gc;
for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
obj = iterator.Next()) {
+ if (IsInaccessible(obj)) continue;
InstanceType instance_type = obj->map()->instance_type();
if (InstanceTypeChecker::IsCode(instance_type) ||
InstanceTypeChecker::IsBytecodeArray(instance_type)) {
diff --git a/deps/v8/src/logging/runtime-call-stats.h b/deps/v8/src/logging/runtime-call-stats.h
index 9197dd27520..1ab0baba1b4 100644
--- a/deps/v8/src/logging/runtime-call-stats.h
+++ b/deps/v8/src/logging/runtime-call-stats.h
@@ -431,7 +431,6 @@ namespace v8::internal {
V(OptimizeConcurrentPrepare) \
V(OptimizeFinalizePipelineJob) \
V(OptimizeHeapBrokerInitialization) \
- V(OptimizeRevectorizer) \
V(OptimizeSerialization) \
V(OptimizeSerializeMetadata) \
V(OptimizeSynchronous) \
diff --git a/deps/v8/src/maglev/arm/maglev-assembler-arm-inl.h b/deps/v8/src/maglev/arm/maglev-assembler-arm-inl.h
index 5768993d27c..c39bbb20636 100644
--- a/deps/v8/src/maglev/arm/maglev-assembler-arm-inl.h
+++ b/deps/v8/src/maglev/arm/maglev-assembler-arm-inl.h
@@ -331,6 +331,14 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, element_address, element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MemOperand element_address = MemOperand(data_pointer, index);
+ LoadUnsignedField(result, element_address, element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
@@ -353,7 +361,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -487,6 +497,18 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ if (size == 2) {
+ rev(value, value);
+ lsr(value, value, Operand(16));
+ } else if (size == 4) {
+ rev(value, value);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline void MaglevAssembler::IncrementInt32(Register reg) {
add(reg, reg, Operand(1));
}
@@ -661,6 +683,57 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
vstr(src, dst);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ UseScratchRegisterScope temps(this);
+ SwVfpRegister temp_vfps = SwVfpRegister::no_reg();
+ if (dst.code() < 16) {
+ temp_vfps = LowDwVfpRegister::from_code(dst.code()).low();
+ } else {
+ temp_vfps = temps.AcquireS();
+ }
+ Register scratch = temps.Acquire();
+ ldr(scratch, MemOperand(base, index));
+ vmov(temp_vfps, scratch);
+ vcvt_f64_f32(dst, temp_vfps);
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ UseScratchRegisterScope temps(this);
+ SwVfpRegister temp_vfps = SwVfpRegister::no_reg();
+ if (dst.code() < 16) {
+ temp_vfps = LowDwVfpRegister::from_code(dst.code()).low();
+ } else {
+ temp_vfps = temps.AcquireS();
+ }
+ Register scratch = temps.Acquire();
+ ldr(scratch, MemOperand(base, index));
+ rev(scratch, scratch);
+ vmov(temp_vfps, scratch);
+ vcvt_f64_f32(dst, temp_vfps);
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ UseScratchRegisterScope temps(this);
+ SwVfpRegister temp_vfps = temps.AcquireS();
+ vcvt_f32_f64(temp_vfps, src);
+ Register scratch = temps.Acquire();
+ vmov(scratch, temp_vfps);
+ str(scratch, MemOperand(base, index));
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ UseScratchRegisterScope temps(this);
+ SwVfpRegister temp_vfps = temps.AcquireS();
+ vcvt_f32_f64(temp_vfps, src);
+ Register scratch = temps.Acquire();
+ vmov(scratch, temp_vfps);
+ rev(scratch, scratch);
+ str(scratch, MemOperand(base, index));
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -1370,7 +1443,7 @@ inline Condition MaglevAssembler::FunctionEntryStackCheck(
int stack_check_offset) {
TemporaryRegisterScope temps(this);
Register stack_cmp_reg = sp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = temps.AcquireScratch();
sub(stack_cmp_reg, sp, Operand(stack_check_offset));
}
@@ -1438,6 +1511,10 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
result, FieldMemOperand(object, offset));
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) {
+ dmb(ISH);
+}
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/arm/maglev-ir-arm.cc b/deps/v8/src/maglev/arm/maglev-ir-arm.cc
index b2b421fe64b..c86773c2b1f 100644
--- a/deps/v8/src/maglev/arm/maglev-ir-arm.cc
+++ b/deps/v8/src/maglev/arm/maglev-ir-arm.cc
@@ -1022,18 +1022,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
ToDoubleRegister(ValueInput()));
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- // The hole value is a signalling NaN, so just silence it to get the
- // float64 value.
- __ VFPCanonicalizeNaN(ToDoubleRegister(this->result()),
- ToDoubleRegister(ValueInput()));
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -1053,25 +1041,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
- set_temporaries_needed(1);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
-
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch = temps.Acquire();
- __ JumpIfNotHoleNan(value, scratch, &done);
- __ Move(value, UndefinedNan());
- __ bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1084,47 +1053,26 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- {
- Register stack_limit = scratch0;
- __ LoadStackLimit(stack_limit, StackLimitKind::kInterruptStackLimit);
- __ cmp(sp, stack_limit);
- __ b(hi, &next);
- }
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- Register function = scratch0;
- __ ldr(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
- __ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ b(*done); // All done, continue.
- __ bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
Register function = scratch0;
__ ldr(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
+ __ Push(Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
+ Register function = scratch0;
+ __ ldr(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ Push(function);
__ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
@@ -1150,15 +1098,17 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
- set_temporaries_needed(1);
+ set_temporaries_needed(try_osr() ? 3 : 1);
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
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 b2c1602641f..8a8e874a87f 100644
--- a/deps/v8/src/maglev/arm64/maglev-assembler-arm64-inl.h
+++ b/deps/v8/src/maglev/arm64/maglev-assembler-arm64-inl.h
@@ -479,9 +479,9 @@ inline void MaglevAssembler::BuildTypedArrayDataPointer(Register data_pointer,
inline MemOperand MaglevAssembler::TypedArrayElementOperand(
Register data_pointer, Register index, int element_size) {
- Add(data_pointer, data_pointer,
- Operand(index, LSL, ShiftFromScale(element_size)));
- return MemOperand(data_pointer);
+ // The accesses this operand feeds are always exactly element_size wide, so
+ // the scaled register-offset addressing mode can fold the index shift.
+ return MemOperand(data_pointer, index, LSL, ShiftFromScale(element_size));
}
inline void MaglevAssembler::StoreDataViewElement(Register value,
@@ -500,6 +500,14 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, element_address, element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MemOperand element_address = MemOperand(data_pointer, index);
+ LoadUnsignedField(result, element_address, element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
@@ -529,7 +537,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -546,7 +556,9 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
void MaglevAssembler::LoadFixedArrayElementWithoutDecompressing(
Register result, Register array, Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -689,6 +701,18 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ if (size == 2) {
+ Rev16(value, value);
+ Uxth(value, value);
+ } else if (size == 4) {
+ Rev32(value, value);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline void MaglevAssembler::IncrementInt32(Register reg) {
Add(reg.W(), reg.W(), Immediate(1));
}
@@ -839,6 +863,36 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
Str(src, dst);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ LoadFloat32(dst, MemOperand(base, index));
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ Ldr(scratch.W(), MemOperand(base, index));
+ Rev(scratch.W(), scratch.W());
+ Fmov(dst.S(), scratch.W());
+ Fcvt(dst, dst.S());
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ StoreFloat32(MemOperand(base, index), src);
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ TemporaryRegisterScope temps(this);
+ DoubleRegister scratch_double = temps.AcquireScratchDouble();
+ Fcvt(scratch_double.S(), src);
+ Register scratch = temps.AcquireScratch();
+ Fmov(scratch.W(), scratch_double.S());
+ Rev(scratch.W(), scratch.W());
+ Str(scratch.W(), MemOperand(base, index));
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -1363,9 +1417,28 @@ inline void MaglevAssembler::CompareInt32AndBranch(
Register r1, int32_t value, Condition cond, Label* if_true,
Label::Distance true_distance, bool fallthrough_when_true, Label* if_false,
Label::Distance false_distance, bool fallthrough_when_false) {
- Cmp(r1.W(), Immediate(value));
- Branch(cond, if_true, true_distance, fallthrough_when_true, if_false,
- false_distance, fallthrough_when_false);
+ // Mirror Branch's fallthrough resolution, but emit the compare and the
+ // jump together through CompareAndBranch, so comparing against zero with
+ // an eq/ne/lt/ge condition folds to a single cbz/cbnz/tbz/tbnz. Other
+ // immediates and conditions keep the cmp + b.cond shape. When both targets
+ // fall through, nothing is emitted: the compare fed only this branch, so
+ // its flags are dead.
+ if (fallthrough_when_false) {
+ if (fallthrough_when_true) {
+ // If both paths are a fallthrough, do nothing.
+ DCHECK_EQ(if_true, if_false);
+ return;
+ }
+ // Jump over the false block if true, otherwise fall through into it.
+ CompareAndBranch(r1.W(), Immediate(value), cond, if_true);
+ } else {
+ // Jump to the false block if true.
+ CompareAndBranch(r1.W(), Immediate(value), NegateCondition(cond), if_false);
+ // Jump to the true block if it's not the next block.
+ if (!fallthrough_when_true) {
+ Jump(if_true, true_distance);
+ }
+ }
}
inline void MaglevAssembler::CompareInt32AndBranch(
@@ -1381,9 +1454,23 @@ inline void MaglevAssembler::CompareIntPtrAndBranch(
Register r1, int32_t value, Condition cond, Label* if_true,
Label::Distance true_distance, bool fallthrough_when_true, Label* if_false,
Label::Distance false_distance, bool fallthrough_when_false) {
- Cmp(r1.X(), Immediate(value));
- Branch(cond, if_true, true_distance, fallthrough_when_true, if_false,
- false_distance, fallthrough_when_false);
+ // See CompareInt32AndBranch.
+ if (fallthrough_when_false) {
+ if (fallthrough_when_true) {
+ // If both paths are a fallthrough, do nothing.
+ DCHECK_EQ(if_true, if_false);
+ return;
+ }
+ // Jump over the false block if true, otherwise fall through into it.
+ CompareAndBranch(r1.X(), Immediate(value), cond, if_true);
+ } else {
+ // Jump to the false block if true.
+ CompareAndBranch(r1.X(), Immediate(value), NegateCondition(cond), if_false);
+ // Jump to the true block if it's not the next block.
+ if (!fallthrough_when_true) {
+ Jump(if_true, true_distance);
+ }
+ }
}
inline void MaglevAssembler::CompareSmiAndJumpIf(Register r1, Tagged<Smi> value,
@@ -1562,7 +1649,7 @@ inline Condition MaglevAssembler::FunctionEntryStackCheck(
int stack_check_offset) {
TemporaryRegisterScope temps(this);
Register stack_cmp_reg = sp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = temps.AcquireScratch();
Sub(stack_cmp_reg, sp, stack_check_offset);
}
@@ -1630,6 +1717,10 @@ inline void MaglevAssembler::MaybeEmitPlaceHolderForDeopt() {
// Implemented only for x64.
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) {
+ Dmb(InnerShareable, BarrierAll);
+}
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/arm64/maglev-ir-arm64.cc b/deps/v8/src/maglev/arm64/maglev-ir-arm64.cc
index 8db266fe6aa..cdeb38c639c 100644
--- a/deps/v8/src/maglev/arm64/maglev-ir-arm64.cc
+++ b/deps/v8/src/maglev/arm64/maglev-ir-arm64.cc
@@ -1002,18 +1002,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
ToDoubleRegister(ValueInput()));
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- // The hole value is a signalling NaN, so just silence it to get the
- // float64 value.
- __ CanonicalizeNaN(ToDoubleRegister(this->result()),
- ToDoubleRegister(ValueInput()));
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -1033,25 +1021,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
- set_temporaries_needed(1);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
-
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch = temps.Acquire();
- __ JumpIfNotHoleNan(value, scratch.W(), &done);
- __ Move(value, UndefinedNan());
- __ Bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1064,47 +1033,30 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- {
- Register stack_limit = scratch0;
- __ LoadStackLimit(stack_limit, StackLimitKind::kInterruptStackLimit);
- __ Cmp(sp, stack_limit);
- __ B(&next, hi);
- }
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- Register function = scratch0;
- __ Ldr(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
- __ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ B(*done); // All done, continue.
- __ Bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
+ UseScratchRegisterScope temps(masm);
+ Register function = scratch0;
+ Register osr_offset = temps.AcquireX();
+ __ Ldr(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ Move(
+ osr_offset,
+ Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
+ __ Push(function, osr_offset);
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
Register function = scratch0;
__ Ldr(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
__ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
@@ -1132,15 +1084,17 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
- set_temporaries_needed(1);
+ set_temporaries_needed(try_osr() ? 3 : 2);
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
diff --git a/deps/v8/src/maglev/loong64/maglev-assembler-loong64-inl.h b/deps/v8/src/maglev/loong64/maglev-assembler-loong64-inl.h
index 5c00ef27f68..5eb4bb54005 100644
--- a/deps/v8/src/maglev/loong64/maglev-assembler-loong64-inl.h
+++ b/deps/v8/src/maglev/loong64/maglev-assembler-loong64-inl.h
@@ -532,10 +532,13 @@ inline void MaglevAssembler::BuildTypedArrayDataPointer(Register data_pointer,
inline MemOperand MaglevAssembler::TypedArrayElementOperand(
Register data_pointer, Register index, int element_size) {
const int shift = ShiftFromScale(element_size);
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ Bstrpick_d(scratch, index, 31, 0);
if (shift == 0) {
- Add_d(data_pointer, data_pointer, index);
+ Add_d(data_pointer, data_pointer, scratch);
} else {
- Alsl_d(data_pointer, index, data_pointer, shift);
+ Alsl_d(data_pointer, scratch, data_pointer, shift);
}
return MemOperand(data_pointer, 0);
}
@@ -556,15 +559,28 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, element_address, element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MemOperand element_address = MemOperand(data_pointer, index);
+ LoadUnsignedField(result, element_address, element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
int offset) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ // Int32 inputs are sign-extended on loong64; ensure the index contributes a
+ // non-negative offset to the 64-bit element address.
+ Bstrpick_d(scratch, index, 31, 0);
const int shift = ShiftFromScale(scale);
if (shift == 0) {
- Add_d(result, object, index);
+ Add_d(result, object, scratch);
} else {
- Alsl_d(result, index, object, shift);
+ Alsl_d(result, scratch, object, shift);
}
LoadTaggedField(result, FieldMemOperand(result, offset));
}
@@ -590,7 +606,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -607,11 +625,16 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
void MaglevAssembler::LoadFixedArrayElementWithoutDecompressing(
Register result, Register array, Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
- Alsl_d(result, index, array, kTaggedSizeLog2);
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ Bstrpick_d(scratch, index, 31, 0);
+ Alsl_d(result, scratch, array, kTaggedSizeLog2);
MacroAssembler::LoadTaggedFieldWithoutDecompressing(
result, FieldMemOperand(result, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -627,7 +650,8 @@ void MaglevAssembler::LoadFixedDoubleArrayElement(DoubleRegister result,
}
MaglevAssembler::TemporaryRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
- Alsl_d(scratch, index, array, kDoubleSizeLog2);
+ Bstrpick_d(scratch, index, 31, 0);
+ Alsl_d(scratch, scratch, array, kDoubleSizeLog2);
Fld_d(result, FieldMemOperand(scratch, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -635,7 +659,8 @@ inline void MaglevAssembler::StoreFixedDoubleArrayElement(
Register array, Register index, DoubleRegister value) {
MaglevAssembler::TemporaryRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
- Alsl_d(scratch, index, array, kDoubleSizeLog2);
+ Bstrpick_d(scratch, index, 31, 0);
+ Alsl_d(scratch, scratch, array, kDoubleSizeLog2);
Fst_d(value, FieldMemOperand(scratch, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -672,8 +697,11 @@ inline void MaglevAssembler::SetSlotAddressForTaggedField(Register slot_reg,
inline void MaglevAssembler::SetSlotAddressForFixedArrayElement(
Register slot_reg, Register object, Register index) {
DCHECK(!AreAliased(slot_reg, index));
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
Add_d(slot_reg, object, OFFSET_OF_DATA_START(FixedArray) - kHeapObjectTag);
- Alsl_d(slot_reg, index, slot_reg, kTaggedSizeLog2);
+ Bstrpick_d(scratch, index, 31, 0);
+ Alsl_d(slot_reg, scratch, slot_reg, kTaggedSizeLog2);
}
inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(Register object,
@@ -686,7 +714,8 @@ inline void MaglevAssembler::StoreFixedArrayElementNoWriteBarrier(
Register array, Register index, Register value) {
MaglevAssembler::TemporaryRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
- Alsl_d(scratch, index, array, kTaggedSizeLog2);
+ Bstrpick_d(scratch, index, 31, 0);
+ Alsl_d(scratch, scratch, array, kTaggedSizeLog2);
MacroAssembler::StoreTaggedField(
value, FieldMemOperand(scratch, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -751,6 +780,18 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ if (size == 2) {
+ revb_2h(value, value);
+ bstrpick_w(value, value, 15, 0);
+ } else if (size == 4) {
+ ByteSwap(value, value, 4);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline void MaglevAssembler::IncrementInt32(Register reg) {
Add_w(reg, reg, Operand(1));
}
@@ -901,6 +942,36 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
Fst_d(src, dst);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ LoadFloat32(dst, MemOperand(base, index));
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ Ld_w(scratch, MemOperand(base, index));
+ ByteSwap(scratch, scratch, 4);
+ movgr2fr_w(dst, scratch);
+ fcvt_d_s(dst, dst);
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ StoreFloat32(MemOperand(base, index), src);
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ TemporaryRegisterScope temps(this);
+ DoubleRegister scratch_double = temps.AcquireScratchDouble();
+ fcvt_s_d(scratch_double, src);
+ Register scratch = temps.AcquireScratch();
+ movfr2gr_s(scratch, scratch_double);
+ ByteSwap(scratch, scratch, 4);
+ St_w(scratch, MemOperand(base, index));
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -1797,7 +1868,7 @@ inline Condition MaglevAssembler::FunctionEntryStackCheck(
int stack_check_offset) {
TemporaryRegisterScope temps(this);
Register stack_cmp_reg = sp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = temps.AcquireScratch();
Sub_d(stack_cmp_reg, sp, Operand(stack_check_offset));
}
@@ -1862,6 +1933,8 @@ inline void MaglevAssembler::MaybeEmitPlaceHolderForDeopt() {
// Implemented only for x64.
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) { dbar(0); }
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/loong64/maglev-ir-loong64.cc b/deps/v8/src/maglev/loong64/maglev-ir-loong64.cc
index 75cf70d4d4c..270e9426ff8 100644
--- a/deps/v8/src/maglev/loong64/maglev-ir-loong64.cc
+++ b/deps/v8/src/maglev/loong64/maglev-ir-loong64.cc
@@ -1073,18 +1073,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
ToDoubleRegister(ValueInput()));
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineAsRegister(this);
-}
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- // The hole value is a signalling NaN, so just silence it to get the float64
- // value.
- __ FPUCanonicalizeNaN(ToDoubleRegister(result()),
- ToDoubleRegister(ValueInput()));
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -1104,25 +1092,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
- set_temporaries_needed(1);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
-
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch = temps.Acquire();
- __ JumpIfNotHoleNan(value, scratch, &done);
- __ Move(value, UndefinedNan());
- __ bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1135,48 +1104,26 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- {
- Register stack_limit = scratch0;
- __ LoadStackLimit(stack_limit, StackLimitKind::kInterruptStackLimit);
- __ MacroAssembler::Branch(&next, ugt, sp, Operand(stack_limit),
- Label::Distance::kNear);
- }
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- Register function = scratch0;
- __ Ld_d(function,
- MemOperand(fp, StandardFrameConstants::kFunctionOffset));
- __ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ MacroAssembler::Branch(*done); // All done, continue.
- __ bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
Register function = scratch0;
__ Ld_d(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
+ __ Push(Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
+ Register function = scratch0;
+ __ Ld_d(function, MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ Push(function);
__ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
@@ -1212,16 +1159,17 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
-
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
- set_temporaries_needed(1);
+ set_temporaries_needed(try_osr() ? 3 : 1);
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
diff --git a/deps/v8/src/maglev/maglev-assembler.cc b/deps/v8/src/maglev/maglev-assembler.cc
index 2531ca9ee51..bf944fe8f08 100644
--- a/deps/v8/src/maglev/maglev-assembler.cc
+++ b/deps/v8/src/maglev/maglev-assembler.cc
@@ -10,6 +10,7 @@
#include "src/codegen/reglist.h"
#include "src/maglev/maglev-assembler-inl.h"
#include "src/maglev/maglev-code-generator.h"
+#include "src/maglev/maglev-ir-inl.h"
#include "src/numbers/conversions.h"
#include "src/objects/fixed-array.h"
#include "src/objects/instance-type.h"
@@ -168,17 +169,20 @@ void MaglevAssembler::ToBoolean(Register value, CheckType check_type,
TemporaryRegisterScope temps(this);
if (check_type == CheckType::kCheckHeapObject) {
- // Check if {{value}} is Smi.
- Condition is_smi = CheckSmi(value);
- JumpToDeferredIf(
- is_smi,
- [](MaglevAssembler* masm, Register value, ZoneLabelRef is_true,
- ZoneLabelRef is_false) {
- // Check if {value} is not zero.
- __ CompareSmiAndJumpIf(value, Smi::FromInt(0), kEqual, *is_false);
- __ Jump(*is_true);
- },
- value, is_true, is_false);
+ // Check if {{value}} is Smi. Going through JumpIfSmi rather than a
+ // CheckSmi condition lets arm64 use tbz instead of tst+b.eq.
+ if (v8_flags.code_comments) {
+ RecordComment("-- Jump to deferred code");
+ }
+ JumpIfSmi(value, MakeDeferredCode(
+ [](MaglevAssembler* masm, Register value,
+ ZoneLabelRef is_true, ZoneLabelRef is_false) {
+ // Check if {value} is not zero.
+ __ CompareSmiAndJumpIf(value, Smi::FromInt(0),
+ kEqual, *is_false);
+ __ Jump(*is_true);
+ },
+ value, is_true, is_false));
} else if (v8_flags.debug_code) {
AssertNotSmi(value);
}
@@ -776,6 +780,116 @@ void MaglevAssembler::ResetLastYoungAllocation() {
ExternalReference::last_young_allocation_address(isolate_);
Move(last_young_allocation_address, 0);
}
+
+namespace {
+
+void AttemptOnStackReplacement(MaglevAssembler* masm,
+ ZoneLabelRef no_code_for_osr,
+ ReduceInterruptBudgetForLoop* node,
+ Register scratch0, Register scratch1,
+ FeedbackSlot feedback_slot) {
+ // 1) Presence of cached OSR Turbofan code.
+ // 2) The OSR urgency exceeds the current loop depth - in that case, call
+ // into runtime to trigger a Turbofan OSR compilation. A non-zero return
+ // value means we should deopt into Ignition which will handle all further
+ // necessary steps (rewriting the stack frame, jumping to OSR'd code).
+ //
+ // See also: InterpreterAssembler::OnStackReplacement.
+
+ __ AssertFeedbackVector(scratch0, scratch1);
+
+ // Case 1).
+ Label deopt;
+ __ TryLoadOptimizedOsrCode(scratch1, CodeKind::TURBOFAN_JS, scratch0,
+ feedback_slot, &deopt, Label::kFar);
+
+ // Case 2).
+ {
+ __ LoadByte(scratch1, FieldMemOperand(
+ scratch0, offsetof(FeedbackVector, osr_state_)));
+ __ DecodeField<FeedbackVector::OsrUrgencyBits>(scratch1);
+ __ JumpIfByte(kUnsignedLessThanEqual, scratch1, node->loop_depth(),
+ *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);
+
+ {
+ // The osr_urgency exceeds the current loop_depth, signaling an OSR
+ // request. Call into runtime to compile.
+ RegisterSnapshot snapshot = node->register_snapshot();
+ DCHECK(!snapshot.live_registers.has(scratch1));
+ SaveRegisterStateForCall save_register_state(masm, snapshot);
+ __ Push(Smi::FromInt(node->osr_offset().ToInt()));
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kCompileOptimizedOSRFromMaglev, 1);
+ save_register_state.DefineSafepoint();
+ __ Move(scratch1, kReturnRegister0);
+ }
+
+ // A `0` return value means there is no OSR code available yet. Continue
+ // execution in Maglev, OSR code will be picked up once it exists and is
+ // cached on the feedback vector.
+ __ CompareInt32AndJumpIf(scratch1, 0, kEqual, *no_code_for_osr);
+ }
+
+ __ bind(&deopt);
+ if (V8_LIKELY(v8_flags.turbofan)) {
+ // None of the mutated input registers should be a register input into the
+ // eager deopt info.
+ DCHECK_REGLIST_EMPTY(
+ RegList{scratch0, scratch1} &
+ GetGeneralRegistersUsedAsInputs(node->eager_deopt_info()));
+ __ EmitEagerDeopt(node, DeoptimizeReason::kPrepareForOnStackReplacement);
+ } else {
+ // Continue execution in Maglev. With TF disabled we cannot OSR and thus it
+ // doesn't make sense to start the process. We do still perform all
+ // remaining bookkeeping above though, to keep Maglev code behavior roughly
+ // the same in both configurations.
+ __ Jump(*no_code_for_osr);
+ }
+}
+
+} // namespace
+
+void MaglevAssembler::TryOnStackReplacement(ReduceInterruptBudgetForLoop* node,
+ FeedbackSlot feedback_slot) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch0 = temps.Acquire();
+ Register scratch1 = temps.Acquire();
+
+ const Register osr_state = scratch1;
+ Move(scratch0,
+ compilation_info()->toplevel_compilation_unit()->feedback().object());
+ AssertFeedbackVector(scratch0, scratch1);
+ LoadByte(osr_state,
+ FieldMemOperand(scratch0, offsetof(FeedbackVector, osr_state_)));
+
+ ZoneLabelRef no_code_for_osr(this);
+
+ if (v8_flags.maglev_osr) {
+ // In case we use maglev_osr, we need to explicitly know if there is
+ // turbofan code waiting for us (i.e., ignore the
+ // MaybeHasMaglevOsrCodeBit).
+ DecodeField<
+ base::BitFieldUnion<FeedbackVector::OsrUrgencyBits,
+ FeedbackVector::MaybeHasTurbofanOsrCodeBit>>(
+ osr_state);
+ }
+
+ // The quick initial OSR check. If it passes, we proceed on to more
+ // expensive OSR logic.
+ static_assert(FeedbackVector::MaybeHasTurbofanOsrCodeBit::encode(true) >
+ FeedbackVector::kMaxOsrUrgency);
+ CompareInt32AndJumpIf(
+ osr_state, node->loop_depth(), kUnsignedGreaterThan,
+ MakeDeferredCode(AttemptOnStackReplacement, no_code_for_osr, node,
+ scratch0, scratch1, feedback_slot));
+ bind(*no_code_for_osr);
+}
#undef __
} // namespace maglev
diff --git a/deps/v8/src/maglev/maglev-assembler.h b/deps/v8/src/maglev/maglev-assembler.h
index 2fab17ca342..ea0e60fc69e 100644
--- a/deps/v8/src/maglev/maglev-assembler.h
+++ b/deps/v8/src/maglev/maglev-assembler.h
@@ -7,6 +7,7 @@
#include "src/base/logging.h"
#include "src/base/strong-alias.h"
+#include "src/codegen/atomic-memory-order.h"
#include "src/codegen/machine-type.h"
#include "src/codegen/macro-assembler.h"
#include "src/common/globals.h"
@@ -244,6 +245,8 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
Register object, int offset, Register value,
RegisterSnapshot register_snapshot, IndirectPointerTag tag);
+ inline void MemoryBarrier(AtomicMemoryOrder order);
+
// Preserves all registers that are in the register snapshot, but is otherwise
// allowed to clobber both input registers if they are not in the snapshot.
//
@@ -282,6 +285,7 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
inline void StoreField(MemOperand operand, Register value, int element_size);
inline void ReverseByteOrder(Register value, int element_size);
+ inline void ReverseByteOrderUnsigned(Register value, int element_size);
inline void BuildTypedArrayDataPointer(Register data_pointer,
Register object);
@@ -292,6 +296,9 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
Register index, int element_size);
inline void LoadDataViewElement(Register result, Register data_pointer,
Register index, int element_size);
+ inline void LoadUnsignedDataViewElement(Register result,
+ Register data_pointer, Register index,
+ int element_size);
enum class CharCodeMaskMode { kValueIsInRange, kMustApplyMask };
@@ -502,6 +509,16 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
inline void LoadFloat64(DoubleRegister dst, MemOperand src);
inline void StoreFloat64(MemOperand dst, DoubleRegister src);
+ inline void LoadUnalignedFloat32(DoubleRegister dst, Register base,
+ Register index);
+ inline void LoadUnalignedFloat32AndReverseByteOrder(DoubleRegister dst,
+ Register base,
+ Register index);
+ inline void StoreUnalignedFloat32(Register base, Register index,
+ DoubleRegister src);
+ inline void ReverseByteOrderAndStoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src);
inline void LoadUnalignedFloat64(DoubleRegister dst, Register base,
Register index);
inline void LoadUnalignedFloat64AndReverseByteOrder(DoubleRegister dst,
@@ -860,6 +877,9 @@ class V8_EXPORT_PRIVATE MaglevAssembler : public MacroAssembler {
void ResetLastYoungAllocation();
+ void TryOnStackReplacement(ReduceInterruptBudgetForLoop* node,
+ FeedbackSlot feedback_slot);
+
compiler::NativeContextRef native_context() const {
return code_gen_state()->broker()->target_native_context();
}
diff --git a/deps/v8/src/maglev/maglev-basic-block.h b/deps/v8/src/maglev/maglev-basic-block.h
index b30e6731cb6..785b22f2a72 100644
--- a/deps/v8/src/maglev/maglev-basic-block.h
+++ b/deps/v8/src/maglev/maglev-basic-block.h
@@ -157,14 +157,6 @@ class BasicBlock {
state_->phis()->Add(phi);
}
- ExceptionHandlerInfo::List& exception_handlers() {
- return exception_handlers_;
- }
-
- void AddExceptionHandler(ExceptionHandlerInfo* handler) {
- exception_handlers_.Add(handler);
- }
-
int predecessor_count() const {
if (type_ == kEdgeSplit || type_ == kOther) {
DCHECK_NOT_NULL(predecessor());
@@ -185,6 +177,14 @@ class BasicBlock {
return state_->predecessor_at(i);
}
+ // Only loop headers of non-resumable loops are guaranteed to have a forward
+ // edge; a resumable loop can be entered through its resume edges alone.
+ BasicBlock* forward_predecessor() const {
+ DCHECK(is_loop());
+ DCHECK_EQ(predecessor_count(), 2);
+ return predecessor_at(0);
+ }
+
BasicBlock* backedge_predecessor() const {
DCHECK(is_loop());
return predecessor_at(predecessor_count() - 1);
@@ -365,7 +365,7 @@ class BasicBlock {
}
bool has_register_merge = false;
#ifdef V8_ENABLE_MAGLEV
- if (!state()->register_state().is_initialized()) {
+ if (!state()->has_register_state()) {
// This can happen when the graph has disconnected blocks; bail out and
// don't jump thread them.
return true;
@@ -400,7 +400,6 @@ class BasicBlock {
ZoneVector<Node*> nodes_;
ControlNode* control_node_;
- ExceptionHandlerInfo::List exception_handlers_;
union {
MergePointInterpreterFrameState* state_;
diff --git a/deps/v8/src/maglev/maglev-compiler.cc b/deps/v8/src/maglev/maglev-compiler.cc
index 050da4b2b99..06dd7c5e301 100644
--- a/deps/v8/src/maglev/maglev-compiler.cc
+++ b/deps/v8/src/maglev/maglev-compiler.cc
@@ -181,7 +181,7 @@ bool MaglevCompiler::Compile(LocalIsolate* local_isolate,
TRACE_EVENT(TRACE_DISABLED_BY_DEFAULT("v8.compile"),
"V8.Maglev.Truncation");
SYNCHRONIZATION_POINT("MaglevTruncation");
- GraphBackwardProcessor<PropagateTruncationProcessor> propagate;
+ GraphBackwardProcessor<PropagateTruncationProcessor> propagate(graph);
propagate.ProcessGraph(graph);
PrintGraph(graph, v8_flags.print_maglev_graphs,
MaglevPhase::kTruncationPropagation);
diff --git a/deps/v8/src/maglev/maglev-concurrent-dispatcher.cc b/deps/v8/src/maglev/maglev-concurrent-dispatcher.cc
index 9c1da9cef63..45bcecaa63a 100644
--- a/deps/v8/src/maglev/maglev-concurrent-dispatcher.cc
+++ b/deps/v8/src/maglev/maglev-concurrent-dispatcher.cc
@@ -124,7 +124,7 @@ CompilationJob::Status MaglevCompilationJob::AbortOptimization(
CompilationJob::Status MaglevCompilationJob::PrepareJobImpl(Isolate* isolate) {
if (function()->shared()->GetBytecodeArray(isolate)->length() >
- v8_flags.max_optimized_bytecode_size) {
+ v8_flags.max_maglev_optimized_bytecode_size) {
return AbortOptimization(isolate, BailoutReason::kFunctionTooBig);
}
BeginPhaseKind("V8.MaglevPrepareJob");
@@ -304,13 +304,15 @@ class MaglevConcurrentDispatcher::JobTask final : public v8::JobTask {
RuntimeCallCounterId::kOptimizeBackgroundMaglev);
CompilationJob::Status status =
job->ExecuteJob(local_isolate.runtime_call_stats(), &local_isolate);
- if (status == CompilationJob::SUCCEEDED) {
- outgoing_queue()->Enqueue(std::move(job));
- isolate()->stack_guard()->RequestInstallMaglevCode();
- } else {
- UnparkedScope unparked_scope(&local_isolate);
- job.reset();
- }
+ // A retry leaves the job in kReadyToExecute, which finalization cannot
+ // handle, so it must never reach the outgoing queue.
+ CHECK_NE(status, CompilationJob::RETRY_ON_MAIN_THREAD);
+ outgoing_queue()->Enqueue(std::move(job));
+ // Requests the interrupt that finalizes the job on the main thread,
+ // which happens even in case of failure.
+ // TODO(victorgomes): Consider renaming this to
+ // RequestMaglevJobFinalization.
+ isolate()->stack_guard()->RequestInstallMaglevCode();
} else if (destruction_queue()->Dequeue(&job)) {
// Maglev jobs aren't cheap to destruct, so destroy them here in the
// background thread rather than on the main thread.
diff --git a/deps/v8/src/maglev/maglev-graph-builder.cc b/deps/v8/src/maglev/maglev-graph-builder.cc
index 4f682b99819..0995c6cf3b7 100644
--- a/deps/v8/src/maglev/maglev-graph-builder.cc
+++ b/deps/v8/src/maglev/maglev-graph-builder.cc
@@ -73,12 +73,15 @@
#include "src/objects/instance-type-inl.h"
#include "src/objects/instance-type.h"
#include "src/objects/js-array.h"
+#include "src/objects/js-collection-iterator.h"
+#include "src/objects/js-collection.h"
#include "src/objects/js-function.h"
#include "src/objects/js-generator.h"
#include "src/objects/js-objects.h"
#include "src/objects/literal-objects-inl.h"
#include "src/objects/name-inl.h"
#include "src/objects/object-list-macros.h"
+#include "src/objects/ordered-hash-table.h"
#include "src/objects/property-cell.h"
#include "src/objects/property-details.h"
#include "src/objects/shared-function-info.h"
@@ -96,7 +99,7 @@ namespace v8::internal::maglev {
TraceLogger(tracer()) << __VA_ARGS__; \
}
-#define FAIL(...) \
+#define MAGLEV_FAIL(...) \
TRACE("Failed " << __func__ << ":" << __LINE__ << ": " << __VA_ARGS__); \
return {};
@@ -261,145 +264,15 @@ MaglevGraphBuilder::LazyDeoptResultLocationScope::
builder_->lazy_deopt_result_location_scope_ = previous_;
}
-class V8_NODISCARD MaglevGraphBuilder::DeoptFrameScopeBase {
- public:
- DeoptFrameScopeBase(MaglevGraphBuilder* builder, Builtin continuation,
- compiler::OptionalJSFunctionRef maybe_js_target = {},
- base::Vector<ValueNode* const> parameters = {})
- : builder_(builder),
- data_(DeoptFrame::BuiltinContinuationFrameData{
- continuation,
- parameters.empty() ? base::Vector<ValueNode*>{}
- : builder->zone()->CloneVector(parameters),
- builder->GetContext(), maybe_js_target}) {
- builder->current_interpreter_frame().virtual_objects().Snapshot();
- if (parameters.size() > 0) {
- if (InlinedAllocation* receiver =
- parameters[0]->TryCast<InlinedAllocation>()) {
- // We escape the first argument, since the builtin continuation call can
- // trigger a stack iteration, which expects the receiver to be a
- // meterialized object.
- receiver->ForceEscaping();
- }
- } else {
- DCHECK(data_.get<DeoptFrame::BuiltinContinuationFrameData>()
- .parameters.empty());
- }
- }
-
- DeoptFrameScopeBase(MaglevGraphBuilder* builder, ValueNode* receiver)
- : builder_(builder),
- data_(DeoptFrame::ConstructInvokeStubFrameData{
- *builder->compilation_unit(), builder->GetCurrentSourcePosition(),
- receiver, builder->GetContext()}) {
- builder_->current_interpreter_frame().virtual_objects().Snapshot();
- }
-
- ~DeoptFrameScopeBase() {
- // We might have cached a checkpointed frame which includes this scope;
- // reset it just in case.
- builder_->latest_checkpointed_frame_ = nullptr;
- }
-
- DeoptFrame::FrameData& data() { return data_; }
- const DeoptFrame::FrameData& data() const { return data_; }
-
- protected:
- MaglevGraphBuilder* builder() { return builder_; }
-
- private:
- MaglevGraphBuilder* builder_;
- DeoptFrame::FrameData data_;
-};
-
-namespace {
-
-void DebugVerifyBuiltinDeoptFrame(const DeoptFrame::FrameData& data,
- compiler::ContinuationFrameStateMode mode) {
-#ifdef DEBUG
- DCHECK_EQ(data.tag(), DeoptFrame::FrameType::kBuiltinContinuationFrame);
- const DeoptFrame::BuiltinContinuationFrameData& frame =
- data.get<DeoptFrame::BuiltinContinuationFrameData>();
- if (frame.maybe_js_target) {
- int stack_parameter_count =
- Builtins::GetStackParameterCount(frame.builtin_id);
- DCHECK_EQ(stack_parameter_count,
- frame.parameters.length() +
- compiler::DeoptimizerParameterCountFor(mode));
- } else {
- CallInterfaceDescriptor descriptor =
- Builtins::CallInterfaceDescriptorFor(frame.builtin_id);
- DCHECK_EQ(descriptor.GetParameterCount(),
- frame.parameters.length() +
- compiler::DeoptimizerParameterCountFor(mode));
- }
-#endif
-}
-
-} // namespace
-
-class V8_NODISCARD MaglevGraphBuilder::LazyDeoptFrameScope
- : public MaglevGraphBuilder::DeoptFrameScopeBase {
- public:
- LazyDeoptFrameScope(MaglevGraphBuilder* builder, Builtin continuation,
- compiler::OptionalJSFunctionRef maybe_js_target = {},
- base::Vector<ValueNode* const> parameters = {})
- : DeoptFrameScopeBase(builder, continuation, maybe_js_target, parameters),
- parent_(builder->current_lazy_deopt_scope_) {
- DebugVerifyBuiltinDeoptFrame(data(),
- compiler::ContinuationFrameStateMode::LAZY);
- builder->current_lazy_deopt_scope_ = this;
- }
-
- LazyDeoptFrameScope(MaglevGraphBuilder* builder, ValueNode* receiver)
- : DeoptFrameScopeBase(builder, receiver),
- parent_(builder->current_lazy_deopt_scope_) {
- builder->current_lazy_deopt_scope_ = this;
- }
-
- ~LazyDeoptFrameScope() { builder()->current_lazy_deopt_scope_ = parent_; }
-
- LazyDeoptFrameScope* parent() const { return parent_; }
-
- private:
- MaglevGraphBuilder::LazyDeoptFrameScope* parent_;
-};
-
-class V8_NODISCARD MaglevGraphBuilder::EagerDeoptFrameScope
- : public MaglevGraphBuilder::DeoptFrameScopeBase {
- public:
- EagerDeoptFrameScope(MaglevGraphBuilder* builder, Builtin continuation,
- compiler::OptionalJSFunctionRef maybe_js_target = {},
- base::Vector<ValueNode* const> parameters = {})
- : DeoptFrameScopeBase(builder, continuation, maybe_js_target, parameters),
- parent_(builder->current_lazy_deopt_scope_) {
- DebugVerifyBuiltinDeoptFrame(data(),
- compiler::ContinuationFrameStateMode::EAGER);
- // Eager deopt continuations cannot be nested, so this should always be
- // null.
- DCHECK_NULL(builder->current_eager_deopt_scope_);
- builder->current_eager_deopt_scope_ = this;
- }
-
- ~EagerDeoptFrameScope() { builder()->current_eager_deopt_scope_ = nullptr; }
-
- LazyDeoptFrameScope* parent() const { return parent_; }
-
- private:
- // An eager deopt continuation's parent has to be a lazy deopt continuation,
- // because we want to continue _after_ the eager deopt continuation completes.
- MaglevGraphBuilder::LazyDeoptFrameScope* parent_;
-};
-
class MaglevGraphBuilder::MaglevSubGraphBuilder::LoopLabel {
public:
private:
- explicit LoopLabel(MergePointInterpreterFrameState* merge_state,
+ explicit LoopLabel(LoopMergePointInterpreterFrameState* merge_state,
BasicBlock* loop_header)
: merge_state_(merge_state), loop_header_(loop_header) {}
friend class MaglevSubGraphBuilder;
- MergePointInterpreterFrameState* merge_state_ = nullptr;
+ LoopMergePointInterpreterFrameState* merge_state_ = nullptr;
BasicBlock* loop_header_;
};
@@ -513,10 +386,10 @@ MaglevGraphBuilder::MaglevSubGraphBuilder::BeginLoop(
// Create a state for the loop header, with two predecessors (the above jump
// and the back edge), and initialise with the current state.
- MergePointInterpreterFrameState* loop_state =
+ LoopMergePointInterpreterFrameState* loop_state =
MergePointInterpreterFrameState::NewForLoop(
- variable_frame_, *dummy_unit_, builder_->is_inline(),
- builder_->graph(), 0, 2, loop_header_liveness, loop_info);
+ *dummy_unit_, builder_->is_inline(), builder_->graph(), 0, 2,
+ loop_header_liveness, loop_info);
{
BorrowParentKnownNodeAspectsAndVOs borrow(this);
@@ -758,6 +631,7 @@ MaglevGraphBuilder::MaglevGraphBuilder(LocalIsolate* local_isolate,
allow_loop_peeling_(v8_flags.maglev_loop_peeling),
loop_effects_stack_(zone()),
decremented_predecessor_offsets_(zone()),
+ loop_headers_(bytecode().length() + 1, zone()),
loop_headers_to_peel_(bytecode().length(), zone()),
// Add an extra jump_target slot for the inline exit if needed.
jump_targets_(zone()->AllocateArray<BasicBlockRef>(
@@ -941,29 +815,6 @@ void MaglevGraphBuilder::BuildRegisterFrameInitialization(
}
void MaglevGraphBuilder::BuildMergeStates() {
- auto offset_and_info = bytecode_analysis().GetLoopInfos().begin();
- auto end = bytecode_analysis().GetLoopInfos().end();
- while (offset_and_info != end &&
- offset_and_info->loop_start() < entrypoint_) {
- ++offset_and_info;
- }
- for (; offset_and_info != end; ++offset_and_info) {
- const compiler::LoopInfo& loop_info = *offset_and_info;
- int offset = loop_info.loop_start();
- if (loop_headers_to_peel_.Contains(offset)) {
- // Peeled loops are treated like normal merges at first. We will construct
- // the proper loop header merge state when reaching the `JumpLoop` of the
- // peeled iteration.
- continue;
- }
- const compiler::BytecodeLivenessState* liveness = GetInLivenessFor(offset);
- DCHECK_NULL(merge_states_[offset]);
- TRACE("- Creating loop merge state at @" << offset);
- merge_states_[offset] = MergePointInterpreterFrameState::NewForLoop(
- current_interpreter_frame_, *compilation_unit_, is_inline(), graph(),
- offset, predecessor_count(offset), liveness, &loop_info);
- }
-
if (bytecode().handler_table_size() > 0) {
HandlerTable table(*bytecode().object());
for (uint32_t i = 0; i < table.NumberOfRangeEntries(); i++) {
@@ -1162,9 +1013,9 @@ DeoptFrame* MaglevGraphBuilder::GetDeoptFrameForEagerCall(
interpreter::Bytecodes::WritesAccumulator(iterator_.current_bytecode()) ||
interpreter::Bytecodes::ClobbersAccumulator(
iterator_.current_bytecode()));
- DeoptFrame* deopt_frame =
- GetDeoptFrameForLazyDeoptHelper(interpreter::Register::invalid_value(), 0,
- current_lazy_deopt_scope_, true, false);
+ DeoptFrame* deopt_frame = GetDeoptFrameForLazyDeoptHelper(
+ interpreter::Register::invalid_value(), 0,
+ reducer_.current_lazy_deopt_scope(), true, false);
return AddInlinedArgumentsToDeoptFrame(deopt_frame, unit, closure, args);
}
@@ -1206,7 +1057,7 @@ DeoptFrame* MaglevGraphBuilder::GetLatestCheckpointedFrame() {
[&](ValueNode* node, interpreter::Register) { AddDeoptUse(node); });
AddDeoptUse(latest_checkpointed_frame_->as_interpreted().closure());
- EagerDeoptFrameScope* deopt_scope = current_eager_deopt_scope_;
+ EagerDeoptFrameScope* deopt_scope = reducer_.current_eager_deopt_scope();
if (deopt_scope != nullptr) {
AddDeoptUseToScopeData(deopt_scope->data());
latest_checkpointed_frame_ = zone()->New<DeoptFrame>(
@@ -1228,10 +1079,11 @@ MaglevGraphBuilder::GetDeoptFrameForLazyDeopt(bool can_throw) {
} else {
std::tie(result_location, result_size) = GetResultLocationAndSize();
}
- return std::make_tuple(GetDeoptFrameForLazyDeoptHelper(
- result_location, result_size,
- current_lazy_deopt_scope_, false, can_throw),
- result_location, result_size);
+ return std::make_tuple(
+ GetDeoptFrameForLazyDeoptHelper(result_location, result_size,
+ reducer_.current_lazy_deopt_scope(),
+ false, can_throw),
+ result_location, result_size);
}
void MaglevGraphBuilder::AddDeoptUseToScopeData(
@@ -1413,8 +1265,8 @@ ReduceResult MaglevGraphBuilder::GetInternalizedString(
}
ReduceResult MaglevGraphBuilder::GetTruncatedInt32ForToNumber(
- ValueNode* value, NodeType allowed_input_type) {
- return reducer_.GetTruncatedInt32ForToNumber(value, allowed_input_type);
+ ValueNode* value, NodeType assumed_input_type) {
+ return reducer_.GetTruncatedInt32ForToNumber(value, assumed_input_type);
}
namespace {
@@ -1536,10 +1388,12 @@ using Float64NodeFor = typename Float64NodeForHelper<kOperation>::type;
template <Operation kOperation>
ReduceResult MaglevGraphBuilder::BuildGenericUnaryOperationNode() {
- FeedbackSlot slot_index = GetSlotOperand(0);
ValueNode* value = GetAccumulator();
return SetAccumulator(AddNewNode<GenericNodeForOperation<kOperation>>(
- {value}, compiler::FeedbackSource{feedback(), slot_index}));
+ {value}, compiler::EmbeddedFeedbackSource{
+ indirect_handle(iterator_.bytecode_array(), local_isolate()),
+ iterator_.GetEmbeddedFeedbackOffset(
+ kUnaryEmbeddedFeedbackOperandIndex)}));
}
template <Operation kOperation>
@@ -1578,11 +1432,11 @@ ReduceResult MaglevGraphBuilder::BuildInt32UnaryOperationNode() {
}
ReduceResult MaglevGraphBuilder::BuildTruncatingInt32BitwiseNotForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
ValueNode* value;
GET_VALUE_OR_ABORT(
value, GetTruncatedInt32ForToNumber(
- current_interpreter_frame_.accumulator(), allowed_input_type));
+ current_interpreter_frame_.accumulator(), assumed_input_type));
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldInt32UnaryOperation<Operation::kBitwiseNot>(value),
SetAccumulator);
@@ -1606,7 +1460,7 @@ ReduceResult MaglevGraphBuilder::BuildInt32BinaryOperationNode() {
template <Operation kOperation>
ReduceResult
MaglevGraphBuilder::BuildTruncatingInt32BinaryOperationNodeForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
static_assert(BinaryOperationIsBitwiseInt32<kOperation>());
ValueNode* left;
ValueNode* right;
@@ -1615,16 +1469,16 @@ MaglevGraphBuilder::BuildTruncatingInt32BinaryOperationNodeForToNumber(
right,
GetTruncatedInt32ForToNumber(
current_interpreter_frame_.get(iterator_.GetRegisterOperand(0)),
- allowed_input_type));
+ assumed_input_type));
left = right;
} else {
GET_VALUE_OR_ABORT(
left, GetTruncatedInt32ForToNumber(current_interpreter_frame_.get(
iterator_.GetRegisterOperand(0)),
- allowed_input_type));
+ assumed_input_type));
GET_VALUE_OR_ABORT(right, GetTruncatedInt32ForToNumber(
current_interpreter_frame_.accumulator(),
- allowed_input_type));
+ assumed_input_type));
}
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldInt32BinaryOperation<kOperation>(left, right),
@@ -1651,12 +1505,12 @@ ReduceResult MaglevGraphBuilder::BuildInt32BinarySmiOperationNode() {
template <Operation kOperation>
ReduceResult
MaglevGraphBuilder::BuildTruncatingInt32BinarySmiOperationNodeForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
static_assert(BinaryOperationIsBitwiseInt32<kOperation>());
ValueNode* left;
GET_VALUE_OR_ABORT(
left, GetTruncatedInt32ForToNumber(
- current_interpreter_frame_.accumulator(), allowed_input_type));
+ current_interpreter_frame_.accumulator(), assumed_input_type));
int32_t constant = iterator_.GetImmediateOperand(0);
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldInt32BinaryOperation<kOperation>(left, constant),
@@ -1667,16 +1521,16 @@ MaglevGraphBuilder::BuildTruncatingInt32BinarySmiOperationNodeForToNumber(
template <Operation kOperation>
ReduceResult MaglevGraphBuilder::BuildFloat64BinarySmiOperationNodeForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
// TODO(v8:7700): Do constant identity folding. Make sure to normalize
// HoleyFloat64 nodes if folded.
ValueNode* left;
GET_VALUE_OR_ABORT(left,
- GetAccumulatorFloat64ForToNumber(allowed_input_type));
+ GetAccumulatorFloat64ForArithmetic(assumed_input_type));
double constant = static_cast<double>(iterator_.GetImmediateOperand(0));
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldFloat64BinaryOperationForToNumber<kOperation>(
- GetTaggedToFloat64ConversionType(allowed_input_type), left, constant),
+ assumed_input_type, left, constant),
SetAccumulator);
ValueNode* right = GetFloat64Constant(constant);
return SetAccumulator(AddNewNode<Float64NodeFor<kOperation>>({left, right}));
@@ -1684,15 +1538,15 @@ ReduceResult MaglevGraphBuilder::BuildFloat64BinarySmiOperationNodeForToNumber(
template <Operation kOperation>
ReduceResult MaglevGraphBuilder::BuildFloat64UnaryOperationNodeForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
// TODO(v8:7700): Do constant identity folding. Make sure to normalize
// HoleyFloat64 nodes if folded.
ValueNode* value;
GET_VALUE_OR_ABORT(value,
- GetAccumulatorFloat64ForToNumber(allowed_input_type));
+ GetAccumulatorFloat64ForArithmetic(assumed_input_type));
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldFloat64UnaryOperationForToNumber<kOperation>(
- GetTaggedToFloat64ConversionType(allowed_input_type), value),
+ assumed_input_type, value),
SetAccumulator);
switch (kOperation) {
case Operation::kNegate:
@@ -1710,24 +1564,24 @@ ReduceResult MaglevGraphBuilder::BuildFloat64UnaryOperationNodeForToNumber(
template <Operation kOperation>
ReduceResult MaglevGraphBuilder::BuildFloat64BinaryOperationNodeForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
// TODO(v8:7700): Do constant identity folding. Make sure to normalize
// HoleyFloat64 nodes if folded.
ValueNode* left;
GET_VALUE_OR_ABORT(left,
- LoadRegisterFloat64ForToNumber(0, allowed_input_type));
+ LoadRegisterFloat64ForArithmetic(0, assumed_input_type));
ValueNode* right;
GET_VALUE_OR_ABORT(right,
- GetAccumulatorFloat64ForToNumber(allowed_input_type));
+ GetAccumulatorFloat64ForArithmetic(assumed_input_type));
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldFloat64BinaryOperationForToNumber<kOperation>(
- GetTaggedToFloat64ConversionType(allowed_input_type), left, right),
+ assumed_input_type, left, right),
SetAccumulator);
return SetAccumulator(AddNewNode<Float64NodeFor<kOperation>>({left, right}));
}
namespace {
-NodeType BinopHintToNodeTypeAndConversionType(BinaryOperationHint hint) {
+NodeType BinopHintToAssumedInputType(BinaryOperationHint hint) {
switch (hint) {
case BinaryOperationHint::kSignedSmall:
return NodeType::kSmi;
@@ -1772,8 +1626,8 @@ constexpr bool BigIntBinaryOperationHasBuiltin(Operation operation) {
template <Operation kOperation>
ReduceResult MaglevGraphBuilder::VisitUnaryOperation() {
- FeedbackNexus nexus = FeedbackNexusForOperand(0);
- BinaryOperationHint feedback_hint = nexus.GetBinaryOperationFeedback();
+ BinaryOperationHint feedback_hint =
+ iterator_.GetEmbeddedOperationHint<BinaryOperationFeedback>();
switch (feedback_hint) {
case BinaryOperationHint::kNone:
return reducer_.EmitUnconditionalDeopt(
@@ -1783,16 +1637,15 @@ ReduceResult MaglevGraphBuilder::VisitUnaryOperation() {
case BinaryOperationHint::kAdditiveSafeInteger:
case BinaryOperationHint::kNumber:
case BinaryOperationHint::kNumberOrOddball: {
- auto allowed_input_type =
- BinopHintToNodeTypeAndConversionType(feedback_hint);
+ auto assumed_input_type = BinopHintToAssumedInputType(feedback_hint);
if constexpr (BinaryOperationIsBitwiseInt32<kOperation>()) {
static_assert(kOperation == Operation::kBitwiseNot);
- return BuildTruncatingInt32BitwiseNotForToNumber(allowed_input_type);
+ return BuildTruncatingInt32BitwiseNotForToNumber(assumed_input_type);
} else if (feedback_hint == BinaryOperationHint::kSignedSmall) {
return BuildInt32UnaryOperationNode<kOperation>();
}
return BuildFloat64UnaryOperationNodeForToNumber<kOperation>(
- allowed_input_type);
+ assumed_input_type);
break;
}
case BinaryOperationHint::kBigInt:
@@ -2140,7 +1993,7 @@ ReduceResult MaglevGraphBuilder::BuildFloat64SpeculateSafeAdd(
DCHECK(flags_.can_speculative_additive_safe_int);
PROCESS_AND_RETURN_IF_DONE(
reducer_.TryFoldFloat64BinaryOperationForToNumber<Operation::kAdd>(
- TaggedToFloat64ConversionType::kOnlyNumber, left, right),
+ NodeType::kNumber, left, right),
SetAccumulator);
ReduceResult result = AddNewNode<Float64SpeculateSafeAdd>({left, right});
if (result.IsDoneWithValue()) {
@@ -2173,11 +2026,10 @@ ReduceResult MaglevGraphBuilder::VisitBinaryOperation() {
case BinaryOperationHint::kSignedSmallInputs:
case BinaryOperationHint::kNumber:
case BinaryOperationHint::kNumberOrOddball: {
- NodeType allowed_input_type =
- BinopHintToNodeTypeAndConversionType(feedback_hint);
+ NodeType assumed_input_type = BinopHintToAssumedInputType(feedback_hint);
if constexpr (BinaryOperationIsBitwiseInt32<kOperation>()) {
return BuildTruncatingInt32BinaryOperationNodeForToNumber<kOperation>(
- allowed_input_type);
+ assumed_input_type);
} else if (feedback_hint == BinaryOperationHint::kSignedSmall) {
if constexpr (kOperation == Operation::kExponentiate) {
// Exponentiate never updates the feedback to be a Smi.
@@ -2187,7 +2039,7 @@ ReduceResult MaglevGraphBuilder::VisitBinaryOperation() {
}
} else {
return BuildFloat64BinaryOperationNodeForToNumber<kOperation>(
- allowed_input_type);
+ assumed_input_type);
}
break;
}
@@ -2268,11 +2120,10 @@ ReduceResult MaglevGraphBuilder::VisitBinarySmiOperation() {
case BinaryOperationHint::kSignedSmallInputs:
case BinaryOperationHint::kNumber:
case BinaryOperationHint::kNumberOrOddball: {
- NodeType allowed_input_type =
- BinopHintToNodeTypeAndConversionType(feedback_hint);
+ NodeType assumed_input_type = BinopHintToAssumedInputType(feedback_hint);
if constexpr (BinaryOperationIsBitwiseInt32<kOperation>()) {
return BuildTruncatingInt32BinarySmiOperationNodeForToNumber<
- kOperation>(allowed_input_type);
+ kOperation>(assumed_input_type);
} else if (feedback_hint == BinaryOperationHint::kSignedSmall) {
if constexpr (kOperation == Operation::kExponentiate) {
// Exponentiate never updates the feedback to be a Smi.
@@ -2282,7 +2133,7 @@ ReduceResult MaglevGraphBuilder::VisitBinarySmiOperation() {
}
} else {
return BuildFloat64BinarySmiOperationNodeForToNumber<kOperation>(
- allowed_input_type);
+ assumed_input_type);
}
break;
}
@@ -2483,7 +2334,7 @@ ReduceResult MaglevGraphBuilder::VisitCompareOperation() {
return MaybeOddball(LoadRegister(0)) || MaybeOddball(GetAccumulator());
};
- auto GetConversionType = [](CompareOperationHint hint) {
+ auto GetAssumedInputType = [](CompareOperationHint hint) {
switch (hint) {
case CompareOperationHint::kNumber:
return NodeType::kNumber;
@@ -2549,10 +2400,10 @@ ReduceResult MaglevGraphBuilder::VisitCompareOperation() {
if (TryConstantFoldUint32ComparedToZero(left, right)) {
return ReduceResult::Done();
}
- auto allowed_input_type = GetConversionType(hint);
- GET_VALUE_OR_ABORT(left, GetFloat64ForToNumber(left, allowed_input_type));
+ auto assumed_input_type = GetAssumedInputType(hint);
+ GET_VALUE_OR_ABORT(left, GetFloat64ForToNumber(left, assumed_input_type));
GET_VALUE_OR_ABORT(right,
- GetFloat64ForToNumber(right, allowed_input_type));
+ GetFloat64ForToNumber(right, assumed_input_type));
if (left->Is<Float64Constant>() && right->Is<Float64Constant>()) {
double left_value = left->Cast<Float64Constant>()->value().get_scalar();
double right_value =
@@ -3026,7 +2877,7 @@ ReduceResult MaglevGraphBuilder::StoreAndCacheContextSlot(
unobserved_context_slot_stores_[key] = store;
} else {
if (known_node_aspects().may_have_aliasing_contexts() !=
- KnownNodeAspects::ContextSlotLoadsAlias::kYes) {
+ KnownNodeAspects::ContextSlotLoadsAlias::kAlways) {
auto last_store = unobserved_context_slot_stores_.find(key);
if (last_store != unobserved_context_slot_stores_.end()) {
MarkNodeDead(last_store->second);
@@ -4214,6 +4065,12 @@ ReduceResult MaglevGraphBuilder::BuildStoreFixedArrayElement(
// TODO(victorgomes): Support storing element to a virtual object. If we
// modify the elements array, we need to modify the original object to point
// to the new elements array.
+
+ // Unfortunately we need to check for empty types this late. If you think we
+ // can detect them earlier, have a look at
+ // test/mjsunit/maglev/regress-538884561-2.js.
+ ABORT_IF_EMPTY_TYPE(value);
+
if (CanElideWriteBarrier(elements, value)) {
return AddNewNode<StoreFixedArrayElementNoWriteBarrier>(
{elements, index, value});
@@ -4227,29 +4084,32 @@ ReduceResult MaglevGraphBuilder::BuildStoreFixedDoubleArrayElement(
ElementsKind elements_kind, ValueNode* elements, ValueNode* index,
ValueNode* value) {
// TODO(victorgomes): Support storing double element to a virtual object.
- if (value->value_representation() == ValueRepresentation::kHoleyFloat64) {
- DCHECK_EQ(elements_kind, HOLEY_DOUBLE_ELEMENTS);
- return AddNewNode<StoreFixedHoleyDoubleArrayElement>(
- {elements, index, value});
- }
- DCHECK_EQ(value->value_representation(), ValueRepresentation::kFloat64);
+ DCHECK(value->is_float64_or_holey_float64());
+ if (value->is_holey_float64()) {
+ if (value->MayBeHoleOrUndefinedNan()) {
+ // The value can be undefined. Both NaN patterns mean undefined here, but
+ // an array element only ever holds the undefined one, so the store
+ // rewrites the hole NaN into it.
+ DCHECK(IsHoleyElementsKind(elements_kind));
+ return AddNewNode<StoreFixedHoleyDoubleArrayElement>(
+ {elements, index, value});
+ }
+ value = AddNewNodeNoInputConversion<UnsafeHoleyFloat64ToFloat64>({value});
+ }
+ if (value->MayBeHoleOrUndefinedNan()) {
+ GET_VALUE_OR_ABORT(value, AddNewNode<Float64ToSilencedFloat64>({value}));
+ }
+ CHECK(!value->MayBeHoleOrUndefinedNan());
return AddNewNode<StoreFixedDoubleArrayElement>({elements, index, value});
}
ReduceResult MaglevGraphBuilder::BuildLoadHoleyFixedDoubleArrayElement(
ValueNode* elements, ValueNode* index, bool convert_hole) {
- if (convert_hole) {
- return AddNewNode<LoadHoleyFixedDoubleArrayElement>({elements, index});
- } else {
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- return AddNewNode<
- LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole>(
- {elements, index});
-#else
- return AddNewNode<LoadHoleyFixedDoubleArrayElementCheckedNotHole>(
- {elements, index});
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
- }
+ ValueNode* load;
+ GET_VALUE_OR_ABORT(
+ load, AddNewNode<LoadHoleyFixedDoubleArrayElement>({elements, index}));
+ if (convert_hole) return load;
+ return GetFloat64(load);
}
bool MaglevGraphBuilder::CanTreatHoleAsUndefined(
@@ -4631,7 +4491,10 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildStoreField(
if (access_info.IsFastDataConstant()) {
// Force conversion to Float64 to ensure we can check for hole NaN.
GET_VALUE_OR_ABORT(value, GetFloat64(value));
- GET_VALUE_OR_ABORT(value, GetSilencedNaN(value));
+ if (value->MayBeHoleOrUndefinedNan()) {
+ GET_VALUE_OR_ABORT(value,
+ AddNewNode<Float64ToSilencedFloat64>({value}));
+ }
}
if (access_info.HasTransitionMap()) {
// Allocate the mutable double box owned by the field.
@@ -4730,8 +4593,7 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildPropertyLoad(
lookup_start_object);
case compiler::PropertyAccessInfo::kModuleExport: {
ValueNode* cell = GetConstant(access_info.constant().value().AsCell());
- return BuildLoadTaggedField(cell, offsetof(Cell, maybe_value_),
- NodeType::kUnknown, false, name);
+ return BuildLoadTaggedField(cell, offsetof(Cell, maybe_value_));
}
case compiler::PropertyAccessInfo::kStringLength: {
DCHECK_EQ(receiver, lookup_start_object);
@@ -5058,9 +4920,7 @@ ReduceResult MaglevGraphBuilder::GetUint32ElementIndex(ValueNode* object) {
return object;
case ValueRepresentation::kFloat64:
- if (auto constant = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, object,
- TaggedToFloat64ConversionType::kOnlyNumber)) {
+ if (auto constant = TryGetFloat64Constant(object, NodeType::kNumber)) {
uint32_t uint32_value;
if (!DoubleToUint32IfEqualToSelf(constant->get_scalar(),
&uint32_value)) {
@@ -5094,8 +4954,8 @@ MaybeReduceResult MaglevGraphBuilder::TryBuildElementAccessOnString(
return {};
}
- RETURN_IF_DONE(TryReduceConstantStringAt(object, index_object,
- StringAtOOBMode::kElement));
+ RETURN_IF_DONE(reducer_.TryReduceConstantStringAt(object, index_object,
+ StringAtOOBMode::kElement));
// Ensure that {object} is actually a String.
RETURN_IF_ABORT(BuildCheckString(object));
@@ -5463,10 +5323,9 @@ ReduceResult MaglevGraphBuilder::BuildElementLoadOnJSArrayOrJSObject(
auto emit_load = [&]() -> ReduceResult {
ValueNode* result;
if (elements_kind == HOLEY_DOUBLE_ELEMENTS) {
- GET_VALUE_OR_ABORT(result, BuildLoadHoleyFixedDoubleArrayElement(
- elements_array, index,
- CanTreatHoleAsUndefined(maps) &&
- LoadModeHandlesHoles(load_mode)));
+ GET_VALUE_OR_ABORT(
+ result, BuildLoadHoleyFixedDoubleArrayElement(
+ elements_array, index, CanTreatHoleAsUndefined(maps)));
} else if (elements_kind == PACKED_DOUBLE_ELEMENTS) {
GET_VALUE_OR_ABORT(
result, BuildLoadFixedDoubleArrayElement(elements_array, index));
@@ -5529,20 +5388,10 @@ ReduceResult MaglevGraphBuilder::ConvertForStoring(ValueNode* value,
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
if (kind == ElementsKind::HOLEY_DOUBLE_ELEMENTS) {
value->MaybeRecordUseReprHint(UseRepresentation::kHoleyFloat64);
- ValueNode* value_hf64;
- GET_VALUE_OR_ABORT(value_hf64, GetHoleyFloat64(value));
- // We still have to convert hole nans to undefined nans for storing.
- GET_VALUE_OR_ABORT(
- value, AddNewNode<HoleyFloat64ConvertHoleToUndefined>({value_hf64}));
- return value;
+ return GetHoleyFloat64(value);
}
#endif // V8_ENABLE_UNDEFINED_DOUBLE
- // Make sure we do not store signalling NaNs into double arrays.
- // TODO(leszeks): Consider making this a bit on StoreFixedDoubleArrayElement
- // rather than a separate node.
- ValueNode* float64_value;
- GET_VALUE_OR_ABORT(float64_value, GetFloat64(value));
- return GetSilencedNaN(float64_value);
+ return GetFloat64(value);
}
if (IsSmiElementsKind(kind)) return GetSmiValue(value);
return value;
@@ -6373,20 +6222,14 @@ MaglevGraphBuilder::FindContinuationForPolymorphicPropertyLoadImpl() {
// side and the generic call on the other.
if (IsOffsetAMergePoint(offset)) return true;
- // We currently can't continue a polymorphic load across a peeled
- // loop header -- not because of any actual semantic reason, a peeled
- // loop should be just like straightline code, but just because this
- // iteration isn't compatible with the PeelLoop iteration.
+ // The continuation replays bytecodes without BuildBody's loop-header
+ // hook, so it must not span a loop header.
//
// TODO(leszeks): We could probably make loop peeling work happen on the
// JumpLoop rather than loop header, and then this continuation code
- // would work. Only for the first peeled iteration though, not for
- // speeling.
- if (loop_headers_to_peel_.Contains(offset)) return true;
-
- // Loop peeling should be the only reason there was no merge point for a
- // loop header.
- DCHECK(!bytecode_analysis_.IsLoopHeader(offset));
+ // would work for peeled loops. Only for the first peeled iteration
+ // though, not for speeling.
+ if (IsLoopHeader(offset)) return true;
// We can't currently continue a polymorphic load over a try-catch
// start/end -- again, not for any semantic reason, but just because
@@ -6506,15 +6349,6 @@ void MaglevGraphBuilder::AdvanceThroughContinuationForPolymorphicPropertyLoad(
}
}
-ReduceResult MaglevGraphBuilder::BuildLoadStringLength(ValueNode* string) {
- RETURN_IF_DONE(reducer_.TryReduceStringLength(string));
- ValueNode* result;
- GET_VALUE_OR_ABORT(result, AddNewNode<StringLength>({string}));
- reducer_.RecordKnownProperty(string, PropertyKey::StringLength(), result,
- true, compiler::AccessMode::kLoad);
- return result;
-}
-
template <typename GenericAccessFunc>
MaybeReduceResult MaglevGraphBuilder::TryBuildProxyPropertyAccess(
ValueNode* receiver, ValueNode* lookup_start_object, compiler::NameRef name,
@@ -6654,15 +6488,6 @@ ReduceResult MaglevGraphBuilder::VisitGetNamedProperty() {
AddNewNode<LoadNamedGeneric>({context, object}, name, feedback_source));
}
-MaybeReduceResult MaglevGraphBuilder::GetConstantSingleCharacterStringFromCode(
- uint16_t code) {
- // Only handle the one-byte character case, which accesses roots.
- if (code <= String::kMaxOneByteCharCode) {
- return GetRootConstant(RootsTable::SingleCharacterStringIndex(code));
- }
- return {};
-}
-
ReduceResult MaglevGraphBuilder::VisitGetNamedPropertyFromSuper() {
// GetNamedPropertyFromSuper <receiver> <name_index> <slot>
ValueNode* receiver = LoadRegister(0);
@@ -6769,7 +6594,7 @@ ReduceResult MaglevGraphBuilder::BuildGetKeyedProperty(
case compiler::ProcessedFeedback::kNamedAccess: {
ValueNode* key = GetAccumulator();
RETURN_IF_ABORT(BuildCheckInternalizedStringValueOrByReference(
- key, processed_feedback.AsNamedAccess().original_name_maybe_thin(),
+ key, processed_feedback.AsNamedAccess().name(),
DeoptimizeReason::kKeyedAccessChanged));
compiler::NameRef name = processed_feedback.AsNamedAccess().name();
@@ -6820,14 +6645,14 @@ ReduceResult MaglevGraphBuilder::VisitGetKeyedProperty() {
compiler::ProcessedFeedback::kElementAccess &&
processed_feedback->AsElementAccess().transition_groups().empty()) {
if (auto constant = TryGetConstant<Name>(GetAccumulator())) {
- compiler::NameRef name = constant.value();
// IsArrayIndex requires IsUniqueName, i.e. thin strings must be
- // unpacked. Subtle: Refine() still takes the original `name`.
- compiler::NameRef unpacked_name = name.UnpackIfThin(broker());
+ // unpacked.
+ compiler::NameRef unpacked_name =
+ constant.value().UnpackIfThin(broker());
if (unpacked_name.IsUniqueName() &&
!unpacked_name.object()->IsArrayIndex()) {
- processed_feedback =
- &processed_feedback->AsElementAccess().Refine(broker(), name);
+ processed_feedback = &processed_feedback->AsElementAccess().Refine(
+ broker(), unpacked_name);
}
}
}
@@ -7041,7 +6866,7 @@ ReduceResult MaglevGraphBuilder::VisitGetPrivateField() {
case compiler::ProcessedFeedback::kNamedAccess: {
RETURN_IF_ABORT(BuildCheckInternalizedStringValueOrByReference(
name.value(),
- processed_feedback.AsNamedAccess().original_name_maybe_thin(),
+ processed_feedback.AsNamedAccess().name(),
DeoptimizeReason::kKeyedAccessChanged));
compiler::NameRef name_ref = processed_feedback.AsNamedAccess().name();
@@ -7173,7 +6998,7 @@ ReduceResult MaglevGraphBuilder::BuildSetKeyedProperty(
case compiler::ProcessedFeedback::kNamedAccess: {
RETURN_IF_ABORT(BuildCheckInternalizedStringValueOrByReference(
- index, processed_feedback.AsNamedAccess().original_name_maybe_thin(),
+ index, processed_feedback.AsNamedAccess().name(),
DeoptimizeReason::kKeyedAccessChanged));
RETURN_IF_DONE(TryBuildNamedAccess(
@@ -8003,13 +7828,13 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayForEach(
if (!receiver) return {};
if (args.count() < 1) {
- FAIL(" to reduce Array.prototype.forEach - not enough arguments");
+ MAGLEV_FAIL(" to reduce Array.prototype.forEach - not enough arguments");
}
MapInference inference(this, receiver);
auto possible_maps = inference.TryGetPossibleMaps();
if (!possible_maps) {
- FAIL(" to reduce Array.prototype.forEach - receiver map is unknown");
+ MAGLEV_FAIL(" to reduce Array.prototype.forEach - receiver map is unknown");
}
// Map checks are inserted by TryReduceArrayIteratingBuiltin below, no need
@@ -8018,21 +7843,22 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayForEach(
ElementsKind elements_kind;
if (!CanInlineArrayIteratingBuiltin(broker(), *possible_maps,
&elements_kind)) {
- FAIL(
+ MAGLEV_FAIL(
" to reduce Array.prototype.forEach - doesn't support fast array "
"iteration or incompatible maps");
}
// TODO(leszeks): May only be needed for holey elements kinds.
if (!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL(
+ MAGLEV_FAIL(
" to reduce Array.prototype.forEach - invalidated no elements "
"protector");
}
ValueNode* callback = args[0];
if (!callback->is_tagged()) {
- FAIL(" to reduce Array.prototype.forEach - callback is untagged value")
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.forEach - callback is untagged value")
}
auto get_lazy_deopt_scope =
@@ -8040,7 +7866,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayForEach(
ValueNode* callback, ValueNode* this_arg, ValueNode* index_int32,
ValueNode* next_index_int32, ValueNode* original_length) {
return LazyDeoptFrameScope(
- this, Builtin::kArrayForEachLoopLazyDeoptContinuation, target,
+ &reducer_, GetContext(),
+ Builtin::kArrayForEachLoopLazyDeoptContinuation, target,
base::VectorOf<ValueNode*>({receiver, callback, this_arg,
next_index_int32, original_length}));
};
@@ -8050,7 +7877,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayForEach(
ValueNode* callback, ValueNode* this_arg, ValueNode* index_int32,
ValueNode* next_index_int32, ValueNode* original_length) {
return EagerDeoptFrameScope(
- this, Builtin::kArrayForEachLoopEagerDeoptContinuation, target,
+ &reducer_, GetContext(),
+ Builtin::kArrayForEachLoopEagerDeoptContinuation, target,
base::VectorOf<ValueNode*>({receiver, callback, this_arg,
next_index_int32, original_length}));
};
@@ -8072,7 +7900,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayMap(
}
if (!broker()->dependencies()->DependOnArraySpeciesProtector()) {
- FAIL(
+ MAGLEV_FAIL(
" to reduce Array.prototype.map - invalidated array species "
"protector");
}
@@ -8128,7 +7956,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayMap(
ValueNode* original_length) {
DCHECK_NOT_NULL(result_array);
return LazyDeoptFrameScope(
- this, Builtin::kArrayMapLoopLazyDeoptContinuation, target,
+ &reducer_, GetContext(), Builtin::kArrayMapLoopLazyDeoptContinuation,
+ target,
base::VectorOf<ValueNode*>({receiver, callback, this_arg, result_array,
index_int32, original_length}));
};
@@ -8141,7 +7970,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayMap(
ValueNode* original_length) {
DCHECK_NOT_NULL(result_array);
return EagerDeoptFrameScope(
- this, Builtin::kArrayMapLoopEagerDeoptContinuation, target,
+ &reducer_, GetContext(), Builtin::kArrayMapLoopEagerDeoptContinuation,
+ target,
base::VectorOf<ValueNode*>({receiver, callback, this_arg, result_array,
next_index_int32, original_length}));
};
@@ -8174,33 +8004,35 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayIteratingBuiltin(
if (!receiver) return {};
if (args.count() < 1) {
- FAIL(" to reduce " << name << " - not enough arguments");
+ MAGLEV_FAIL(" to reduce " << name << " - not enough arguments");
}
MapInference inference(this, receiver);
auto possible_maps = inference.TryGetPossibleMaps();
if (!possible_maps) {
- FAIL(" to reduce " << name << " - receiver map is unknown");
+ MAGLEV_FAIL(" to reduce " << name << " - receiver map is unknown");
}
ElementsKind elements_kind;
if (!CanInlineArrayIteratingBuiltin(broker(), *possible_maps,
&elements_kind)) {
- FAIL(" to reduce "
- << name << " - doesn't support fast array iteration or incompatible"
- << " maps");
+ MAGLEV_FAIL(" to reduce "
+ << name
+ << " - doesn't support fast array iteration or incompatible"
+ << " maps");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
// TODO(leszeks): May only be needed for holey elements kinds.
if (!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL(" to reduce " << name << " - invalidated no elements protector");
+ MAGLEV_FAIL(" to reduce " << name
+ << " - invalidated no elements protector");
}
ValueNode* callback = args[0];
if (!callback->is_tagged()) {
- FAIL(" to reduce " << name << " - callback is untagged value");
+ MAGLEV_FAIL(" to reduce " << name << " - callback is untagged value");
}
ValueNode* this_arg =
@@ -8374,77 +8206,84 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayIteratingBuiltin(
// No need to finish the loop if this code is unreachable.
if (!result.IsDoneWithAbort()) {
- if (process_element_callback) {
- ValueNode* value = result.value();
- RETURN_IF_ABORT((*process_element_callback)(index_int32, value));
- }
-
- // If any of the receiver's maps were unstable maps, we have to re-check the
- // maps on each iteration, in case the callback changed them. That said, we
- // know that the maps are valid on the first iteration, so we can rotate the
- // check to _after_ the callback, and then elide it if the receiver maps are
- // still known to be valid (i.e. the known maps after the call are contained
- // inside the known maps before the call).
- bool recheck_maps_after_call = receiver_maps_were_unstable;
- if (recheck_maps_after_call) {
- // No need to recheck maps if there are known maps...
- MapInference inference_after_call(this, receiver);
- // ... for which no side effect has occurred after recording them...
- if (inference_after_call.all_maps_are_fresh()) {
- if (auto receiver_maps_after_call =
- inference_after_call.TryGetPossibleMaps()) {
- // ... and those known maps are equal to, or a subset of, the maps
- // before the call.
- recheck_maps_after_call =
- !receiver_maps_before_loop.contains(*receiver_maps_after_call);
+ ReduceResult loop_body_result = [&]() -> ReduceResult {
+ if (process_element_callback) {
+ ValueNode* value = result.value();
+ RETURN_IF_ABORT((*process_element_callback)(index_int32, value));
+ }
+
+ // If any of the receiver's maps were unstable maps, we have to re-check
+ // the maps on each iteration, in case the callback changed them. That
+ // said, we know that the maps are valid on the first iteration, so we can
+ // rotate the check to _after_ the callback, and then elide it if the
+ // receiver maps are still known to be valid (i.e. the known maps after
+ // the call are contained inside the known maps before the call).
+ bool recheck_maps_after_call = receiver_maps_were_unstable;
+ if (recheck_maps_after_call) {
+ // No need to recheck maps if there are known maps...
+ MapInference inference_after_call(this, receiver);
+ // ... for which no side effect has occurred after recording them...
+ if (inference_after_call.all_maps_are_fresh()) {
+ if (auto receiver_maps_after_call =
+ inference_after_call.TryGetPossibleMaps()) {
+ // ... and those known maps are equal to, or a subset of, the maps
+ // before the call.
+ recheck_maps_after_call =
+ !receiver_maps_before_loop.contains(*receiver_maps_after_call);
+ }
}
}
- }
- // Make sure to finish the loop if we eager deopt in the map check or index
- // check.
- const EagerDeoptFrameScope& eager_deopt_scope =
- get_eager_deopt_scope(target, receiver, callback, this_arg, index_int32,
- next_index_int32, original_length);
-
- if (recheck_maps_after_call) {
- // Build the CheckMap manually, since we're doing it with already known
- // maps rather than feedback, and we don't need to update known node
- // aspects or types since we're at the end of the loop anyway.
- bool emit_check_with_migration = std::any_of(
- receiver_maps_before_loop.begin(), receiver_maps_before_loop.end(),
- [](compiler::MapRef map) { return map.is_migration_target(); });
- if (emit_check_with_migration) {
- RETURN_IF_ABORT(AddNewNode<CheckMapsWithMigration>(
- {receiver}, receiver_maps_before_loop,
- CheckType::kOmitHeapObjectCheck));
- } else {
- RETURN_IF_ABORT(AddNewNode<CheckMaps>({receiver},
- receiver_maps_before_loop,
- CheckType::kOmitHeapObjectCheck));
+ // Make sure to finish the loop if we eager deopt in the map check or
+ // index check.
+ const EagerDeoptFrameScope& eager_deopt_scope =
+ get_eager_deopt_scope(target, receiver, callback, this_arg,
+ index_int32, next_index_int32, original_length);
+
+ if (recheck_maps_after_call) {
+ // Build the CheckMap manually, since we're doing it with already known
+ // maps rather than feedback, and we don't need to update known node
+ // aspects or types since we're at the end of the loop anyway.
+ bool emit_check_with_migration = std::any_of(
+ receiver_maps_before_loop.begin(), receiver_maps_before_loop.end(),
+ [](compiler::MapRef map) { return map.is_migration_target(); });
+ if (emit_check_with_migration) {
+ RETURN_IF_ABORT(AddNewNode<CheckMapsWithMigration>(
+ {receiver}, receiver_maps_before_loop,
+ CheckType::kOmitHeapObjectCheck));
+ } else {
+ RETURN_IF_ABORT(
+ AddNewNode<CheckMaps>({receiver}, receiver_maps_before_loop,
+ CheckType::kOmitHeapObjectCheck));
+ }
}
- }
- // Check if the index is still in bounds, in case the callback changed the
- // length.
- ValueNode* current_length;
- GET_VALUE_OR_ABORT(current_length, BuildLoadJSArrayLength(receiver));
- sub_builder.set(var_length, current_length);
+ // Check if the index is still in bounds, in case the callback changed the
+ // length.
+ ValueNode* current_length;
+ GET_VALUE_OR_ABORT(current_length, BuildLoadJSArrayLength(receiver));
+ sub_builder.set(var_length, current_length);
- // Reference compare the loaded length against the original length. If this
- // is the same value node, then we didn't have any side effects and didn't
- // clear the cached length.
- if (current_length != original_length) {
- RETURN_IF_ABORT(
- TryBuildCheckInt32Condition(original_length_int32, current_length,
- AssertCondition::kUnsignedLessThanEqual,
- DeoptimizeReason::kArrayLengthChanged));
- }
+ // Reference compare the loaded length against the original length. If
+ // this is the same value node, then we didn't have any side effects and
+ // didn't clear the cached length.
+ if (current_length != original_length) {
+ RETURN_IF_ABORT(
+ TryBuildCheckInt32Condition(original_length_int32, current_length,
+ AssertCondition::kUnsignedLessThanEqual,
+ DeoptimizeReason::kArrayLengthChanged));
+ }
+ return ReduceResult::Done();
+ }();
+ // loop_body_result is either Done or DoneWithAbort. An abort sets
+ // current_block to null, which GotoOrTrim and EndLoop below both handle --
+ // no explicit check needed.
+ USE(loop_body_result);
}
if (skip_call.has_value()) {
sub_builder.GotoOrTrim(&*skip_call);
- sub_builder.Bind(&*skip_call);
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&*skip_call));
}
sub_builder.set(var_index, next_index_int32);
@@ -8453,8 +8292,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayIteratingBuiltin(
// ```
// bind end
// ```
- sub_builder.Bind(&loop_end);
-
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&loop_end));
return ReduceResult::Done();
}
@@ -8462,12 +8300,56 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
+ // Don't inline Generator.prototype.next across native contexts.
+ if (target.native_context(broker()) != broker()->target_native_context()) {
+ return {};
+ }
+
ValueNode* receiver = args.receiver();
if (!receiver) return {};
- RETURN_IF_ABORT(BuildCheckInstanceType(receiver, NodeType::kJSGeneratorObject,
- JS_GENERATOR_OBJECT_TYPE,
- JS_GENERATOR_OBJECT_TYPE));
+ MapInference inference(this, receiver);
+ auto possible_maps = inference.TryGetPossibleMaps();
+ bool can_use_static_maps = false;
+ if (possible_maps && !possible_maps->is_empty()) {
+ can_use_static_maps = true;
+ for (compiler::MapRef map : *possible_maps) {
+ if (map.instance_type() != JS_GENERATOR_OBJECT_TYPE) {
+ can_use_static_maps = false;
+ break;
+ }
+ compiler::OptionalObjectRef ctor = map.GetConstructor(broker());
+ if (!ctor.has_value() || !ctor->IsJSFunction() ||
+ !ctor->AsJSFunction().native_context(broker()).equals(
+ target.native_context(broker()))) {
+ return {};
+ }
+ }
+ }
+
+ if (can_use_static_maps) {
+ RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
+ } else {
+ RETURN_IF_ABORT(BuildCheckInstanceType(
+ receiver, NodeType::kJSGeneratorObject, JS_GENERATOR_OBJECT_TYPE,
+ JS_GENERATOR_OBJECT_TYPE));
+
+ ValueNode* context;
+ GET_VALUE_OR_ABORT(
+ context,
+ BuildLoadTaggedField(receiver, offsetof(JSGeneratorObject, context_)));
+ ValueNode* context_map;
+ GET_VALUE_OR_ABORT(context_map, BuildLoadMap(context));
+ ValueNode* native_context;
+ GET_VALUE_OR_ABORT(
+ native_context,
+ BuildLoadTaggedField(
+ context_map,
+ offsetof(Map, constructor_or_back_pointer_or_native_context_)));
+ RETURN_IF_ABORT(BuildCheckValueByReference(native_context,
+ target.native_context(broker()),
+ DeoptimizeReason::kWrongValue));
+ }
ValueNode* continuation;
GET_VALUE_OR_ABORT(continuation,
@@ -8483,6 +8365,16 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
GetSmiConstant(JSGeneratorObject::kGeneratorExecuting);
ValueNode* next_constant = GetSmiConstant(JSGeneratorObject::kNext);
+ // If any of the constants have an empty type, we're in dead code, and the
+ // write barrier elision logic inside StoreTaggedFieldNoWriteBarrier will be
+ // confused. Bail out now. Ideally, this would be done inside
+ // BuildStoreTaggedFieldNoWriteBarrier, but in the code below we want to
+ // assert there won't be deopts after we've called into user code, and we have
+ // no way to distinguish an abort (reducer_.BuildAbort()) from a deopt.
+ ABORT_IF_EMPTY_TYPE(closed_constant);
+ ABORT_IF_EMPTY_TYPE(executing_constant);
+ ABORT_IF_EMPTY_TYPE(next_constant);
+
MaglevSubGraphBuilder::Label generator_already_closed(&subgraph, 1);
MaglevSubGraphBuilder::Label generator_finished(&subgraph, 1);
MaglevSubGraphBuilder::Label allocation_not_skipped(&subgraph, 1);
@@ -8517,7 +8409,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGeneratorPrototypeNext(
ValueNode* result;
{
LazyDeoptFrameScope lazy_deopt_scope(
- this, Builtin::kGeneratorPrototypeNextLazyDeoptContinuation, target,
+ &reducer_, GetContext(),
+ Builtin::kGeneratorPrototypeNextLazyDeoptContinuation, target,
base::VectorOf<ValueNode*>(
{GetRootConstant(RootIndex::kUndefinedValue), receiver,
GetRootConstant(RootIndex::kTheHoleValue)}));
@@ -8637,7 +8530,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayIteratorPrototypeNext(
if (!receiver->Is<InlinedAllocation>()) return {};
VirtualObject* iterator = receiver->Cast<InlinedAllocation>()->object();
if (!iterator->map() || !iterator->map()->IsJSArrayIteratorMap()) {
- FAIL("iterator is not a JS array iterator object");
+ MAGLEV_FAIL("iterator is not a JS array iterator object");
}
std::optional<MapInference> map_inference;
@@ -8677,7 +8570,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayIteratorPrototypeNext(
map_inference.emplace(this, iterated_object);
auto possible_maps = map_inference->TryGetPossibleMaps();
if (!possible_maps) {
- FAIL("iterated object is unknown");
+ MAGLEV_FAIL("iterated object is unknown");
}
for (compiler::MapRef map : *possible_maps) {
if (!process_map(map)) {
@@ -8710,11 +8603,11 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayIteratorPrototypeNext(
if (double_kind.has_value() && IsHoleyElementsKind(*double_kind) &&
!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL("no elements protector");
+ MAGLEV_FAIL("no elements protector");
}
if (tagged_kind.has_value() && IsHoleyElementsKind(*tagged_kind) &&
!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL("no elements protector");
+ MAGLEV_FAIL("no elements protector");
}
if (map_inference.has_value()) {
@@ -8911,512 +8804,121 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypeSlice(
return BuildCallBuiltin<Builtin::kCloneFastJSArray>({receiver});
}
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringFromCharCode(
+MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeStartsWith(
compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
- if (args.count() != 1) return {};
- ValueNode* value;
- GET_VALUE_OR_ABORT(
- value, GetTruncatedInt32ForToNumber(args[0], NodeType::kNumberOrOddball));
- return AddNewNode<BuiltinStringFromCharCode>({value});
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceConstantStringAt(
- ValueNode* receiver, ValueNode* index, StringAtOOBMode oob_mode) {
- auto constant_receiver = TryGetConstant<HeapObject>(receiver);
- if (!constant_receiver) return {};
- if (!constant_receiver->IsString()) {
- return reducer_.EmitUnconditionalDeopt(DeoptimizeReason::kNotAString);
- }
- compiler::StringRef string = constant_receiver->AsString();
- auto maybe_constant_index = TryGetInt32Constant(index);
- if (!maybe_constant_index) return {};
- int32_t constant_index = *maybe_constant_index;
-
- if (static_cast<uint32_t>(constant_index) >= string.length()) {
- switch (oob_mode) {
- case StringAtOOBMode::kElement:
- // For element access, a negative index triggers a named lookup rather
- // than an element lookup; when this is the case, we shouldn't be trying
- // to optimize an elements access at all, so deopt.
- if (constant_index < 0) {
- return reducer_.EmitUnconditionalDeopt(
- DeoptimizeReason::kOutOfBounds);
- }
- // Otherwise, this is hole-like access, so guard against elements on the
- // prototype to return undefined.
- if (broker()->dependencies()->DependOnNoElementsProtector()) {
- return GetRootConstant(RootIndex::kUndefinedValue);
- }
- // If the no elements protector is invalidated, unconditionally deopt.
- // This shouldn't trigger a deopt look because the feedback should
- // transition to megamorphic.
- return reducer_.EmitUnconditionalDeopt(DeoptimizeReason::kOutOfBounds);
- case StringAtOOBMode::kCharAt: {
- // OOB for charAt is always the empty string.
- return GetRootConstant(RootIndex::kempty_string);
- }
- }
- UNREACHABLE();
- }
- if (std::optional<uint16_t> value =
- string.GetChar(broker(), constant_index)) {
- return GetConstantSingleCharacterStringFromCode(*value);
- }
- return {};
-}
+ ValueNode* search_element =
+ args[0] ? args[0] : GetRootConstant(RootIndex::kundefined_string);
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeSubstring(
- compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall()) return {};
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
- if (args.count() != 1 && args.count() != 2) return {};
+ if (!NodeTypeIs(GetType(search_element), NodeType::kString)) return {};
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- RETURN_IF_ABORT(BuildCheckString(receiver));
+ ValueNode* start_arg = GetValueOrUndefined(args[1]);
+ ValueNode* start =
+ start_arg->IsUndefinedValue() ? GetInt32Constant(0) : start_arg;
- ValueNode* start_index = args[0];
- ValueNode* end_index;
- if (args.count() > 1) {
- end_index = args[1];
- } else {
- GET_VALUE_OR_ABORT(end_index, BuildLoadStringLength(receiver));
- }
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+ RETURN_IF_ABORT(BuildCheckSmi(start));
- ValueNode* zero = GetInt32Constant(0);
- ValueNode* length;
- GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
+ ValueNode* receiver_length;
+ GET_VALUE_OR_ABORT(receiver_length, BuildLoadStringLength(receiver));
+ // min(max(start, 0), receiver_length)
+ ValueNode* max_value;
+ GET_VALUE_OR_ABORT(max_value, BuildInt32Max(start, GetInt32Constant(0)));
+ ValueNode* min_value;
+ GET_VALUE_OR_ABORT(min_value, BuildInt32Min(max_value, receiver_length));
ValueNode* clamped_start;
- GET_VALUE_OR_ABORT(clamped_start, BuildInt32Max(start_index, zero));
- GET_VALUE_OR_ABORT(clamped_start, BuildInt32Min(clamped_start, length));
+ GET_VALUE_OR_ABORT(clamped_start, GetInt32(min_value));
- ValueNode* clamped_end;
- GET_VALUE_OR_ABORT(clamped_end, BuildInt32Max(end_index, zero));
- GET_VALUE_OR_ABORT(clamped_end, BuildInt32Min(clamped_end, length));
+ ValueNode* search_length;
+ GET_VALUE_OR_ABORT(search_length, BuildLoadStringLength(search_element));
- ValueNode* from;
- GET_VALUE_OR_ABORT(from, BuildInt32Min(clamped_start, clamped_end));
- ValueNode* to;
- GET_VALUE_OR_ABORT(to, BuildInt32Max(clamped_start, clamped_end));
- return AddNewNode<StringSubstring>({receiver, from, to});
-}
+ // TODO(all): Introduce a ForInt32 helper.
+ MaglevSubGraphBuilder sub_graph(this, 2);
+ MaglevSubGraphBuilder::Variable ret_val(0);
+ MaglevSubGraphBuilder::Variable var_i(1);
+ MaglevSubGraphBuilder::Label done(&sub_graph, 2, {&ret_val});
+ MaglevSubGraphBuilder::Label return_false(&sub_graph, 2);
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeCharAt(
- compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall({SpeculationMode::kDisallowBoundsCheckSpeculation})) {
- return {};
- }
+ // receiver_length - clamped_start < search_length
+ ValueNode* remaining;
+ GET_VALUE_OR_ABORT(
+ remaining, AddNewNode<Int32Subtract>({receiver_length, clamped_start}));
+ RETURN_IF_ABORT(sub_graph.GotoIfTrue<BranchIfInt32Compare>(
+ &return_false, {remaining, search_length}, Operation::kLessThan));
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- ValueNode* index;
- if (args.count() == 0) {
- // Index is the undefined object. ToIntegerOrInfinity(undefined) = 0.
- index = GetInt32Constant(0);
- } else {
- GET_VALUE_OR_ABORT(index, GetInt32ElementIndex(args[0]));
- }
- // Any other argument is ignored.
+ // i = 0
+ sub_graph.set(var_i, GetInt32Constant(0));
+ MaglevSubGraphBuilder::LoopLabel loop_header = sub_graph.BeginLoop({&var_i});
+ MaglevSubGraphBuilder::Label return_true(&sub_graph, 1);
- RETURN_IF_DONE(
- TryReduceConstantStringAt(receiver, index, StringAtOOBMode::kCharAt));
+ ValueNode* index_int32 = sub_graph.get(var_i);
- // Ensure that {receiver} is actually a String.
- RETURN_IF_ABORT(BuildCheckString(receiver));
- // And index is below length.
- ValueNode* length;
- GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
+ // if (i < search_length) continue; else exit loop
+ RETURN_IF_ABORT(sub_graph.GotoIfFalse<BranchIfInt32Compare>(
+ &return_true, {index_int32, search_length}, Operation::kLessThan));
- auto GetCharAt = [&]() -> ReduceResult {
- return AddNewNode<StringAt>({receiver, index});
- };
- if (reducer_.current_speculation_mode() ==
- SpeculationMode::kDisallowBoundsCheckSpeculation) {
- return Select(
- [&](BranchBuilder& builder) {
- // Do unsafe conversions of length and index into uint32, to do an
- // unsigned comparison. The index might actually be a negative signed
- // value, but this "unsafe" cast will still work, converting it into a
- // large unsigned value which compares greater than the length.
- return BuildBranchIfUint32Compare(
- builder, Operation::kLessThan,
- // 'index' and 'length' are both int32, so no input conversion is
- // needed.
- AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({index}),
- AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({length}));
- },
- [&]() -> ReduceResult { return GetCharAt(); },
- [&]() -> ReduceResult {
- return GetRootConstant(RootIndex::kempty_string);
- });
- }
+ // pos = clamped_start + i
+ ValueNode* pos;
+ GET_VALUE_OR_ABORT(pos, AddNewNode<Int32Add>({clamped_start, index_int32}));
- DCHECK_EQ(reducer_.current_speculation_mode(),
- SpeculationMode::kAllowSpeculation);
- RETURN_IF_ABORT(TryBuildCheckInt32Condition(
- index, length, AssertCondition::kUnsignedLessThan,
- DeoptimizeReason::kOutOfBounds));
- return GetCharAt();
+ // TODO(dmercadier): without static knowledge about maps shapes (which we
+ // probably don't have), BuildGetCharCodeAt generates fairly expensive code
+ // since it needs to handle all string shapes. It would be more efficient to
+ // have a pre-processing before the loop that computes a single linear buffer
+ // for each string (+ maybe an index, for SlicedString in particular), that's
+ // then accessed directly in the loop (cf StringPrepareForGetCodeUnit in
+ // Turboshaft). Here in particular, the loop doesn't contain anything that can
+ // trigger a GC, so this should be safe.
+ ValueNode* lhs_ch;
+ GET_VALUE_OR_ABORT(lhs_ch, BuildGetCharCodeAt(receiver, pos));
+ ValueNode* rhs_ch;
+ GET_VALUE_OR_ABORT(rhs_ch, BuildGetCharCodeAt(search_element, index_int32));
+ ValueNode* is_equal;
+ GET_VALUE_OR_ABORT(is_equal, BuildTaggedEqual(lhs_ch, rhs_ch));
+
+ // If chars are not equal, return false.
+ RETURN_IF_ABORT(sub_graph.GotoIfFalse<BranchIfRootConstant>(
+ &return_false, {is_equal}, RootIndex::kTrueValue));
+
+ // i++; goto loop_header
+ ValueNode* next_index_int32;
+ GET_VALUE_OR_ABORT(
+ next_index_int32,
+ AddNewNode<Int32Add>({sub_graph.get(var_i), GetInt32Constant(1)}));
+ sub_graph.set(var_i, next_index_int32);
+ sub_graph.EndLoop(&loop_header);
+
+ sub_graph.Bind(&return_true);
+ sub_graph.set(ret_val, GetRootConstant(RootIndex::kTrueValue));
+ sub_graph.Goto(&done);
+
+ sub_graph.Bind(&return_false);
+ sub_graph.set(ret_val, GetRootConstant(RootIndex::kFalseValue));
+ sub_graph.Goto(&done);
+
+ sub_graph.Bind(&done);
+ return sub_graph.get(ret_val);
}
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeCharCodeAt(
+MaybeReduceResult MaglevGraphBuilder::TryReduceDataViewPrototypeGetByteLength(
compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall({SpeculationMode::kDisallowBoundsCheckSpeculation})) {
+ // We cannot check CanSpeculateCall here, since this is a getter.
+
+ if (!broker()->dependencies()->DependOnArrayBufferDetachingProtector()) {
+ // TODO(victorgomes): Add checks whether the array has been detached.
return {};
}
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- ValueNode* index;
- if (args.count() == 0) {
- // Index is the undefined object. ToIntegerOrInfinity(undefined) = 0.
- index = GetInt32Constant(0);
- } else {
- GET_VALUE_OR_ABORT(index, GetInt32ElementIndex(args[0]));
- }
- // Any other argument is ignored.
-
- // Try to constant-fold if receiver and index are constant
- if (auto cst = TryGetConstant<String>(receiver)) {
- if (index->Is<Int32Constant>()) {
- int idx = index->Cast<Int32Constant>()->value();
- if (idx >= 0 && static_cast<uint32_t>(idx) < cst->length()) {
- if (std::optional<uint16_t> value = cst->GetChar(broker(), idx)) {
- return GetSmiConstant(*value);
- }
- }
- }
- }
-
- // Ensure that {receiver} is actually a String.
- RETURN_IF_ABORT(BuildCheckString(receiver));
- // And index is below length.
- ValueNode* length;
- GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
-
- if (reducer_.current_speculation_mode() ==
- SpeculationMode::kDisallowBoundsCheckSpeculation) {
- return Select(
- [&](BranchBuilder& builder) {
- // Do unsafe conversions of length and index into uint32, to do an
- // unsigned comparison. The index might actually be a negative signed
- // value, but this "unsafe" cast will still work, converting it into a
- // large unsigned value which compares greater than the length.
- return BuildBranchIfUint32Compare(
- builder, Operation::kLessThan,
- // 'index' and 'length' are both int32, so no input conversion is
- // needed.
- AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({index}),
- AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({length}));
- },
- [&]() -> ReduceResult { return BuildGetCharCodeAt(receiver, index); },
- [&]() -> ReduceResult {
- return GetRootConstant(RootIndex::kNanValue);
- });
- }
-
- RETURN_IF_ABORT(TryBuildCheckInt32Condition(
- index, length, AssertCondition::kUnsignedLessThan,
- DeoptimizeReason::kOutOfBounds));
- return BuildGetCharCodeAt(receiver, index);
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeCodePointAt(
- compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall({SpeculationMode::kDisallowBoundsCheckSpeculation})) {
- return {};
- }
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- ValueNode* index;
- if (args.count() == 0) {
- // Index is the undefined object. ToIntegerOrInfinity(undefined) = 0.
- index = GetInt32Constant(0);
- } else {
- GET_VALUE_OR_ABORT(index, GetInt32ElementIndex(args[0]));
- }
- // Any other argument is ignored.
- // Ensure that {receiver} is actually a String.
- RETURN_IF_ABORT(BuildCheckString(receiver));
- // And index is below length.
- ValueNode* length;
- GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
-
- auto GetCodePointAt = [&]() -> ReduceResult {
- return AddNewNode<BuiltinStringPrototypeCharCodeOrCodePointAt>(
- {receiver, index},
- BuiltinStringPrototypeCharCodeOrCodePointAt::kCodePointAt);
- };
-
- if (reducer_.current_speculation_mode() ==
- SpeculationMode::kDisallowBoundsCheckSpeculation) {
- return Select(
- [&](BranchBuilder& builder) {
- // Do unsafe conversions of length and index into uint32, to do an
- // unsigned comparison. The index might actually be a negative signed
- // value, but this "unsafe" cast will still work, converting it into a
- // large unsigned value which compares greater than the length.
- return BuildBranchIfUint32Compare(
- builder, Operation::kLessThan,
- // 'index' and 'length' are both int32, so no input conversion is
- // needed.
- AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({index}),
- AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({length}));
- },
- [&]() -> ReduceResult { return GetCodePointAt(); },
- [&]() -> ReduceResult {
- return GetRootConstant(RootIndex::kUndefinedValue);
- });
- }
-
- RETURN_IF_ABORT(TryBuildCheckInt32Condition(
- index, length, AssertCondition::kUnsignedLessThan,
- DeoptimizeReason::kOutOfBounds));
- return GetCodePointAt();
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeSlice(
- compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall()) return {};
-
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- // Ensure that {receiver} is actually a String.
- RETURN_IF_ABORT(BuildCheckString(receiver));
-
- if (args.count() == 1) {
- // Reduce slice(-1).
- if (std::optional<int32_t> index_const = TryGetInt32Constant(args[0]);
- index_const && *index_const == -1) {
- ValueNode* receiver_length;
- GET_VALUE_OR_ABORT(receiver_length, BuildLoadStringLength(receiver));
-
- return Select(
- [&](BranchBuilder& builder) {
- return BuildBranchIfInt32Compare(builder, Operation::kEqual,
- receiver_length,
- GetInt32Constant(0));
- },
- [&] { return GetRootConstant(RootIndex::kempty_string); },
- [&] {
- ValueNode* index_last;
- // TODO(marja): Consider TryReduceConstantStringAt.
- GET_VALUE_OR_ABORT(index_last,
- AddNewNode<Int32Subtract>(
- {receiver_length, GetInt32Constant(1)}));
- return AddNewNode<StringAt>({receiver, index_last});
- });
- }
- }
-
- ValueNode* start_index;
- bool start_is_undefined = false;
- if (args.count() >= 1) {
- if (RootConstant* root_cst = args[0]->TryCast<RootConstant>()) {
- start_is_undefined = (root_cst->index() == RootIndex::kUndefinedValue);
- }
- }
- if (args.count() == 0 || start_is_undefined) {
- start_index = GetInt32Constant(0);
- } else {
- GET_VALUE_OR_ABORT(start_index, GetInt32(args[0]));
- }
-
- ValueNode* end_index;
- bool end_is_undefined = false;
- if (args.count() >= 2) {
- if (RootConstant* root_cst = args[1]->TryCast<RootConstant>()) {
- end_is_undefined = (root_cst->index() == RootIndex::kUndefinedValue);
- }
- }
- if (args.count() < 2 || end_is_undefined) {
- // Use String::kMaxLength as sentinel, as it is >= receiver.length it
- // will be set to receiver.length when the node is lowered. This avoids
- // loading the string length here.
- end_index = GetInt32Constant(String::kMaxLength);
- } else {
- GET_VALUE_OR_ABORT(end_index, GetInt32(args[1]));
- }
-
- return AddNewNode<StringSlice>({receiver, start_index, end_index});
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeIndexOfIncludes(
- CallArguments& args, bool is_includes) {
- if (!CanSpeculateCall()) return {};
-
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- RETURN_IF_ABORT(BuildCheckString(receiver));
-
- ValueNode* search_element =
- args.count() > 0 ? args[0]
- : GetRootConstant(RootIndex::kundefined_string);
- RETURN_IF_ABORT(BuildCheckString(search_element));
-
- ValueNode* start = args.count() > 1 ? args[1] : GetInt32Constant(0);
- ValueNode* receiver_length;
- GET_VALUE_OR_ABORT(receiver_length, BuildLoadStringLength(receiver));
-
- // min(max(start, 0), receiver_length)
- ValueNode* max_value;
- GET_VALUE_OR_ABORT(max_value, BuildInt32Max(start, GetInt32Constant(0)));
- ValueNode* clamped_start;
- GET_VALUE_OR_ABORT(clamped_start, BuildInt32Min(max_value, receiver_length));
-
- // TODO(496266449): Change StringIndexOf value representation type to
- // kSmi and remove this GetSmiValue call.
- ValueNode* clamped_start_smi;
- GET_VALUE_OR_ABORT(clamped_start_smi, GetSmiValue(clamped_start));
-
- ValueNode* result;
- GET_VALUE_OR_ABORT(
- result,
- AddNewNode<StringIndexOf>({receiver, search_element, clamped_start_smi}));
-
- if (is_includes) {
- return AddNewNode<Int32Compare>({result, GetInt32Constant(0)},
- Operation::kGreaterThanOrEqual);
- } else {
- return result;
- }
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeIndexOf(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryReduceStringPrototypeIndexOfIncludes(args, false);
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeIncludes(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryReduceStringPrototypeIndexOfIncludes(args, true);
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeStartsWith(
- compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall()) return {};
-
- ValueNode* search_element =
- args[0] ? args[0] : GetRootConstant(RootIndex::kundefined_string);
-
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
-
- if (!NodeTypeIs(GetType(search_element), NodeType::kString)) return {};
-
- ValueNode* start_arg = GetValueOrUndefined(args[1]);
- ValueNode* start =
- start_arg->IsUndefinedValue() ? GetInt32Constant(0) : start_arg;
-
- RETURN_IF_ABORT(BuildCheckString(receiver));
- RETURN_IF_ABORT(BuildCheckSmi(start));
-
- ValueNode* receiver_length;
- GET_VALUE_OR_ABORT(receiver_length, BuildLoadStringLength(receiver));
-
- // min(max(start, 0), receiver_length)
- ValueNode* max_value;
- GET_VALUE_OR_ABORT(max_value, BuildInt32Max(start, GetInt32Constant(0)));
- ValueNode* min_value;
- GET_VALUE_OR_ABORT(min_value, BuildInt32Min(max_value, receiver_length));
- ValueNode* clamped_start;
- GET_VALUE_OR_ABORT(clamped_start, GetInt32(min_value));
-
- ValueNode* search_length;
- GET_VALUE_OR_ABORT(search_length, BuildLoadStringLength(search_element));
-
- // TODO(all): Introduce a ForInt32 helper.
- MaglevSubGraphBuilder sub_graph(this, 2);
- MaglevSubGraphBuilder::Variable ret_val(0);
- MaglevSubGraphBuilder::Variable var_i(1);
- MaglevSubGraphBuilder::Label done(&sub_graph, 2, {&ret_val});
- MaglevSubGraphBuilder::Label return_false(&sub_graph, 2);
-
- // receiver_length - clamped_start < search_length
- ValueNode* remaining;
- GET_VALUE_OR_ABORT(
- remaining, AddNewNode<Int32Subtract>({receiver_length, clamped_start}));
- RETURN_IF_ABORT(sub_graph.GotoIfTrue<BranchIfInt32Compare>(
- &return_false, {remaining, search_length}, Operation::kLessThan));
-
- // i = 0
- sub_graph.set(var_i, GetInt32Constant(0));
- MaglevSubGraphBuilder::LoopLabel loop_header = sub_graph.BeginLoop({&var_i});
- MaglevSubGraphBuilder::Label return_true(&sub_graph, 1);
-
- ValueNode* index_int32 = sub_graph.get(var_i);
-
- // if (i < search_length) continue; else exit loop
- RETURN_IF_ABORT(sub_graph.GotoIfFalse<BranchIfInt32Compare>(
- &return_true, {index_int32, search_length}, Operation::kLessThan));
-
- // pos = clamped_start + i
- ValueNode* pos;
- GET_VALUE_OR_ABORT(pos, AddNewNode<Int32Add>({clamped_start, index_int32}));
-
- // TODO(dmercadier): without static knowledge about maps shapes (which we
- // probably don't have), BuildGetCharCodeAt generates fairly expensive code
- // since it needs to handle all string shapes. It would be more efficient to
- // have a pre-processing before the loop that computes a single linear buffer
- // for each string (+ maybe an index, for SlicedString in particular), that's
- // then accessed directly in the loop (cf StringPrepareForGetCodeUnit in
- // Turboshaft). Here in particular, the loop doesn't contain anything that can
- // trigger a GC, so this should be safe.
- ValueNode* lhs_ch;
- GET_VALUE_OR_ABORT(lhs_ch, BuildGetCharCodeAt(receiver, pos));
- ValueNode* rhs_ch;
- GET_VALUE_OR_ABORT(rhs_ch, BuildGetCharCodeAt(search_element, index_int32));
- ValueNode* is_equal;
- GET_VALUE_OR_ABORT(is_equal, BuildTaggedEqual(lhs_ch, rhs_ch));
-
- // If chars are not equal, return false.
- RETURN_IF_ABORT(sub_graph.GotoIfFalse<BranchIfRootConstant>(
- &return_false, {is_equal}, RootIndex::kTrueValue));
-
- // i++; goto loop_header
- ValueNode* next_index_int32;
- GET_VALUE_OR_ABORT(
- next_index_int32,
- AddNewNode<Int32Add>({sub_graph.get(var_i), GetInt32Constant(1)}));
- sub_graph.set(var_i, next_index_int32);
- sub_graph.EndLoop(&loop_header);
-
- sub_graph.Bind(&return_true);
- sub_graph.set(ret_val, GetRootConstant(RootIndex::kTrueValue));
- sub_graph.Goto(&done);
-
- sub_graph.Bind(&return_false);
- sub_graph.set(ret_val, GetRootConstant(RootIndex::kFalseValue));
- sub_graph.Goto(&done);
-
- sub_graph.Bind(&done);
- return sub_graph.get(ret_val);
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceStringPrototypeIterator(
- compiler::JSFunctionRef target, CallArguments& args) {
- if (!CanSpeculateCall()) return {};
- ValueNode* receiver = GetValueOrUndefined(args.receiver());
- // Ensure that {receiver} is actually a String.
- RETURN_IF_ABORT(BuildCheckString(receiver));
- compiler::MapRef map =
- broker()->target_native_context().initial_string_iterator_map(broker());
- VirtualObject* string_iterator =
- reducer_.CreateJSStringIterator(map, receiver);
- return reducer_.BuildInlinedAllocation(string_iterator,
- AllocationType::kYoung);
-}
-
-MaybeReduceResult MaglevGraphBuilder::TryReduceDataViewPrototypeGetByteLength(
- compiler::JSFunctionRef target, CallArguments& args) {
- // We cannot check CanSpeculateCall here, since this is a getter.
-
- if (!broker()->dependencies()->DependOnArrayBufferDetachingProtector()) {
- // TODO(victorgomes): Add checks whether the array has been detached.
- return {};
- }
- // TODO(victorgomes): Add data view to known types.
+ // TODO(victorgomes): Add data view to known types.
ValueNode* receiver = GetValueOrUndefined(args.receiver());
MapInference inference(this, receiver);
auto possible_receiver_maps = inference.TryGetPossibleMaps();
if (!possible_receiver_maps) {
- FAIL(" to reduce DataView.get byteLength - unknown receiver map");
+ MAGLEV_FAIL(" to reduce DataView.get byteLength - unknown receiver map");
}
// Don't optimize if any of the known maps is something else than a DataView
@@ -9592,6 +9094,405 @@ MaglevGraphBuilder::BuildJSArrayBuiltinMapSwitchOnElementsKind(
return any_successful ? ReduceResult::Done() : ReduceResult::DoneWithAbort();
}
+MaybeReduceResult MaglevGraphBuilder::TryReduceMapIteratorPrototypeNext(
+ compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceCollectionIteratorPrototypeNext(
+ target, args, CollectionKind::kMap, OrderedHashMap::kEntrySize,
+ RootIndex::kEmptyOrderedHashMap);
+}
+
+MaybeReduceResult MaglevGraphBuilder::TryReduceSetIteratorPrototypeNext(
+ compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceCollectionIteratorPrototypeNext(
+ target, args, CollectionKind::kSet, OrderedHashSet::kEntrySize,
+ RootIndex::kEmptyOrderedHashSet);
+}
+
+MaybeReduceResult MaglevGraphBuilder::TryReduceCollectionIteratorPrototypeNext(
+ compiler::JSFunctionRef target, CallArguments& args,
+ CollectionKind collection_kind, int entry_size,
+ RootIndex empty_collection_root) {
+ if (!CanSpeculateCall()) return {};
+ // The iterator result and the key-value array are built from this native
+ // context's maps, which is only correct if the callee's realm is ours.
+ if (!target.native_context(broker()).equals(
+ broker()->target_native_context())) {
+ MAGLEV_FAIL(" to reduce collection iterator next - cross-realm target");
+ }
+ ValueNode* receiver = args.receiver();
+ if (!receiver) return {};
+
+ // A bail inside the step reaches the caller as a failed reduction, so that
+ // the call falls back to the builtin.
+ return BuildCollectionIteratorStep(
+ receiver, collection_kind, entry_size, empty_collection_root,
+ [&](ValueNode* value, ValueNode* is_done) -> ReduceResult {
+ compiler::MapRef iter_result_map =
+ broker()->target_native_context().iterator_result_map(broker());
+ VirtualObject* iter_result =
+ reducer_.CreateJSIteratorResult(iter_result_map, value, is_done);
+ return reducer_.BuildInlinedAllocation(iter_result,
+ AllocationType::kYoung);
+ });
+}
+
+// Advances a Map/Set iterator by one entry, mirroring TurboFan's
+// JSCallReducer::ReduceCollectionIteratorPrototypeNext. {build_result} turns
+// the produced value and done flag into the result of the reduction, so a
+// for-of consumer can skip materializing a JSIteratorResult.
+MaybeReduceResult MaglevGraphBuilder::BuildCollectionIteratorStep(
+ ValueNode* receiver, CollectionKind collection_kind, int entry_size,
+ RootIndex empty_collection_root,
+ BuildIteratorStepResultCallback build_result) {
+ compiler::NativeContextRef native_context = broker()->target_native_context();
+ bool is_map_collection = collection_kind == CollectionKind::kMap;
+ // The iterator kinds of this native context, the common for-of kind first.
+ base::SmallVector<std::pair<InstanceType, compiler::MapRef>, 3> kind_maps;
+ if (is_map_collection) {
+ kind_maps = {{JS_MAP_KEY_VALUE_ITERATOR_TYPE,
+ native_context.map_key_value_iterator_map(broker())},
+ {JS_MAP_KEY_ITERATOR_TYPE,
+ native_context.map_key_iterator_map(broker())},
+ {JS_MAP_VALUE_ITERATOR_TYPE,
+ native_context.map_value_iterator_map(broker())}};
+ } else {
+ kind_maps = {{JS_SET_VALUE_ITERATOR_TYPE,
+ native_context.set_value_iterator_map(broker())},
+ {JS_SET_KEY_VALUE_ITERATOR_TYPE,
+ native_context.set_key_value_iterator_map(broker())}};
+ }
+
+ static_assert(OrderedHashMap::NextTableIndex() ==
+ OrderedHashSet::NextTableIndex());
+ static_assert(OrderedHashMap::NumberOfElementsIndex() ==
+ OrderedHashSet::NumberOfElementsIndex());
+ static_assert(OrderedHashMap::NumberOfDeletedElementsIndex() ==
+ OrderedHashSet::NumberOfDeletedElementsIndex());
+ static_assert(OrderedHashMap::NumberOfBucketsIndex() ==
+ OrderedHashSet::NumberOfBucketsIndex());
+ static_assert(OrderedHashMap::HashTableStartIndex() ==
+ OrderedHashSet::HashTableStartIndex());
+
+ MaglevSubGraphBuilder sub_builder(this, 4);
+ MaglevSubGraphBuilder::Variable var_index(0);
+ MaglevSubGraphBuilder::Variable var_value(1);
+ MaglevSubGraphBuilder::Variable var_done(2);
+ MaglevSubGraphBuilder::Variable var_kind(3);
+
+ // The kind is decided by comparing against {kind_maps}, so the receiver has
+ // to be one of them. Use its instance type statically when all possible maps
+ // agree; otherwise dispatch on the kind at runtime. The dynamic path is not a
+ // rare fallback: inside a resumable function nothing is known at the resume
+ // merge, and a site can be polymorphic in the iteration kind.
+ std::optional<InstanceType> static_instance_type;
+ bool kind_is_dynamic = false;
+
+ auto find_kind = [&](compiler::MapRef map) {
+ return std::find_if(
+ kind_maps.begin(), kind_maps.end(),
+ [&](auto& kind_map) { return map.equals(kind_map.second); });
+ };
+
+ if (InlinedAllocation* allocation = receiver->TryCast<InlinedAllocation>()) {
+ // A freshly allocated iterator (e.g. from an inlined entries() call)
+ // carries its map, and needs no check.
+ compiler::OptionalMapRef map = allocation->object()->map();
+ if (!map.has_value()) {
+ MAGLEV_FAIL(" to reduce collection iterator next - unknown receiver map");
+ }
+ auto kind_map = find_kind(*map);
+ if (kind_map == kind_maps.end()) {
+ MAGLEV_FAIL(
+ " to reduce collection iterator next - receiver is not an iterator "
+ "of this context");
+ }
+ static_instance_type = kind_map->first;
+ // The table transition below is a subgraph loop, which the virtual
+ // object tracking does not recognise as a loop: its loads would fold to
+ // the state from before the loop and never observe the stores on the
+ // backedge. Materialize the iterator so those become real memory
+ // accesses.
+ allocation->ForceEscaping();
+ } else if (MapInference inference(this, receiver);
+ auto possible_maps = inference.TryGetPossibleMaps()) {
+ if (possible_maps->is_empty()) {
+ return ReduceResult::DoneWithAbort();
+ }
+ for (compiler::MapRef map : *possible_maps) {
+ auto kind_map = find_kind(map);
+ if (kind_map == kind_maps.end()) {
+ MAGLEV_FAIL(
+ " to reduce collection iterator next - receiver is not an iterator "
+ "of this context");
+ }
+ if (!static_instance_type) {
+ static_instance_type = kind_map->first;
+ } else if (*static_instance_type != kind_map->first) {
+ kind_is_dynamic = true;
+ }
+ }
+ if (kind_is_dynamic) {
+ static_instance_type.reset();
+ }
+ RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
+ } else {
+ base::SmallVector<compiler::MapRef, 3> maps;
+ for (auto& [type, map] : kind_maps) maps.push_back(map);
+ RETURN_IF_ABORT(BuildCheckMaps(receiver, base::VectorOf(maps)));
+ kind_is_dynamic = true;
+ }
+
+ if (kind_is_dynamic) {
+ // The map is one of {kind_maps} by now, so the last kind needs no
+ // comparison of its own.
+ MaglevSubGraphBuilder::Label kind_determined(
+ &sub_builder, static_cast<int>(kind_maps.size()), {&var_kind});
+ ValueNode* receiver_map;
+ GET_VALUE_OR_ABORT(receiver_map, BuildLoadMap(receiver));
+ for (size_t i = 0; i + 1 < kind_maps.size(); i++) {
+ sub_builder.set(var_kind, GetInt32Constant(kind_maps[i].first));
+ RETURN_IF_ABORT(sub_builder.GotoIfTrue<BranchIfReferenceEqual>(
+ &kind_determined, {receiver_map, GetConstant(kind_maps[i].second)}));
+ }
+ sub_builder.set(var_kind, GetInt32Constant(kind_maps.back().first));
+ sub_builder.Goto(&kind_determined);
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&kind_determined));
+ // Without this the phi untagging inserts a CheckedSmiSizedInt32 at the
+ // kind comparisons below, which deopt after the index store.
+ RETURN_IF_ABORT(
+ reducer_.RecordType(sub_builder.get(var_kind), NodeType::kSmi));
+ }
+
+ // Transition the iterator to the latest table if there were mutations
+ // (rehash/shrink) while iterating: an obsolete table's number-of-elements
+ // slot is reused as the link to its replacement, so the hot path only
+ // checks that the slot still holds a Smi.
+ {
+ MaglevSubGraphBuilder::Label table_is_current(&sub_builder, 1);
+ MaglevSubGraphBuilder::LoopLabel heal_loop = sub_builder.BeginLoop({});
+ ValueNode* table;
+ GET_VALUE_OR_ABORT(
+ table,
+ BuildLoadTaggedField(receiver, offsetof(JSCollectionIterator, table_),
+ NodeType::kAnyHeapObject));
+ ValueNode* next_table;
+ GET_VALUE_OR_ABORT(
+ next_table,
+ AddNewNode<LoadFixedArrayElement>(
+ {table, GetInt32Constant(OrderedHashMap::NextTableIndex())},
+ LoadType::kUnknown));
+ RETURN_IF_ABORT(
+ sub_builder.GotoIfTrue<BranchIfSmi>(&table_is_current, {next_table}));
+ ValueNode* index;
+ GET_VALUE_OR_ABORT(
+ index,
+ BuildLoadTaggedField(receiver, offsetof(JSCollectionIterator, index_),
+ NodeType::kSmi));
+ // Nothing has been stored to the iterator yet, so the frame state attached
+ // to the call can safely re-execute next() from the beginning.
+ ValueNode* healed_index =
+ BuildCallBuiltin<Builtin::kOrderedHashTableHealIndex>({table, index});
+ RETURN_IF_ABORT(reducer_.RecordType(healed_index, NodeType::kSmi));
+ RETURN_IF_ABORT(BuildStoreTaggedField(
+ receiver, healed_index, offsetof(JSCollectionIterator, index_),
+ StoreTaggedMode::kDefault));
+ RETURN_IF_ABORT(BuildStoreTaggedField(
+ receiver, next_table, offsetof(JSCollectionIterator, table_),
+ StoreTaggedMode::kDefault));
+ sub_builder.EndLoop(&heal_loop);
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&table_is_current));
+ }
+
+ ValueNode* table;
+ GET_VALUE_OR_ABORT(
+ table,
+ BuildLoadTaggedField(receiver, offsetof(JSCollectionIterator, table_),
+ NodeType::kAnyHeapObject));
+ ValueNode* index_tagged;
+ GET_VALUE_OR_ABORT(
+ index_tagged,
+ BuildLoadTaggedField(receiver, offsetof(JSCollectionIterator, index_),
+ NodeType::kSmi));
+
+ ValueNode* number_of_buckets;
+ GET_VALUE_OR_ABORT(
+ number_of_buckets,
+ AddNewNode<LoadFixedArrayElement>(
+ {table, GetInt32Constant(OrderedHashMap::NumberOfBucketsIndex())},
+ LoadType::kSmi));
+ ValueNode* number_of_buckets_int32;
+ GET_VALUE_OR_ABORT(number_of_buckets_int32, GetInt32(number_of_buckets));
+ ValueNode* number_of_elements;
+ GET_VALUE_OR_ABORT(
+ number_of_elements,
+ AddNewNode<LoadFixedArrayElement>(
+ {table, GetInt32Constant(OrderedHashMap::NumberOfElementsIndex())},
+ LoadType::kSmi));
+ ValueNode* number_of_deleted;
+ GET_VALUE_OR_ABORT(
+ number_of_deleted,
+ AddNewNode<LoadFixedArrayElement>(
+ {table,
+ GetInt32Constant(OrderedHashMap::NumberOfDeletedElementsIndex())},
+ LoadType::kSmi));
+ ValueNode* number_of_elements_int32;
+ GET_VALUE_OR_ABORT(number_of_elements_int32, GetInt32(number_of_elements));
+ ValueNode* number_of_deleted_int32;
+ GET_VALUE_OR_ABORT(number_of_deleted_int32, GetInt32(number_of_deleted));
+ ValueNode* used_capacity;
+ GET_VALUE_OR_ABORT(used_capacity,
+ AddNewNode<Int32Add>(
+ {number_of_elements_int32, number_of_deleted_int32}));
+
+ int done_predecessors = static_instance_type.has_value()
+ ? 2
+ : 1 + static_cast<int>(kind_maps.size());
+ MaglevSubGraphBuilder::Label exhausted(&sub_builder, 1);
+ MaglevSubGraphBuilder::Label found(&sub_builder, 1);
+ MaglevSubGraphBuilder::Label done(&sub_builder, done_predecessors,
+ {&var_value, &var_done});
+
+ sub_builder.set(var_index, index_tagged);
+ sub_builder.set(var_value, GetRootConstant(RootIndex::kUndefinedValue));
+ sub_builder.set(var_done, GetBooleanConstant(true));
+
+ MaglevSubGraphBuilder::LoopLabel scan_loop =
+ sub_builder.BeginLoop({&var_index});
+ Phi* loop_index_tagged = sub_builder.get(var_index)->Cast<Phi>();
+ RETURN_IF_ABORT(reducer_.RecordType(loop_index_tagged, NodeType::kSmi));
+ ValueNode* loop_index;
+ GET_VALUE_OR_ABORT(loop_index, GetInt32(loop_index_tagged));
+ RETURN_IF_ABORT(sub_builder.GotoIfFalse<BranchIfInt32Compare>(
+ &exhausted, {loop_index, used_capacity}, Operation::kLessThan));
+
+ ValueNode* entry_times_size;
+ GET_VALUE_OR_ABORT(
+ entry_times_size,
+ AddNewNode<Int32Multiply>({loop_index, GetInt32Constant(entry_size)}));
+ ValueNode* entry_offset;
+ GET_VALUE_OR_ABORT(
+ entry_offset,
+ AddNewNode<Int32Add>({entry_times_size, number_of_buckets_int32}));
+ ValueNode* entry_start;
+ GET_VALUE_OR_ABORT(
+ entry_start,
+ AddNewNode<Int32Add>(
+ {entry_offset,
+ GetInt32Constant(OrderedHashMap::HashTableStartIndex())}));
+ ValueNode* entry_key;
+ GET_VALUE_OR_ABORT(entry_key, AddNewNode<LoadFixedArrayElement>(
+ {table, entry_start}, LoadType::kUnknown));
+ ValueNode* next_index;
+ GET_VALUE_OR_ABORT(next_index, AddNewNode<Int32Increment>({loop_index}));
+ RETURN_IF_ABORT(sub_builder.GotoIfFalse<BranchIfRootConstant>(
+ &found, {entry_key}, RootIndex::kHashTableHoleValue));
+ sub_builder.set(var_index, next_index);
+ sub_builder.EndLoop(&scan_loop);
+
+ {
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&found));
+ // No deopts are allowed after this store, since re-executing the builtin
+ // would advance the index a second time. The index is bounded by the
+ // table capacity, so it is Smi-sized and the store's input conversion
+ // tags it without a check.
+ RETURN_IF_ABORT(reducer_.RecordType(next_index, NodeType::kSmi));
+ RETURN_IF_ABORT(BuildStoreTaggedFieldNoWriteBarrier(
+ receiver, next_index, offsetof(JSCollectionIterator, index_),
+ StoreTaggedMode::kDefault));
+
+ auto load_entry_value = [&]() -> ReduceResult {
+ ValueNode* value_offset;
+ GET_VALUE_OR_ABORT(
+ value_offset,
+ AddNewNode<Int32Add>(
+ {entry_start, GetInt32Constant(OrderedHashMap::kValueOffset)}));
+ return AddNewNode<LoadFixedArrayElement>({table, value_offset},
+ LoadType::kUnknown);
+ };
+
+ sub_builder.set(var_done, GetBooleanConstant(false));
+ if (static_instance_type.has_value()) {
+ ValueNode* value = entry_key;
+ switch (*static_instance_type) {
+ case JS_MAP_KEY_ITERATOR_TYPE:
+ case JS_SET_VALUE_ITERATOR_TYPE:
+ break;
+ case JS_SET_KEY_VALUE_ITERATOR_TYPE:
+ GET_VALUE_OR_ABORT(
+ value, BuildAndAllocateKeyValueArray(entry_key, entry_key));
+ break;
+ case JS_MAP_VALUE_ITERATOR_TYPE:
+ case JS_MAP_KEY_VALUE_ITERATOR_TYPE: {
+ ValueNode* entry_value;
+ GET_VALUE_OR_ABORT(entry_value, load_entry_value());
+ value = entry_value;
+ if (*static_instance_type == JS_MAP_KEY_VALUE_ITERATOR_TYPE) {
+ GET_VALUE_OR_ABORT(
+ value, BuildAndAllocateKeyValueArray(entry_key, entry_value));
+ }
+ break;
+ }
+ default:
+ UNREACHABLE();
+ }
+ sub_builder.set(var_value, value);
+ sub_builder.Goto(&done);
+ } else if (is_map_collection) {
+ ValueNode* kind = sub_builder.get(var_kind);
+ // The for-of kind is the common one, so settle it with a single
+ // comparison.
+ MaglevSubGraphBuilder::Label not_key_value(&sub_builder, 1);
+ RETURN_IF_ABORT(sub_builder.GotoIfFalse<BranchIfInt32Compare>(
+ ¬_key_value,
+ {kind, GetInt32Constant(JS_MAP_KEY_VALUE_ITERATOR_TYPE)},
+ Operation::kEqual));
+ {
+ ValueNode* entry_value;
+ GET_VALUE_OR_ABORT(entry_value, load_entry_value());
+ ValueNode* pair;
+ GET_VALUE_OR_ABORT(
+ pair, BuildAndAllocateKeyValueArray(entry_key, entry_value));
+ sub_builder.set(var_value, pair);
+ sub_builder.Goto(&done);
+ }
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(¬_key_value));
+ sub_builder.set(var_value, entry_key);
+ RETURN_IF_ABORT(sub_builder.GotoIfTrue<BranchIfInt32Compare>(
+ &done, {kind, GetInt32Constant(JS_MAP_KEY_ITERATOR_TYPE)},
+ Operation::kEqual));
+ ValueNode* entry_value;
+ GET_VALUE_OR_ABORT(entry_value, load_entry_value());
+ sub_builder.set(var_value, entry_value);
+ sub_builder.Goto(&done);
+ } else {
+ ValueNode* kind = sub_builder.get(var_kind);
+ sub_builder.set(var_value, entry_key);
+ RETURN_IF_ABORT(sub_builder.GotoIfTrue<BranchIfInt32Compare>(
+ &done, {kind, GetInt32Constant(JS_SET_VALUE_ITERATOR_TYPE)},
+ Operation::kEqual));
+ ValueNode* pair;
+ GET_VALUE_OR_ABORT(pair,
+ BuildAndAllocateKeyValueArray(entry_key, entry_key));
+ sub_builder.set(var_value, pair);
+ sub_builder.Goto(&done);
+ }
+ }
+
+ {
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&exhausted));
+ // Mark the iterator as exhausted, releasing the table.
+ RETURN_IF_ABORT(BuildStoreTaggedFieldNoWriteBarrier(
+ receiver, GetRootConstant(empty_collection_root),
+ offsetof(JSCollectionIterator, table_), StoreTaggedMode::kDefault));
+ sub_builder.set(var_value, GetRootConstant(RootIndex::kUndefinedValue));
+ sub_builder.set(var_done, GetBooleanConstant(true));
+ sub_builder.Goto(&done);
+ }
+
+ RETURN_IF_ABORT(sub_builder.TrimPredecessorsAndBind(&done));
+ return build_result(sub_builder.get(var_value), sub_builder.get(var_done));
+}
+
MaybeReduceResult MaglevGraphBuilder::TryReduceMapPrototypeGet(
compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
@@ -9605,10 +9506,10 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceMapPrototypeGet(
}
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
- FAIL(" to reduce Map.prototype.Get - no receiver");
+ MAGLEV_FAIL(" to reduce Map.prototype.Get - no receiver");
}
if (args.count() != 1) {
- FAIL(" to reduce Map.prototype.Get - invalid argument count");
+ MAGLEV_FAIL(" to reduce Map.prototype.Get - invalid argument count");
}
ValueNode* receiver = GetValueOrUndefined(args.receiver());
@@ -9617,7 +9518,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceMapPrototypeGet(
// If the map set is not found, then we don't know anything about the map of
// the receiver, so bail.
if (!possible_receiver_maps) {
- FAIL(" to reduce Map.prototype.Get - unknown receiver map");
+ MAGLEV_FAIL(" to reduce Map.prototype.Get - unknown receiver map");
}
// If the set of possible maps is empty, then there's no possible map for this
@@ -9631,7 +9532,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceMapPrototypeGet(
}
if (!AllOfInstanceTypesAre(*possible_receiver_maps, JS_MAP_TYPE)) {
- FAIL(" to reduce Map.prototype.Get - wrong receiver maps");
+ MAGLEV_FAIL(" to reduce Map.prototype.Get - wrong receiver maps");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
@@ -9662,17 +9563,17 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceWeakMapPrototypeGet(
if (!is_turbolev()) return {};
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
- FAIL(" to reduce WeakMap.prototype.Get - no receiver");
+ MAGLEV_FAIL(" to reduce WeakMap.prototype.Get - no receiver");
}
if (args.count() != 1) {
- FAIL(" to reduce WeakMap.prototype.Get - invalid argument count");
+ MAGLEV_FAIL(" to reduce WeakMap.prototype.Get - invalid argument count");
}
ValueNode* receiver = GetValueOrUndefined(args.receiver());
MapInference inference(this, receiver);
auto possible_receiver_maps = inference.TryGetPossibleMaps();
if (!possible_receiver_maps) {
- FAIL(" to reduce WeakMap.prototype.Get - unknown receiver map");
+ MAGLEV_FAIL(" to reduce WeakMap.prototype.Get - unknown receiver map");
}
if (possible_receiver_maps->is_empty()) {
@@ -9680,7 +9581,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceWeakMapPrototypeGet(
}
if (!AllOfInstanceTypesAre(*possible_receiver_maps, JS_WEAK_MAP_TYPE)) {
- FAIL(" to reduce WeakMap.prototype.Get - wrong receiver maps");
+ MAGLEV_FAIL(" to reduce WeakMap.prototype.Get - wrong receiver maps");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
@@ -9703,13 +9604,13 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceSetPrototypeHas(
if (!receiver) return {};
if (args.count() != 1) {
- FAIL(" to reduce Set.prototype.has - invalid argument count");
+ MAGLEV_FAIL(" to reduce Set.prototype.has - invalid argument count");
}
MapInference inference(this, receiver);
auto possible_receiver_maps = inference.TryGetPossibleMaps();
if (!possible_receiver_maps) {
- FAIL(" to reduce Set.prototype.has - receiver map is unknown");
+ MAGLEV_FAIL(" to reduce Set.prototype.has - receiver map is unknown");
}
// If the set of possible maps is empty, then there's no possible map for this
@@ -9723,7 +9624,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceSetPrototypeHas(
}
if (!AllOfInstanceTypesAre(*possible_receiver_maps, JS_SET_TYPE)) {
- FAIL(" to reduce Set.prototype.has - wrong receiver maps");
+ MAGLEV_FAIL(" to reduce Set.prototype.has - wrong receiver maps");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
@@ -9781,20 +9682,20 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypeSort(
if (!receiver) return {};
if (args.count() < 1) {
- FAIL(" to reduce Array.prototype.sort - no comparefn provided");
+ MAGLEV_FAIL(" to reduce Array.prototype.sort - no comparefn provided");
}
// Require the receiver to have known maps that support fast array iteration.
MapInference inference(this, receiver);
auto possible_maps = inference.TryGetPossibleMaps();
if (!possible_maps) {
- FAIL(" to reduce Array.prototype.sort - unknown receiver maps");
+ MAGLEV_FAIL(" to reduce Array.prototype.sort - unknown receiver maps");
}
ElementsKind elements_kind;
if (!CanInlineArrayIteratingBuiltin(broker(), *possible_maps,
&elements_kind)) {
- FAIL(
+ MAGLEV_FAIL(
" to reduce Array.prototype.sort - elements kind does not support fast"
" array iteration");
}
@@ -9806,25 +9707,29 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypeSort(
[&](compiler::MapRef map) {
return map.elements_kind() != elements_kind;
})) {
- FAIL(" to reduce Array.prototype.sort - receiver elements kinds disagree");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.sort - receiver elements kinds disagree");
}
// Holey arrays require holes to be moved to the end of the sorted result
// (ECMA-262 23.1.3.30 step 5, skip-holes mode). The insertion sort does
// not implement this, so bail out for any holey kind.
if (IsHoleyElementsKind(elements_kind)) {
- FAIL(" to reduce Array.prototype.sort - holey elements not supported");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.sort - holey elements not supported");
}
// See the comment at the top of this function for why PACKED_DOUBLE is
// not handled (FixedDoubleArray <-> FixedArray bridging on the deopt
// continuation path).
if (IsDoubleElementsKind(elements_kind)) {
- FAIL(" to reduce Array.prototype.sort - PACKED_DOUBLE not supported");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.sort - PACKED_DOUBLE not supported");
}
if (!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL(" to reduce Array.prototype.sort - no elements protector invalid");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.sort - no elements protector invalid");
}
// Require comparefn to be a statically-known interpreted JSFunction.
@@ -9842,13 +9747,13 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypeSort(
} else if (auto* cc = comparefn->TryCast<CreateClosure>()) {
comparefn_shared = cc->shared_function_info();
} else {
- FAIL(
+ MAGLEV_FAIL(
" to reduce Array.prototype.sort - comparefn is not a statically-known"
" function");
}
if (!comparefn_shared->HasBytecodeArray()) {
- FAIL(" to reduce Array.prototype.sort - comparefn has no bytecode");
+ MAGLEV_FAIL(" to reduce Array.prototype.sort - comparefn has no bytecode");
}
// All static preconditions satisfied. Commit the reduction.
@@ -9961,8 +9866,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypeSort(
// spec's _items_ snapshot and writes back originalLength elements,
// independent of any cmp side effects on the receiver.
EagerDeoptFrameScope eager_deopt_scope(
- this, Builtin::kArraySortContinueFromSnapshotEagerDeoptContinuation,
- target,
+ &reducer_, GetContext(),
+ Builtin::kArraySortContinueFromSnapshotEagerDeoptContinuation, target,
base::VectorOf<ValueNode*>({receiver, comparefn, temp_array, length}));
MaglevSubGraphBuilder::Label outer_end(&sub_builder, 1);
@@ -10038,8 +9943,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypeSort(
// the inner-loop body below). The continuation feeds temp_array and
// the original length to the generic PowerSort tail.
LazyDeoptFrameScope restart_sort(
- this, Builtin::kArraySortContinueFromSnapshotLazyDeoptContinuation,
- target,
+ &reducer_, GetContext(),
+ Builtin::kArraySortContinueFromSnapshotLazyDeoptContinuation, target,
base::VectorOf<ValueNode*>(
{receiver, comparefn, temp_array, length}));
@@ -10198,11 +10103,11 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
if (!CanSpeculateCall()) return {};
// We can't reduce Function#call when there is no receiver function.
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
- FAIL(" to reduce Array.prototype.push - no receiver");
+ MAGLEV_FAIL(" to reduce Array.prototype.push - no receiver");
}
if (args.count() == 0) {
- FAIL(" to reduce Array.prototype.push - no argument");
+ MAGLEV_FAIL(" to reduce Array.prototype.push - no argument");
}
ValueNode* receiver = GetValueOrUndefined(args.receiver());
@@ -10211,7 +10116,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
// If the map set is not found, then we don't know anything about the map of
// the receiver, so bail.
if (!possible_maps) {
- FAIL(" to reduce Array.prototype.push - unknown receiver map");
+ MAGLEV_FAIL(" to reduce Array.prototype.push - unknown receiver map");
}
// If the set of possible maps is empty, then there's no possible map for this
@@ -10225,7 +10130,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
}
if (!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL(" to reduce Array.prototype.push - NoElementsProtector invalidated");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.push - NoElementsProtector invalidated");
}
// Check that inlining resizing array builtins is supported and group maps
@@ -10250,7 +10156,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
if (!CanInlineArrayResizingBuiltin(broker(), *possible_maps, map_kinds,
elements_kind_to_index, &unique_kind_count,
false)) {
- FAIL(" to reduce Array.prototype.push - Map doesn't support fast resizing");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.push - Map doesn't support fast resizing");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
@@ -10288,9 +10195,13 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
{old_array_length,
GetInt32Constant(static_cast<int>(args.count()))}));
- ValueNode* last_index;
- GET_VALUE_OR_ABORT(last_index,
- AddNewNode<Int32Decrement>({new_array_length}));
+ // The last element will be stored at index old_length + count - 1, which
+ // for the common single-argument push is just the old length.
+ ValueNode* last_index = old_array_length;
+ if (args.count() > 1) {
+ GET_VALUE_OR_ABORT(last_index,
+ AddNewNode<Int32Decrement>({new_array_length}));
+ }
ValueNode* elements_array;
GET_VALUE_OR_ABORT(elements_array, BuildLoadElements(receiver));
@@ -10345,10 +10256,14 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePush(
for (int index = 0; index < static_cast<int>(args_to_store.size());
index++) {
- ValueNode* store_index;
- GET_VALUE_OR_ABORT(
- store_index,
- AddNewNode<Int32Add>({old_array_length, GetInt32Constant(index)}));
+ // The element is stored at index old_length + index; don't emit an
+ // "old_length + 0" node for the first element.
+ ValueNode* store_index = old_array_length;
+ if (index != 0) {
+ GET_VALUE_OR_ABORT(
+ store_index,
+ AddNewNode<Int32Add>({old_array_length, GetInt32Constant(index)}));
+ }
ValueNode* value = args_to_store[index];
@@ -10384,7 +10299,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePop(
if (!CanSpeculateCall()) return {};
// We can't reduce Function#call when there is no receiver function.
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
- FAIL(" to reduce Array.prototype.pop - no receiver");
+ MAGLEV_FAIL(" to reduce Array.prototype.pop - no receiver");
}
ValueNode* receiver = GetValueOrUndefined(args.receiver());
@@ -10394,7 +10309,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePop(
// If the map set is not found, then we don't know anything about the map of
// the receiver, so bail.
if (!possible_maps) {
- FAIL(" to reduce Array.prototype.pop - unknown receiver map");
+ MAGLEV_FAIL(" to reduce Array.prototype.pop - unknown receiver map");
}
// If the set of possible maps is empty, then there's no possible map for this
@@ -10408,7 +10323,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePop(
}
if (!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL(" to reduce Array.prototype.pop - NoElementsProtector invalidated");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.pop - NoElementsProtector invalidated");
}
constexpr int max_kind_count = 4;
@@ -10448,7 +10364,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePop(
if (!CanInlineArrayResizingBuiltin(broker(), *possible_maps, map_kinds,
elements_kind_to_index, &unique_kind_count,
true)) {
- FAIL(" to reduce Array.prototype.pop - Map doesn't support fast resizing");
+ MAGLEV_FAIL(
+ " to reduce Array.prototype.pop - Map doesn't support fast resizing");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
@@ -10504,9 +10421,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceArrayPrototypePop(
if (IsDoubleElementsKind(kind)) {
GET_VALUE_OR_ABORT(value, BuildLoadFixedDoubleArrayElement(
writable_elements_array, new_array_length));
- RETURN_IF_ABORT(BuildStoreFixedDoubleArrayElement(
- kind, writable_elements_array, new_array_length,
- GetFloat64Constant(Float64::FromBits(kHoleNanInt64))));
+ RETURN_IF_ABORT(AddNewNode<StoreFixedDoubleArrayHole>(
+ {writable_elements_array, new_array_length}));
} else {
DCHECK(IsSmiElementsKind(kind) || IsObjectElementsKind(kind));
GET_VALUE_OR_ABORT(value, BuildLoadFixedArrayElement(
@@ -10834,6 +10750,10 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceStringConstructor(
MaybeReduceResult MaglevGraphBuilder::TryReduceBuiltin(
compiler::JSFunctionRef target, compiler::SharedFunctionInfoRef shared,
CallArguments& args, const compiler::FeedbackSource& feedback_source) {
+ if (V8_UNLIKELY(v8_flags.maglev_disable_builtin_reducers)) return {};
+ if (target.native_context(broker()) != broker()->target_native_context()) {
+ return {};
+ }
if (args.mode() != CallArguments::kDefault) {
// TODO(victorgomes): Maybe inline the spread stub? Or call known function
// directly if arguments list is an array.
@@ -10843,8 +10763,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceBuiltin(
if (!shared.HasBuiltinId()) return {};
TRACE(" ! Trying to reduce builtin " << Builtins::name(shared.builtin_id()));
// First try the builtins that have been migrated to MaglevReducer.
- RETURN_IF_DONE(reducer_.TryReduceBuiltin(shared.builtin_id(), target, args,
- feedback_source));
+ RETURN_IF_DONE(reducer_.TryReduceBuiltin(shared.builtin_id(), GetContext(),
+ target, args, feedback_source));
// Then fall back to the builtins that are only reduced in the graph builder.
switch (shared.builtin_id()) {
#define CASE(Name, ...) \
@@ -11316,8 +11236,13 @@ ReduceResult MaglevGraphBuilder::BuildCheckInternalizedStringValueOrByReference(
constant->equals(*expected_primitive)) {
return ReduceResult::Done();
}
- // If it is a constant but not the expected primitive, it will definitely
- // fail the BuildCheckValueByReference below and deopt.
+ // The constant may be a ThinString referring to the expected string.
+ if (constant->IsString() &&
+ constant->AsString().UnpackIfThin(broker()).equals(expected_string)) {
+ return ReduceResult::Done();
+ }
+ // Otherwise it will definitely fail the BuildCheckValueByReference below
+ // and deopt.
} else {
if (IntersectType(GetType(node), allowed_type) == NodeType::kNone) {
return reducer_.EmitUnconditionalDeopt(reason);
@@ -11367,9 +11292,7 @@ ReduceResult MaglevGraphBuilder::BuildCheckNumericalValue(
}
}
- if (TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node,
- TaggedToFloat64ConversionType::kOnlyNumber)) {
+ if (TryGetFloat64Constant(node, NodeType::kNumber)) {
// This a non-smi float64 constant ==> deopting.
return reducer_.EmitUnconditionalDeopt(reason);
}
@@ -11383,9 +11306,8 @@ ReduceResult MaglevGraphBuilder::BuildCheckNumericalValue(
DCHECK(ref.IsHeapNumber());
Float64 ref_value = Float64::FromBits(ref.AsHeapNumber().value_as_bits());
- if (std::optional<Float64> cst = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node,
- TaggedToFloat64ConversionType::kOnlyNumber)) {
+ if (std::optional<Float64> cst =
+ TryGetFloat64Constant(node, NodeType::kNumber)) {
if (cst->is_nan() && ref_value.is_nan()) {
return ReduceResult::Done();
}
@@ -11423,15 +11345,7 @@ ReduceResult MaglevGraphBuilder::BuildConvertHoleToUndefined(ValueNode* node) {
}
ReduceResult MaglevGraphBuilder::BuildCheckNotHole(ValueNode* node) {
- if (!node->is_tagged()) return ReduceResult::Done();
- compiler::OptionalHeapObjectRef maybe_constant =
- TryGetConstant<HeapObject>(node);
- if (maybe_constant) {
- if (maybe_constant.value().IsTheHole()) {
- return reducer_.EmitUnconditionalDeopt(DeoptimizeReason::kHole);
- }
- return ReduceResult::Done();
- }
+ RETURN_IF_DONE(reducer_.TryFoldCheckNotHole(node));
return AddNewNode<CheckNotHole>({node});
}
@@ -11708,6 +11622,168 @@ ReduceResult MaglevGraphBuilder::BuildCallForwardArgumentsElements(
tagged_context, start_index, target_type);
}
+std::optional<base::SmallVector<ValueNode*, 8>>
+MaglevGraphBuilder::TryExtractArgumentsFromElements(
+ VirtualObject* arguments_object, const CallArguments& args,
+ size_t num_args_to_copy) {
+ constexpr size_t kMaxArityForOptimizedSpread = 32;
+
+ auto build_arguments = [&](int32_t capacity, auto get_element_at)
+ -> std::optional<base::SmallVector<ValueNode*, 8>> {
+ ValueNode* length_node =
+ arguments_object->get(JSStrictArgumentsObject::kLengthOffset);
+ std::optional<int32_t> maybe_length = TryGetInt32Constant(length_node);
+ if (!maybe_length.has_value() || *maybe_length < 0 ||
+ *maybe_length > capacity) {
+ return {};
+ }
+ int32_t length = *maybe_length;
+
+ if (num_args_to_copy + static_cast<size_t>(length) >
+ kMaxArityForOptimizedSpread) {
+ return {};
+ }
+
+ bool has_hole = false;
+ base::SmallVector<ValueNode*, 8> arg_list;
+ const bool has_receiver =
+ args.receiver_mode() != ConvertReceiverMode::kNullOrUndefined;
+ arg_list.reserve((has_receiver ? 1 : 0) + num_args_to_copy + length);
+ if (has_receiver) {
+ DCHECK_NOT_NULL(args.receiver());
+ arg_list.push_back(args.receiver());
+ }
+ for (size_t i = 0; i < num_args_to_copy; i++) {
+ arg_list.push_back(args[i]);
+ }
+ for (int32_t i = 0; i < length; i++) {
+ std::optional<ValueNode*> element = get_element_at(i, has_hole);
+ if (!element.has_value()) {
+ return {};
+ }
+ arg_list.push_back(*element);
+ }
+ if (has_hole) {
+ if (!broker()->dependencies()->DependOnNoElementsProtector()) {
+ return {};
+ }
+ }
+ return arg_list;
+ };
+
+ ValueNode* elements_value =
+ arguments_object->get(offsetof(JSObject, elements_));
+
+ if (auto* root_constant = elements_value->TryCast<RootConstant>()) {
+ if (root_constant->index() != RootIndex::kEmptyFixedArray) {
+ return {};
+ }
+ return build_arguments(
+ 0, [](int32_t, bool&) -> std::optional<ValueNode*> { UNREACHABLE(); });
+ }
+
+ if (auto* constant_value = elements_value->TryCast<HeapConstant>()) {
+ if (constant_value->object().IsFixedArray()) {
+ compiler::FixedArrayRef elements =
+ constant_value->object().AsFixedArray();
+ return build_arguments(
+ elements.length(),
+ [&](int32_t i, bool& has_hole) -> std::optional<ValueNode*> {
+ const auto element =
+ elements.TryGet(broker(), static_cast<uint32_t>(i));
+ if (!element.has_value()) {
+ return {};
+ }
+ if (element->IsTheHole()) {
+ has_hole = true;
+ return GetRootConstant(RootIndex::kUndefinedValue);
+ }
+ return GetConstant(element.value());
+ });
+ }
+ if (constant_value->object().IsFixedDoubleArray()) {
+ compiler::FixedDoubleArrayRef elements =
+ constant_value->object().AsFixedDoubleArray();
+ return build_arguments(
+ elements.length(),
+ [&](int32_t i, bool& has_hole) -> std::optional<ValueNode*> {
+ Float64 value = elements.GetFromImmutableFixedDoubleArray(i);
+ if (value.is_hole_nan()) {
+ has_hole = true;
+ return GetRootConstant(RootIndex::kUndefinedValue);
+ }
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ if (value.is_undefined_nan()) {
+ return GetRootConstant(RootIndex::kUndefinedValue);
+ }
+#endif
+ return GetFloat64Constant(value);
+ });
+ }
+ return {};
+ }
+
+ if (auto* inlined_allocation = elements_value->TryCast<InlinedAllocation>()) {
+ VirtualObject* elements = GetObjectFromAllocation(inlined_allocation);
+ ValueNode* elements_length_node =
+ elements->get(offsetof(FixedArray, length_));
+ std::optional<int32_t> maybe_elements_length =
+ TryGetInt32Constant(elements_length_node);
+ if (!maybe_elements_length.has_value() || *maybe_elements_length < 0) {
+ return {};
+ }
+ int32_t capacity = *maybe_elements_length;
+ if (elements->map()->IsFixedArrayMap()) {
+ return build_arguments(
+ capacity,
+ [&](int32_t i, bool& has_hole) -> std::optional<ValueNode*> {
+ ValueNode* el = elements->get(FixedArray::OffsetOfElementAt(i));
+ if (auto* cst = el->TryCast<RootConstant>()) {
+ if (cst->index() == RootIndex::kTheHoleValue) {
+ has_hole = true;
+ el = GetRootConstant(RootIndex::kUndefinedValue);
+ }
+ }
+ return el->Unwrap();
+ });
+ }
+ if (elements->map()->IsFixedDoubleArrayMap()) {
+ return build_arguments(
+ capacity,
+ [&](int32_t i, bool& has_hole) -> std::optional<ValueNode*> {
+ ValueNode* el =
+ elements->get(FixedDoubleArray::OffsetOfElementAt(i));
+ if (auto* float_cst = el->TryCast<Float64Constant>()) {
+ if (float_cst->value().is_hole_nan()) {
+ has_hole = true;
+ el = GetRootConstant(RootIndex::kUndefinedValue);
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ } else if (float_cst->value().is_undefined_nan()) {
+ el = GetRootConstant(RootIndex::kUndefinedValue);
+#endif
+ }
+ } else if (auto* holey_cst = el->TryCast<HoleyFloat64Constant>()) {
+ if (holey_cst->value().is_hole_nan()) {
+ has_hole = true;
+ el = GetRootConstant(RootIndex::kUndefinedValue);
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ } else if (holey_cst->value().is_undefined_nan()) {
+ el = GetRootConstant(RootIndex::kUndefinedValue);
+#endif
+ }
+ } else if (el->properties().value_representation() ==
+ ValueRepresentation::kHoleyFloat64) {
+ return {};
+ }
+ return el->Unwrap();
+ });
+ }
+ return {};
+ }
+
+ return {};
+}
+
ReduceResult MaglevGraphBuilder::ReduceCallWithArrayLikeForArgumentsObject(
ValueNode* target_node, CallArguments& args,
VirtualObject* arguments_object,
@@ -11715,57 +11791,28 @@ ReduceResult MaglevGraphBuilder::ReduceCallWithArrayLikeForArgumentsObject(
DCHECK_EQ(args.mode(), CallArguments::kWithArrayLike);
DCHECK(arguments_object->map()->IsJSArgumentsObjectMap() ||
arguments_object->map()->IsJSArrayMap());
- args.PopArrayLikeArgument();
ValueNode* elements_value =
arguments_object->get(offsetof(JSObject, elements_));
if (ArgumentsElements* arguments_elements =
elements_value->TryCast<ArgumentsElements>()) {
- return BuildCallForwardArgumentsElements<CallForwardVarargs>(
- target_node, args, arguments_elements);
- }
-
- if (elements_value->Is<RootConstant>()) {
- // It is a RootConstant, Elements can only be the empty fixed array.
- DCHECK_EQ(elements_value->Cast<RootConstant>()->index(),
- RootIndex::kEmptyFixedArray);
- CallArguments new_args(ConvertReceiverMode::kAny, {args.receiver()});
- return ReduceCall(target_node, new_args, feedback_source);
- }
-
- if (HeapConstant* constant_value = elements_value->TryCast<HeapConstant>()) {
- DCHECK(constant_value->object().IsFixedArray());
- compiler::FixedArrayRef elements = constant_value->object().AsFixedArray();
- base::SmallVector<ValueNode*, 8> arg_list;
- DCHECK_NOT_NULL(args.receiver());
- arg_list.push_back(args.receiver());
- for (int i = 0; i < static_cast<int>(args.count()); i++) {
- arg_list.push_back(args[i]);
+ ValueNode* length_node =
+ arguments_object->get(JSStrictArgumentsObject::kLengthOffset);
+ if (length_node->Is<ArgumentsLength>() || length_node->Is<RestLength>()) {
+ args.PopArrayLikeArgument();
+ return BuildCallForwardArgumentsElements<CallForwardVarargs>(
+ target_node, args, arguments_elements);
}
- for (uint32_t i = 0; i < elements.length(); i++) {
- arg_list.push_back(GetConstant(*elements.TryGet(broker(), i)));
- }
- CallArguments new_args(ConvertReceiverMode::kAny, std::move(arg_list));
- return ReduceCall(target_node, new_args, feedback_source);
}
- DCHECK(elements_value->Is<InlinedAllocation>());
- InlinedAllocation* allocation = elements_value->Cast<InlinedAllocation>();
- VirtualObject* elements = allocation->object();
-
- base::SmallVector<ValueNode*, 8> arg_list;
- DCHECK_NOT_NULL(args.receiver());
- arg_list.push_back(args.receiver());
- for (int i = 0; i < static_cast<int>(args.count()); i++) {
- arg_list.push_back(args[i]);
+ std::optional<base::SmallVector<ValueNode*, 8>> arg_list =
+ TryExtractArgumentsFromElements(arguments_object, args, args.count() - 1);
+ if (!arg_list.has_value()) {
+ // On fallthrough, create a generic call.
+ return BuildGenericCall(target_node, Call::TargetType::kAny, args,
+ feedback_source);
}
- DCHECK(elements->get(offsetof(FixedArray, length_))->Is<Int32Constant>());
- int length = elements->get(offsetof(FixedArray, length_))
- ->Cast<Int32Constant>()
- ->value();
- for (int i = 0; i < length; i++) {
- arg_list.push_back(elements->get(FixedArray::OffsetOfElementAt(i)));
- }
- CallArguments new_args(ConvertReceiverMode::kAny, std::move(arg_list));
+
+ CallArguments new_args(ConvertReceiverMode::kAny, std::move(*arg_list));
return ReduceCall(target_node, new_args, feedback_source);
}
@@ -11780,23 +11827,35 @@ MaglevGraphBuilder::TryReduceConstructWithSpreadForArgumentsObject(
ValueNode* elements_value =
arguments_object->get(offsetof(JSObject, elements_));
- if (ArgumentsElements* arguments_elements =
- elements_value->TryCast<ArgumentsElements>()) {
- // For call/construct with spread, we need to also install a code
- // dependency on the array iterator lookup protector cell to ensure
- // that no one messed with the %ArrayIteratorPrototype%.next method.
- if (!broker()->dependencies()->DependOnArrayIteratorProtector()) return {};
-
- // Remove spread.
+ if (auto* arguments_elements = elements_value->TryCast<ArgumentsElements>()) {
+ ValueNode* length_node =
+ arguments_object->get(JSStrictArgumentsObject::kLengthOffset);
+ if (!length_node->Is<ArgumentsLength>() && !length_node->Is<RestLength>()) {
+ return {};
+ }
+ if (!broker()->dependencies()->DependOnArrayIteratorProtector()) {
+ return {};
+ }
args.PopSpread();
-
ValueNode* tagged_new_target;
GET_VALUE_OR_ABORT(tagged_new_target, GetTaggedValue(new_target));
return BuildCallForwardArgumentsElements<ConstructForwardVarargs>(
target, args, arguments_elements, tagged_new_target);
}
- return {};
+ std::optional<base::SmallVector<ValueNode*, 8>> arg_list =
+ TryExtractArgumentsFromElements(arguments_object, args, args.count() - 1);
+ if (!arg_list.has_value()) {
+ return {};
+ }
+
+ if (!broker()->dependencies()->DependOnArrayIteratorProtector()) {
+ return {};
+ }
+
+ CallArguments new_args(ConvertReceiverMode::kNullOrUndefined,
+ std::move(*arg_list));
+ return BuildConstruct(target, new_target, new_args, feedback_source);
}
namespace {
@@ -11809,29 +11868,47 @@ bool IsSloppyMappedArgumentsObject(compiler::JSHeapBroker* broker,
} // namespace
std::optional<VirtualObject*>
-MaglevGraphBuilder::TryGetNonEscapingArgumentsObject(ValueNode* value) {
- if (!value->Is<InlinedAllocation>()) return {};
- InlinedAllocation* alloc = value->Cast<InlinedAllocation>();
- // Although the arguments object has not been changed so far, since it is not
- // escaping, it could be modified after this bytecode if it is inside a loop.
- if (IsInsideLoop()) {
- if (!is_loop_effect_tracking() ||
- !loop_effects_->allocations.contains(alloc)) {
- return {};
+MaglevGraphBuilder::TryGetNonEscapingArgumentsOrArray(ValueNode* value) {
+ auto try_get_non_escaping_alloc = [&](ValueNode* node) -> InlinedAllocation* {
+ if (!node->Is<InlinedAllocation>()) {
+ return nullptr;
+ }
+ InlinedAllocation* alloc = node->Cast<InlinedAllocation>();
+ if (IsInsideLoop() && (!is_loop_effect_tracking() ||
+ !loop_effects_->allocations.contains(alloc))) {
+ return nullptr;
}
+ if (IsEscaping(alloc)) {
+ return nullptr;
+ }
+ return alloc;
+ };
+
+ InlinedAllocation* alloc = try_get_non_escaping_alloc(value);
+ if (!alloc) {
+ return {};
+ }
+
+ VirtualObject* object = GetObjectFromAllocation(alloc);
+ if (!object || !object->has_static_map()) {
+ return {};
}
- // TODO(victorgomes): We can probably loosen the IsNotEscaping requirement if
- // we keep track of the arguments object changes so far.
- if (IsEscaping(alloc)) return {};
- VirtualObject* object = alloc->object();
- if (!object->has_static_map()) return {};
- // TODO(victorgomes): Support simple JSArray forwarding.
compiler::MapRef map = *object->map();
- // It is a rest parameter, if it is an array with ArgumentsElements node as
- // the elements array.
- if (map.IsJSArrayMap() &&
- object->get(offsetof(JSObject, elements_))->Is<ArgumentsElements>()) {
- return object;
+ if (map.IsJSArrayMap()) {
+ if (!map.supports_fast_array_iteration(broker())) {
+ return {};
+ }
+ ValueNode* elements = object->get(offsetof(JSObject, elements_));
+ // Object is the rest parameter.
+ if (elements->Is<ArgumentsElements>()) {
+ return object;
+ }
+ if (try_get_non_escaping_alloc(elements)) {
+ return object;
+ }
+ if (elements->Is<RootConstant>() || elements->Is<HeapConstant>()) {
+ return object;
+ }
}
// TODO(victorgomes): We can loosen the IsSloppyMappedArgumentsObject
// requirement if there is no stores to the mapped arguments.
@@ -11847,9 +11924,8 @@ ReduceResult MaglevGraphBuilder::ReduceCallWithArrayLike(
const compiler::FeedbackSource& feedback_source) {
DCHECK_EQ(args.mode(), CallArguments::kWithArrayLike);
- // TODO(victorgomes): Add the case for JSArrays and Rest parameter.
if (std::optional<VirtualObject*> arguments_object =
- TryGetNonEscapingArgumentsObject(args.array_like_argument())) {
+ TryGetNonEscapingArgumentsOrArray(args.array_like_argument())) {
RETURN_IF_DONE(ReduceCallWithArrayLikeForArgumentsObject(
target_node, args, *arguments_object, feedback_source));
}
@@ -11859,9 +11935,70 @@ ReduceResult MaglevGraphBuilder::ReduceCallWithArrayLike(
feedback_source);
}
+ReduceResult MaglevGraphBuilder::ReduceCallWithSpread(
+ ValueNode* target_node, CallArguments& args,
+ const compiler::FeedbackSource& feedback_source) {
+ DCHECK_EQ(args.mode(), CallArguments::kWithSpread);
+
+ if (std::optional<VirtualObject*> arguments_object =
+ TryGetNonEscapingArgumentsOrArray(args.spread())) {
+ MaybeReduceResult result = TryReduceCallWithSpreadForArgumentsObject(
+ target_node, args, *arguments_object, feedback_source);
+ RETURN_IF_DONE(result);
+ }
+
+ // On fallthrough, create a generic call.
+ return BuildGenericCall(target_node, Call::TargetType::kAny, args,
+ feedback_source);
+}
+
+MaybeReduceResult MaglevGraphBuilder::TryReduceCallWithSpreadForArgumentsObject(
+ ValueNode* target_node, CallArguments& args,
+ VirtualObject* arguments_object,
+ const compiler::FeedbackSource& feedback_source) {
+ DCHECK_EQ(args.mode(), CallArguments::kWithSpread);
+ DCHECK_NOT_NULL(arguments_object);
+ DCHECK(arguments_object->map()->IsJSArgumentsObjectMap() ||
+ arguments_object->map()->IsJSArrayMap());
+
+ auto* elements_value = arguments_object->get(offsetof(JSObject, elements_));
+ if (auto* arguments_elements = elements_value->TryCast<ArgumentsElements>()) {
+ ValueNode* length_node =
+ arguments_object->get(JSStrictArgumentsObject::kLengthOffset);
+ if (!length_node->Is<ArgumentsLength>() && !length_node->Is<RestLength>()) {
+ return {};
+ }
+ if (!broker()->dependencies()->DependOnArrayIteratorProtector()) {
+ return {};
+ }
+ args.PopSpread();
+ return BuildCallForwardArgumentsElements<CallForwardVarargs>(
+ target_node, args, arguments_elements);
+ }
+
+ std::optional<base::SmallVector<ValueNode*, 8>> arg_list =
+ TryExtractArgumentsFromElements(arguments_object, args, args.count() - 1);
+ if (!arg_list.has_value()) {
+ return {};
+ }
+
+ if (!broker()->dependencies()->DependOnArrayIteratorProtector()) {
+ return {};
+ }
+
+ CallArguments new_args(ConvertReceiverMode::kAny, std::move(*arg_list));
+ return ReduceCall(target_node, new_args, feedback_source);
+}
+
ReduceResult MaglevGraphBuilder::ReduceCall(
ValueNode* target_node, CallArguments& args,
const compiler::FeedbackSource& feedback_source) {
+ if (args.mode() == CallArguments::kWithArrayLike) {
+ return ReduceCallWithArrayLike(target_node, args, feedback_source);
+ }
+ if (args.mode() == CallArguments::kWithSpread) {
+ return ReduceCallWithSpread(target_node, args, feedback_source);
+ }
if (compiler::OptionalJSFunctionRef maybe_constant =
TryGetConstant<JSFunction>(target_node)) {
MaybeReduceResult result = TryReduceCallForTarget(
@@ -12149,38 +12286,41 @@ ReduceResult MaglevGraphBuilder::VisitIntrinsicGeneratorYieldResult(
compiler::MapRef map =
broker()->target_native_context().iterator_result_map(broker());
- MaglevSubGraphBuilder sub_graph(this, 1);
- MaglevSubGraphBuilder::Variable ret_val(0);
- MaglevSubGraphBuilder::Label done_label(&sub_graph, 2, {&ret_val});
- MaglevSubGraphBuilder::Label allocate_label(&sub_graph, 1);
-
// Check if yielded_value_ is TheHole (signaling to skip allocating the result
// object).
ValueNode* current_yielded_value;
GET_VALUE_OR_ABORT(current_yielded_value,
BuildLoadTaggedField(generator, offsetof(JSGeneratorObject,
yielded_value_)));
- RETURN_IF_ABORT(sub_graph.GotoIfFalse<BranchIfRootConstant>(
- &allocate_label, {current_yielded_value}, RootIndex::kTheHoleValue));
- RETURN_IF_ABORT(BuildStoreTaggedField(
- generator, value, offsetof(JSGeneratorObject, yielded_value_),
- StoreTaggedMode::kDefault));
+ Subgraph<MaglevGraphBuilder> subgraph(&reducer_, 1);
+ Subgraph<MaglevGraphBuilder>::Variable ret_val(0);
- sub_graph.set(ret_val, GetRootConstant(RootIndex::kTheHoleValue));
- sub_graph.Goto(&done_label);
+ RETURN_IF_ABORT(subgraph.Branch(
+ {&ret_val},
+ [&](BranchBuilder& builder) {
+ return BuildBranchIfRootConstant(builder, current_yielded_value,
+ RootIndex::kTheHoleValue);
+ },
+ [&] {
+ RETURN_IF_ABORT(BuildStoreTaggedField(
+ generator, value, offsetof(JSGeneratorObject, yielded_value_),
+ StoreTaggedMode::kDefault));
+ subgraph.set(ret_val, GetRootConstant(RootIndex::kTheHoleValue));
+ return ReduceResult::Done();
+ },
+ [&] {
+ VirtualObject* iter_result = reducer_.CreateJSIteratorResult(
+ map, value, GetBooleanConstant(false));
+ ValueNode* alloc_result;
+ GET_VALUE_OR_ABORT(alloc_result,
+ reducer_.BuildInlinedAllocation(
+ iter_result, AllocationType::kYoung));
+ subgraph.set(ret_val, alloc_result);
+ return ReduceResult::Done();
+ }));
- sub_graph.Bind(&allocate_label);
- VirtualObject* iter_result =
- reducer_.CreateJSIteratorResult(map, value, GetBooleanConstant(false));
- ValueNode* alloc_result;
- GET_VALUE_OR_ABORT(alloc_result, reducer_.BuildInlinedAllocation(
- iter_result, AllocationType::kYoung));
- sub_graph.set(ret_val, alloc_result);
- sub_graph.Goto(&done_label);
-
- sub_graph.Bind(&done_label);
- SetAccumulator(sub_graph.get(ret_val));
+ SetAccumulator(subgraph.get(ret_val));
return ReduceResult::Done();
}
@@ -12386,7 +12526,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceAsyncFunctionReject(
// point will still return the {promise} instead of the result of the
// JSRejectPromise operation (which yields undefined).
LazyDeoptFrameScope deopt_continuation(
- this, Builtin::kAsyncFunctionLazyDeoptContinuation, {},
+ &reducer_, GetContext(), Builtin::kAsyncFunctionLazyDeoptContinuation, {},
base::VectorOf<ValueNode*>({promise}));
// Disable the additional debug event for the rejection since a
@@ -12461,8 +12601,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceAsyncFunctionResolve(
// point will still return the {promise} instead of the result of the
// JSResolvePromise operation (which yields undefined).
LazyDeoptFrameScope deopt_continuation(
- this, Builtin::kAsyncFunctionLazyDeoptContinuation, {},
- base::VectorOf<ValueNode*>({promise}));
+ &reducer_, GetContext(), Builtin::kAsyncFunctionLazyDeoptContinuation,
+ {}, base::VectorOf<ValueNode*>({promise}));
BuildCallBuiltin<Builtin::kResolvePromise>({promise, value});
}
@@ -12571,7 +12711,7 @@ ReduceResult MaglevGraphBuilder::BuildAndAllocateKeyValueArray(
broker()->target_native_context().js_array_packed_elements_map(broker());
VirtualObject* array;
GET_VALUE_OR_ABORT(array, reducer_.CreateJSArray(map, map.instance_size(),
- GetInt32Constant(2)));
+ GetSmiConstant(2)));
array->set(offsetof(JSObject, elements_), elements);
return reducer_.BuildInlinedAllocation(array, AllocationType::kYoung);
}
@@ -12836,6 +12976,15 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructArrayConstructor(
// elements_kind below.
bool values_all_smis = true, values_all_numbers = true,
values_any_nonnumber = false;
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ auto is_undefined = [&](ValueNode* node, NodeType node_type) {
+ if (auto* root = node->TryCast<RootConstant>()) {
+ return root->index() == RootIndex::kUndefinedValue;
+ }
+ return NodeTypeIs(node_type, NodeType::kUndefined);
+ };
+ bool has_undefined = false;
+#endif
base::SmallVector<ValueNode*, 16> values;
values.reserve(arity);
for (ValueNode* v : args) {
@@ -12844,9 +12993,17 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructArrayConstructor(
values_all_smis = false;
if (!NodeTypeIs(node_type, NodeType::kNumber)) {
values_all_numbers = false;
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ if (is_undefined(v, node_type)) {
+ has_undefined = true;
+ } else if (!NodeTypeCanBe(node_type, NodeType::kNumber)) {
+ values_any_nonnumber = true;
+ }
+#else
if (!NodeTypeCanBe(node_type, NodeType::kNumber)) {
values_any_nonnumber = true;
}
+#endif
}
}
values.push_back(v);
@@ -12859,6 +13016,11 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructArrayConstructor(
elements_kind, IsHoleyElementsKind(elements_kind)
? HOLEY_DOUBLE_ELEMENTS
: PACKED_DOUBLE_ELEMENTS);
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ } else if (!values_any_nonnumber && has_undefined) {
+ elements_kind =
+ GetMoreGeneralElementsKind(elements_kind, HOLEY_DOUBLE_ELEMENTS);
+#endif
} else if (values_any_nonnumber) {
// We statically know that at least one value is not a number.
elements_kind = GetMoreGeneralElementsKind(
@@ -12889,13 +13051,20 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructArrayConstructor(
}
} else if (IsDoubleElementsKind(elements_kind)) {
for (ValueNode*& v : values) {
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ if (is_undefined(v, GetType(v))) {
+ v = graph()->GetHoleyFloat64Constant(Float64::undefined_nan());
+ continue;
+ }
+#endif
if (!NodeTypeIs(GetType(v), NodeType::kNumber)) {
RETURN_IF_ABORT(BuildCheckNumber(v));
}
DCHECK(NodeTypeIs(GetType(v), NodeType::kNumber));
- ValueNode* float64_value;
- GET_VALUE_OR_ABORT(float64_value, GetFloat64(v));
- GET_VALUE_OR_ABORT(v, GetSilencedNaN(float64_value));
+ GET_VALUE_OR_ABORT(v, GetFloat64(v));
+ if (v->MayBeHoleOrUndefinedNan()) {
+ GET_VALUE_OR_ABORT(v, AddNewNode<Float64ToSilencedFloat64>({v}));
+ }
}
}
@@ -12936,7 +13105,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructBuiltin(
value = GetRootConstant(RootIndex::kempty_string);
} else {
LazyDeoptFrameScope deopt_continuation(
- this, Builtin::kStringCreateLazyDeoptContinuation, target_function,
+ &reducer_, GetContext(),
+ Builtin::kStringCreateLazyDeoptContinuation, target_function,
base::VectorOf<ValueNode*>(
{GetRootConstant(RootIndex::kTheHoleValue)}));
GET_VALUE_OR_ABORT(value,
@@ -12946,9 +13116,16 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstructBuiltin(
reducer_.CreateJSStringWrapper(value), AllocationType::kYoung);
}
case Builtin::kPromiseConstructor:
- case Builtin::kTypedArrayConstructor:
// TODO(victorgomes): specialize more known constants builtin targets.
break;
+ case Builtin::kTypedArrayConstructor: {
+ LazyDeoptFrameScope construct(
+ &reducer_, GetContext(), GetRootConstant(RootIndex::kTheHoleValue),
+ *compilation_unit(), GetCurrentSourcePosition());
+ RETURN_IF_DONE(reducer_.TryReduceTypedArrayConstructor(
+ GetContext(), target_function, new_target, args));
+ break;
+ }
default:
break;
}
@@ -12959,7 +13136,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceJSConstructStub(
compiler::JSFunctionRef target_constant,
compiler::SharedFunctionInfoRef shared_function_info, ValueNode* target,
ValueNode* new_target, CallArguments& args,
- compiler::FeedbackSource& feedback_source) {
+ const compiler::FeedbackSource& feedback_source) {
DCHECK_EQ(target_constant, TryGetConstant<HeapObject>(target).value());
// Emit an inlined version of the construct stub. This can be either
@@ -12974,7 +13151,9 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceJSConstructStub(
args.set_receiver(implicit_receiver);
ValueNode* call_result;
{
- LazyDeoptFrameScope construct(this, implicit_receiver);
+ LazyDeoptFrameScope construct(&reducer_, GetContext(), implicit_receiver,
+ *compilation_unit(),
+ GetCurrentSourcePosition());
MaybeReduceResult result = TryBuildCallKnownJSFunction(
target_constant, new_target, args, feedback_source);
RETURN_IF_ABORT(result);
@@ -13033,7 +13212,9 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceJSConstructStub(
args.set_receiver(implicit_receiver);
ValueNode* call_result;
{
- LazyDeoptFrameScope construct(this, implicit_receiver);
+ LazyDeoptFrameScope construct(&reducer_, GetContext(), implicit_receiver,
+ *compilation_unit(),
+ GetCurrentSourcePosition());
MaybeReduceResult result = TryBuildCallKnownJSFunction(
target_constant, new_target, args, feedback_source);
RETURN_IF_ABORT(result);
@@ -13061,7 +13242,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceJSConstructStub(
MaybeReduceResult MaglevGraphBuilder::TryReduceConstruct(
compiler::HeapObjectRef target_constant, ValueNode* target,
ValueNode* new_target, CallArguments& args,
- compiler::FeedbackSource& feedback_source) {
+ const compiler::FeedbackSource& feedback_source) {
// If we have AllocationSite feedback, we take a different path that calls
// TryReduceConstructArrayConstructor directly.
DCHECK(!target_constant.IsAllocationSite());
@@ -13106,7 +13287,7 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceConstruct(
ReduceResult MaglevGraphBuilder::BuildConstruct(
ValueNode* target, ValueNode* new_target, CallArguments& args,
- compiler::FeedbackSource& feedback_source) {
+ const compiler::FeedbackSource& feedback_source) {
compiler::ProcessedFeedback const& processed_feedback =
broker()->GetFeedbackForCall(feedback_source);
if (processed_feedback.IsInsufficient()) {
@@ -13117,10 +13298,9 @@ ReduceResult MaglevGraphBuilder::BuildConstruct(
// Enable feedback-based speculation.
SaveCallSpeculationScope saved(this, feedback_source);
- // TODO(victorgomes): Add the case for Rest parameter.
if (args.mode() == CallArguments::kWithSpread) {
if (std::optional<VirtualObject*> arguments_object =
- TryGetNonEscapingArgumentsObject(args.spread())) {
+ TryGetNonEscapingArgumentsOrArray(args.spread())) {
PROCESS_AND_RETURN_IF_DONE(
TryReduceConstructWithSpreadForArgumentsObject(
target, new_target, args, *arguments_object, feedback_source),
@@ -13321,7 +13501,7 @@ ReduceResult MaglevGraphBuilder::BuildToNumberOrToNumeric(
return ReduceResult::Done();
case ValueRepresentation::kHoleyFloat64: {
- return SetAccumulator(AddNewNode<HoleyFloat64ToSilencedFloat64>({value}));
+ return SetAccumulator(AddNewNode<UnsafeHoleyFloat64ToFloat64>({value}));
}
case ValueRepresentation::kTagged:
@@ -13474,7 +13654,8 @@ ReduceResult MaglevGraphBuilder::VisitArrayDestructure() {
ValueNode* iterator;
{
LazyDeoptFrameScope lazy_deopt_scope(
- this, Builtin::kArrayDestructureLazyDeoptContinuation, {},
+ &reducer_, GetContext(),
+ Builtin::kArrayDestructureLazyDeoptContinuation, {},
base::VectorOf<ValueNode*>(
{the_hole, the_hole, minus_one_node, first_reg_node, count_node}));
// This is not allowed to return DoneWithAbort (i.e. unconditionally eager
@@ -13494,7 +13675,8 @@ ReduceResult MaglevGraphBuilder::VisitArrayDestructure() {
ValueNode* next_method;
{
LazyDeoptFrameScope lazy_deopt_scope(
- this, Builtin::kArrayDestructureLazyDeoptContinuation, {},
+ &reducer_, GetContext(),
+ Builtin::kArrayDestructureLazyDeoptContinuation, {},
base::VectorOf<ValueNode*>(
{iterator, the_hole, minus_one_node, first_reg_node, count_node}));
// This is not allowed to return DoneWithAbort (i.e. unconditionally eager
@@ -13547,7 +13729,8 @@ ReduceResult MaglevGraphBuilder::VisitArrayDestructure() {
ValueNode* step_result;
{
LazyDeoptFrameScope lazy_deopt_scope(
- this, Builtin::kArrayDestructureLazyDeoptContinuation, {},
+ &reducer_, GetContext(),
+ Builtin::kArrayDestructureLazyDeoptContinuation, {},
base::VectorOf<ValueNode*>(
{iterator, next_method, index_node, first_reg_node, count_node}));
// The lazy deopt continuation will write only from `i` up to count, so
@@ -14451,8 +14634,8 @@ void MaglevGraphBuilder::BuildLoopForPeeling() {
// predecessors: the two copies of `JumpLoop`.
InitializePredecessorCount(loop_header, 2);
merge_states_[loop_header] = MergePointInterpreterFrameState::NewForLoop(
- current_interpreter_frame_, *compilation_unit_, is_inline(), graph(),
- loop_header, 2, GetInLivenessFor(loop_header),
+ *compilation_unit_, is_inline(), graph(), loop_header, 2,
+ GetInLivenessFor(loop_header),
&bytecode_analysis_.GetLoopInfoFor(loop_header),
/* has_been_peeled */ true);
@@ -14484,7 +14667,7 @@ void MaglevGraphBuilder::EndLoopEffects(int loop_header) {
// TODO(olivf): Update merge states dominated by the loop header with
// information we know to be unaffected by the loop.
if (merge_states_[loop_header] && merge_states_[loop_header]->is_loop()) {
- merge_states_[loop_header]->set_loop_effects(loop_effects_);
+ merge_states_[loop_header]->AsLoopHeader()->set_loop_effects(loop_effects_);
}
if (loop_effects_stack_.size() > 1) {
LoopEffects* inner_effects = loop_effects_;
@@ -14502,20 +14685,24 @@ ReduceResult MaglevGraphBuilder::VisitJumpLoop() {
const int32_t loop_offset = iterator_.GetImmediateOperand(1);
const FeedbackSlot feedback_slot = iterator_.GetSlotOperand(2);
int target = iterator_.GetJumpTargetOffset();
-
- if (ShouldEmitInterruptBudgetChecks()) {
- int reduction = relative_jump_bytecode_offset *
- v8_flags.osr_from_maglev_interrupt_scale_factor;
- RETURN_IF_ABORT(AddNewNode<ReduceInterruptBudgetForLoop>(
- {GetFeedbackCell()}, reduction > 0 ? reduction : 1));
- } else {
- RETURN_IF_ABORT(AddNewNode<HandleNoHeapWritesInterrupt>({}));
- }
-
- if (ShouldEmitOsrInterruptBudgetChecks()) {
- RETURN_IF_ABORT(AddNewNode<TryOnStackReplacement>(
- {GetClosure()}, loop_offset, feedback_slot,
- BytecodeOffset(iterator_.current_offset()), compilation_unit_));
+ BytecodeOffset jump_loop_osr_offset =
+ BytecodeOffset(iterator_.current_offset());
+
+ if (V8_LIKELY(!v8_flags.disable_loop_stack_checks)) {
+ bool osr =
+ ShouldEmitOsrInterruptBudgetChecks(feedback_slot, jump_loop_osr_offset);
+ if (ShouldEmitInterruptBudgetChecks()) {
+ int reduction = relative_jump_bytecode_offset *
+ v8_flags.osr_from_maglev_interrupt_scale_factor;
+ BytecodeOffset osr_offset =
+ osr ? jump_loop_osr_offset : BytecodeOffset::None();
+ FeedbackSlot slot = osr ? feedback_slot : FeedbackSlot::Invalid();
+ RETURN_IF_ABORT(AddNewNode<ReduceInterruptBudgetForLoop>(
+ {GetFeedbackCell()}, reduction > 0 ? reduction : 1, osr_offset,
+ loop_offset, slot));
+ } else {
+ RETURN_IF_ABORT(AddNewNode<HandleNoHeapWritesInterrupt>({}));
+ }
}
bool is_peeled_loop = loop_headers_to_peel_.Contains(target);
@@ -14526,7 +14713,7 @@ ReduceResult MaglevGraphBuilder::VisitJumpLoop() {
ClobberAccumulator();
if (in_optimistic_peeling_iteration()) {
// Let's see if we can finish this loop without peeling it.
- if (!merge_states_[target]->TryMergeLoop(
+ if (!merge_states_[target]->AsLoopHeader()->TryMergeLoop(
broker(), graph(), is_tracing(), *compilation_unit(),
current_interpreter_frame_, FinishLoopBlock,
GetLatestCheckpointedFrame())) {
@@ -14538,9 +14725,9 @@ ReduceResult MaglevGraphBuilder::VisitJumpLoop() {
}
} else {
BasicBlock* block = FinishLoopBlock();
- merge_states_[target]->MergeLoop(graph(), is_tracing(), *compilation_unit(),
- current_interpreter_frame_, block,
- GetLatestCheckpointedFrame());
+ merge_states_[target]->AsLoopHeader()->MergeLoop(
+ graph(), is_tracing(), *compilation_unit(), current_interpreter_frame_,
+ block, GetLatestCheckpointedFrame());
block->set_predecessor_id(merge_states_[target]->predecessor_count() - 1);
if (is_peeled_loop) {
DCHECK(!in_peeled_iteration());
@@ -14597,18 +14784,10 @@ ReduceResult MaglevGraphBuilder::VisitJumpIfToBooleanFalseConstant() {
void MaglevGraphBuilder::MergeIntoFrameState(BasicBlock* predecessor,
int target) {
if (merge_states_[target] == nullptr) {
- bool jumping_to_peeled_iteration = bytecode_analysis().IsLoopHeader(target);
- DCHECK_EQ(jumping_to_peeled_iteration,
- loop_headers_to_peel_.Contains(target));
- const compiler::BytecodeLivenessState* liveness = GetInLivenessFor(target);
- if (jumping_to_peeled_iteration) {
- // The peeled iteration is missing the backedge.
- DecrementDeadPredecessorAndAccountForPeeling(target);
- }
// If there's no target frame state, allocate a new one.
merge_states_[target] = MergePointInterpreterFrameState::New(
*compilation_unit_, current_interpreter_frame_, target,
- predecessor_count(target), predecessor, liveness,
+ predecessor_count(target), predecessor, GetInLivenessFor(target),
GetCurrentScopeInfo());
} else {
@@ -14645,12 +14824,6 @@ void MaglevGraphBuilder::MergeDeadIntoFrameState(int target,
!merge_state->has_context_scope_info()) {
merge_state->set_context_scope_info(GetCurrentScopeInfo());
}
- // If this merge is the last one which kills a loop merge, remove that
- // merge state.
- if (merge_state->is_unmerged_unreachable_loop()) {
- TRACE("! Killing loop merge state at @" << target);
- merge_state = nullptr;
- }
}
// Track scope infos for revived mergepoints. Skip the "fallthrough" patch
// since it's just unnecessarily expensive to stash away to scope infos.
@@ -14682,8 +14855,7 @@ void MaglevGraphBuilder::MergeDeadLoopIntoFrameState(int target) {
if (V8_LIKELY(merge_states_[target])) {
DCHECK_EQ(merge_states_[target]->predecessor_count(),
predecessor_count(target));
- if (is_loop_effect_tracking_enabled() &&
- !merge_states_[target]->is_unmerged_unreachable_loop()) {
+ if (is_loop_effect_tracking_enabled()) {
EndLoopEffects(target);
}
merge_states_[target]->MergeDeadLoop(*compilation_unit_);
@@ -15696,7 +15868,8 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGetIterator(
// TryBuildLoadNamedProperty can eager deopt on e.g. a failed map check --
// this shouldn't pick up this lazy deopt frame.
LazyDeoptFrameScope deopt_continuation(
- this, Builtin::kGetIteratorWithFeedbackLazyDeoptContinuation, {},
+ &reducer_, GetContext(),
+ Builtin::kGetIteratorWithFeedbackLazyDeoptContinuation, {},
base::VectorOf<ValueNode*>({receiver, GetSmiConstant(call_slot_index),
GetConstant(feedback())}));
MaybeReduceResult result_load =
@@ -15720,14 +15893,15 @@ MaybeReduceResult MaglevGraphBuilder::TryReduceGetIterator(
// If the call eager deopts (e.g. because of incorrect speculation of the
// call target), we need to do the full call in the continuation.
EagerDeoptFrameScope eager_deopt_continuation(
- this, Builtin::kCallIteratorWithFeedback, {},
+ &reducer_, GetContext(), Builtin::kCallIteratorWithFeedback, {},
base::VectorOf<ValueNode*>({receiver, iterator_method,
GetSmiConstant(call_slot_index),
GetConstant(feedback())}));
// If the call lazy deopts, we can assume the call itself happened and the
// continuation only has to do the post-call checks.
LazyDeoptFrameScope deopt_continuation(
- this, Builtin::kCallIteratorWithFeedbackLazyDeoptContinuation);
+ &reducer_, GetContext(),
+ Builtin::kCallIteratorWithFeedbackLazyDeoptContinuation);
FeedbackSlot call_slot = FeedbackVector::ToSlot(call_slot_index);
compiler::FeedbackSource call_feedback{feedback(), call_slot};
@@ -16062,7 +16236,8 @@ ReduceResult MaglevGraphBuilder::BuildForOfNextFallback(
CallArguments args(ConvertReceiverMode::kAny, {iterator});
{
LazyDeoptFrameScope lazy_call_scope(
- this, Builtin::kForOfNextResultDeoptContinuation, {}, {});
+ &reducer_, GetContext(), Builtin::kForOfNextResultDeoptContinuation, {},
+ {});
GET_VALUE_OR_ABORT(result_object,
ReduceCall(next_method, args, feedback_source));
@@ -16071,14 +16246,15 @@ ReduceResult MaglevGraphBuilder::BuildForOfNextFallback(
ValueNode* done;
{
EagerDeoptFrameScope eager_done_scope(
- this, Builtin::kForOfNextResultDeoptContinuation, {},
+ &reducer_, GetContext(), Builtin::kForOfNextResultDeoptContinuation, {},
base::VectorOf<ValueNode*>({result_object}));
// Check if result is a JSReceiver.
RETURN_IF_ABORT(BuildCheckJSReceiver(result_object));
LazyDeoptFrameScope lazy_done_scope(
- this, Builtin::kForOfNextLoadDoneLazyDeoptContinuation, {},
+ &reducer_, GetContext(),
+ Builtin::kForOfNextLoadDoneLazyDeoptContinuation, {},
base::VectorOf<ValueNode*>({result_object}));
// Load 'done' property.
@@ -16107,11 +16283,12 @@ ReduceResult MaglevGraphBuilder::BuildForOfNextFallback(
},
[&]() -> ReduceResult {
EagerDeoptFrameScope eager_value_scope(
- this, Builtin::kForOfNextLoadValueEagerDeoptContinuation, {},
+ &reducer_, GetContext(),
+ Builtin::kForOfNextLoadValueEagerDeoptContinuation, {},
base::VectorOf<ValueNode*>({result_object}));
LazyDeoptFrameScope lazy_value_scope(
- this, Builtin::kForOfNextLoadValueLazyDeoptContinuation, {},
- {});
+ &reducer_, GetContext(),
+ Builtin::kForOfNextLoadValueLazyDeoptContinuation, {}, {});
RETURN_IF_DONE(TryBuildLoadNamedProperty(
result_object, broker()->value_string(), value_feedback));
return AddNewNode<LoadNamedGeneric>({GetContext(), result_object},
@@ -16461,11 +16638,15 @@ void MaglevGraphBuilder::BuildBody() {
for (iterator_.SetOffset(entrypoint_); !iterator_.done();
iterator_.Advance()) {
local_isolate_->heap()->Safepoint();
- if (V8_UNLIKELY(
- loop_headers_to_peel_.Contains(iterator_.current_offset()))) {
- PeelLoop();
- DCHECK_EQ(iterator_.current_bytecode(), interpreter::Bytecode::kJumpLoop);
- continue;
+ int offset = iterator_.current_offset();
+ if (V8_UNLIKELY(IsLoopHeader(offset))) {
+ if (loop_headers_to_peel_.Contains(offset)) {
+ PeelLoop();
+ DCHECK_EQ(iterator_.current_bytecode(),
+ interpreter::Bytecode::kJumpLoop);
+ continue;
+ }
+ BuildLoopHeader(offset);
}
if (VisitSingleBytecode().IsDoneWithAbort()) {
MarkBytecodeDead();
@@ -16502,13 +16683,11 @@ bool MaglevGraphBuilder::ShouldEmitInterruptBudgetChecks() {
return v8_flags.force_emit_interrupt_budget_checks || v8_flags.turbofan;
}
-bool MaglevGraphBuilder::ShouldEmitOsrInterruptBudgetChecks() {
+bool MaglevGraphBuilder::ShouldEmitOsrInterruptBudgetChecks(
+ FeedbackSlot feedback_slot, BytecodeOffset osr_offset) {
if (!v8_flags.turbofan || !v8_flags.use_osr || !v8_flags.osr_from_maglev) {
return false;
}
- if (!graph_->is_osr() && !v8_flags.always_osr_from_maglev) {
- return false;
- }
// TODO(olivf) OSR from maglev requires lazy recompilation (see
// CompileOptimizedOSRFromMaglev for details). Without this we end up in
// deopt loops, e.g., in chromium content_unittests.
@@ -16522,7 +16701,28 @@ bool MaglevGraphBuilder::ShouldEmitOsrInterruptBudgetChecks() {
// same maglev osr code again, before reaching the turbofan OSR code in the
// callee. The solution is to support osr from maglev without
// deoptimization.
- return !is_inline();
+ if (is_inline()) {
+ return false;
+ }
+ auto osr_from_maglev =
+ OsrFromMaglevStrategies::FromIntegral(v8_flags.osr_from_maglev);
+ if (osr_from_maglev.contains(OsrFromMaglevStrategy::kAlways)) {
+ return true;
+ }
+ if (osr_from_maglev.contains(OsrFromMaglevStrategy::kOnOsrCompile) &&
+ graph_->is_osr()) {
+ return true;
+ }
+ if (osr_from_maglev.contains(OsrFromMaglevStrategy::kIfLoopOsrd)) {
+ if (graph_->is_osr() && compilation_unit_->osr_offset() == osr_offset) {
+ return true;
+ }
+ std::optional<Tagged<Code>> maybe_osr_code =
+ FeedbackNexusForSlot(feedback_slot)
+ .GetOptimizedOsrCode(broker()->isolate());
+ if (maybe_osr_code.has_value()) return true;
+ }
+ return false;
}
BasicBlock* MaglevGraphBuilder::CreateEdgeSplitBlock(
@@ -16573,6 +16773,96 @@ void MaglevGraphBuilder::ProcessMergePointAtExceptionHandlerStart(int offset) {
}
}
+void MaglevGraphBuilder::BuildLoopHeader(int offset) {
+ DCHECK(bytecode_analysis().IsLoopHeader(offset));
+ DCHECK(!loop_headers_to_peel_.Contains(offset));
+ DCHECK_IMPLIES(merge_states_[offset] != nullptr,
+ !merge_states_[offset]->is_loop() &&
+ !merge_states_[offset]->is_exception_handler());
+ const compiler::LoopInfo& loop_info =
+ bytecode_analysis().GetLoopInfoFor(offset);
+ // The nodes below belong to the loop header, not to the bytecode we were
+ // building before it.
+ UpdateSourceAndBytecodePosition(offset);
+
+ if (current_block() == nullptr && merge_states_[offset] == nullptr) {
+ // No live forward edge reaches the header. A resumable loop is also
+ // entered through resume edges that bypass its header, so it can still be
+ // reached through its back-edge alone. Any other loop is dead, and
+ // VisitSingleBytecode aborts it.
+ DCHECK_EQ(predecessor_count(offset), 0);
+ if (!loop_info.resumable() || is_inline() || graph()->is_osr()) return;
+ LoopMergePointInterpreterFrameState* loop_state =
+ MergePointInterpreterFrameState::NewForLoop(
+ *compilation_unit_, is_inline(), graph(), offset, 1,
+ GetInLivenessFor(offset), &loop_info);
+ // The forward edges died before reaching the header, but they still carry
+ // the context scope info of the loop entry, which MergeDeadIntoFrameState
+ // stashed away for us.
+ if (auto it = dead_scope_infos_.find(offset);
+ it != dead_scope_infos_.end()) {
+ loop_state->set_context_scope_info(it->second);
+ }
+ merge_states_[offset] = loop_state;
+ UpdatePredecessorCount(offset, 1);
+ return;
+ }
+
+ // Merge the fallthrough edge with the other forward edges, if there are any.
+ if (current_block() != nullptr && merge_states_[offset] != nullptr) {
+ MergeIntoFrameState(FinishBlockNoAbort<Jump>({}, &jump_targets_[offset]),
+ offset);
+ }
+
+ // The loop header takes a single forward edge. When the bytecode has
+ // several, they are merged in a pre-header block, which becomes the block we
+ // are currently building.
+ DCHECK_IMPLIES(merge_states_[offset] == nullptr,
+ predecessor_count(offset) == 1);
+ if (MergePointInterpreterFrameState* forward = merge_states_[offset]) {
+ DCHECK_EQ(forward->predecessors_so_far(), forward->predecessor_count());
+ current_interpreter_frame_.CopyFrom(*compilation_unit_, *forward);
+ SetCurrentScopeInfo(forward->context_scope_info());
+ if (forward->predecessor_count() > 1) {
+ TRACE(TraceColor::kDarkYellow
+ << "New block (loop pre-header @" << forward << ") at "
+ << compilation_unit()->shared_function_info().object());
+ ProcessMergePointPredecessors(*forward, jump_targets_[offset]);
+ StartNewBlock(/*predecessor*/ nullptr, forward, jump_targets_[offset]);
+ // The forward jumps are bound to the pre-header, so the loop header
+ // needs a fresh ref list.
+ new (&jump_targets_[offset]) BasicBlockRef();
+ }
+ }
+
+ uint32_t forward_predecessor_count = predecessor_count(offset);
+ LoopMergePointInterpreterFrameState* loop_state =
+ MergePointInterpreterFrameState::NewForLoop(
+ *compilation_unit_, is_inline(), graph(), offset, 2,
+ GetInLivenessFor(offset), &loop_info);
+
+ // Close the loop's single forward predecessor, unless the jump that reached
+ // this offset already closed it.
+ BasicBlock* predecessor;
+ if (current_block() != nullptr) {
+ predecessor =
+ !loop_state->is_resumable_loop() && need_checkpointed_loop_entry()
+ ? FinishBlockNoAbort<CheckpointedJump>({}, &jump_targets_[offset])
+ : FinishBlockNoAbort<Jump>({}, &jump_targets_[offset]);
+ } else {
+ predecessor = merge_states_[offset]->predecessor_at(0);
+ }
+
+ // From now on the loop header has exactly two predecessors: the forward edge
+ // above and the back-edge.
+ merge_states_[offset] = loop_state;
+ UpdatePredecessorCount(offset,
+ 2 - static_cast<int>(forward_predecessor_count));
+ loop_state->Merge(graph(), is_tracing(), *compilation_unit_,
+ current_interpreter_frame_, predecessor,
+ GetCurrentScopeInfo());
+}
+
void MaglevGraphBuilder::ProcessMergePoint(int offset,
bool preserve_known_node_aspects) {
// First copy the merge state to be the current state.
@@ -16809,18 +17099,14 @@ ReduceResult MaglevGraphBuilder::VisitSingleBytecode() {
current_for_in_state.enum_cache_indices = nullptr;
}
if (current_block() != nullptr) {
+ // BuildLoopHeader already consumed the fallthrough edge of a loop header.
+ DCHECK(!merge_state->is_loop());
DCHECK(!preserve_known_node_aspects);
// TODO(leszeks): Re-evaluate this DCHECK, we might hit it if the only
// bytecodes in this basic block were only register juggling.
// DCHECK(!node_buffer().empty());
- BasicBlock* predecessor;
- if (merge_state->is_loop() && !merge_state->is_resumable_loop() &&
- need_checkpointed_loop_entry()) {
- predecessor =
- FinishBlockNoAbort<CheckpointedJump>({}, &jump_targets_[offset]);
- } else {
- predecessor = FinishBlockNoAbort<Jump>({}, &jump_targets_[offset]);
- }
+ BasicBlock* predecessor =
+ FinishBlockNoAbort<Jump>({}, &jump_targets_[offset]);
merge_state->Merge(graph(), is_tracing(), *compilation_unit_,
current_interpreter_frame_, predecessor,
GetCurrentScopeInfo());
@@ -16845,12 +17131,6 @@ ReduceResult MaglevGraphBuilder::VisitSingleBytecode() {
return ReduceResult::DoneWithAbort();
}
ProcessMergePointAtExceptionHandlerStart(offset);
- } else if (merge_state->is_unmerged_unreachable_loop()) {
- // We encountered a loop header that is only reachable by the JumpLoop
- // back-edge, but the bytecode_analysis didn't notice upfront. This can
- // e.g. be a loop that is entered on a dead fall-through.
- static_assert(kLoopsMustBeEnteredThroughHeader);
- return ReduceResult::DoneWithAbort();
} else {
ProcessMergePoint(offset, preserve_known_node_aspects);
}
@@ -16867,12 +17147,7 @@ ReduceResult MaglevGraphBuilder::VisitSingleBytecode() {
// some earlier deopt). Mark this bytecode dead too and return.
// TODO(leszeks): Merge these two conditions by marking dead states with
// a sentinel value.
- if (predecessor_count(offset) == 1) {
- CHECK_NULL(merge_state);
- CHECK(bytecode_analysis().IsLoopHeader(offset));
- } else {
- CHECK_EQ(predecessor_count(offset), 0);
- }
+ CHECK_EQ(predecessor_count(offset), 0);
return ReduceResult::DoneWithAbort();
}
@@ -17002,14 +17277,14 @@ ReduceResult MaglevGraphBuilder::GetFloat64(interpreter::Register reg) {
}
ReduceResult MaglevGraphBuilder::GetFloat64ForToNumber(
- ValueNode* value, NodeType allowed_input_type) {
- return reducer_.GetFloat64ForToNumber(value, allowed_input_type);
+ ValueNode* value, NodeType assumed_input_type) {
+ return reducer_.GetFloat64ForToNumber(value, assumed_input_type);
}
ReduceResult MaglevGraphBuilder::GetFloat64ForToNumber(
- interpreter::Register reg, NodeType allowed_input_type) {
+ interpreter::Register reg, NodeType assumed_input_type) {
return GetFloat64ForToNumber(current_interpreter_frame_.get(reg),
- allowed_input_type);
+ assumed_input_type);
}
ReduceResult MaglevGraphBuilder::GetHoleyFloat64(ValueNode* value) {
@@ -17024,11 +17299,9 @@ std::optional<uint32_t> MaglevGraphBuilder::TryGetUint32Constant(
ValueNode* value) {
return reducer_.TryGetUint32Constant(value);
}
-std::optional<Float64> MaglevGraphBuilder::TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation use_repr, ValueNode* value,
- TaggedToFloat64ConversionType conversion_type) {
- return reducer_.TryGetFloat64OrHoleyFloat64Constant(use_repr, value,
- conversion_type);
+std::optional<Float64> MaglevGraphBuilder::TryGetFloat64Constant(
+ ValueNode* value, NodeType assumed_input_type) {
+ return reducer_.TryGetFloat64Constant(value, assumed_input_type);
}
MaybeHandle<String> MaglevGraphBuilder::TryGetStringConstant(ValueNode* value) {
@@ -17148,34 +17421,6 @@ void MaglevGraphBuilder::Print(const char* str, ValueNode* value) {
Print(value);
}
-ReduceResult MaglevGraphBuilder::GetSilencedNaN(ValueNode* value) {
- DCHECK_EQ(value->properties().value_representation(),
- ValueRepresentation::kFloat64);
-
- // We only need to check for silenced NaN in non-conversion nodes or
- // conversion from tagged, since they can't be signalling NaNs.
- if (value->is_conversion()) {
- // A conversion node should have at least one input.
- DCHECK_GE(value->input_count(), 1);
- // If the conversion node is tagged, we could be reading a fabricated sNaN
- // value (built using a BufferArray for example).
- if (!value->input(0).node()->properties().is_tagged()) {
- return value;
- }
- }
-
- // Special case constants, since we know what they are.
- Float64Constant* constant = value->TryCast<Float64Constant>();
- if (constant) {
- constexpr double quiet_NaN = std::numeric_limits<double>::quiet_NaN();
- if (!constant->value().is_nan()) return constant;
- return GetFloat64Constant(quiet_NaN);
- }
-
- // Silence all other values.
- return AddNewNode<Float64ToSilencedFloat64>({value});
-}
-
ValueNode* MaglevGraphBuilder::GetSecondValue(ValueNode* result) {
// GetSecondReturnedValue must be added just after a node that calls a
// builtin that expects 2 returned values. It simply binds kReturnRegister1
@@ -17244,13 +17489,6 @@ void MaglevGraphBuilder::AttachExceptionHandlerInfo(NodeBase* node) {
ExceptionHandlerInfo(ExceptionHandlerInfo::kLazyDeopt);
DCHECK(node->exception_handler_info()->HasExceptionHandler());
DCHECK(node->exception_handler_info()->ShouldLazyDeopt());
- if (node->Is<CallKnownJSFunction>()) {
- if (flags_.is_non_eager_inlining_enabled) {
- // Ensure that we always have the handler of inline call
- // candidates.
- current_block()->AddExceptionHandler(node->exception_handler_info());
- }
- }
return;
}
@@ -17272,8 +17510,6 @@ void MaglevGraphBuilder::AttachExceptionHandlerInfo(NodeBase* node) {
DCHECK(node->exception_handler_info()->HasExceptionHandler());
DCHECK(!node->exception_handler_info()->ShouldLazyDeopt());
- current_block()->AddExceptionHandler(node->exception_handler_info());
-
if (MaglevGraphBuilder* handler = catch_block.handler_builder) {
// Merge the current state into the handler state.
handler->GetCatchBlockFrameState()->MergeThrow(
@@ -17287,12 +17523,6 @@ void MaglevGraphBuilder::AttachExceptionHandlerInfo(NodeBase* node) {
// case.
new (node->exception_handler_info()) ExceptionHandlerInfo();
DCHECK(!node->exception_handler_info()->HasExceptionHandler());
- if (node->Is<CallKnownJSFunction>()) {
- if (flags_.is_non_eager_inlining_enabled) {
- // Ensure that we always have the handler of inline call candidates.
- current_block()->AddExceptionHandler(node->exception_handler_info());
- }
- }
}
}
@@ -17356,12 +17586,12 @@ BasicBlock* MaglevGraphBuilder::FinishBlockNoAbort(
void MaglevGraphBuilder::StartFallthroughBlock(int next_block_offset,
BasicBlock* predecessor) {
// Start a new block for the fallthrough path, unless it's a merge point, in
- // which case we merge our state into it. That merge-point could also be a
- // loop header, in which case the merge state might not exist yet (if the
- // only predecessors are this path and the JumpLoop).
+ // which case we merge our state into it. A loop header always needs a merge
+ // state to hold its loop phis, even with a single forward edge.
DCHECK_NULL(current_block());
- if (predecessor_count(next_block_offset) == 1) {
+ if (predecessor_count(next_block_offset) == 1 &&
+ !IsLoopHeader(next_block_offset)) {
TRACE(TraceColor::kDarkYellow
<< "New block (single fallthrough) at "
<< *compilation_unit_->shared_function_info().object()
@@ -17455,6 +17685,11 @@ void MaglevGraphBuilder::CalculatePredecessorCounts() {
// with DeoptimizeReason::kOSREarlyExit.
InitializePredecessorCount(iterator.GetJumpTargetOffset(), 0);
}
+ } else if (bytecode == interpreter::Bytecode::kJumpLoop) {
+ // A loop header is the target of a JumpLoop. It counts its forward
+ // edges only, since the back-edge is added when BuildLoopHeader
+ // creates the loop merge state.
+ loop_headers_.Add(iterator.GetJumpTargetOffset());
} else {
UpdatePredecessorCount(iterator.GetJumpTargetOffset(), 1);
}
@@ -17520,15 +17755,8 @@ ReduceResult MaglevGraphBuilder::BuildSmiUntag(ValueNode* node) {
return reducer_.BuildSmiUntag(node);
}
-ReduceResult MaglevGraphBuilder::BuildGetCharCodeAt(ValueNode* string,
- ValueNode* index) {
- return AddNewNode<BuiltinStringPrototypeCharCodeOrCodePointAt>(
- {string, index},
- BuiltinStringPrototypeCharCodeOrCodePointAt::kCharCodeAt);
-}
-
#undef TRACE
-#undef FAIL
+#undef MAGLEV_FAIL
#undef TRACE_CANNOT_INLINE
} // namespace v8::internal::maglev
diff --git a/deps/v8/src/maglev/maglev-graph-builder.h b/deps/v8/src/maglev/maglev-graph-builder.h
index 9802401fa0e..b7daff41462 100644
--- a/deps/v8/src/maglev/maglev-graph-builder.h
+++ b/deps/v8/src/maglev/maglev-graph-builder.h
@@ -10,6 +10,7 @@
#include <utility>
#include "src/base/base-export.h"
+#include "src/base/enum-set.h"
#include "src/base/functional/function-ref.h"
#include "src/base/logging.h"
#include "src/base/vector.h"
@@ -92,9 +93,11 @@ class MaglevGraphBuilder {
using MapInference = maglev::MapInference<MaglevGraphBuilder>;
using CallArguments = ::v8::internal::maglev::CallArguments;
- class EagerDeoptFrameScope;
+ using EagerDeoptFrameScope =
+ MaglevReducer<MaglevGraphBuilder>::EagerDeoptFrameScope;
- class LazyDeoptFrameScope;
+ using LazyDeoptFrameScope =
+ MaglevReducer<MaglevGraphBuilder>::LazyDeoptFrameScope;
class V8_NODISCARD LazyDeoptResultLocationScope {
public:
@@ -135,6 +138,7 @@ class MaglevGraphBuilder {
BasicBlock* EndPrologue();
void PeelLoop();
void BuildLoopForPeeling();
+ void BuildLoopHeader(int offset);
void OsrAnalyzePrequel();
@@ -161,6 +165,9 @@ class MaglevGraphBuilder {
Float64Constant* GetFloat64Constant(Float64 constant) {
return graph()->GetFloat64Constant(constant);
}
+ HoleyFloat64Constant* GetHoleyFloat64Constant(Float64 constant) {
+ return graph()->GetHoleyFloat64Constant(constant);
+ }
RootConstant* GetRootConstant(RootIndex index) {
return graph()->GetRootConstant(index);
}
@@ -195,9 +202,6 @@ class MaglevGraphBuilder {
return current_interpreter_frame_;
}
MaglevCallerDetails* caller_details() const { return caller_details_; }
- const LazyDeoptFrameScope* current_lazy_deopt_scope() const {
- return current_lazy_deopt_scope_;
- }
compiler::JSHeapBroker* broker() const { return broker_; }
LocalIsolate* local_isolate() const { return local_isolate_; }
@@ -221,6 +225,15 @@ class MaglevGraphBuilder {
std::tuple<DeoptFrame*, interpreter::Register, int> GetDeoptFrameForLazyDeopt(
bool can_throw);
+ void OnBeginDeoptFrameScope() {
+ current_interpreter_frame_.virtual_objects().Snapshot();
+ }
+ void OnEndDeoptFrameScope() {
+ // We might have cached a checkpointed frame which includes this scope;
+ // reset it just in case.
+ latest_checkpointed_frame_ = nullptr;
+ }
+
bool need_checkpointed_loop_entry() {
return v8_flags.maglev_speculative_hoist_phi_untagging ||
v8_flags.maglev_licm;
@@ -281,8 +294,6 @@ class MaglevGraphBuilder {
void InitializeScopeInfo();
- class DeoptFrameScopeBase;
-
// Helper class for building a subgraph with its own control flow, that is not
// attached to any bytecode.
//
@@ -358,8 +369,16 @@ class MaglevGraphBuilder {
}
public:
+ enum class OsrFromMaglevStrategy {
+ kOnOsrCompile,
+ kIfLoopOsrd,
+ kAlways,
+ };
+ using OsrFromMaglevStrategies = base::EnumSet<OsrFromMaglevStrategy>;
+
bool ShouldEmitInterruptBudgetChecks();
- bool ShouldEmitOsrInterruptBudgetChecks();
+ bool ShouldEmitOsrInterruptBudgetChecks(FeedbackSlot feedback_slot,
+ BytecodeOffset osr_offset);
bool MaglevIsTopTier() const { return !v8_flags.turbofan && v8_flags.maglev; }
BasicBlock* CreateEdgeSplitBlock(BasicBlockRef& jump_targets,
@@ -377,6 +396,11 @@ class MaglevGraphBuilder {
void RegisterPhisWithGraphLabeller(
MergePointInterpreterFrameState& merge_state);
+ // Return true if the given offset is a loop header. Their merge state is
+ // only created once all the forward edges have been merged, so this can be
+ // true for offsets the graph builder hasn't reached yet.
+ bool IsLoopHeader(int offset) const { return loop_headers_.Contains(offset); }
+
// Return true if the given offset is a merge point, i.e. there are jumps
// targetting it.
bool IsOffsetAMergePoint(int offset) const {
@@ -553,8 +577,6 @@ class MaglevGraphBuilder {
iterator_.GetConstantForOperand(operand_index, local_isolate()))));
}
- MaybeReduceResult GetConstantSingleCharacterStringFromCode(uint16_t);
-
ValueNode* GetRegisterInput(Register reg);
// Move an existing ValueNode between two registers. You can pass
@@ -612,12 +634,12 @@ class MaglevGraphBuilder {
//
// Deopts if the ToNumber is non-trivial.
ReduceResult GetTruncatedInt32ForToNumber(ValueNode* value,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
ReduceResult GetTruncatedInt32ForToNumber(interpreter::Register reg,
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
return GetTruncatedInt32ForToNumber(current_interpreter_frame_.get(reg),
- allowed_input_type);
+ assumed_input_type);
}
// Get an Int32 representation node whose value is equivalent to the ToUint8
@@ -642,11 +664,14 @@ class MaglevGraphBuilder {
return reducer_.GetCheckType(type);
}
+ ReduceResult BuildAbort(AbortReason reason) {
+ return reducer_.BuildAbort(reason);
+ }
+
std::optional<int32_t> TryGetInt32Constant(ValueNode* value);
std::optional<uint32_t> TryGetUint32Constant(ValueNode* value);
- std::optional<Float64> TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation use_repr, ValueNode* value,
- TaggedToFloat64ConversionType conversion_type);
+ std::optional<Float64> TryGetFloat64Constant(ValueNode* value,
+ NodeType assumed_input_type);
MaybeHandle<String> TryGetStringConstant(ValueNode* value);
// Get an Int32 representation node whose value is equivalent to the given
@@ -658,10 +683,6 @@ class MaglevGraphBuilder {
ReduceResult EnsureInt32(ValueNode* value, bool can_be_heap_number = false);
ReduceResult EnsureInt32(interpreter::Register reg);
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- std::optional<double> TryGetHoleyFloat64Constant(ValueNode* value);
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
// Get a Float64 representation node whose value is equivalent to the given
// node.
//
@@ -678,9 +699,9 @@ class MaglevGraphBuilder {
// Deopts if the ToNumber value is not exactly representable as a Float64, or
// the ToNumber is non-trivial.
ReduceResult GetFloat64ForToNumber(ValueNode* value,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
ReduceResult GetFloat64ForToNumber(interpreter::Register reg,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
ValueNode* GetAccumulator() {
return current_interpreter_frame_.get(
@@ -695,9 +716,9 @@ class MaglevGraphBuilder {
}
ReduceResult GetAccumulatorTruncatedInt32ForToNumber(
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
return GetTruncatedInt32ForToNumber(
- interpreter::Register::virtual_accumulator(), allowed_input_type);
+ interpreter::Register::virtual_accumulator(), assumed_input_type);
}
ValueNode* GetAccumulatorUint8ClampedForToNumber() {
@@ -705,12 +726,28 @@ class MaglevGraphBuilder {
interpreter::Register::virtual_accumulator());
}
- ReduceResult GetAccumulatorFloat64ForToNumber(NodeType allowed_input_type) {
+ ReduceResult GetAccumulatorFloat64ForToNumber(NodeType assumed_input_type) {
return GetFloat64ForToNumber(interpreter::Register::virtual_accumulator(),
- allowed_input_type);
+ assumed_input_type);
}
- ReduceResult GetSilencedNaN(ValueNode* value);
+ // An operand that is already HoleyFloat64 can keep its undefined and let the
+ // arithmetic turn it into a NaN, instead of deopting on it.
+ NodeType AllowUndefinedInputForArithmetic(interpreter::Register reg,
+ NodeType assumed_input_type) {
+ if (NodeTypeIs(assumed_input_type, NodeType::kNumber) &&
+ current_interpreter_frame_.get(reg)->value_representation() ==
+ ValueRepresentation::kHoleyFloat64) {
+ return NodeType::kNumberOrUndefined;
+ }
+ return assumed_input_type;
+ }
+
+ ReduceResult GetAccumulatorFloat64ForArithmetic(NodeType assumed_input_type) {
+ interpreter::Register reg = interpreter::Register::virtual_accumulator();
+ return GetFloat64ForToNumber(
+ reg, AllowUndefinedInputForArithmetic(reg, assumed_input_type));
+ }
bool IsRegisterEqualToAccumulator(int operand_index) {
interpreter::Register source = iterator_.GetRegisterOperand(operand_index);
@@ -724,9 +761,16 @@ class MaglevGraphBuilder {
}
ReduceResult LoadRegisterFloat64ForToNumber(int operand_index,
- NodeType allowed_input_type) {
+ NodeType assumed_input_type) {
return GetFloat64ForToNumber(iterator_.GetRegisterOperand(operand_index),
- allowed_input_type);
+ assumed_input_type);
+ }
+
+ ReduceResult LoadRegisterFloat64ForArithmetic(int operand_index,
+ NodeType assumed_input_type) {
+ interpreter::Register reg = iterator_.GetRegisterOperand(operand_index);
+ return GetFloat64ForToNumber(
+ reg, AllowUndefinedInputForArithmetic(reg, assumed_input_type));
}
template <typename NodeT>
@@ -857,7 +901,9 @@ class MaglevGraphBuilder {
V(DataViewPrototypeGetByteLength) \
V(FunctionPrototypeApply) \
V(FunctionPrototypeCall) \
+ V(MapIteratorPrototypeNext) \
V(MapPrototypeGet) \
+ V(SetIteratorPrototypeNext) \
V(WeakMapPrototypeGet) \
V(ObjectPrototypeGetProto) \
V(ObjectGetPrototypeOf) \
@@ -869,16 +915,7 @@ class MaglevGraphBuilder {
V(NumberParseInt) \
V(SetPrototypeHas) \
V(StringConstructor) \
- V(StringFromCharCode) \
- V(StringPrototypeCharAt) \
- V(StringPrototypeCharCodeAt) \
- V(StringPrototypeCodePointAt) \
- V(StringPrototypeSlice) \
- V(StringPrototypeSubstring) \
- V(StringPrototypeStartsWith) \
- V(StringPrototypeIndexOf) \
- V(StringPrototypeIncludes) \
- V(StringPrototypeIterator)
+ V(StringPrototypeStartsWith)
#define DEFINE_BUILTIN_REDUCER(Name, ...) \
MaybeReduceResult TryReduce##Name(compiler::JSFunctionRef target, \
@@ -920,17 +957,6 @@ class MaglevGraphBuilder {
const std::optional<ProcessElementCallback>& process_element_callback =
{});
- // OOB StringAt access behaves differently for elements (needs the elements
- // protector, positive indices, and returns undefined) and charAt (allows
- // negative indices, returns empty string).
- enum class StringAtOOBMode { kElement, kCharAt };
- MaybeReduceResult TryReduceConstantStringAt(ValueNode* object,
- ValueNode* index,
- StringAtOOBMode oob_mode);
-
- MaybeReduceResult TryReduceStringPrototypeIndexOfIncludes(CallArguments& args,
- bool is_includes);
-
MaybeReduceResult TryReduceGetProto(ValueNode* node);
template <typename MapKindsT, typename IndexToElementsKindFunc,
@@ -1052,6 +1078,10 @@ class MaglevGraphBuilder {
CallArguments& args,
ArgumentsElements* elements,
Args&&... extra_arg);
+ std::optional<base::SmallVector<ValueNode*, 8>>
+ TryExtractArgumentsFromElements(VirtualObject* arguments_object,
+ const CallArguments& args,
+ size_t num_args_to_copy);
ReduceResult ReduceCallWithArrayLikeForArgumentsObject(
ValueNode* target_node, CallArguments& args,
VirtualObject* arguments_object,
@@ -1059,6 +1089,13 @@ class MaglevGraphBuilder {
ReduceResult ReduceCallWithArrayLike(
ValueNode* target_node, CallArguments& args,
const compiler::FeedbackSource& feedback_source);
+ MaybeReduceResult TryReduceCallWithSpreadForArgumentsObject(
+ ValueNode* target_node, CallArguments& args,
+ VirtualObject* arguments_object,
+ const compiler::FeedbackSource& feedback_source);
+ ReduceResult ReduceCallWithSpread(
+ ValueNode* target_node, CallArguments& args,
+ const compiler::FeedbackSource& feedback_source);
ReduceResult ReduceCall(ValueNode* target_node, CallArguments& args,
const compiler::FeedbackSource& feedback_source =
compiler::FeedbackSource());
@@ -1073,6 +1110,18 @@ class MaglevGraphBuilder {
ValueNode* BuildElementsArray(ElementsKind elements_kind,
base::Vector<ValueNode*> values);
ReduceResult BuildAndAllocateKeyValueArray(ValueNode* key, ValueNode* value);
+
+ MaybeReduceResult TryReduceCollectionIteratorPrototypeNext(
+ compiler::JSFunctionRef target, CallArguments& args,
+ CollectionKind collection_kind, int entry_size,
+ RootIndex empty_collection_root);
+
+ using BuildIteratorStepResultCallback =
+ base::FunctionRef<ReduceResult(ValueNode* value, ValueNode* is_done)>;
+ MaybeReduceResult BuildCollectionIteratorStep(
+ ValueNode* receiver, CollectionKind collection_kind, int entry_size,
+ RootIndex empty_collection_root,
+ BuildIteratorStepResultCallback build_result);
ReduceResult BuildAndAllocateJSArray(
compiler::MapRef map, ValueNode* length, ValueNode* elements,
const compiler::SlackTrackingPrediction& slack_tracking_prediction,
@@ -1101,18 +1150,18 @@ class MaglevGraphBuilder {
compiler::JSFunctionRef function,
compiler::SharedFunctionInfoRef shared_function_info, ValueNode* target,
ValueNode* new_target, CallArguments& args,
- compiler::FeedbackSource& feedback_source);
+ const compiler::FeedbackSource& feedback_source);
MaybeReduceResult TryReduceConstruct(
compiler::HeapObjectRef target_constant, ValueNode* target,
ValueNode* new_target, CallArguments& args,
- compiler::FeedbackSource& feedback_source);
+ const compiler::FeedbackSource& feedback_source);
MaybeReduceResult TryReduceConstructWithSpreadForArgumentsObject(
ValueNode* target, ValueNode* new_target, CallArguments& args,
VirtualObject* arguments_object,
const compiler::FeedbackSource& feedback_source);
ReduceResult BuildConstruct(ValueNode* target, ValueNode* new_target,
CallArguments& args,
- compiler::FeedbackSource& feedback_source);
+ const compiler::FeedbackSource& feedback_source);
MaybeReduceResult TryBuildScriptContextStore(
const compiler::GlobalAccessFeedback& global_access_feedback);
@@ -1133,7 +1182,9 @@ class MaglevGraphBuilder {
std::pair<interpreter::Register, interpreter::Register> result);
ReduceResult BuildSmiUntag(ValueNode* node);
- ReduceResult BuildGetCharCodeAt(ValueNode* string, ValueNode* index);
+ ReduceResult BuildGetCharCodeAt(ValueNode* string, ValueNode* index) {
+ return reducer_.BuildGetCharCodeAt(string, index);
+ }
ReduceResult BuildCheckSmi(ValueNode* object);
ReduceResult BuildCheckNumber(ValueNode* object);
@@ -1465,7 +1516,9 @@ class MaglevGraphBuilder {
compiler::NameRef name) {
return reducer_.TryReuseKnownPropertyLoad(lookup_start_object, name);
}
- ReduceResult BuildLoadStringLength(ValueNode* string);
+ ReduceResult BuildLoadStringLength(ValueNode* string) {
+ return reducer_.BuildLoadStringLength(string);
+ }
// Converts the input node to a representation that's valid to store into an
// array with elements kind |kind|.
@@ -1488,7 +1541,7 @@ class MaglevGraphBuilder {
const DeoptFrame& frame,
const MaglevGraphBuilder::LazyDeoptFrameScope* parent_scope);
- std::optional<VirtualObject*> TryGetNonEscapingArgumentsObject(
+ std::optional<VirtualObject*> TryGetNonEscapingArgumentsOrArray(
ValueNode* value);
MaybeReduceResult TryBuildFastCreateObjectOrArrayLiteral(
@@ -1525,27 +1578,27 @@ class MaglevGraphBuilder {
template <Operation kOperation>
ReduceResult BuildInt32UnaryOperationNode();
ReduceResult BuildTruncatingInt32BitwiseNotForToNumber(
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
template <Operation kOperation>
ReduceResult BuildInt32BinaryOperationNode();
template <Operation kOperation>
ReduceResult BuildInt32BinarySmiOperationNode();
template <Operation kOperation>
ReduceResult BuildTruncatingInt32BinaryOperationNodeForToNumber(
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
template <Operation kOperation>
ReduceResult BuildTruncatingInt32BinarySmiOperationNodeForToNumber(
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
template <Operation kOperation>
ReduceResult BuildFloat64UnaryOperationNodeForToNumber(
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
template <Operation kOperation>
ReduceResult BuildFloat64BinaryOperationNodeForToNumber(
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
template <Operation kOperation>
ReduceResult BuildFloat64BinarySmiOperationNodeForToNumber(
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
ReduceResult BuildFloat64SpeculateSafeAdd(ValueNode* left, ValueNode* right);
@@ -1853,6 +1906,8 @@ class MaglevGraphBuilder {
void PrewalkBytecode();
ZoneVector<int> decremented_predecessor_offsets_;
+ // The set of loop headers reachable from the entrypoint.
+ BitVector loop_headers_;
// The set of loop headers for which we decided to do loop peeling.
BitVector loop_headers_to_peel_;
@@ -1896,8 +1951,6 @@ class MaglevGraphBuilder {
int inlining_id_ = SourcePosition::kNotInlined;
uint32_t next_handler_table_index_ = 0;
- EagerDeoptFrameScope* current_eager_deopt_scope_ = nullptr;
- LazyDeoptFrameScope* current_lazy_deopt_scope_ = nullptr;
LazyDeoptResultLocationScope* lazy_deopt_result_location_scope_ = nullptr;
struct HandlerTableEntry {
diff --git a/deps/v8/src/maglev/maglev-graph-labeller.h b/deps/v8/src/maglev/maglev-graph-labeller.h
index 60e8ff8d408..912249a2409 100644
--- a/deps/v8/src/maglev/maglev-graph-labeller.h
+++ b/deps/v8/src/maglev/maglev-graph-labeller.h
@@ -114,7 +114,7 @@ MaglevGraphLabeller* GetCurrentGraphLabeller();
#ifdef V8_ENABLE_MAGLEV_GRAPH_PRINTER
-class PrintNode {
+class V8_EXPORT_PRIVATE PrintNode {
public:
explicit PrintNode(const NodeBase* node, bool has_regalloc_data = false,
bool skip_targets = false)
@@ -132,7 +132,7 @@ class PrintNode {
const bool skip_targets_;
};
-class PrintNodeLabel {
+class V8_EXPORT_PRIVATE PrintNodeLabel {
public:
explicit PrintNodeLabel(const NodeBase* node) : node_(node) {}
diff --git a/deps/v8/src/maglev/maglev-graph-optimizer.cc b/deps/v8/src/maglev/maglev-graph-optimizer.cc
index 2e4407d7c14..c4a40248555 100644
--- a/deps/v8/src/maglev/maglev-graph-optimizer.cc
+++ b/deps/v8/src/maglev/maglev-graph-optimizer.cc
@@ -28,6 +28,77 @@ namespace v8 {
namespace internal {
namespace maglev {
+namespace {
+
+// The scope's captured nodes become inputs of the cloned deopt frame, so they
+// need a deopt use each. Without it, reducing the current node can drop their
+// last regular use, letting dead node sweeping remove a node that the frame
+// still references.
+void AddDeoptUseToScopeData(const DeoptFrame::FrameData& data,
+ const VirtualObjectList& virtual_objects) {
+ switch (data.tag()) {
+ case DeoptFrame::FrameType::kInterpretedFrame:
+ case DeoptFrame::FrameType::kInlinedArgumentsFrame:
+ // These frames are never created as deopt scope.
+ UNREACHABLE();
+ case DeoptFrame::FrameType::kConstructInvokeStubFrame:
+ data.get<DeoptFrame::ConstructInvokeStubFrameData>()
+ .receiver->AddDeoptUse(virtual_objects);
+ data.get<DeoptFrame::ConstructInvokeStubFrameData>().context->AddDeoptUse(
+ virtual_objects);
+ break;
+ case DeoptFrame::FrameType::kBuiltinContinuationFrame:
+ data.get<DeoptFrame::BuiltinContinuationFrameData>().context->AddDeoptUse(
+ virtual_objects);
+ for (ValueNode* node :
+ data.get<DeoptFrame::BuiltinContinuationFrameData>().parameters) {
+ node->AddDeoptUse(virtual_objects);
+ }
+ break;
+ }
+}
+
+DeoptFrame* GetDeoptFrameForLazyDeoptHelper(
+ Zone* zone, MaglevReducer<MaglevGraphOptimizer>::LazyDeoptFrameScope* scope,
+ DeoptFrame* parent, const VirtualObjectList& virtual_objects) {
+ if (scope == nullptr) return parent;
+ DeoptFrame* new_parent = GetDeoptFrameForLazyDeoptHelper(
+ zone, scope->parent(), parent, virtual_objects);
+ AddDeoptUseToScopeData(scope->data(), virtual_objects);
+ return zone->New<DeoptFrame>(scope->data(), new_parent);
+}
+
+} // namespace
+
+std::tuple<DeoptFrame*, interpreter::Register, int>
+MaglevGraphOptimizer::GetDeoptFrameForLazyDeopt(bool can_throw) {
+ CHECK(current_node()->properties().can_lazy_deopt());
+ auto [frame, result_location, result_size] =
+ current_node()->lazy_deopt_info()->GetFrameForCloning();
+
+ if (reducer_.current_lazy_deopt_scope() != nullptr) {
+ frame = GetDeoptFrameForLazyDeoptHelper(graph()->zone(),
+ reducer_.current_lazy_deopt_scope(),
+ frame, frame->GetVirtualObjects());
+ }
+ return {frame, result_location, result_size};
+}
+
+DeoptFrame* MaglevGraphOptimizer::GetDeoptFrameForEagerDeopt() {
+ CHECK(current_node()->properties().has_eager_deopt_info());
+ DeoptFrame* frame = ¤t_node()->eager_deopt_info()->top_frame();
+
+ auto* eager_scope = reducer_.current_eager_deopt_scope();
+ if (eager_scope != nullptr) {
+ const VirtualObjectList& virtual_objects = frame->GetVirtualObjects();
+ frame = GetDeoptFrameForLazyDeoptHelper(
+ graph()->zone(), eager_scope->parent(), frame, virtual_objects);
+ AddDeoptUseToScopeData(eager_scope->data(), virtual_objects);
+ frame = graph()->zone()->New<DeoptFrame>(eager_scope->data(), frame);
+ }
+ return frame;
+}
+
#define RETURN_IF_SUCCESS(res) \
do { \
auto _res = (res); \
@@ -186,9 +257,19 @@ Subgraph<MaglevGraphOptimizer>::Subgraph(
saved_block_(reducer->current_block()),
saved_position_(reducer->current_block_position()),
saved_kna_(&reducer->known_node_aspects()),
- parent_(reducer->active_subgraph_) {
+ parent_(reducer->active_subgraph_),
+ stashed_nodes_at_(zone_),
+ stashed_nodes_at_end_(zone_) {
reducer_->active_subgraph_ = this;
- reducer_->FlushNodesToBlock();
+ if (parent_ == nullptr) {
+ DCHECK_IMPLIES(
+ reducer_->HasPendingSplice(),
+ reducer_->new_nodes_at_.empty() && reducer_->new_nodes_at_end_.empty());
+ std::swap(stashed_nodes_at_, reducer_->new_nodes_at_);
+ std::swap(stashed_nodes_at_end_, reducer_->new_nodes_at_end_);
+ } else {
+ reducer_->FlushNodesToBlock();
+ }
// Create entry block.
BasicBlock* entry =
@@ -267,6 +348,16 @@ Subgraph<MaglevGraphOptimizer>::~Subgraph() {
reducer_->set_current_block(saved_block_);
reducer_->SetNewNodePosition(saved_position_);
reducer_->set_known_node_aspects(saved_kna_);
+
+ if (parent_ == nullptr) {
+ DCHECK(reducer_->new_nodes_at_.empty());
+ DCHECK(reducer_->new_nodes_at_end_.empty());
+ std::swap(stashed_nodes_at_, reducer_->new_nodes_at_);
+ std::swap(stashed_nodes_at_end_, reducer_->new_nodes_at_end_);
+ if (!is_empty) {
+ reducer_->FlushNodesToBlock();
+ }
+ }
}
void Subgraph<MaglevGraphOptimizer>::MergeIntoLabel(Label* label,
@@ -311,7 +402,8 @@ void Subgraph<MaglevGraphOptimizer>::Bind(Label* label) {
// Pull merged frame state + KNA back into variable_frame_, then move KNA
// onto the reducer as the active aspects.
- variable_frame_.CopyFrom(*dummy_unit_, *merge_state);
+ variable_frame_.CopyFrom(*dummy_unit_, *merge_state,
+ /*preserve_known_node_aspects=*/true, zone_);
reducer_->set_known_node_aspects(variable_frame_.known_node_aspects());
variable_frame_.clear_known_node_aspects();
@@ -381,7 +473,19 @@ MaglevGraphOptimizer::MaglevGraphOptimizer(
: reducer_(this, graph),
kna_processor_(kna_processor),
ranges_(ranges),
- block_range_refinements_(graph->zone()) {}
+ block_range_refinements_(graph->zone()),
+ removed_identities_(graph->zone()) {}
+
+void MaglevGraphOptimizer::PostProcessGraph(Graph* graph) {
+ // Only drop the Identity's forwarding use when nothing references it
+ // anymore, otherwise the unwrapped node would be left without a use and
+ // could be swept by dead node elimination.
+ for (Identity* identity : removed_identities_) {
+ if (identity->is_used()) continue;
+ identity->input_node(0)->remove_use();
+ }
+ removed_identities_.clear();
+}
BlockProcessResult MaglevGraphOptimizer::PreProcessBasicBlock(
BasicBlock* block) {
@@ -532,7 +636,7 @@ ProcessResult MaglevGraphOptimizer::ReplaceWith(
if (result.IsDoneWithAbort()) {
return DeoptAndTruncate(DeoptimizeReason::kUnknown);
}
- return ProcessResult::kContinue;
+ return ProcessResult::kRevisit;
}
ProcessResult MaglevGraphOptimizer::RemoveCurrentNode() {
@@ -550,7 +654,7 @@ void MaglevGraphOptimizer::UnwrapInputs() {
ValueNode* MaglevGraphOptimizer::GetConstantWithRepresentation(
ValueNode* node, UseRepresentation use_repr,
- std::optional<TaggedToFloat64ConversionType> conversion_type) {
+ std::optional<NodeType> assumed_input_type) {
switch (use_repr) {
case UseRepresentation::kInt32:
case UseRepresentation::kTruncatedInt32: {
@@ -560,19 +664,22 @@ ValueNode* MaglevGraphOptimizer::GetConstantWithRepresentation(
}
return nullptr;
}
- case UseRepresentation::kFloat64:
- case UseRepresentation::kHoleyFloat64: {
- DCHECK(conversion_type.has_value());
- auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(use_repr, node,
- *conversion_type);
+ case UseRepresentation::kFloat64: {
+ DCHECK(assumed_input_type.has_value());
+ auto cst = reducer_.TryGetFloat64Constant(node, *assumed_input_type);
if (cst.has_value()) {
- if (use_repr == UseRepresentation::kHoleyFloat64) {
- return reducer_.GetHoleyFloat64Constant(cst.value());
- }
return reducer_.GetFloat64Constant(cst.value());
}
return nullptr;
}
+ case UseRepresentation::kHoleyFloat64: {
+ DCHECK(assumed_input_type.has_value());
+ auto cst = reducer_.TryGetHoleyFloat64Constant(node, *assumed_input_type);
+ if (cst.has_value()) {
+ return reducer_.GetHoleyFloat64Constant(cst.value());
+ }
+ return nullptr;
+ }
default:
return nullptr;
}
@@ -580,19 +687,20 @@ ValueNode* MaglevGraphOptimizer::GetConstantWithRepresentation(
MaybeReduceResult MaglevGraphOptimizer::GetUntaggedValueWithRepresentation(
ValueNode* node, UseRepresentation use_repr,
- std::optional<TaggedToFloat64ConversionType> conversion_type) {
+ std::optional<NodeType> assumed_input_type) {
DCHECK_NE(use_repr, UseRepresentation::kTagged);
if (node->value_representation() == ValueRepresentationFromUse(use_repr)) {
return node;
}
if (node->Is<ReturnedValue>()) {
ValueNode* input = node->input_node(0);
- return GetUntaggedValueWithRepresentation(input, use_repr, conversion_type);
+ return GetUntaggedValueWithRepresentation(input, use_repr,
+ assumed_input_type);
}
// We try getting constant before bailing out and/or calling the reducer,
// since it does not emit a conversion node.
if (ValueNode* cst =
- GetConstantWithRepresentation(node, use_repr, conversion_type)) {
+ GetConstantWithRepresentation(node, use_repr, assumed_input_type)) {
return cst;
}
if (node->is_tagged()) {
@@ -601,6 +709,12 @@ MaybeReduceResult MaglevGraphOptimizer::GetUntaggedValueWithRepresentation(
known_node_aspects().GetOrCreateInfoFor(broker(), node);
auto& alternative = node_info->alternative();
if (ValueNode* alt = alternative.get(use_repr)) return alt;
+ // If `node` is itself tagging an untagged value, convert that value
+ // directly instead of untagging the tagged result.
+ if (node->is_conversion()) {
+ return GetUntaggedValueWithRepresentation(node->input_node(0), use_repr,
+ assumed_input_type);
+ }
return {};
}
// TODO(victorgomes): The GetXXX functions may emit a conversion node that
@@ -613,17 +727,14 @@ MaybeReduceResult MaglevGraphOptimizer::GetUntaggedValueWithRepresentation(
case UseRepresentation::kInt32:
return reducer_.GetInt32(node);
case UseRepresentation::kTruncatedInt32:
- DCHECK(conversion_type.has_value());
- return reducer_.GetTruncatedInt32ForToNumber(
- node, GetAllowedTypeFromConversionType(*conversion_type));
+ DCHECK(assumed_input_type.has_value());
+ return reducer_.GetTruncatedInt32ForToNumber(node, *assumed_input_type);
case UseRepresentation::kFloat64:
- DCHECK(conversion_type.has_value());
- return reducer_.GetFloat64ForToNumber(
- node, GetAllowedTypeFromConversionType(*conversion_type));
+ DCHECK(assumed_input_type.has_value());
+ return reducer_.GetFloat64ForToNumber(node, *assumed_input_type);
case UseRepresentation::kHoleyFloat64:
- DCHECK(conversion_type.has_value());
- return reducer_.GetHoleyFloat64ForToNumber(
- node, GetAllowedTypeFromConversionType(*conversion_type));
+ DCHECK(assumed_input_type.has_value());
+ return reducer_.GetHoleyFloat64ForToNumber(node, *assumed_input_type);
default:
return {};
}
@@ -680,12 +791,11 @@ std::optional<ProcessResult> MaglevGraphOptimizer::TryFoldFloat64Operation(
MaybeReduceResult result;
if constexpr (IsUnaryOperation(kOperation)) {
result = reducer_.TryFoldFloat64UnaryOperationForToNumber<kOperation>(
- TaggedToFloat64ConversionType::kOnlyNumber, node->input_node(0));
+ NodeType::kNumber, node->input_node(0));
} else {
static_assert(IsBinaryOperation(kOperation));
result = reducer_.TryFoldFloat64BinaryOperationForToNumber<kOperation>(
- TaggedToFloat64ConversionType::kOnlyNumber, node->input_node(0),
- node->input_node(1));
+ NodeType::kNumber, node->input_node(0), node->input_node(1));
}
if (!result.IsDone()) return {};
if (result.IsDoneWithAbort()) {
@@ -756,12 +866,6 @@ void MaglevGraphOptimizer::AttachExceptionHandlerInfo(NodeBase* node) {
new (node->exception_handler_info())
ExceptionHandlerInfo(info->catch_block(), info->depth());
}
- if (node->Is<CallKnownJSFunction>()) {
- // Ensure that we always have the handler of inline call
- // candidates.
- reducer_.current_block()->AddExceptionHandler(
- node->exception_handler_info());
- }
}
template <typename NodeT>
@@ -827,9 +931,8 @@ ProcessResult MaglevGraphOptimizer::VisitCheckIntPtrIsSmi(
ProcessResult MaglevGraphOptimizer::VisitCheckFloat64IsSmi(
CheckFloat64IsSmi* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->input_node(0),
+ NodeType::kNumberOrOddball)) {
if (IsSmiDouble(cst.value().get_scalar())) {
return RemoveCurrentNode();
}
@@ -840,9 +943,8 @@ ProcessResult MaglevGraphOptimizer::VisitCheckFloat64IsSmi(
ProcessResult MaglevGraphOptimizer::VisitCheckHoleyFloat64IsSmi(
CheckHoleyFloat64IsSmi* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kHoleyFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetHoleyFloat64Constant(
+ node->input_node(0), NodeType::kNumberOrOddball)) {
if (IsSmiDouble(cst.value().get_scalar())) {
return RemoveCurrentNode();
}
@@ -982,7 +1084,8 @@ ProcessResult MaglevGraphOptimizer::VisitCheckJSReceiverOrNullOrUndefined(
ProcessResult MaglevGraphOptimizer::VisitCheckNotHole(
CheckNotHole* node, const ProcessingState& state) {
- // TODO(b/424157317): Optimize.
+ REMOVE_AND_RETURN_IF_DONE(
+ reducer_.TryFoldCheckNotHole(node->ObjectInput().node()));
return ProcessResult::kContinue;
}
@@ -1040,9 +1143,8 @@ ProcessResult MaglevGraphOptimizer::VisitCheckValueEqualsInt32(
ProcessResult MaglevGraphOptimizer::VisitCheckFloat64SameValue(
CheckFloat64SameValue* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->input_node(0),
+ NodeType::kNumberOrOddball)) {
double left = cst.value().get_scalar();
double right = node->value().get_scalar();
bool same_value = false;
@@ -1146,11 +1248,6 @@ ProcessResult MaglevGraphOptimizer::VisitGeneratorStore(
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::VisitTryOnStackReplacement(
- TryOnStackReplacement* node, const ProcessingState& state) {
- // TODO(b/424157317): Optimize.
- return ProcessResult::kContinue;
-}
ProcessResult MaglevGraphOptimizer::VisitStoreMap(
StoreMap* node, const ProcessingState& state) {
@@ -1197,6 +1294,22 @@ ProcessResult MaglevGraphOptimizer::VisitStoreFixedDoubleArrayElement(
StoreFixedDoubleArrayElement* node, const ProcessingState& state) {
REMOVE_AND_RETURN_IF_DONE(
AbortIfInvalidFixedArrayIndex<FixedDoubleArray>(node));
+ // A reduction can have replaced the value with one that carries the hole or
+ // undefined NaN since the store chose not to canonicalize.
+ ValueNode* value = node->ValueInput().node();
+ if (value->MayBeHoleOrUndefinedNan()) {
+ node->change_input(
+ StoreFixedDoubleArrayElement::kValueIndex,
+ reducer_.AddNewNodeNoInputConversion<Float64ToSilencedFloat64>(
+ {value}));
+ }
+ return ProcessResult::kContinue;
+}
+
+ProcessResult MaglevGraphOptimizer::VisitStoreFixedDoubleArrayHole(
+ StoreFixedDoubleArrayHole* node, const ProcessingState& state) {
+ REMOVE_AND_RETURN_IF_DONE(
+ AbortIfInvalidFixedArrayIndex<FixedDoubleArray>(node));
return ProcessResult::kContinue;
}
@@ -1236,8 +1349,8 @@ ProcessResult MaglevGraphOptimizer::VisitStoreDoubleConstantTypedArrayElement(
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::VisitStoreSignedIntDataViewElement(
- StoreSignedIntDataViewElement* node, const ProcessingState& state) {
+ProcessResult MaglevGraphOptimizer::VisitStoreInt32DataViewElement(
+ StoreInt32DataViewElement* node, const ProcessingState& state) {
// TODO(b/424157317): Optimize.
return ProcessResult::kContinue;
}
@@ -1315,7 +1428,7 @@ ProcessResult MaglevGraphOptimizer::VisitThrowReferenceErrorIfHole(
switch (node->ValueInput().node()->IsTheHole()) {
case Tribool::kTrue: {
return ThrowAndTruncate(Throw::kThrowAccessedUninitializedVariable,
- node->ValueInput().node());
+ reducer_.GetConstant(node->name()));
}
case Tribool::kFalse:
// Not the hole; removing.
@@ -1394,14 +1507,18 @@ ProcessResult MaglevGraphOptimizer::VisitTransitionAndStoreArrayElement(
ProcessResult MaglevGraphOptimizer::VisitIdentity(
Identity* node, const ProcessingState& state) {
- // If a non-eager inlined function returns a tagged value, we substitute the
- // call with an Identity. The node is then removed from the graph here. All
- // references to it will be removed in this graph optimizer pass.
+ // If a non-eager inlined function returns a tagged value, the call is
+ // substituted with an Identity. The node is then removed from the graph here.
+ // All references to it will be removed in this graph optimizer pass, except
+ // frame state uses. The forwarding use can thus only be dropped once it is
+ // certain that no frame state references this Identity, which is done lazily
+ // at the end of the pass.
//
- // Unlike RemoveCurrentNode(), we must not clear the input here: the Identity
- // stays a valid forwarding stub (UnwrapIdentities walks input(0)) until every
- // remaining user has been revisited, so we only drop our use of the input.
- node->input_node(0)->remove_use();
+ // TODO(b/542023485): This is only needed because use counts are an
+ // overapproximation. Once they are exact, this can simply return kContinue
+ // and let dead node elimination sweep the Identity once its use count reaches
+ // zero, which makes the deferral below unnecessary.
+ removed_identities_.push_back(node);
return ProcessResult::kRemove;
}
@@ -1474,8 +1591,9 @@ ProcessResult MaglevGraphOptimizer::VisitCall(Call* node,
Builtin builtin_id = shared.builtin_id();
if (MaglevGraphBuilder::IsReducibleBuiltin(builtin_id)) {
CallArguments args(node);
- MaybeReduceResult reduction = reducer_.TryReduceBuiltin(
- builtin_id, *target_function, args, node->feedback());
+ MaybeReduceResult reduction =
+ reducer_.TryReduceBuiltin(builtin_id, node->ContextInput().node(),
+ *target_function, args, node->feedback());
if (reduction.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
}
@@ -1677,7 +1795,8 @@ ProcessResult MaglevGraphOptimizer::VisitCallKnownBuiltin(
CallArguments args(node);
MaybeReduceResult reduction = reducer_.TryReduceBuiltin(
- node->builtin_id(), *target_function, args, node->feedback_source());
+ node->builtin_id(), node->ContextInput().node(), *target_function, args,
+ node->feedback_source());
if (!reduction.IsDone()) return ProcessResult::kContinue;
if (reduction.IsDoneWithAbort()) {
return ProcessResult::kTruncateBlock;
@@ -1969,17 +2088,14 @@ ProcessResult MaglevGraphOptimizer::VisitLoadHoleyFixedDoubleArrayElement(
return ProcessResult::kContinue;
}
-ProcessResult
-MaglevGraphOptimizer::VisitLoadHoleyFixedDoubleArrayElementCheckedNotHole(
- LoadHoleyFixedDoubleArrayElementCheckedNotHole* node,
- const ProcessingState& state) {
- REMOVE_AND_RETURN_IF_DONE(
- AbortIfInvalidFixedArrayIndex<FixedDoubleArray>(node));
+ProcessResult MaglevGraphOptimizer::VisitLoadInt32DataViewElement(
+ LoadInt32DataViewElement* node, const ProcessingState& state) {
+ // TODO(b/424157317): Optimize.
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::VisitLoadSignedIntDataViewElement(
- LoadSignedIntDataViewElement* node, const ProcessingState& state) {
+ProcessResult MaglevGraphOptimizer::VisitLoadUint32DataViewElement(
+ LoadUint32DataViewElement* node, const ProcessingState& state) {
// TODO(b/424157317): Optimize.
return ProcessResult::kContinue;
}
@@ -2507,36 +2623,35 @@ ProcessResult MaglevGraphOptimizer::VisitCheckedSmiTagHoleyFloat64(
UNTAGGING_CASE(UnsafeSmiUntag, Int32, {})
UNTAGGING_CASE(CheckedNumberToInt32, Int32, {})
UNTAGGING_CASE(TruncateUnsafeNumberOrOddballToInt32, TruncatedInt32,
- node->conversion_type())
-UNTAGGING_CASE(UnsafeNumberOrOddballToFloat64, Float64, node->conversion_type())
-UNTAGGING_CASE(UnsafeNumberToFloat64, Float64,
- TaggedToFloat64ConversionType::kOnlyNumber)
+ node->assumed_input_type())
+UNTAGGING_CASE(UnsafeNumberOrOddballToFloat64, Float64,
+ node->assumed_input_type())
+UNTAGGING_CASE(UnsafeNumberToFloat64, Float64, NodeType::kNumber)
UNTAGGING_CASE(UnsafeNumberOrOddballToHoleyFloat64, HoleyFloat64,
- node->conversion_type())
+ node->assumed_input_type())
#undef UNTAGGING_CASE
// Checked tagged-input conversions whose check is already implied by the known
// type of their input are downgraded in-place to their unsafe equivalent.
-#define DOWNGRADABLE_UNTAGGING_CASE(Node, UnsafeNode, Repr, ConvType) \
- ProcessResult MaglevGraphOptimizer::Visit##Node( \
- Node* node, const ProcessingState& state) { \
- REPLACE_AND_RETURN_IF_DONE(GetUntaggedValueWithRepresentation( \
- node->input_node(0), UseRepresentation::k##Repr, ConvType)); \
- if (reducer_.CheckType(node->input_node(0), \
- GetAllowedTypeFromConversionType(ConvType))) { \
- node->OverwriteWith(Opcode::k##UnsafeNode); \
- } \
- return ProcessResult::kContinue; \
+#define DOWNGRADABLE_UNTAGGING_CASE(Node, UnsafeNode, Repr, ConvType) \
+ ProcessResult MaglevGraphOptimizer::Visit##Node( \
+ Node* node, const ProcessingState& state) { \
+ REPLACE_AND_RETURN_IF_DONE(GetUntaggedValueWithRepresentation( \
+ node->input_node(0), UseRepresentation::k##Repr, ConvType)); \
+ if (reducer_.CheckType(node->input_node(0), ConvType)) { \
+ node->OverwriteWith(Opcode::k##UnsafeNode); \
+ } \
+ return ProcessResult::kContinue; \
}
DOWNGRADABLE_UNTAGGING_CASE(TruncateCheckedNumberOrOddballToInt32,
TruncateUnsafeNumberOrOddballToInt32,
- TruncatedInt32, node->conversion_type())
+ TruncatedInt32, node->assumed_input_type())
DOWNGRADABLE_UNTAGGING_CASE(CheckedNumberOrOddballToFloat64,
UnsafeNumberOrOddballToFloat64, Float64,
- node->conversion_type())
+ node->assumed_input_type())
DOWNGRADABLE_UNTAGGING_CASE(CheckedNumberOrOddballToHoleyFloat64,
UnsafeNumberOrOddballToHoleyFloat64, HoleyFloat64,
- node->conversion_type())
+ node->assumed_input_type())
#undef DOWNGRADABLE_UNTAGGING_CASE
ProcessResult MaglevGraphOptimizer::VisitCheckedSmiUntag(
@@ -2584,8 +2699,7 @@ ProcessResult MaglevGraphOptimizer::VisitCheckedSmiUntag(
ProcessResult MaglevGraphOptimizer::VisitCheckedNumberToFloat64(
CheckedNumberToFloat64* node, const ProcessingState& state) {
MaybeReduceResult maybe_alt = GetUntaggedValueWithRepresentation(
- node->input_node(0), UseRepresentation::kFloat64,
- TaggedToFloat64ConversionType::kOnlyNumber);
+ node->input_node(0), UseRepresentation::kFloat64, NodeType::kNumber);
if (maybe_alt.IsDoneWithValue()) {
ValueNode* alt = maybe_alt.value();
// If the alternative check is weaker then the current node, then
@@ -2619,6 +2733,12 @@ ProcessResult MaglevGraphOptimizer::VisitUnsafeHoleyFloat64ToFloat64(
ProcessResult MaglevGraphOptimizer::VisitUnsafeFloat64ToHoleyFloat64(
UnsafeFloat64ToHoleyFloat64* node, const ProcessingState& state) {
// TODO(b/424157317): Optimize.
+ // A reduction can have replaced the input with one that carries the hole or
+ // undefined NaN since the widen was chosen, and widening those would give
+ // them back their meaning.
+ if (node->ValueInput().node()->MayBeHoleOrUndefinedNan()) {
+ node->OverwriteWith(Opcode::kChangeFloat64ToHoleyFloat64);
+ }
return ProcessResult::kContinue;
}
@@ -2628,12 +2748,6 @@ ProcessResult MaglevGraphOptimizer::VisitFloat64ToSilencedFloat64(
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64ToSilencedFloat64(
- HoleyFloat64ToSilencedFloat64* node, const ProcessingState& state) {
- // TODO(b/424157317): Optimize.
- return ProcessResult::kContinue;
-}
-
ProcessResult MaglevGraphOptimizer::VisitChangeFloat64ToHoleyFloat64(
ChangeFloat64ToHoleyFloat64* node, const ProcessingState& state) {
// TODO(b/424157317): Optimize.
@@ -2642,26 +2756,12 @@ ProcessResult MaglevGraphOptimizer::VisitChangeFloat64ToHoleyFloat64(
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64ConvertHoleToUndefined(
- HoleyFloat64ConvertHoleToUndefined* node, const ProcessingState& state) {
- // TODO(b/424157317): Optimize.
- return ProcessResult::kContinue;
-}
-
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64IsUndefinedOrHole(
HoleyFloat64IsUndefinedOrHole* node, const ProcessingState& state) {
// TODO(b/424157317): Optimize.
return ProcessResult::kContinue;
}
-ProcessResult MaglevGraphOptimizer::
- VisitLoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole(
- LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole* node,
- const ProcessingState& state) {
- // TODO(b/424157317): Optimize.
- return ProcessResult::kContinue;
-}
-
#else
ProcessResult MaglevGraphOptimizer::VisitHoleyFloat64IsHole(
@@ -3097,9 +3197,8 @@ ProcessResult MaglevGraphOptimizer::VisitInt32ToBoolean(
ProcessResult MaglevGraphOptimizer::VisitFloat64Abs(
Float64Abs* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->input_node(0),
+ NodeType::kNumberOrOddball)) {
return ReplaceWith(
reducer_.GetFloat64Constant(std::abs(cst.value().get_scalar())));
}
@@ -3150,9 +3249,8 @@ ProcessResult MaglevGraphOptimizer::VisitFloat64Negate(
ProcessResult MaglevGraphOptimizer::VisitFloat64RoundToFloat32(
Float64RoundToFloat32* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->ValueInput().node(),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->ValueInput().node(),
+ NodeType::kNumberOrOddball)) {
float value = static_cast<float>(cst.value().get_scalar());
return ReplaceWith(reducer_.GetFloat64Constant(static_cast<double>(value)));
}
@@ -3161,9 +3259,8 @@ ProcessResult MaglevGraphOptimizer::VisitFloat64RoundToFloat32(
ProcessResult MaglevGraphOptimizer::VisitFloat64Round(
Float64Round* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->input_node(0),
+ NodeType::kNumberOrOddball)) {
double value = cst.value().get_scalar();
switch (node->kind()) {
case Float64Round::Kind::kFloor:
@@ -3194,14 +3291,12 @@ ProcessResult MaglevGraphOptimizer::VisitFloat64Compare(
ProcessResult MaglevGraphOptimizer::VisitFloat64SameValue(
Float64SameValue* node, const ProcessingState& state) {
- auto left = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kOnlyNumber);
+ auto left =
+ reducer_.TryGetFloat64Constant(node->input_node(0), NodeType::kNumber);
if (!left) return ProcessResult::kContinue;
- auto right = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(1),
- TaggedToFloat64ConversionType::kOnlyNumber);
+ auto right =
+ reducer_.TryGetFloat64Constant(node->input_node(1), NodeType::kNumber);
if (!right) return ProcessResult::kContinue;
return ReplaceWith(reducer_.GetBooleanConstant(
@@ -3210,9 +3305,8 @@ ProcessResult MaglevGraphOptimizer::VisitFloat64SameValue(
ProcessResult MaglevGraphOptimizer::VisitFloat64ToBoolean(
Float64ToBoolean* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->input_node(0),
+ NodeType::kNumberOrOddball)) {
double value = cst.value().get_scalar();
bool boolean_value = value != 0.0 && !std::isnan(value);
return ReplaceWith(reducer_.GetBooleanConstant(
@@ -3251,9 +3345,8 @@ ProcessResult MaglevGraphOptimizer::VisitFloat64Ieee754Binary(
ProcessResult MaglevGraphOptimizer::VisitFloat64Sqrt(
Float64Sqrt* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->input_node(0),
+ NodeType::kNumberOrOddball)) {
return ReplaceWith(
reducer_.GetFloat64Constant(std::sqrt(cst.value().get_scalar())));
}
@@ -3588,9 +3681,8 @@ ProcessResult MaglevGraphOptimizer::VisitBranchIfIntPtrToBooleanTrue(
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64ToBooleanTrue(
BranchIfFloat64ToBooleanTrue* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node->ConditionInput().node(),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetFloat64Constant(node->ConditionInput().node(),
+ NodeType::kNumberOrOddball)) {
double value = cst.value().get_scalar();
bool condition_value = value != 0.0 && !std::isnan(value);
FoldBranch(state.block(), node, condition_value);
@@ -3601,9 +3693,8 @@ ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64ToBooleanTrue(
ProcessResult MaglevGraphOptimizer::VisitBranchIfHoleyFloat64ToBooleanTrue(
BranchIfHoleyFloat64ToBooleanTrue* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kHoleyFloat64, node->ConditionInput().node(),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetHoleyFloat64Constant(
+ node->ConditionInput().node(), NodeType::kNumberOrOddball)) {
bool result;
if (cst.value().is_undefined_or_hole_nan()) {
result = false;
@@ -3621,9 +3712,8 @@ ProcessResult MaglevGraphOptimizer::VisitBranchIfHoleyFloat64ToBooleanTrue(
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64IsUndefinedOrHole(
BranchIfFloat64IsUndefinedOrHole* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kHoleyFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetHoleyFloat64Constant(
+ node->input_node(0), NodeType::kNumberOrOddball)) {
FoldBranch(state.block(), node, cst.value().is_undefined_or_hole_nan());
return ProcessResult::kRevisit;
}
@@ -3634,9 +3724,8 @@ ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64IsUndefinedOrHole(
ProcessResult MaglevGraphOptimizer::VisitBranchIfFloat64IsHole(
BranchIfFloat64IsHole* node, const ProcessingState& state) {
- if (auto cst = reducer_.TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kHoleyFloat64, node->input_node(0),
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = reducer_.TryGetHoleyFloat64Constant(
+ node->input_node(0), NodeType::kNumberOrOddball)) {
FoldBranch(state.block(), node, cst.value().is_undefined_or_hole_nan());
return ProcessResult::kRevisit;
}
diff --git a/deps/v8/src/maglev/maglev-graph-optimizer.h b/deps/v8/src/maglev/maglev-graph-optimizer.h
index 62d680122b8..246d9716793 100644
--- a/deps/v8/src/maglev/maglev-graph-optimizer.h
+++ b/deps/v8/src/maglev/maglev-graph-optimizer.h
@@ -23,14 +23,14 @@ namespace v8 {
namespace internal {
namespace maglev {
-class MaglevGraphOptimizer {
+class V8_EXPORT_PRIVATE MaglevGraphOptimizer {
public:
explicit MaglevGraphOptimizer(
Graph* graph, RecomputeKnownNodeAspectsProcessor& kna_processor,
NodeRanges* ranges = nullptr);
void PreProcessGraph(Graph* graph) {}
- void PostProcessGraph(Graph* graph) {}
+ void PostProcessGraph(Graph* graph);
BlockProcessResult PreProcessBasicBlock(BasicBlock* block);
BlockProcessResult PostProcessBasicBlock(BasicBlock* block);
void PostPhiProcessing() {}
@@ -60,16 +60,10 @@ class MaglevGraphOptimizer {
kna_processor_.set_known_node_aspects(known_node_aspects);
}
- DeoptFrame* GetDeoptFrameForEagerDeopt() {
- CHECK(current_node()->properties().has_eager_deopt_info());
- return ¤t_node()->eager_deopt_info()->top_frame();
- }
+ DeoptFrame* GetDeoptFrameForEagerDeopt();
std::tuple<DeoptFrame*, interpreter::Register, int> GetDeoptFrameForLazyDeopt(
- bool can_throw) {
- CHECK(current_node()->properties().can_lazy_deopt());
- return current_node()->lazy_deopt_info()->GetFrameForCloning();
- }
+ bool can_throw);
void AttachExceptionHandlerInfo(NodeBase* node);
@@ -118,6 +112,10 @@ class MaglevGraphOptimizer {
// for refinements done in the middle of the block.
ZoneMap<ValueNode*, Range> block_range_refinements_;
+ // Identities removed from the graph, whose forwarding use is dropped in
+ // PostProcessGraph. See VisitIdentity.
+ ZoneVector<Identity*> removed_identities_;
+
NodeBase* current_node_;
NodeBase* current_node() const {
@@ -139,13 +137,13 @@ class MaglevGraphOptimizer {
ValueNode* GetConstantWithRepresentation(
ValueNode* node, UseRepresentation repr,
- std::optional<TaggedToFloat64ConversionType> conversion_type);
+ std::optional<NodeType> assumed_input_type);
// Returns a variant of the node with the value representation given. It
// returns nullptr if we need to emit a tagged conversion.
MaybeReduceResult GetUntaggedValueWithRepresentation(
ValueNode* node, UseRepresentation repr,
- std::optional<TaggedToFloat64ConversionType> conversion_type);
+ std::optional<NodeType> assumed_input_type);
// Records the untagged input of a tagging conversion as the matching
// untagged alternative of `tagged`, so a later untagging use can reuse it.
@@ -198,7 +196,7 @@ class MaglevGraphOptimizer {
// the GraphProcessor can stitch the new blocks into the live graph at the
// node currently being visited.
template <>
-class Subgraph<MaglevGraphOptimizer>
+class V8_EXPORT_PRIVATE Subgraph<MaglevGraphOptimizer>
: public SubgraphBase<Subgraph<MaglevGraphOptimizer>,
MaglevGraphOptimizer> {
public:
@@ -245,6 +243,9 @@ class Subgraph<MaglevGraphOptimizer>
KnownNodeAspects* saved_kna_;
// Enclosing subgraph, or nullptr if this is a top-level subgraph.
Subgraph<MaglevGraphOptimizer>* parent_;
+
+ ZoneVector<std::pair<int, Node*>> stashed_nodes_at_;
+ ZoneVector<Node*> stashed_nodes_at_end_;
};
} // namespace maglev
diff --git a/deps/v8/src/maglev/maglev-graph-printer.cc b/deps/v8/src/maglev/maglev-graph-printer.cc
index 79d551a1b45..1f776831c0c 100644
--- a/deps/v8/src/maglev/maglev-graph-printer.cc
+++ b/deps/v8/src/maglev/maglev-graph-printer.cc
@@ -403,7 +403,8 @@ BlockProcessResult MaglevPrintingVisitor::PreProcessBasicBlock(
if (block->state()->is_loop_with_peeled_iteration()) {
os_ << " peeled";
}
- if (const LoopEffects* loop_effects = block->state()->loop_effects()) {
+ if (const LoopEffects* loop_effects =
+ block->state()->AsLoopHeader()->loop_effects()) {
os_ << " (effects:";
if (loop_effects->unstable_aspects_cleared) {
os_ << " ua";
@@ -1086,7 +1087,7 @@ ProcessResult MaglevPrintingVisitor::Process(ControlNode* control_node,
os_ << "\n";
}
#ifdef V8_ENABLE_MAGLEV
- if (target->state()->register_state().is_initialized()) {
+ if (target->state()->has_register_state()) {
PrintVerticalArrows(os_, targets_);
PrintPadding(os_, max_node_id_, -1);
os_ << (has_fallthrough ? "│" : " ");
diff --git a/deps/v8/src/maglev/maglev-graph-processor.h b/deps/v8/src/maglev/maglev-graph-processor.h
index ab0b30c4e60..92a76cd0fb5 100644
--- a/deps/v8/src/maglev/maglev-graph-processor.h
+++ b/deps/v8/src/maglev/maglev-graph-processor.h
@@ -70,6 +70,8 @@ enum class ProcessResult {
// splice.
kRevisit, // Process this node again. Note that the node is allowed to have
// changed.
+ // TODO(dmercadier): add a DCHECK to ensure that processors
+ // converge and that we're not revisiting identical nodes.
kTruncateBlock, // Remove all nodes from this point from the basic block
// (including the current node) and do not call the following
// processors. If the node processor supports splicing and
@@ -229,6 +231,14 @@ class GraphProcessor {
++node_it_;
continue;
}
+#ifdef DEBUG
+ const Node* const* debug_nodes_data = nullptr;
+ size_t debug_nodes_size = 0;
+ if constexpr (SupportsSplice<NodeProcessor>) {
+ debug_nodes_data = block->nodes().data();
+ debug_nodes_size = block->nodes().size();
+ }
+#endif
ProcessResult result = ProcessNodeBase(
node, GetCurrentState(node_it_ - block->nodes().begin()));
if constexpr (SupportsSplice<NodeProcessor>) {
@@ -238,6 +248,13 @@ class GraphProcessor {
DCHECK_IMPLIES(node_processor_.HasPendingSplice(),
result == ProcessResult::kRemove ||
result == ProcessResult::kTruncateBlock);
+#ifdef DEBUG
+ if (!node_processor_.HasPendingSplice() &&
+ result != ProcessResult::kTruncateBlock) {
+ DCHECK_EQ(debug_nodes_data, block->nodes().data());
+ DCHECK_EQ(debug_nodes_size, block->nodes().size());
+ }
+#endif
}
switch (result) {
[[likely]] case ProcessResult::kContinue:
diff --git a/deps/v8/src/maglev/maglev-graph-verifier.h b/deps/v8/src/maglev/maglev-graph-verifier.h
index d13464e62b5..e1ae0dcb3be 100644
--- a/deps/v8/src/maglev/maglev-graph-verifier.h
+++ b/deps/v8/src/maglev/maglev-graph-verifier.h
@@ -51,6 +51,7 @@ class MaglevGraphVerifier {
CHECK(!seen_[block->id()]);
seen_[block->id()] = true;
current_block_ = block;
+ VerifyPredecessors(block);
return BlockProcessResult::kContinue;
}
void PostPhiProcessing() {}
@@ -85,6 +86,22 @@ class MaglevGraphVerifier {
}
private:
+ void VerifyPredecessors(BasicBlock* block) {
+ if (block->is_loop()) {
+ CHECK_GE(block->predecessor_count(), 1);
+ CHECK_LE(block->predecessor_count(), 2);
+ CHECK_IMPLIES(
+ block->predecessor_count() == 1,
+ block->state()->is_resumable_loop() || block->IsUnreachable());
+ CHECK(block->backedge_predecessor()->control_node()->Is<JumpLoop>());
+ }
+ if (block->has_phi()) {
+ for (Phi* phi : *block->phis()) {
+ CHECK_EQ(phi->input_count(), block->predecessor_count());
+ }
+ }
+ }
+
// Immediate dominators (Cooper-Harvey-Kennedy) and each value's defining
// block, so the dominance checks below can ask real dominance questions.
// TODO(victorgomes): Consider merging this with Turboshaft's dominator-tree
diff --git a/deps/v8/src/maglev/maglev-graph.cc b/deps/v8/src/maglev/maglev-graph.cc
index a824690047f..c4817435d72 100644
--- a/deps/v8/src/maglev/maglev-graph.cc
+++ b/deps/v8/src/maglev/maglev-graph.cc
@@ -89,16 +89,15 @@ void Graph::RemoveUnreachableBlocks() {
worklist.pop_back();
if (current->is_dead()) continue;
- for (auto handler : current->exception_handlers()) {
- if (!handler->HasExceptionHandler()) continue;
- if (handler->ShouldLazyDeopt()) continue;
- BasicBlock* catch_block = handler->catch_block();
- if (catch_block->is_dead()) continue;
+ current->ForEachNodeAndControl([&](NodeBase* node) {
+ BasicBlock* catch_block = node->GetLiveCatchBlock();
+ if (catch_block == nullptr) return;
+ if (catch_block->is_dead()) return;
if (!reachable_blocks[catch_block->id()]) {
reachable_blocks[catch_block->id()] = true;
worklist.push_back(catch_block);
}
- }
+ });
current->ForEachSuccessor([&](BasicBlock* succ) {
if (!reachable_blocks[succ->id()]) {
reachable_blocks[succ->id()] = true;
diff --git a/deps/v8/src/maglev/maglev-inlining.cc b/deps/v8/src/maglev/maglev-inlining.cc
index 297e44abcca..94e3001675a 100644
--- a/deps/v8/src/maglev/maglev-inlining.cc
+++ b/deps/v8/src/maglev/maglev-inlining.cc
@@ -196,13 +196,12 @@ MaglevInliner::InliningResult MaglevInliner::BuildInlineFunction(
!call_exception_handler_info->ShouldLazyDeopt()) {
BasicBlock* catch_block = call_exception_handler_info->catch_block();
catch_block_might_be_unreachable = true;
- for (ExceptionHandlerInfo* info : call_block->exception_handlers()) {
- if (info != call_exception_handler_info && info->HasExceptionHandler() &&
- !info->ShouldLazyDeopt() && info->catch_block() == catch_block) {
+ call_block->ForEachNodeAndControl([&](NodeBase* node) {
+ if (node == call_node) return;
+ if (node->GetLiveCatchBlock() == catch_block) {
catch_block_might_be_unreachable = false;
- break;
}
- }
+ });
}
// Remove unreachable catch block if no throwable nodes were added during
// inlining.
@@ -212,12 +211,6 @@ MaglevInliner::InliningResult MaglevInliner::BuildInlineFunction(
graph_->set_may_have_unreachable_blocks(true);
}
- // Remove exception handler info from call block.
- ExceptionHandlerInfo::List rem_handlers_in_call_block;
- call_block->exception_handlers().TruncateAt(&rem_handlers_in_call_block,
- call_exception_handler_info);
- rem_handlers_in_call_block.DropHead();
-
// Truncate the basic block.
ZoneVector<Node*> rem_nodes_in_call_block =
call_block->Split(call_node, zone());
@@ -341,8 +334,6 @@ MaglevInliner::InliningResult MaglevInliner::BuildInlineFunction(
BasicBlock* final_block = inner_graph_builder.FinishInlinedBlockForCaller(
control_node, rem_nodes_in_call_block);
DCHECK_NOT_NULL(final_block);
- final_block->exception_handlers().Append(
- std::move(rem_handlers_in_call_block));
// Update the predecessor of the successors of the {final_block}, that were
// previously pointing to {call_block}.
diff --git a/deps/v8/src/maglev/maglev-interpreter-frame-state.cc b/deps/v8/src/maglev/maglev-interpreter-frame-state.cc
index c35ba2aea80..ed0d40bbbd7 100644
--- a/deps/v8/src/maglev/maglev-interpreter-frame-state.cc
+++ b/deps/v8/src/maglev/maglev-interpreter-frame-state.cc
@@ -112,20 +112,19 @@ void MergePointInterpreterFrameState::set_is_resumable_loop(Graph* graph) {
}
// static
-MergePointInterpreterFrameState* MergePointInterpreterFrameState::NewForLoop(
- const InterpreterFrameState& start_state, const MaglevCompilationUnit& info,
- bool is_inline, Graph* graph, int merge_offset, int predecessor_count,
+LoopMergePointInterpreterFrameState*
+MergePointInterpreterFrameState::NewForLoop(
+ const MaglevCompilationUnit& info, bool is_inline, Graph* graph,
+ int merge_offset, int predecessor_count,
const compiler::BytecodeLivenessState* liveness,
const compiler::LoopInfo* loop_info, bool has_been_peeled) {
- MergePointInterpreterFrameState* state =
- info.zone()->New<MergePointInterpreterFrameState>(
+ LoopMergePointInterpreterFrameState* state =
+ info.zone()->New<LoopMergePointInterpreterFrameState>(
info, merge_offset, predecessor_count, 0,
- info.zone()->AllocateArray<BasicBlock*>(predecessor_count),
- BasicBlockType::kLoopHeader, liveness, std::nullopt);
+ info.zone()->AllocateArray<BasicBlock*>(predecessor_count), liveness);
state->bitfield_ =
kIsLoopWithPeeledIterationBit::update(state->bitfield_, has_been_peeled);
- state->loop_metadata_ = LoopMetadata{loop_info, nullptr};
if (loop_info->resumable() && !is_inline && !graph->is_osr()) {
// Note that inlined and OSR'd loops are never resumable:
//
@@ -156,8 +155,10 @@ MergePointInterpreterFrameState* MergePointInterpreterFrameState::NewForLoop(
if (assignments.ContainsParameter(reg.ToParameterIndex())) {
entry = state->NewLoopPhi(info.zone(), reg);
} else if (state->is_resumable_loop()) {
- // Copy initial values out of the start state.
- entry = start_state.get(reg);
+ // Copy initial values out of the graph parameters. Resumable loops
+ // are never inlined, so those are the function's own parameters.
+ DCHECK(!is_inline);
+ entry = graph->parameters()[reg.ToParameterIndex()];
// Initialise the alternatives list for this value.
new (&state->per_predecessor_alternatives_[i]) Alternatives::List();
DCHECK(entry->Is<InitialValue>());
@@ -242,17 +243,18 @@ MergePointInterpreterFrameState::MergePointInterpreterFrameState(
int predecessors_so_far, BasicBlock** predecessors, BasicBlockType type,
const compiler::BytecodeLivenessState* liveness,
compiler::OptionalScopeInfoRef context_scope_info)
- : merge_offset_(merge_offset),
- unit_(&info),
+ : unit_(&info),
predecessor_count_(predecessor_count),
predecessors_so_far_(predecessors_so_far),
bitfield_(kBasicBlockTypeBits::encode(type) |
kIsInline::encode(info.is_inline())),
+ merge_offset_(merge_offset),
predecessors_(predecessors),
frame_state_(info, liveness),
context_scope_info_(context_scope_info),
per_predecessor_alternatives_(
- type == BasicBlockType::kExceptionHandlerStart
+ type == BasicBlockType::kExceptionHandlerStart ||
+ type == BasicBlockType::kUnusedExceptionHandlerStart
? nullptr
: info.zone()->AllocateArray<Alternatives::List>(
frame_state_.size(info))) {}
@@ -495,7 +497,7 @@ void MergePointInterpreterFrameState::Merge(
DCHECK_LE(predecessors_so_far_, predecessor_count_);
}
-void MergePointInterpreterFrameState::MergeLoop(
+void LoopMergePointInterpreterFrameState::MergeLoop(
Graph* graph, bool is_tracing, MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& loop_end_state, BasicBlock* loop_end_block,
DeoptFrame* backedge_deopt_frame) {
@@ -523,25 +525,9 @@ void MergePointInterpreterFrameState::MergeLoop(
});
predecessors_so_far_++;
DCHECK_EQ(predecessors_so_far_, predecessor_count_);
-
- // We have to clear the LoopInfo (which is used to record more precise use
- // hints for Phis) for 2 reasons:
- //
- // - Phi::RecordUseReprHint checks if a use is inside the loop defining the
- // Phi by checking if the LoopInfo of the loop Phi "Contains" the current
- // bytecode offset, but this will be wrong if the Phi is in a function that
- // was inlined (because the LoopInfo contains the first and last bytecode
- // offset of the loop **in its own function**).
- //
- // - LoopInfo is obtained from the {header_to_info_} member of
- // BytecodeAnalysis, but the BytecodeAnalysis is a member of the
- // MaglevGraphBuilder, and thus gets destructed when the MaglevGraphBuilder
- // created for inlining is destructed. LoopInfo would then become a stale
- // pointer.
- ClearLoopInfo();
}
-bool MergePointInterpreterFrameState::TryMergeLoop(
+bool LoopMergePointInterpreterFrameState::TryMergeLoop(
compiler::JSHeapBroker* broker, Graph* graph, bool is_tracing,
MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& loop_end_state,
@@ -559,7 +545,6 @@ bool MergePointInterpreterFrameState::TryMergeLoop(
*known_node_aspects_)) {
const MaglevCompilationInfo* info = compilation_unit.info();
TRACE(TraceColor::kRed << "Merging failed, peeling loop instead... ");
- ClearLoopInfo();
return false;
}
@@ -586,7 +571,6 @@ bool MergePointInterpreterFrameState::TryMergeLoop(
}
});
if (!phis_can_merge) {
- ClearLoopInfo();
return false;
}
@@ -614,23 +598,9 @@ bool MergePointInterpreterFrameState::TryMergeLoop(
});
predecessors_so_far_++;
DCHECK_EQ(predecessors_so_far_, predecessor_count_);
- ClearLoopInfo();
return true;
}
-void MergePointInterpreterFrameState::set_loop_effects(
- LoopEffects* loop_effects) {
- DCHECK(is_loop());
- DCHECK(loop_metadata_.has_value());
- loop_metadata_->loop_effects = loop_effects;
-}
-
-const LoopEffects* MergePointInterpreterFrameState::loop_effects() {
- DCHECK(is_loop());
- DCHECK(loop_metadata_.has_value());
- return loop_metadata_->loop_effects;
-}
-
void MergePointInterpreterFrameState::MergeThrow(
Graph* graph, bool is_tracing, const InterpreterFrameState& handler_frame,
const KnownNodeAspects& known_node_aspects,
diff --git a/deps/v8/src/maglev/maglev-interpreter-frame-state.h b/deps/v8/src/maglev/maglev-interpreter-frame-state.h
index 7d35640a61b..e6def7bf9b8 100644
--- a/deps/v8/src/maglev/maglev-interpreter-frame-state.h
+++ b/deps/v8/src/maglev/maglev-interpreter-frame-state.h
@@ -28,6 +28,7 @@ namespace maglev {
class BasicBlock;
class Graph;
+class LoopMergePointInterpreterFrameState;
class MergePointInterpreterFrameState;
struct LoopEffects;
@@ -262,8 +263,6 @@ class MergePointRegisterState {
#ifdef V8_ENABLE_MAGLEV
public:
- bool is_initialized() const { return values_[0].GetPayload().is_initialized; }
-
template <typename Function>
void ForEachGeneralRegister(Function&& f) {
RegisterState* current_value = &values_[0];
@@ -304,8 +303,7 @@ class MergePointInterpreterFrameState {
const compiler::BytecodeLivenessState* liveness,
compiler::OptionalScopeInfoRef context_scope_info);
- static MergePointInterpreterFrameState* NewForLoop(
- const InterpreterFrameState& start_state,
+ static LoopMergePointInterpreterFrameState* NewForLoop(
const MaglevCompilationUnit& info, bool is_inline, Graph* graph,
int merge_offset, int predecessor_count,
const compiler::BytecodeLivenessState* liveness,
@@ -344,21 +342,8 @@ class MergePointInterpreterFrameState {
LoopEffects* loop_effects = nullptr);
void InitializeWithBasicBlock(BasicBlock* current_block);
- // Merges an unmerged framestate with a possibly merged framestate into |this|
- // framestate.
- void MergeLoop(Graph* graph, bool is_tracing,
- MaglevCompilationUnit& compilation_unit,
- InterpreterFrameState& loop_end_state,
- BasicBlock* loop_end_block, DeoptFrame* backedge_deopt_frame);
- void set_loop_effects(LoopEffects* loop_effects);
- const LoopEffects* loop_effects();
- // Merges a frame-state that might not be mergable, in which case we need to
- // re-compile the loop again. Calls FinishBlock only if the merge succeeded.
- bool TryMergeLoop(compiler::JSHeapBroker* broker, Graph* graph,
- bool is_tracing, MaglevCompilationUnit& compilation_unit,
- InterpreterFrameState& loop_end_state,
- const std::function<BasicBlock*()>& FinishBlock,
- DeoptFrame* backedge_deopt_frame);
+ inline LoopMergePointInterpreterFrameState* AsLoopHeader();
+ inline const LoopMergePointInterpreterFrameState* AsLoopHeader() const;
// Merges an unmerged framestate into a possibly merged framestate at the
// start of the target catchblock.
@@ -431,7 +416,16 @@ class MergePointInterpreterFrameState {
const CompactInterpreterFrameState& frame_state() const {
return frame_state_;
}
- MergePointRegisterState& register_state() { return register_state_; }
+ bool has_register_state() const { return register_state_ != nullptr; }
+ MergePointRegisterState& register_state() {
+ DCHECK_NOT_NULL(register_state_);
+ return *register_state_;
+ }
+ void set_register_state(MergePointRegisterState* register_state) {
+ DCHECK_NULL(register_state_);
+ DCHECK_NOT_NULL(register_state);
+ register_state_ = register_state;
+ }
bool has_phi() const { return !phis_.is_empty(); }
Phi::List* phis() { return &phis_; }
@@ -487,13 +481,6 @@ class MergePointInterpreterFrameState {
return is_loop() && predecessors_so_far_ < predecessor_count_;
}
- bool is_unmerged_unreachable_loop() const {
- // If there is only one predecessor, and it's not set, then this is a loop
- // merge with no forward control flow entering it.
- return is_unmerged_loop() && !is_resumable_loop() &&
- predecessor_count_ == 1 && predecessors_so_far_ == 0;
- }
-
bool IsUnreachableByForwardEdge() const;
bool IsUnreachable() const;
@@ -519,24 +506,6 @@ class MergePointInterpreterFrameState {
const MaglevCompilationUnit& unit() const { return *unit_; }
- DeoptFrame* backedge_deopt_frame() const { return backedge_deopt_frame_; }
-
- KnownNodeAspects* backedge_known_node_aspects() const {
- DCHECK(is_loop());
- DCHECK_NOT_NULL(backedge_known_node_aspects_);
- return backedge_known_node_aspects_;
- }
-
- const compiler::LoopInfo* loop_info() const {
- DCHECK(loop_metadata_.has_value());
- DCHECK_NOT_NULL(loop_metadata_->loop_info);
- return loop_metadata_->loop_info;
- }
- void ClearLoopInfo() { loop_metadata_->loop_info = nullptr; }
- bool HasLoopInfo() const {
- return loop_metadata_.has_value() && loop_metadata_->loop_info;
- }
-
interpreter::Register catch_block_context_register() const {
DCHECK(is_exception_handler());
return catch_block_context_register_;
@@ -576,12 +545,19 @@ class MergePointInterpreterFrameState {
template <typename T, typename... Args>
friend T* Zone::New(Args&&... args);
+ protected:
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);
+ void MergeLoopValue(Graph* graph, bool is_tracing,
+ interpreter::Register owner,
+ const KnownNodeAspects& unmerged_aspects,
+ ValueNode* merged, ValueNode* unmerged);
+
+ private:
void MergePhis(Graph* graph, bool is_tracing,
MaglevCompilationUnit& compilation_unit,
InterpreterFrameState& unmerged, BasicBlock* predecessor,
@@ -608,11 +584,6 @@ class MergePointInterpreterFrameState {
Graph* graph, const KnownNodeAspects& unmerged_aspects, ValueNode* merged,
ValueNode* unmerged);
- void MergeLoopValue(Graph* graph, bool is_tracing,
- interpreter::Register owner,
- const KnownNodeAspects& unmerged_aspects,
- ValueNode* merged, ValueNode* unmerged);
-
ValueNode* NewLoopPhi(Zone* zone, interpreter::Register reg);
ValueNode* NewExceptionPhi(Zone* zone, interpreter::Register reg) {
@@ -623,48 +594,110 @@ class MergePointInterpreterFrameState {
return result;
}
- int merge_offset_;
+ protected:
const MaglevCompilationUnit* unit_;
uint32_t predecessor_count_;
uint32_t predecessors_so_far_;
uint32_t bitfield_;
+ int merge_offset_;
BasicBlock** predecessors_;
Phi::List phis_;
CompactInterpreterFrameState frame_state_;
- MergePointRegisterState register_state_;
KnownNodeAspects* known_node_aspects_ = nullptr;
compiler::OptionalScopeInfoRef context_scope_info_;
- // The KNA from the backedge (end of the loop). Only used for loop headers.
- KnownNodeAspects* backedge_known_node_aspects_ = nullptr;
-
union {
// {pre_predecessor_alternatives_} is used to keep track of the alternatives
// of Phi inputs. Once the block has been merged, it's not used anymore.
Alternatives::List* per_predecessor_alternatives_;
- // {backedge_deopt_frame_} is used to record 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 (and will only be set for
- // loop headers), when the header has already been merged and
- // {per_predecessor_alternatives_} is thus not used anymore.
- DeoptFrame* backedge_deopt_frame_;
// For catch blocks, store the interpreter register holding the context.
// This will be the same value for all incoming merges.
interpreter::Register catch_block_context_register_;
};
- struct LoopMetadata {
- const compiler::LoopInfo* loop_info;
- const LoopEffects* loop_effects;
- };
- std::optional<LoopMetadata> loop_metadata_ = std::nullopt;
+ // Set by the register allocator, which only publishes it here once it is
+ // fully initialized. Never set when the Maglev graph is only used as
+ // Turbolev's frontend.
+ MergePointRegisterState* register_state_ = nullptr;
};
+// Merge states of loop headers carry additional fields. They are only created
+// by NewForLoop; is_loop() implies that the state is a
+// LoopMergePointInterpreterFrameState.
+class LoopMergePointInterpreterFrameState final
+ : public MergePointInterpreterFrameState {
+ public:
+ // Merges an unmerged framestate with a possibly merged framestate into |this|
+ // framestate.
+ void MergeLoop(Graph* graph, bool is_tracing,
+ MaglevCompilationUnit& compilation_unit,
+ InterpreterFrameState& loop_end_state,
+ BasicBlock* loop_end_block, DeoptFrame* backedge_deopt_frame);
+ // Merges a frame-state that might not be mergable, in which case we need to
+ // re-compile the loop again. Calls FinishBlock only if the merge succeeded.
+ bool TryMergeLoop(compiler::JSHeapBroker* broker, Graph* graph,
+ bool is_tracing, MaglevCompilationUnit& compilation_unit,
+ InterpreterFrameState& loop_end_state,
+ const std::function<BasicBlock*()>& FinishBlock,
+ DeoptFrame* backedge_deopt_frame);
+
+ void set_loop_effects(LoopEffects* loop_effects) {
+ loop_effects_ = loop_effects;
+ }
+ const LoopEffects* loop_effects() const { return loop_effects_; }
+
+ DeoptFrame* backedge_deopt_frame() const { return backedge_deopt_frame_; }
+
+ KnownNodeAspects* backedge_known_node_aspects() const {
+ DCHECK_NOT_NULL(backedge_known_node_aspects_);
+ return backedge_known_node_aspects_;
+ }
+
+ private:
+ template <typename T, typename... Args>
+ friend T* Zone::New(Args&&... args);
+
+ LoopMergePointInterpreterFrameState(
+ const MaglevCompilationUnit& info, int merge_offset,
+ int predecessor_count, int predecessors_so_far, BasicBlock** predecessors,
+ const compiler::BytecodeLivenessState* liveness)
+ : MergePointInterpreterFrameState(
+ info, merge_offset, predecessor_count, predecessors_so_far,
+ predecessors, BasicBlockType::kLoopHeader, liveness, std::nullopt) {
+ }
+
+ const LoopEffects* loop_effects_ = nullptr;
+ // The KNA from the backedge (end of the loop).
+ KnownNodeAspects* backedge_known_node_aspects_ = nullptr;
+ // 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;
+};
+
+inline LoopMergePointInterpreterFrameState*
+MergePointInterpreterFrameState::AsLoopHeader() {
+ DCHECK(is_loop());
+ return static_cast<LoopMergePointInterpreterFrameState*>(this);
+}
+
+inline const LoopMergePointInterpreterFrameState*
+MergePointInterpreterFrameState::AsLoopHeader() const {
+ DCHECK(is_loop());
+ return static_cast<const LoopMergePointInterpreterFrameState*>(this);
+}
+
+#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);
+#endif
+
struct LoopEffects {
explicit LoopEffects(int loop_header, Zone* zone)
:
@@ -686,6 +719,11 @@ struct LoopEffects {
bool unstable_aspects_cleared = false;
bool elements_kind_transitioned = false;
bool may_have_aliasing_contexts = false;
+ bool WritesContextSlotOffset(int offset) const {
+ return std::any_of(
+ context_slot_written.begin(), context_slot_written.end(),
+ [offset](const auto& key) { return std::get<int>(key) == offset; });
+ }
void Merge(const LoopEffects* other) {
if (!unstable_aspects_cleared) {
unstable_aspects_cleared = other->unstable_aspects_cleared;
diff --git a/deps/v8/src/maglev/maglev-ir.cc b/deps/v8/src/maglev/maglev-ir.cc
index 4ea43c7fa37..e8d91edd72a 100644
--- a/deps/v8/src/maglev/maglev-ir.cc
+++ b/deps/v8/src/maglev/maglev-ir.cc
@@ -7,6 +7,7 @@
#include <cmath>
#include <limits>
#include <optional>
+#include <type_traits>
#include "src/api/api.h"
#include "src/base/bounds.h"
@@ -469,7 +470,7 @@ bool CheckToBooleanOnAllRoots(LocalIsolate* local_isolate) {
/* Also ignore any non-JSAny values. */ \
if ((roots.name() != roots.undefined_value() || \
RootIndex::k##CamelName == RootIndex::kUndefinedValue) && \
- !IsAnyHole(roots.name()) && Is<JSAny>(roots.name())) { \
+ !IsInaccessible(roots.name()) && Is<JSAny>(roots.name())) { \
DCHECK_EQ(Object::BooleanValue(roots.name(), local_isolate), \
RootToBoolean(RootIndex::k##CamelName)); \
}
@@ -641,6 +642,83 @@ bool NodeBase::IsStructurallyEqualTo(const NodeBase* other) const {
UNREACHABLE();
}
+bool ValueNode::MayBeHoleOrUndefinedNan() const {
+ DCHECK(is_float64_or_holey_float64());
+ switch (opcode()) {
+ // Values built out of integers, values that were canonicalized already, and
+ // conversions that deopt on the hole and undefined NaNs.
+ case Opcode::kChangeInt32ToFloat64:
+ case Opcode::kChangeInt32ToHoleyFloat64:
+ case Opcode::kChangeIntPtrToFloat64:
+ case Opcode::kChangeUint32ToFloat64:
+ case Opcode::kChangeUint32ToHoleyFloat64:
+ case Opcode::kChangeFloat64ToHoleyFloat64:
+ case Opcode::kFloat64ToSilencedFloat64:
+ case Opcode::kCheckedHoleyFloat64ToFloat64:
+ return false;
+
+ // Both patterns are signalling NaNs, and an IEEE 754 arithmetic
+ // instruction never returns one: a NaN operand comes back quieted, and a
+ // NaN produced out of non-NaN operands is the default quiet NaN. This says
+ // nothing about the operations implemented as a call into C, which can
+ // hand back the NaN they were given.
+ case Opcode::kFloat64Add:
+ case Opcode::kFloat64SpeculateSafeAdd:
+ case Opcode::kFloat64Subtract:
+ case Opcode::kFloat64Multiply:
+ case Opcode::kFloat64Divide:
+ case Opcode::kFloat64Sqrt:
+ return false;
+
+ case Opcode::kFloat64Constant:
+ return Cast<Float64Constant>()->value().is_signalling_nan();
+ case Opcode::kHoleyFloat64Constant:
+ return Cast<HoleyFloat64Constant>()->value().is_signalling_nan();
+
+ // Casts that reinterpret the bits without touching them, so they carry the
+ // patterns exactly when their input does.
+ case Opcode::kReturnedValue:
+ case Opcode::kUnsafeHoleyFloat64ToFloat64:
+ case Opcode::kUnsafeFloat64ToHoleyFloat64:
+ return input_node(0)->MayBeHoleOrUndefinedNan();
+
+ // Reads of memory that anyone can write the patterns into, and operations
+ // on the bits rather than on the value: negating 0x7FF7'FFFF'FFF7'FFFF
+ // yields the hole, and Float64Max returns its input untouched when both
+ // inputs are the same node.
+ case Opcode::kLoadFloat64:
+ case Opcode::kLoadFixedDoubleArrayElement:
+ case Opcode::kLoadHoleyFixedDoubleArrayElement:
+ case Opcode::kLoadDoubleDataViewElement:
+ case Opcode::kLoadDoubleTypedArrayElement:
+ case Opcode::kLoadDoubleConstantTypedArrayElement:
+ case Opcode::kCheckedNumberToFloat64:
+ case Opcode::kCheckedNumberOrOddballToFloat64:
+ case Opcode::kCheckedNumberOrOddballToHoleyFloat64:
+ case Opcode::kUnsafeNumberToFloat64:
+ case Opcode::kUnsafeNumberOrOddballToFloat64:
+ case Opcode::kUnsafeNumberOrOddballToHoleyFloat64:
+ case Opcode::kFloat64Abs:
+ case Opcode::kFloat64Negate:
+ case Opcode::kFloat64Max:
+ case Opcode::kFloat64Min:
+ case Opcode::kFloat64Round:
+ case Opcode::kFloat64RoundToFloat32:
+ case Opcode::kFloat64Modulus:
+ case Opcode::kFloat64Exponentiate:
+ case Opcode::kFloat64Ieee754Unary:
+ case Opcode::kFloat64Ieee754Binary:
+ // TODO(victorgomes): Look through the inputs instead.
+ case Opcode::kPhi:
+ return true;
+
+ default:
+ // Every node that can produce a Float64 or HoleyFloat64 value has to be
+ // classified above.
+ UNREACHABLE();
+ }
+}
+
void ValueNode::SetHint(compiler::InstructionOperand hint) {
DCHECK_EQ(state_, kRegallocInfo);
auto node_info = regalloc_info();
@@ -764,11 +842,16 @@ Tribool ValueNode::IsTheHole() const {
return ToTribool(cst->index() == RootIndex::kTheHoleValue);
}
if (const LoadTaggedField* load = TryCast<LoadTaggedField>()) {
- // Modules variables can be the hole.
- if (load->offset() == offsetof(Cell, maybe_value_)) {
- return Tribool::kMaybe;
+ // There are a few ways that this can load a hole, for instance through a
+ // modules variable, or because this is actually a load from a FixedArray
+ // (TryBuildLoadFixedArrayElementConstantIndex emits LoadTaggedField instead
+ // of LoadFixedArrayElement when the index is known).
+ if (load->type() != NodeType::kUnknown) {
+ // There is no NodeType that contains the hole, so if this load has a
+ // type, it cannot be the hole.
+ return Tribool::kFalse;
}
- return Tribool::kFalse;
+ return Tribool::kMaybe;
}
if (const LoadFixedArrayElement* load = TryCast<LoadFixedArrayElement>()) {
if (load->load_type() != LoadType::kUnknown) {
@@ -972,6 +1055,16 @@ void InlinedAllocation::VerifyInputs() const {
CheckInputIs(0, Opcode::kAllocationBlock);
}
+void UnsafeFloat64ToHoleyFloat64::VerifyInputs() const {
+ Base::VerifyInputs();
+ CHECK(!input_node(0)->UnwrapIdentities()->MayBeHoleOrUndefinedNan());
+}
+
+void StoreFixedDoubleArrayElement::VerifyInputs() const {
+ Base::VerifyInputs();
+ CHECK(!ValueInput().node()->UnwrapIdentities()->MayBeHoleOrUndefinedNan());
+}
+
AllocationBlock* InlinedAllocation::allocation_block() {
return AllocationBlockInput().node()->Cast<AllocationBlock>();
}
@@ -1526,20 +1619,21 @@ constexpr Builtin BuiltinFor(Operation operation) {
} // namespace
template <class Derived, Operation kOperation>
-void UnaryWithFeedbackNode<Derived, kOperation>::SetValueLocationConstraints() {
- using D = UnaryOp_WithFeedbackDescriptor;
+void UnaryWithEmbeddedFeedbackNode<Derived,
+ kOperation>::SetValueLocationConstraints() {
+ using D = UnaryOp_WithEmbeddedFeedbackDescriptor;
UseFixed(ValueInput(), D::GetRegisterParameter(D::kValue));
DefineAsFixed(this, kReturnRegister0);
}
template <class Derived, Operation kOperation>
-void UnaryWithFeedbackNode<Derived, kOperation>::GenerateCode(
+void UnaryWithEmbeddedFeedbackNode<Derived, kOperation>::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
__ CallBuiltin<BuiltinFor(kOperation)>(
masm->native_context().object(), // context
ValueInput(), // value
- feedback().index(), // feedback slot
- feedback().vector // feedback vector
+ feedback().offset_, // feedback offset
+ feedback().bytecode_array_ // bytecode array
);
masm->DefineExceptionHandlerAndLazyDeoptPoint(this);
}
@@ -2064,93 +2158,84 @@ void CheckedSmiDecrement::GenerateCode(MaglevAssembler* masm,
namespace {
-void JumpToFailIfNotHeapNumberOrOddball(
- MaglevAssembler* masm, Register value,
- TaggedToFloat64ConversionType conversion_type, Label* fail) {
+void JumpToFailIfNotHeapNumberOrOddball(MaglevAssembler* masm, Register value,
+ NodeType assumed_input_type,
+ Label* fail) {
if (!fail && !v8_flags.debug_code) return;
static_assert(InstanceType::HEAP_NUMBER_TYPE + 1 ==
InstanceType::ODDBALL_TYPE);
- switch (conversion_type) {
- case TaggedToFloat64ConversionType::kNumberOrBoolean: {
- // Check if HeapNumber or Boolean, jump to fail otherwise.
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register map = temps.AcquireScratch();
+ if (NodeTypeIs(assumed_input_type, NodeType::kNumber)) {
+ // Check if HeapNumber, jump to fail otherwise.
+ if (fail) {
+ __ JumpIfNotObjectType(value, InstanceType::HEAP_NUMBER_TYPE, fail);
+ } else {
+ __ AssertObjectType(value, InstanceType::HEAP_NUMBER_TYPE,
+ AbortReason::kUnexpectedValue);
+ }
+ } else if (NodeTypeIs(assumed_input_type, NodeType::kNumberOrBoolean)) {
+ // Check if HeapNumber or Boolean, jump to fail otherwise.
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ Register map = temps.AcquireScratch();
#if V8_STATIC_ROOTS_BOOL
- static_assert(StaticReadOnlyRoot::kBooleanMap + Map::kSize ==
- StaticReadOnlyRoot::kHeapNumberMap);
- __ LoadMapForCompare(map, value);
- if (fail) {
- __ JumpIfObjectNotInRange(map, StaticReadOnlyRoot::kBooleanMap,
- StaticReadOnlyRoot::kHeapNumberMap, fail);
- } else {
- __ AssertObjectInRange(map, StaticReadOnlyRoot::kBooleanMap,
- StaticReadOnlyRoot::kHeapNumberMap,
- AbortReason::kUnexpectedValue);
- }
+ static_assert(StaticReadOnlyRoot::kBooleanMap + Map::kSize ==
+ StaticReadOnlyRoot::kHeapNumberMap);
+ __ LoadMapForCompare(map, value);
+ if (fail) {
+ __ JumpIfObjectNotInRange(map, StaticReadOnlyRoot::kBooleanMap,
+ StaticReadOnlyRoot::kHeapNumberMap, fail);
+ } else {
+ __ AssertObjectInRange(map, StaticReadOnlyRoot::kBooleanMap,
+ StaticReadOnlyRoot::kHeapNumberMap,
+ AbortReason::kUnexpectedValue);
+ }
#else
- Label done;
- __ LoadMap(map, value);
- __ CompareRoot(map, RootIndex::kHeapNumberMap);
- __ JumpIf(kEqual, &done);
- __ CompareRoot(map, RootIndex::kBooleanMap);
- if (fail) {
- __ JumpIf(kNotEqual, fail);
- } else {
- __ Assert(kEqual, AbortReason::kUnexpectedValue);
- }
- __ bind(&done);
-#endif
- break;
+ Label done;
+ __ LoadMap(map, value);
+ __ CompareRoot(map, RootIndex::kHeapNumberMap);
+ __ JumpIf(kEqual, &done);
+ __ CompareRoot(map, RootIndex::kBooleanMap);
+ if (fail) {
+ __ JumpIf(kNotEqual, fail);
+ } else {
+ __ Assert(kEqual, AbortReason::kUnexpectedValue);
}
+ __ bind(&done);
+#endif
+ } else if (NodeTypeIs(assumed_input_type, NodeType::kNumberOrUndefined)) {
+ // Check if HeapNumber or Undefined, jump to fail otherwise.
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ Register map = temps.AcquireScratch();
- case TaggedToFloat64ConversionType::kNumberOrUndefined: {
- // Check if HeapNumber or Undefined, jump to fail otherwise.
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register map = temps.AcquireScratch();
-
- Label done;
- __ LoadMap(map, value);
- __ CompareRoot(map, RootIndex::kHeapNumberMap);
- __ JumpIf(kEqual, &done);
- __ CompareRoot(map, RootIndex::kUndefinedMap);
- if (fail) {
- __ JumpIf(kNotEqual, fail);
- } else {
- __ Assert(kEqual, AbortReason::kUnexpectedValue);
- }
- __ bind(&done);
- break;
+ Label done;
+ __ LoadMap(map, value);
+ __ CompareRoot(map, RootIndex::kHeapNumberMap);
+ __ JumpIf(kEqual, &done);
+ __ CompareRoot(map, RootIndex::kUndefinedMap);
+ if (fail) {
+ __ JumpIf(kNotEqual, fail);
+ } else {
+ __ Assert(kEqual, AbortReason::kUnexpectedValue);
+ }
+ __ bind(&done);
+ } else {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ // Check if HeapNumber or Oddball, jump to fail otherwise.
+ if (fail) {
+ __ JumpIfObjectTypeNotInRange(value, InstanceType::HEAP_NUMBER_TYPE,
+ InstanceType::ODDBALL_TYPE, fail);
+ } else {
+ __ AssertObjectTypeInRange(value, InstanceType::HEAP_NUMBER_TYPE,
+ InstanceType::ODDBALL_TYPE,
+ AbortReason::kUnexpectedValue);
}
-
- case TaggedToFloat64ConversionType::kNumberOrOddball:
- // Check if HeapNumber or Oddball, jump to fail otherwise.
- if (fail) {
- __ JumpIfObjectTypeNotInRange(value, InstanceType::HEAP_NUMBER_TYPE,
- InstanceType::ODDBALL_TYPE, fail);
- } else {
- __ AssertObjectTypeInRange(value, InstanceType::HEAP_NUMBER_TYPE,
- InstanceType::ODDBALL_TYPE,
- AbortReason::kUnexpectedValue);
- }
- break;
- case TaggedToFloat64ConversionType::kOnlyNumber:
- // Check if HeapNumber, jump to fail otherwise.
- if (fail) {
- __ JumpIfNotObjectType(value, InstanceType::HEAP_NUMBER_TYPE, fail);
- } else {
- __ AssertObjectType(value, InstanceType::HEAP_NUMBER_TYPE,
- AbortReason::kUnexpectedValue);
- }
- break;
}
}
void TryUnboxNumberOrOddball(MaglevAssembler* masm, DoubleRegister dst,
Register clobbered_src,
- TaggedToFloat64ConversionType conversion_type,
- Label* fail) {
+ NodeType assumed_input_type, Label* fail) {
Label is_not_smi, done;
// Check if Smi.
__ JumpIfNotSmi(clobbered_src, &is_not_smi, Label::kNear);
@@ -2159,7 +2244,7 @@ void TryUnboxNumberOrOddball(MaglevAssembler* masm, DoubleRegister dst,
__ Int32ToDouble(dst, clobbered_src);
__ Jump(&done);
__ bind(&is_not_smi);
- JumpToFailIfNotHeapNumberOrOddball(masm, clobbered_src, conversion_type,
+ JumpToFailIfNotHeapNumberOrOddball(masm, clobbered_src, assumed_input_type,
fail);
__ LoadHeapNumberOrOddballValue(dst, clobbered_src);
__ bind(&done);
@@ -2175,7 +2260,7 @@ void CheckedNumberOrOddballToFloat64::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
Register value = ToRegister(ValueInput());
TryUnboxNumberOrOddball(masm, ToDoubleRegister(result()), value,
- conversion_type(),
+ assumed_input_type(),
__ GetDeoptLabel(this, deoptimize_reason()));
}
@@ -2187,8 +2272,7 @@ void CheckedNumberToFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register value = ToRegister(ValueInput());
TryUnboxNumberOrOddball(
- masm, ToDoubleRegister(result()), value,
- TaggedToFloat64ConversionType::kOnlyNumber,
+ masm, ToDoubleRegister(result()), value, NodeType::kNumber,
__ GetDeoptLabel(this, DeoptimizeReason::kNotANumber));
}
@@ -2210,7 +2294,7 @@ void CheckedNumberOrOddballToHoleyFloat64::GenerateCode(
__ Int32ToDouble(dst, src);
__ Jump(&done);
__ bind(&is_not_smi);
- JumpToFailIfNotHeapNumberOrOddball(masm, src, conversion_type(), fail);
+ JumpToFailIfNotHeapNumberOrOddball(masm, src, assumed_input_type(), fail);
__ LoadHeapNumberOrOddballValue(dst, src);
__ JumpIfNotObjectType(src, InstanceType::HEAP_NUMBER_TYPE, &done,
Label::kNear);
@@ -2226,7 +2310,7 @@ void UnsafeNumberOrOddballToFloat64::GenerateCode(
MaglevAssembler* masm, const ProcessingState& state) {
Register value = ToRegister(ValueInput());
TryUnboxNumberOrOddball(masm, ToDoubleRegister(result()), value,
- conversion_type(), nullptr);
+ assumed_input_type(), nullptr);
}
void UnsafeNumberToFloat64::SetValueLocationConstraints() {
@@ -2237,7 +2321,7 @@ void UnsafeNumberToFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register value = ToRegister(ValueInput());
TryUnboxNumberOrOddball(masm, ToDoubleRegister(result()), value,
- TaggedToFloat64ConversionType::kOnlyNumber, nullptr);
+ NodeType::kNumber, nullptr);
}
void UnsafeNumberOrOddballToHoleyFloat64::SetValueLocationConstraints() {
@@ -2257,7 +2341,7 @@ void UnsafeNumberOrOddballToHoleyFloat64::GenerateCode(
__ Int32ToDouble(dst, src);
__ Jump(&done);
__ bind(&is_not_smi);
- JumpToFailIfNotHeapNumberOrOddball(masm, src, conversion_type(), nullptr);
+ JumpToFailIfNotHeapNumberOrOddball(masm, src, assumed_input_type(), nullptr);
__ LoadHeapNumberOrOddballValue(dst, src);
__ JumpIfNotObjectType(src, InstanceType::HEAP_NUMBER_TYPE, &done,
Label::kNear);
@@ -2283,8 +2367,8 @@ void CheckedNumberToInt32::GenerateCode(MaglevAssembler* masm,
__ Jump(&done);
__ bind(&is_not_smi);
// Check if Number.
- JumpToFailIfNotHeapNumberOrOddball(
- masm, value, TaggedToFloat64ConversionType::kOnlyNumber, deopt_label);
+ JumpToFailIfNotHeapNumberOrOddball(masm, value, NodeType::kNumber,
+ deopt_label);
__ LoadHeapNumberValue(double_value, value);
__ TryTruncateDoubleToInt32(ToRegister(result()), double_value, deopt_label);
__ bind(&done);
@@ -2292,9 +2376,10 @@ void CheckedNumberToInt32::GenerateCode(MaglevAssembler* masm,
namespace {
-void EmitTruncateNumberOrOddballToInt32(
- MaglevAssembler* masm, Register value, Register result_reg,
- TaggedToFloat64ConversionType conversion_type, Label* not_a_number) {
+void EmitTruncateNumberOrOddballToInt32(MaglevAssembler* masm, Register value,
+ Register result_reg,
+ NodeType assumed_input_type,
+ Label* not_a_number) {
Label is_not_smi, done;
// Check if Smi.
__ JumpIfNotSmi(value, &is_not_smi, Label::kNear);
@@ -2302,7 +2387,7 @@ void EmitTruncateNumberOrOddballToInt32(
__ SmiToInt32(value);
__ Jump(&done, Label::kNear);
__ bind(&is_not_smi);
- JumpToFailIfNotHeapNumberOrOddball(masm, value, conversion_type,
+ JumpToFailIfNotHeapNumberOrOddball(masm, value, assumed_input_type,
not_a_number);
MaglevAssembler::TemporaryRegisterScope temps(masm);
DoubleRegister double_value = temps.AcquireScratchDouble();
@@ -2390,8 +2475,8 @@ void TruncateCheckedNumberOrOddballToInt32::GenerateCode(
DCHECK_EQ(value, result_reg);
Label* deopt_label =
__ GetDeoptLabel(this, DeoptimizeReason::kNotANumberOrOddball);
- EmitTruncateNumberOrOddballToInt32(masm, value, result_reg, conversion_type(),
- deopt_label);
+ EmitTruncateNumberOrOddballToInt32(masm, value, result_reg,
+ assumed_input_type(), deopt_label);
}
void TruncateUnsafeNumberOrOddballToInt32::SetValueLocationConstraints() {
@@ -2403,8 +2488,8 @@ void TruncateUnsafeNumberOrOddballToInt32::GenerateCode(
Register value = ToRegister(ValueInput());
Register result_reg = ToRegister(result());
DCHECK_EQ(value, result_reg);
- EmitTruncateNumberOrOddballToInt32(masm, value, result_reg, conversion_type(),
- nullptr);
+ EmitTruncateNumberOrOddballToInt32(masm, value, result_reg,
+ assumed_input_type(), nullptr);
}
void ChangeInt32ToFloat64::SetValueLocationConstraints() {
@@ -2559,6 +2644,12 @@ void CheckHomomorphicMap::GenerateCode(MaglevAssembler* masm,
int descriptor_index =
LoadHandler::DescriptorIndexBits::decode(handler_value_);
+ // Reject special receivers. Access checks and named interceptors imply
+ // special receiver.
+ __ CompareInstanceTypeAndJumpIf(
+ map, LAST_SPECIAL_RECEIVER_TYPE, kUnsignedLessThanEqual,
+ __ GetDeoptLabel(this, DeoptimizeReason::kWrongMap), Label::kFar);
+
// 1. Check descriptor count.
Register descriptor_count = scratch;
__ LoadInt32(descriptor_count,
@@ -3578,52 +3669,18 @@ void LoadHoleyFixedDoubleArrayElement::GenerateCode(
__ LoadFixedDoubleArrayElement(result_reg, elements, index);
}
-void LoadHoleyFixedDoubleArrayElementCheckedNotHole::
- SetValueLocationConstraints() {
- UseRegister(ElementsInput());
- UseRegister(IndexInput());
- DefineAsRegister(this);
- set_temporaries_needed(1);
-}
-void LoadHoleyFixedDoubleArrayElementCheckedNotHole::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register elements = ToRegister(ElementsInput());
- Register index = ToRegister(IndexInput());
- DoubleRegister result_reg = ToDoubleRegister(result());
- __ LoadFixedDoubleArrayElement(result_reg, elements, index);
- __ JumpIfHoleNan(result_reg, temps.Acquire(),
- __ GetDeoptLabel(this, DeoptimizeReason::kHole));
-}
-
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole::
- SetValueLocationConstraints() {
- UseRegister(ElementsInput());
- UseRegister(IndexInput());
- DefineAsRegister(this);
- set_temporaries_needed(1);
-}
-void LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register elements = ToRegister(ElementsInput());
- Register index = ToRegister(IndexInput());
- DoubleRegister result_reg = ToDoubleRegister(result());
- __ LoadFixedDoubleArrayElement(result_reg, elements, index);
- // TODO(nicohartmann): Should have a combined JumpIfUndefinedOrHoleNan.
- Register scratch = temps.Acquire();
- Label* deopt_label = __ GetDeoptLabel(this, DeoptimizeReason::kHole);
- __ JumpIfUndefinedNan(result_reg, scratch, deopt_label);
- __ JumpIfHoleNan(result_reg, scratch, deopt_label);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
template <typename Derived, ValueRepresentation value_input_rep>
void StoreFixedDoubleArrayElementT<
Derived, value_input_rep>::SetValueLocationConstraints() {
UseRegister(ElementsInput());
UseRegister(IndexInput());
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ if constexpr (value_input_rep == ValueRepresentation::kHoleyFloat64) {
+ UseAndClobberRegister(ValueInput());
+ this->set_temporaries_needed(1);
+ return;
+ }
+#endif // V8_ENABLE_UNDEFINED_DOUBLE
UseRegister(ValueInput());
}
template <typename Derived, ValueRepresentation value_input_rep>
@@ -3638,6 +3695,16 @@ void StoreFixedDoubleArrayElementT<Derived, value_input_rep>::GenerateCode(
__ CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ if constexpr (value_input_rep == ValueRepresentation::kHoleyFloat64) {
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ Register scratch = temps.Acquire();
+ Label done;
+ __ JumpIfNotHoleNan(value, scratch, &done);
+ __ Move(value, UndefinedNan());
+ __ bind(&done);
+ }
+#endif // V8_ENABLE_UNDEFINED_DOUBLE
__ StoreFixedDoubleArrayElement(elements, index, value);
}
@@ -3646,6 +3713,27 @@ template class StoreFixedDoubleArrayElementT<StoreFixedDoubleArrayElement,
template class StoreFixedDoubleArrayElementT<
StoreFixedHoleyDoubleArrayElement, ValueRepresentation::kHoleyFloat64>;
+void StoreFixedDoubleArrayHole::SetValueLocationConstraints() {
+ UseRegister(ElementsInput());
+ UseRegister(IndexInput());
+ set_double_temporaries_needed(1);
+}
+void StoreFixedDoubleArrayHole::GenerateCode(MaglevAssembler* masm,
+ const ProcessingState& state) {
+ Register elements = ToRegister(ElementsInput());
+ Register index = ToRegister(IndexInput());
+ if (v8_flags.debug_code) {
+ __ AssertObjectType(elements, FIXED_DOUBLE_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
+ __ CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
+ AbortReason::kUnexpectedNegativeValue);
+ }
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ DoubleRegister hole = temps.AcquireDouble();
+ __ Move(hole, Float64::hole_nan());
+ __ StoreFixedDoubleArrayElement(elements, index, hole);
+}
+
int StoreMap::MaxCallStackArgs() const {
return WriteBarrierDescriptor::GetStackParameterCount();
}
@@ -3732,7 +3820,24 @@ void StoreTrustedPointerFieldWithWriteBarrier::GenerateCode(
#endif
}
-void LoadSignedIntDataViewElement::SetValueLocationConstraints() {
+namespace {
+
+bool IsSigned(ExternalArrayType element_type) {
+ switch (element_type) {
+#define TYPED_ARRAY_CASE(Type, type, TYPE, ctype) \
+ case kExternal##Type##Array: \
+ DCHECK(std::is_integral_v<ctype>); \
+ return std::is_signed_v<ctype>;
+ TYPED_ARRAYS(TYPED_ARRAY_CASE)
+ default:
+ UNREACHABLE();
+#undef TYPED_ARRAY_CASE
+ }
+}
+
+} // namespace
+
+void LoadInt32DataViewElement::SetValueLocationConstraints() {
// Note: we're not actually using the object input (the DataView itself) since
// {data_pointer_input} already contains the pointer to the data, but we're
// still doing a `UseRegister(object_input())` in order to keep the DataView
@@ -3742,7 +3847,7 @@ void LoadSignedIntDataViewElement::SetValueLocationConstraints() {
UseRegister(DataPointerInput());
UseRegister(IndexInput());
if (IsIsLittleEndianInputConstant() ||
- type_ == ExternalArrayType::kExternalInt8Array) {
+ compiler::ExternalArrayElementSize(external_array_type()) == 1) {
UseAny(IsLittleEndianInput());
} else {
UseRegister(IsLittleEndianInput());
@@ -3750,33 +3855,42 @@ void LoadSignedIntDataViewElement::SetValueLocationConstraints() {
DefineAsRegister(this);
set_temporaries_needed(1);
}
-void LoadSignedIntDataViewElement::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
+void LoadInt32DataViewElement::GenerateCode(MaglevAssembler* masm,
+ const ProcessingState& state) {
Register data_pointer = ToRegister(DataPointerInput());
Register index = ToRegister(IndexInput());
Register result_reg = ToRegister(result());
- int element_size = compiler::ExternalArrayElementSize(type_);
+ int element_size = compiler::ExternalArrayElementSize(external_array_type());
+ bool is_signed = IsSigned(external_array_type());
// We need to make sure we don't clobber is_little_endian_input by writing to
// the result register.
Register reg_with_result = result_reg;
MaglevAssembler::TemporaryRegisterScope temps(masm);
- if (type_ != ExternalArrayType::kExternalInt8Array &&
- !IsIsLittleEndianInputConstant() &&
+ if (element_size > 1 && !IsIsLittleEndianInputConstant() &&
result_reg == ToRegister(IsLittleEndianInput())) {
reg_with_result = temps.Acquire();
}
- __ LoadDataViewElement(reg_with_result, data_pointer, index, element_size);
+ if (is_signed) {
+ __ LoadDataViewElement(reg_with_result, data_pointer, index, element_size);
+ } else {
+ __ LoadUnsignedDataViewElement(reg_with_result, data_pointer, index,
+ element_size);
+ }
// We ignore little endian argument if type is a byte size.
- if (type_ != ExternalArrayType::kExternalInt8Array) {
+ if (element_size > 1) {
if (IsIsLittleEndianInputConstant()) {
if (FromConstantToBool(masm, IsLittleEndianInput().node()) ==
V8_TARGET_BIG_ENDIAN_BOOL) {
DCHECK_EQ(reg_with_result, result_reg);
- __ ReverseByteOrder(result_reg, element_size);
+ if (is_signed) {
+ __ ReverseByteOrder(result_reg, element_size);
+ } else {
+ __ ReverseByteOrderUnsigned(result_reg, element_size);
+ }
}
} else {
ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
@@ -3787,7 +3901,11 @@ void LoadSignedIntDataViewElement::GenerateCode(MaglevAssembler* masm,
V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order,
false);
__ bind(*reverse_byte_order);
- __ ReverseByteOrder(reg_with_result, element_size);
+ if (is_signed) {
+ __ ReverseByteOrder(reg_with_result, element_size);
+ } else {
+ __ ReverseByteOrderUnsigned(reg_with_result, element_size);
+ }
__ bind(*keep_byte_order);
if (reg_with_result != result_reg) {
__ Move(result_reg, reg_with_result);
@@ -3796,7 +3914,57 @@ void LoadSignedIntDataViewElement::GenerateCode(MaglevAssembler* masm,
}
}
-void StoreSignedIntDataViewElement::SetValueLocationConstraints() {
+void LoadUint32DataViewElement::SetValueLocationConstraints() {
+ UseRegister(ObjectInput());
+ UseRegister(DataPointerInput());
+ UseRegister(IndexInput());
+ if (IsIsLittleEndianInputConstant()) {
+ UseAny(IsLittleEndianInput());
+ } else {
+ UseRegister(IsLittleEndianInput());
+ }
+ DefineAsRegister(this);
+ set_temporaries_needed(1);
+}
+void LoadUint32DataViewElement::GenerateCode(MaglevAssembler* masm,
+ const ProcessingState& state) {
+ Register data_pointer = ToRegister(DataPointerInput());
+ Register index = ToRegister(IndexInput());
+ Register result_reg = ToRegister(result());
+
+ Register reg_with_result = result_reg;
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ if (!IsIsLittleEndianInputConstant() &&
+ result_reg == ToRegister(IsLittleEndianInput())) {
+ reg_with_result = temps.Acquire();
+ }
+
+ __ LoadUnsignedDataViewElement(reg_with_result, data_pointer, index, 4);
+
+ if (IsIsLittleEndianInputConstant()) {
+ if (FromConstantToBool(masm, IsLittleEndianInput().node()) ==
+ V8_TARGET_BIG_ENDIAN_BOOL) {
+ DCHECK_EQ(reg_with_result, result_reg);
+ __ ReverseByteOrderUnsigned(result_reg, 4);
+ }
+ } else {
+ ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
+ DCHECK_NE(reg_with_result, ToRegister(IsLittleEndianInput()));
+ __ ToBoolean(
+ ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
+ V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
+ V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order,
+ false);
+ __ bind(*reverse_byte_order);
+ __ ReverseByteOrderUnsigned(reg_with_result, 4);
+ __ bind(*keep_byte_order);
+ if (reg_with_result != result_reg) {
+ __ Move(result_reg, reg_with_result);
+ }
+ }
+}
+
+void StoreInt32DataViewElement::SetValueLocationConstraints() {
// Note: we're not actually using the object input (the DataView itself) since
// {data_pointer_input} already contains the pointer to the data, but we're
// still doing a `UseRegister(object_input())` in order to keep the DataView
@@ -3805,25 +3973,25 @@ void StoreSignedIntDataViewElement::SetValueLocationConstraints() {
UseRegister(DataPointerInput());
UseRegister(IndexInput());
- if (compiler::ExternalArrayElementSize(type_) > 1) {
+ if (compiler::ExternalArrayElementSize(external_array_type()) > 1) {
UseAndClobberRegister(ValueInput());
} else {
UseRegister(ValueInput());
}
if (IsIsLittleEndianInputConstant() ||
- type_ == ExternalArrayType::kExternalInt8Array) {
+ compiler::ExternalArrayElementSize(external_array_type()) == 1) {
UseAny(IsLittleEndianInput());
} else {
UseRegister(IsLittleEndianInput());
}
}
-void StoreSignedIntDataViewElement::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
+void StoreInt32DataViewElement::GenerateCode(MaglevAssembler* masm,
+ const ProcessingState& state) {
Register data_pointer = ToRegister(DataPointerInput());
Register index = ToRegister(IndexInput());
Register value = ToRegister(ValueInput());
- int element_size = compiler::ExternalArrayElementSize(type_);
+ int element_size = compiler::ExternalArrayElementSize(external_array_type());
// We ignore little endian argument if type is a byte size.
if (element_size > 1) {
@@ -3870,31 +4038,62 @@ void LoadDoubleDataViewElement::GenerateCode(MaglevAssembler* masm,
Register index = ToRegister(IndexInput());
DoubleRegister result_reg = ToDoubleRegister(result());
- if (IsIsLittleEndianInputConstant()) {
- if (FromConstantToBool(masm, IsLittleEndianInput().node()) !=
- V8_TARGET_BIG_ENDIAN_BOOL) {
- __ LoadUnalignedFloat64(result_reg, data_pointer, index);
+ if (external_array_type() == ExternalArrayType::kExternalFloat64Array) {
+ if (IsIsLittleEndianInputConstant()) {
+ if (FromConstantToBool(masm, IsLittleEndianInput().node()) !=
+ V8_TARGET_BIG_ENDIAN_BOOL) {
+ __ LoadUnalignedFloat64(result_reg, data_pointer, index);
+ } else {
+ __ LoadUnalignedFloat64AndReverseByteOrder(result_reg, data_pointer,
+ index);
+ }
} else {
+ Label done;
+ ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
+ // TODO(leszeks): We're likely to be calling this on an existing boolean
+ // -- maybe that's a case we should fast-path here and reuse that boolean
+ // value?
+ __ ToBoolean(
+ ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
+ V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
+ V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order,
+ true);
+ __ bind(*keep_byte_order);
+ __ LoadUnalignedFloat64(result_reg, data_pointer, index);
+ __ Jump(&done);
+ // We should swap the bytes if big endian.
+ __ bind(*reverse_byte_order);
__ LoadUnalignedFloat64AndReverseByteOrder(result_reg, data_pointer,
index);
+ __ bind(&done);
}
} else {
- Label done;
- ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
- // TODO(leszeks): We're likely to be calling this on an existing boolean --
- // maybe that's a case we should fast-path here and reuse that boolean
- // value?
- __ ToBoolean(
- ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
- V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
- V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order, true);
- __ bind(*keep_byte_order);
- __ LoadUnalignedFloat64(result_reg, data_pointer, index);
- __ Jump(&done);
- // We should swap the bytes if big endian.
- __ bind(*reverse_byte_order);
- __ LoadUnalignedFloat64AndReverseByteOrder(result_reg, data_pointer, index);
- __ bind(&done);
+ DCHECK_EQ(external_array_type(), ExternalArrayType::kExternalFloat32Array);
+ if (IsIsLittleEndianInputConstant()) {
+ if (FromConstantToBool(masm, IsLittleEndianInput().node()) !=
+ V8_TARGET_BIG_ENDIAN_BOOL) {
+ __ LoadUnalignedFloat32(result_reg, data_pointer, index);
+ } else {
+ __ LoadUnalignedFloat32AndReverseByteOrder(result_reg, data_pointer,
+ index);
+ }
+ } else {
+ Label done;
+ ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
+ __ ToBoolean(
+ ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
+ V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
+ V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order,
+ true);
+ __ bind(*keep_byte_order);
+ __ LoadUnalignedFloat32(result_reg, data_pointer, index);
+ __ Jump(&done);
+ // We should swap the bytes if big endian.
+ __ bind(*reverse_byte_order);
+ __ LoadUnalignedFloat32AndReverseByteOrder(result_reg, data_pointer,
+ index);
+ __ bind(&done);
+ }
}
}
@@ -3920,30 +4119,58 @@ void StoreDoubleDataViewElement::GenerateCode(MaglevAssembler* masm,
Register index = ToRegister(IndexInput());
DoubleRegister value = ToDoubleRegister(ValueInput());
- if (IsIsLittleEndianInputConstant()) {
- if (FromConstantToBool(masm, IsLittleEndianInput().node()) !=
- V8_TARGET_BIG_ENDIAN_BOOL) {
- __ StoreUnalignedFloat64(data_pointer, index, value);
+ if (external_array_type() == ExternalArrayType::kExternalFloat64Array) {
+ if (IsIsLittleEndianInputConstant()) {
+ if (FromConstantToBool(masm, IsLittleEndianInput().node()) !=
+ V8_TARGET_BIG_ENDIAN_BOOL) {
+ __ StoreUnalignedFloat64(data_pointer, index, value);
+ } else {
+ __ ReverseByteOrderAndStoreUnalignedFloat64(data_pointer, index, value);
+ }
} else {
+ Label done;
+ ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
+ // TODO(leszeks): We're likely to be calling this on an existing boolean
+ // -- maybe that's a case we should fast-path here and reuse that boolean
+ // value?
+ __ ToBoolean(
+ ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
+ V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
+ V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order,
+ true);
+ __ bind(*keep_byte_order);
+ __ StoreUnalignedFloat64(data_pointer, index, value);
+ __ Jump(&done);
+ // We should swap the bytes if big endian.
+ __ bind(*reverse_byte_order);
__ ReverseByteOrderAndStoreUnalignedFloat64(data_pointer, index, value);
+ __ bind(&done);
}
} else {
- Label done;
- ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
- // TODO(leszeks): We're likely to be calling this on an existing boolean --
- // maybe that's a case we should fast-path here and reuse that boolean
- // value?
- __ ToBoolean(
- ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
- V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
- V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order, true);
- __ bind(*keep_byte_order);
- __ StoreUnalignedFloat64(data_pointer, index, value);
- __ Jump(&done);
- // We should swap the bytes if big endian.
- __ bind(*reverse_byte_order);
- __ ReverseByteOrderAndStoreUnalignedFloat64(data_pointer, index, value);
- __ bind(&done);
+ DCHECK_EQ(external_array_type(), ExternalArrayType::kExternalFloat32Array);
+ if (IsIsLittleEndianInputConstant()) {
+ if (FromConstantToBool(masm, IsLittleEndianInput().node()) !=
+ V8_TARGET_BIG_ENDIAN_BOOL) {
+ __ StoreUnalignedFloat32(data_pointer, index, value);
+ } else {
+ __ ReverseByteOrderAndStoreUnalignedFloat32(data_pointer, index, value);
+ }
+ } else {
+ Label done;
+ ZoneLabelRef keep_byte_order(masm), reverse_byte_order(masm);
+ __ ToBoolean(
+ ToRegister(IsLittleEndianInput()), CheckType::kCheckHeapObject,
+ V8_TARGET_BIG_ENDIAN_BOOL ? reverse_byte_order : keep_byte_order,
+ V8_TARGET_BIG_ENDIAN_BOOL ? keep_byte_order : reverse_byte_order,
+ true);
+ __ bind(*keep_byte_order);
+ __ StoreUnalignedFloat32(data_pointer, index, value);
+ __ Jump(&done);
+ // We should swap the bytes if big endian.
+ __ bind(*reverse_byte_order);
+ __ ReverseByteOrderAndStoreUnalignedFloat32(data_pointer, index, value);
+ __ bind(&done);
+ }
}
}
@@ -6959,9 +7186,8 @@ void CheckedNumberOrOddballToUint8Clamped::GenerateCode(
// Check if HeapNumber or Oddball, deopt otherwise.
Label* deopt_label =
__ GetDeoptLabel(this, DeoptimizeReason::kNotANumberOrOddball);
- JumpToFailIfNotHeapNumberOrOddball(
- masm, value, TaggedToFloat64ConversionType::kNumberOrOddball,
- deopt_label);
+ JumpToFailIfNotHeapNumberOrOddball(masm, value, NodeType::kNumberOrOddball,
+ deopt_label);
// ToNumber of an oddball reads its to_number_raw field, which lives at the
// same offset as HeapNumber::value_, so the same load works for both.
__ LoadHeapNumberOrOddballValue(double_value, value);
@@ -8187,129 +8413,6 @@ void CheckpointedJump::GenerateCode(MaglevAssembler* masm,
}
}
-namespace {
-
-void AttemptOnStackReplacement(MaglevAssembler* masm,
- ZoneLabelRef no_code_for_osr,
- TryOnStackReplacement* node, Register scratch0,
- Register scratch1, int32_t loop_depth,
- FeedbackSlot feedback_slot,
- BytecodeOffset osr_offset) {
- // Two cases may cause us to attempt OSR, in the following order:
- //
- // 1) Presence of cached OSR Turbofan code.
- // 2) The OSR urgency exceeds the current loop depth - in that case, call
- // into runtime to trigger a Turbofan OSR compilation. A non-zero return
- // value means we should deopt into Ignition which will handle all further
- // necessary steps (rewriting the stack frame, jumping to OSR'd code).
- //
- // See also: InterpreterAssembler::OnStackReplacement.
-
- __ AssertFeedbackVector(scratch0, scratch1);
-
- // Case 1).
- Label deopt;
- Register maybe_target_code = scratch1;
- __ TryLoadOptimizedOsrCode(scratch1, CodeKind::TURBOFAN_JS, scratch0,
- feedback_slot, &deopt, Label::kFar);
-
- // Case 2).
- {
- __ LoadByte(scratch1, FieldMemOperand(
- scratch0, offsetof(FeedbackVector, osr_state_)));
- __ DecodeField<FeedbackVector::OsrUrgencyBits>(scratch1);
- __ JumpIfByte(kUnsignedLessThanEqual, scratch1, loop_depth,
- *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);
-
- // The osr_urgency exceeds the current loop_depth, signaling an OSR
- // request. Call into runtime to compile.
- {
- RegisterSnapshot snapshot = node->register_snapshot();
- DCHECK(!snapshot.live_registers.has(maybe_target_code));
- SaveRegisterStateForCall save_register_state(masm, snapshot);
- DCHECK(!node->unit()->is_inline());
- __ Push(Smi::FromInt(osr_offset.ToInt()));
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kCompileOptimizedOSRFromMaglev, 1);
- save_register_state.DefineSafepoint();
- __ Move(maybe_target_code, kReturnRegister0);
- }
-
- // A `0` return value means there is no OSR code available yet. Continue
- // execution in Maglev, OSR code will be picked up once it exists and is
- // cached on the feedback vector.
- __ CompareInt32AndJumpIf(maybe_target_code, 0, kEqual, *no_code_for_osr);
- }
-
- __ bind(&deopt);
- if (V8_LIKELY(v8_flags.turbofan)) {
- // None of the mutated input registers should be a register input into the
- // eager deopt info.
- DCHECK_REGLIST_EMPTY(
- RegList{scratch0, scratch1} &
- GetGeneralRegistersUsedAsInputs(node->eager_deopt_info()));
- __ EmitEagerDeopt(node, DeoptimizeReason::kPrepareForOnStackReplacement);
- } else {
- // Continue execution in Maglev. With TF disabled we cannot OSR and thus it
- // doesn't make sense to start the process. We do still perform all
- // remaining bookkeeping above though, to keep Maglev code behavior roughly
- // the same in both configurations.
- __ Jump(*no_code_for_osr);
- }
-}
-
-} // namespace
-
-int TryOnStackReplacement::MaxCallStackArgs() const {
- // For the kCompileOptimizedOSRFromMaglev call.
- if (unit()->is_inline()) return 2;
- return 1;
-}
-void TryOnStackReplacement::SetValueLocationConstraints() {
- UseAny(closure());
- set_temporaries_needed(2);
-}
-void TryOnStackReplacement::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch0 = temps.Acquire();
- Register scratch1 = temps.Acquire();
-
- const Register osr_state = scratch1;
- __ Move(scratch0, unit_->feedback().object());
- __ AssertFeedbackVector(scratch0, scratch1);
- __ LoadByte(osr_state,
- FieldMemOperand(scratch0, offsetof(FeedbackVector, osr_state_)));
-
- ZoneLabelRef no_code_for_osr(masm);
-
- if (v8_flags.maglev_osr) {
- // In case we use maglev_osr, we need to explicitly know if there is
- // turbofan code waiting for us (i.e., ignore the MaybeHasMaglevOsrCodeBit).
- __ DecodeField<
- base::BitFieldUnion<FeedbackVector::OsrUrgencyBits,
- FeedbackVector::MaybeHasTurbofanOsrCodeBit>>(
- osr_state);
- }
-
- // The quick initial OSR check. If it passes, we proceed on to more
- // expensive OSR logic.
- static_assert(FeedbackVector::MaybeHasTurbofanOsrCodeBit::encode(true) >
- FeedbackVector::kMaxOsrUrgency);
- __ CompareInt32AndJumpIf(
- osr_state, loop_depth_, kUnsignedGreaterThan,
- __ MakeDeferredCode(AttemptOnStackReplacement, no_code_for_osr, this,
- scratch0, scratch1, loop_depth_, feedback_slot_,
- osr_offset_));
- __ bind(*no_code_for_osr);
-}
-
void JumpLoop::SetValueLocationConstraints() {}
void JumpLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
@@ -8321,8 +8424,31 @@ void BranchIfSmi::SetValueLocationConstraints() {
}
void BranchIfSmi::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
- __ Branch(__ CheckSmi(ToRegister(ConditionInput())), if_true(), if_false(),
- state.next_block());
+ // Mirrors Branch(Condition, ...) fallthrough handling, but goes through
+ // JumpIfSmi/JumpIfNotSmi so arm64 can use tbz/tbnz instead of tst+b.cond.
+ Register value = ToRegister(ConditionInput());
+ BasicBlock* next_block = state.next_block();
+ bool fallthrough_when_true = if_true() == next_block;
+ bool fallthrough_when_false = if_false() == next_block;
+ if (fallthrough_when_false) {
+ if (fallthrough_when_true) {
+ // If both paths are a fallthrough, do nothing. This case is
+ // reachable: edge splitting keeps branch targets distinct in the
+ // graph, but codegen jump threading (RealJumpTarget) can redirect
+ // both targets to the same block.
+ DCHECK_EQ(if_true(), if_false());
+ return;
+ }
+ // Jump over the false block if true, otherwise fall through into it.
+ __ JumpIfSmi(value, if_true()->label());
+ } else {
+ // Jump to the false block if true.
+ __ JumpIfNotSmi(value, if_false()->label());
+ // Jump to the true block if it's not the next block.
+ if (!fallthrough_when_true) {
+ __ Jump(if_true()->label());
+ }
+ }
}
void BranchIfRootConstant::SetValueLocationConstraints() {
@@ -9269,8 +9395,10 @@ void CallRuntime::PrintParams(std::ostream& os) const {
os << "(" << Runtime::FunctionForId(function_id())->name << ")";
}
+int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 3; }
+
void ReduceInterruptBudgetForLoop::PrintParams(std::ostream& os) const {
- os << "(" << amount() << ")";
+ os << "(" << amount() << ", " << osr_offset().ToInt() << ")";
}
void ReduceInterruptBudgetForReturn::PrintParams(std::ostream& os) const {
diff --git a/deps/v8/src/maglev/maglev-ir.h b/deps/v8/src/maglev/maglev-ir.h
index 5062cc86dc7..f81191933fb 100644
--- a/deps/v8/src/maglev/maglev-ir.h
+++ b/deps/v8/src/maglev/maglev-ir.h
@@ -47,6 +47,7 @@
#include "src/objects/arguments.h"
#include "src/objects/heap-number.h"
#include "src/objects/js-array-buffer.h"
+#include "src/objects/js-collection-iterator.h"
#include "src/objects/js-collection.h"
#include "src/objects/js-generator.h"
#include "src/objects/js-promise.h"
@@ -269,158 +270,155 @@ class ExceptionHandlerInfo;
V(UnsafeSmiTagUint32) \
V(UnsafeSmiUntag)
-#define VALUE_NODE_LIST(V) \
- V(Identity) \
- V(DeadValue) \
- V(AllocationBlock) \
- V(ArgumentsElements) \
- V(ArgumentsLength) \
- V(RestLength) \
- V(Call) \
- V(CallBuiltin) \
- V(CallForwardVarargs) \
- V(CallRuntime) \
- V(CallWithArrayLike) \
- V(CallWithSpread) \
- V(CallKnownApiFunction) \
- V(CallKnownBuiltin) \
- V(CallKnownJSFunction) \
- V(CallSelf) \
- V(Construct) \
- V(ConstructForwardVarargs) \
- V(CheckConstructResult) \
- V(CheckDerivedConstructResult) \
- V(ConstructWithSpread) \
- V(ConvertReceiver) \
- V(ConvertHoleToUndefined) \
- V(CreateArrayLiteral) \
- V(CreateShallowArrayLiteral) \
- V(CreateObjectLiteral) \
- V(CreateShallowObjectLiteral) \
- V(CreateFunctionContext) \
- V(CreateClosure) \
- V(FastCreateClosure) \
- V(CreateRegExpLiteral) \
- V(DeleteProperty) \
- V(EnsureWritableFastElements) \
- V(ExtendPropertiesBackingStore) \
- V(InlinedAllocation) \
- V(ForInPrepare) \
- V(ForInNext) \
- V(GeneratorRestoreRegister) \
- V(GetIterator) \
- V(GetSecondReturnedValue) \
- V(GetTemplateObject) \
- V(HasInPrototypeChain) \
- V(InitialValue) \
- V(LoadTaggedField) \
- V(LoadContextSlotNoCells) \
- V(LoadContextSlot) \
- V(LoadFloat64) \
- V(LoadInt32) \
- V(LoadTaggedFieldByFieldIndex) \
- V(LoadFixedArrayElement) \
- V(LoadFixedDoubleArrayElement) \
- V(LoadHoleyFixedDoubleArrayElement) \
- V(LoadHoleyFixedDoubleArrayElementCheckedNotHole) \
- IF_UD(V, LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole) \
- V(LoadSignedIntDataViewElement) \
- V(LoadDoubleDataViewElement) \
- V(LoadTypedArrayLength) \
- V(LoadDataViewByteLength) \
- V(LoadDataViewDataPointer) \
- V(LoadSignedIntTypedArrayElement) \
- V(LoadUnsignedIntTypedArrayElement) \
- V(LoadDoubleTypedArrayElement) \
- V(LoadSignedIntConstantTypedArrayElement) \
- V(LoadUnsignedIntConstantTypedArrayElement) \
- V(LoadDoubleConstantTypedArrayElement) \
- V(LoadEnumCacheLength) \
- V(LoadGlobal) \
- V(LoadNamedGeneric) \
- V(LoadNamedFromSuperGeneric) \
- V(LoadDictionaryField) \
- V(MaybeGrowFastElements) \
- V(MigrateMapIfNeeded) \
- V(SetNamedGeneric) \
- V(DefineNamedOwnGeneric) \
- V(StoreInArrayLiteralGeneric) \
- V(StoreGlobal) \
- V(GetKeyedGeneric) \
- V(SetKeyedGeneric) \
- V(DefineKeyedOwnGeneric) \
- V(Phi) \
- V(RegisterInput) \
- V(CheckedInternalizedString) \
- V(TruncateCheckedNumberAsSafeIntToInt32) \
- V(TruncateUnsafeNumberAsSafeIntToInt32) \
- V(TruncateFloat64AsSafeIntToInt32) \
- V(TruncateHoleyFloat64AsSafeIntToInt32) \
- V(TruncateCheckedNumberOrOddballToInt32) \
- V(TruncateUnsafeNumberOrOddballToInt32) \
- V(TruncateFloat64ToInt32) \
- V(TruncateHoleyFloat64ToInt32) \
- V(TruncateUint32ToInt32) \
- V(Int32ToUint8Clamped) \
- V(Uint32ToUint8Clamped) \
- V(Float64ToUint8Clamped) \
- V(CheckedNumberOrOddballToUint8Clamped) \
- V(Int32CountLeadingZeros) \
- V(TaggedCountLeadingZeros) \
- V(Float64CountLeadingZeros) \
- V(IntPtrToBoolean) \
- V(CheckedNumberOrOddballToFloat64) \
- V(CheckedNumberOrOddballToHoleyFloat64) \
- V(UnsafeNumberOrOddballToFloat64) \
- V(UnsafeNumberOrOddballToHoleyFloat64) \
- V(UnsafeHoleyFloat64ToFloat64) \
- V(UnsafeFloat64ToHoleyFloat64) \
- V(Float64ToSilencedFloat64) \
- V(HoleyFloat64ToSilencedFloat64) \
- IF_UD(V, HoleyFloat64ConvertHoleToUndefined) \
- IF_UD(V, HoleyFloat64IsUndefinedOrHole) \
- IF_NOT_UD(V, HoleyFloat64IsHole) \
- V(LogicalNot) \
- V(SetPendingMessage) \
- V(StringAt) \
- V(StringEqual) \
- V(StringLength) \
- V(StringConcat) \
- V(StringIndexOf) \
- IF_INTL(V, StringLocaleCompareIntl) \
- V(ConsStringMap) \
- V(UnwrapStringWrapper) \
- V(ToBoolean) \
- V(ToBooleanLogicalNot) \
- V(AllocateElementsArray) \
- V(TaggedEqual) \
- V(TaggedNotEqual) \
- V(TestInstanceOf) \
- V(TestUndetectable) \
- V(TestTypeOf) \
- V(ToName) \
- V(ToNumberOrNumeric) \
- V(ToObject) \
- V(ToString) \
- V(TransitionElementsKind) \
- V(Int32ToString) \
- V(Float64ToString) \
- V(SmiToString) \
- V(NumberToString) \
- V(UpdateJSArrayLength) \
- V(VirtualObject) \
- V(GetContinuationPreservedEmbedderData) \
- V(ReturnedValue) \
- V(StringSlice) \
- V(StringSubstring) \
- CONSTANT_VALUE_NODE_LIST(V) \
- CONVERSION_NODE_LIST(V) \
- INT32_OPERATIONS_NODE_LIST(V) \
- FLOAT64_OPERATIONS_NODE_LIST(V) \
- SMI_OPERATIONS_NODE_LIST(V) \
- GENERIC_OPERATIONS_NODE_LIST(V) \
- BIGINT_OPERATIONS_NODE_LIST(V) \
- INLINE_BUILTIN_NODE_LIST(V) \
+#define VALUE_NODE_LIST(V) \
+ V(Identity) \
+ V(DeadValue) \
+ V(AllocationBlock) \
+ V(ArgumentsElements) \
+ V(ArgumentsLength) \
+ V(RestLength) \
+ V(Call) \
+ V(CallBuiltin) \
+ V(CallForwardVarargs) \
+ V(CallRuntime) \
+ V(CallWithArrayLike) \
+ V(CallWithSpread) \
+ V(CallKnownApiFunction) \
+ V(CallKnownBuiltin) \
+ V(CallKnownJSFunction) \
+ V(CallSelf) \
+ V(Construct) \
+ V(ConstructForwardVarargs) \
+ V(CheckConstructResult) \
+ V(CheckDerivedConstructResult) \
+ V(ConstructWithSpread) \
+ V(ConvertReceiver) \
+ V(ConvertHoleToUndefined) \
+ V(CreateArrayLiteral) \
+ V(CreateShallowArrayLiteral) \
+ V(CreateObjectLiteral) \
+ V(CreateShallowObjectLiteral) \
+ V(CreateFunctionContext) \
+ V(CreateClosure) \
+ V(FastCreateClosure) \
+ V(CreateRegExpLiteral) \
+ V(DeleteProperty) \
+ V(EnsureWritableFastElements) \
+ V(ExtendPropertiesBackingStore) \
+ V(InlinedAllocation) \
+ V(ForInPrepare) \
+ V(ForInNext) \
+ V(GeneratorRestoreRegister) \
+ V(GetIterator) \
+ V(GetSecondReturnedValue) \
+ V(GetTemplateObject) \
+ V(HasInPrototypeChain) \
+ V(InitialValue) \
+ V(LoadTaggedField) \
+ V(LoadContextSlotNoCells) \
+ V(LoadContextSlot) \
+ V(LoadFloat64) \
+ V(LoadInt32) \
+ V(LoadTaggedFieldByFieldIndex) \
+ V(LoadFixedArrayElement) \
+ V(LoadFixedDoubleArrayElement) \
+ V(LoadHoleyFixedDoubleArrayElement) \
+ V(LoadInt32DataViewElement) \
+ V(LoadUint32DataViewElement) \
+ V(LoadDoubleDataViewElement) \
+ V(LoadTypedArrayLength) \
+ V(LoadDataViewByteLength) \
+ V(LoadDataViewDataPointer) \
+ V(LoadSignedIntTypedArrayElement) \
+ V(LoadUnsignedIntTypedArrayElement) \
+ V(LoadDoubleTypedArrayElement) \
+ V(LoadSignedIntConstantTypedArrayElement) \
+ V(LoadUnsignedIntConstantTypedArrayElement) \
+ V(LoadDoubleConstantTypedArrayElement) \
+ V(LoadEnumCacheLength) \
+ V(LoadGlobal) \
+ V(LoadNamedGeneric) \
+ V(LoadNamedFromSuperGeneric) \
+ V(LoadDictionaryField) \
+ V(MaybeGrowFastElements) \
+ V(MigrateMapIfNeeded) \
+ V(SetNamedGeneric) \
+ V(DefineNamedOwnGeneric) \
+ V(StoreInArrayLiteralGeneric) \
+ V(StoreGlobal) \
+ V(GetKeyedGeneric) \
+ V(SetKeyedGeneric) \
+ V(DefineKeyedOwnGeneric) \
+ V(Phi) \
+ V(RegisterInput) \
+ V(CheckedInternalizedString) \
+ V(TruncateCheckedNumberAsSafeIntToInt32) \
+ V(TruncateUnsafeNumberAsSafeIntToInt32) \
+ V(TruncateFloat64AsSafeIntToInt32) \
+ V(TruncateHoleyFloat64AsSafeIntToInt32) \
+ V(TruncateCheckedNumberOrOddballToInt32) \
+ V(TruncateUnsafeNumberOrOddballToInt32) \
+ V(TruncateFloat64ToInt32) \
+ V(TruncateHoleyFloat64ToInt32) \
+ V(TruncateUint32ToInt32) \
+ V(Int32ToUint8Clamped) \
+ V(Uint32ToUint8Clamped) \
+ V(Float64ToUint8Clamped) \
+ V(CheckedNumberOrOddballToUint8Clamped) \
+ V(Int32CountLeadingZeros) \
+ V(TaggedCountLeadingZeros) \
+ V(Float64CountLeadingZeros) \
+ V(IntPtrToBoolean) \
+ V(CheckedNumberOrOddballToFloat64) \
+ V(CheckedNumberOrOddballToHoleyFloat64) \
+ V(UnsafeNumberOrOddballToFloat64) \
+ V(UnsafeNumberOrOddballToHoleyFloat64) \
+ V(UnsafeHoleyFloat64ToFloat64) \
+ V(UnsafeFloat64ToHoleyFloat64) \
+ V(Float64ToSilencedFloat64) \
+ IF_UD(V, HoleyFloat64IsUndefinedOrHole) \
+ IF_NOT_UD(V, HoleyFloat64IsHole) \
+ V(LogicalNot) \
+ V(SetPendingMessage) \
+ V(StringAt) \
+ V(StringEqual) \
+ V(StringLength) \
+ V(StringConcat) \
+ V(StringIndexOf) \
+ IF_INTL(V, StringLocaleCompareIntl) \
+ V(ConsStringMap) \
+ V(UnwrapStringWrapper) \
+ V(ToBoolean) \
+ V(ToBooleanLogicalNot) \
+ V(AllocateElementsArray) \
+ V(TaggedEqual) \
+ V(TaggedNotEqual) \
+ V(TestInstanceOf) \
+ V(TestUndetectable) \
+ V(TestTypeOf) \
+ V(ToName) \
+ V(ToNumberOrNumeric) \
+ V(ToObject) \
+ V(ToString) \
+ V(TransitionElementsKind) \
+ V(Int32ToString) \
+ V(Float64ToString) \
+ V(SmiToString) \
+ V(NumberToString) \
+ V(UpdateJSArrayLength) \
+ V(VirtualObject) \
+ V(GetContinuationPreservedEmbedderData) \
+ V(ReturnedValue) \
+ V(StringSlice) \
+ V(StringSubstring) \
+ CONSTANT_VALUE_NODE_LIST(V) \
+ CONVERSION_NODE_LIST(V) \
+ INT32_OPERATIONS_NODE_LIST(V) \
+ FLOAT64_OPERATIONS_NODE_LIST(V) \
+ SMI_OPERATIONS_NODE_LIST(V) \
+ GENERIC_OPERATIONS_NODE_LIST(V) \
+ BIGINT_OPERATIONS_NODE_LIST(V) \
+ INLINE_BUILTIN_NODE_LIST(V) \
TURBOLEV_VALUE_NODE_LIST(V)
#define GAP_MOVE_NODE_LIST(V) \
@@ -469,11 +467,11 @@ class ExceptionHandlerInfo;
V(MajorGCForCompilerTesting) \
V(FunctionEntryStackCheck) \
V(GeneratorStore) \
- V(TryOnStackReplacement) \
V(StoreMap) \
V(StoreFixedArrayElementWithWriteBarrier) \
V(StoreFixedArrayElementNoWriteBarrier) \
V(StoreFixedDoubleArrayElement) \
+ V(StoreFixedDoubleArrayHole) \
V(StoreFixedHoleyDoubleArrayElement) \
V(StoreInt32) \
V(StoreFloat64) \
@@ -481,7 +479,7 @@ class ExceptionHandlerInfo;
V(StoreDoubleTypedArrayElement) \
V(StoreIntConstantTypedArrayElement) \
V(StoreDoubleConstantTypedArrayElement) \
- V(StoreSignedIntDataViewElement) \
+ V(StoreInt32DataViewElement) \
V(StoreDoubleDataViewElement) \
V(StoreTaggedFieldNoWriteBarrier) \
V(StoreTaggedFieldWithWriteBarrier) \
@@ -563,7 +561,7 @@ static constexpr Opcode kFirstOpcode = static_cast<Opcode>(0);
static constexpr Opcode kLastOpcode = static_cast<Opcode>(kOpcodeCount - 1);
#undef PLUS_ONE
-const char* OpcodeToString(Opcode opcode);
+V8_EXPORT_PRIVATE const char* OpcodeToString(Opcode opcode);
inline std::ostream& operator<<(std::ostream& os, Opcode opcode) {
return os << OpcodeToString(opcode);
}
@@ -709,6 +707,7 @@ constexpr bool IsSimpleFieldStore(Opcode opcode) {
opcode == Opcode::kStoreFixedArrayElementWithWriteBarrier ||
opcode == Opcode::kStoreFixedArrayElementNoWriteBarrier ||
opcode == Opcode::kStoreFixedDoubleArrayElement ||
+ opcode == Opcode::kStoreFixedDoubleArrayHole ||
opcode == Opcode::kStoreFixedHoleyDoubleArrayElement ||
opcode == Opcode::kStoreTrustedPointerFieldWithWriteBarrier ||
opcode == Opcode::kStoreContextSlotWithWriteBarrier ||
@@ -727,6 +726,7 @@ constexpr bool IsElementsArrayWrite(Opcode opcode) {
// allocated backing store.
constexpr bool PreservesTaggedKeyedProperties(Opcode opcode) {
return opcode == Opcode::kStoreFixedDoubleArrayElement ||
+ opcode == Opcode::kStoreFixedDoubleArrayHole ||
opcode == Opcode::kStoreFixedHoleyDoubleArrayElement ||
opcode == Opcode::kTransitionElementsKind ||
opcode == Opcode::kTransitionElementsKindOrCheckMap;
@@ -736,7 +736,7 @@ constexpr bool IsTypedArrayStore(Opcode opcode) {
opcode == Opcode::kStoreDoubleTypedArrayElement ||
opcode == Opcode::kStoreIntConstantTypedArrayElement ||
opcode == Opcode::kStoreDoubleConstantTypedArrayElement ||
- opcode == Opcode::kStoreSignedIntDataViewElement ||
+ opcode == Opcode::kStoreInt32DataViewElement ||
opcode == Opcode::kStoreDoubleDataViewElement;
}
@@ -971,43 +971,6 @@ std::ostream& operator<<(std::ostream& os, UseRepresentation repr);
typedef base::EnumSet<ValueRepresentation, int8_t> ValueRepresentationSet;
typedef base::EnumSet<UseRepresentation, int8_t> UseRepresentationSet;
-enum class TaggedToFloat64ConversionType : uint8_t {
- kOnlyNumber,
- kNumberOrUndefined,
- kNumberOrBoolean,
- kNumberOrOddball,
-};
-
-constexpr TaggedToFloat64ConversionType GetTaggedToFloat64ConversionType(
- NodeType type) {
- if (NodeTypeIs(type, NodeType::kNumber)) {
- return TaggedToFloat64ConversionType::kOnlyNumber;
- }
- if (NodeTypeIs(type, NodeType::kNumberOrBoolean)) {
- return TaggedToFloat64ConversionType::kNumberOrBoolean;
- }
- if (NodeTypeIs(type, NodeType::kNumberOrUndefined)) {
- return TaggedToFloat64ConversionType::kNumberOrUndefined;
- }
- DCHECK(NodeTypeIs(type, NodeType::kNumberOrOddball));
- return TaggedToFloat64ConversionType::kNumberOrOddball;
-}
-
-constexpr NodeType GetAllowedTypeFromConversionType(
- TaggedToFloat64ConversionType conversion) {
- switch (conversion) {
- case TaggedToFloat64ConversionType::kOnlyNumber:
- return NodeType::kNumber;
- case TaggedToFloat64ConversionType::kNumberOrUndefined:
- return NodeType::kNumberOrUndefined;
- case TaggedToFloat64ConversionType::kNumberOrBoolean:
- return NodeType::kNumberOrBoolean;
- case TaggedToFloat64ConversionType::kNumberOrOddball:
- return NodeType::kNumberOrOddball;
- }
- UNREACHABLE();
-}
-
constexpr Condition ConditionFor(Operation cond);
constexpr Condition ConditionForNaN();
@@ -1037,21 +1000,6 @@ inline std::ostream& operator<<(std::ostream& os,
UNREACHABLE();
}
-inline std::ostream& operator<<(
- std::ostream& os, const TaggedToFloat64ConversionType& conversion_type) {
- switch (conversion_type) {
- case TaggedToFloat64ConversionType::kOnlyNumber:
- return os << "Number";
- case TaggedToFloat64ConversionType::kNumberOrUndefined:
- return os << "NumberOrUndefined";
- case TaggedToFloat64ConversionType::kNumberOrBoolean:
- return os << "NumberOrBoolean";
- case TaggedToFloat64ConversionType::kNumberOrOddball:
- return os << "NumberOrOddball";
- }
- UNREACHABLE();
-}
-
inline bool HasOnlyJSTypedArrayMaps(base::Vector<const compiler::MapRef> maps) {
for (compiler::MapRef map : maps) {
if (!map.IsJSTypedArrayMap()) return false;
@@ -1993,7 +1941,6 @@ class LazyDeoptInfo : public DeoptInfo {
class ExceptionHandlerInfo {
public:
- using List = base::ThreadedList<ExceptionHandlerInfo>;
enum Mode {
kNoExceptionHandler = -1,
kLazyDeopt = -2,
@@ -2039,12 +1986,6 @@ class ExceptionHandlerInfo {
Label trampoline_entry_;
int depth_;
int pc_offset_;
-
- ExceptionHandlerInfo* next_ = nullptr;
- ExceptionHandlerInfo** next() { return &next_; }
-
- friend List;
- friend base::ThreadedListTraits<ExceptionHandlerInfo>;
};
// Dummy type for the initial raw allocation.
@@ -2362,6 +2303,16 @@ class NodeBase : public ZoneObject {
exception_handler_address());
}
+ // Returns the catch block this node throws to, or nullptr if it cannot throw
+ // or if it lazy deopts instead of dispatching to a handler.
+ BasicBlock* GetLiveCatchBlock() {
+ if (!properties().can_throw()) return nullptr;
+ ExceptionHandlerInfo* info = exception_handler_info();
+ if (!info->HasExceptionHandler()) return nullptr;
+ if (info->ShouldLazyDeopt()) return nullptr;
+ return info->catch_block();
+ }
+
void set_register_snapshot(RegisterSnapshot snapshot) {
DCHECK(properties().needs_register_snapshot());
*reinterpret_cast<RegisterSnapshot*>(register_snapshot_address()) =
@@ -2765,6 +2716,12 @@ class ValueNode : public Node {
return is_float64() || is_holey_float64();
}
+ // Whether the bits of this value could be one of the NaN patterns that
+ // 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;
+
#ifdef V8_COMPRESS_POINTERS
constexpr bool decompresses_tagged_result() const {
return TaggedResultNeedsDecompressField::decode(bitfield());
@@ -3266,7 +3223,7 @@ class DeadValue : public FixedInputValueNodeT<0, DeadValue> {
};
template <class Derived, Operation kOperation>
-class UnaryWithFeedbackNode : public FixedInputValueNodeT<1, Derived> {
+class UnaryWithEmbeddedFeedbackNode : public FixedInputValueNodeT<1, Derived> {
using Base = FixedInputValueNodeT<1, Derived>;
public:
@@ -3274,17 +3231,17 @@ class UnaryWithFeedbackNode : public FixedInputValueNodeT<1, Derived> {
static constexpr OpProperties kProperties = OpProperties::JSCall();
DECLARE_UNOP(Tagged)
- compiler::FeedbackSource feedback() const { return feedback_; }
+ compiler::EmbeddedFeedbackSource feedback() const { return feedback_; }
protected:
- explicit UnaryWithFeedbackNode(uint64_t bitfield,
- const compiler::FeedbackSource& feedback)
+ explicit UnaryWithEmbeddedFeedbackNode(
+ uint64_t bitfield, const compiler::EmbeddedFeedbackSource& feedback)
: Base(bitfield), feedback_(feedback) {}
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- const compiler::FeedbackSource feedback_;
+ const compiler::EmbeddedFeedbackSource feedback_;
};
template <class Derived, Operation kOperation>
@@ -3309,18 +3266,6 @@ class BinaryWithEmbeddedFeedbackNode : public FixedInputValueNodeT<2, Derived> {
const compiler::EmbeddedFeedbackSource feedback_;
};
-#define DEF_OPERATION_WITH_FEEDBACK_NODE(Name, Super, OpName) \
- class Name : public Super<Name, Operation::k##OpName> { \
- using Base = Super<Name, Operation::k##OpName>; \
- \
- public: \
- Name(uint64_t bitfield, const compiler::FeedbackSource& feedback) \
- : Base(bitfield, feedback) {} \
- int MaxCallStackArgs() const { return 0; } \
- void SetValueLocationConstraints(); \
- void GenerateCode(MaglevAssembler*, const ProcessingState&); \
- };
-
#define DEF_OPERATION_WITH_EMBEDDED_FEEDBACK_NODE(Name, Super, OpName) \
class Name : public Super<Name, Operation::k##OpName> { \
using Base = Super<Name, Operation::k##OpName>; \
@@ -3333,8 +3278,9 @@ class BinaryWithEmbeddedFeedbackNode : public FixedInputValueNodeT<2, Derived> {
void GenerateCode(MaglevAssembler*, const ProcessingState&); \
};
-#define DEF_UNARY_WITH_FEEDBACK_NODE(Name) \
- DEF_OPERATION_WITH_FEEDBACK_NODE(Generic##Name, UnaryWithFeedbackNode, Name)
+#define DEF_UNARY_WITH_FEEDBACK_NODE(Name) \
+ DEF_OPERATION_WITH_EMBEDDED_FEEDBACK_NODE( \
+ Generic##Name, UnaryWithEmbeddedFeedbackNode, Name)
#define DEF_BINARY_WITH_EMBEDDED_FEEDBACK_NODE(Name) \
DEF_OPERATION_WITH_EMBEDDED_FEEDBACK_NODE( \
Generic##Name, BinaryWithEmbeddedFeedbackNode, Name)
@@ -3345,7 +3291,6 @@ COMPARISON_OPERATION_LIST(DEF_BINARY_WITH_EMBEDDED_FEEDBACK_NODE)
#undef DEF_UNARY_WITH_FEEDBACK_NODE
#undef DEF_BINARY_WITH_EMBEDDED_FEEDBACK_NODE
-#undef DEF_OPERATION_WITH_FEEDBACK_NODE
#undef DEF_OPERATION_WITH_EMBEDDED_FEEDBACK_NODE
// Number of bits needed to encode an Operation in a node's bitfield.
@@ -4460,12 +4405,12 @@ DEFINE_TRUNCATE_NODE(TruncateHoleyFloat64ToInt32, HoleyFloat64,
class CheckedNumberOrOddballToFloat64
: public FixedInputValueNodeT<1, CheckedNumberOrOddballToFloat64> {
public:
- explicit CheckedNumberOrOddballToFloat64(
- uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
- : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
- conversion_type)) {
- // CheckedNumberToFloat64 should be used instead for kOnlyNumber.
- DCHECK_NE(conversion_type, TaggedToFloat64ConversionType::kOnlyNumber);
+ explicit CheckedNumberOrOddballToFloat64(uint64_t bitfield,
+ NodeType assumed_input_type)
+ : Base(bitfield), assumed_input_type_(assumed_input_type) {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ // CheckedNumberToFloat64 should be used instead for kNumber.
+ DCHECK(!NodeTypeIs(assumed_input_type, NodeType::kNumber));
}
static constexpr OpProperties kProperties =
@@ -4475,77 +4420,67 @@ class CheckedNumberOrOddballToFloat64
// Not a conversion node since it is not reversible.
static_assert(!kProperties.is_conversion());
- TaggedToFloat64ConversionType conversion_type() const {
- return TaggedToFloat64ConversionTypeOffset::decode(Base::bitfield());
- }
+ NodeType assumed_input_type() const { return assumed_input_type_; }
DeoptimizeReason deoptimize_reason() const {
- return conversion_type() == TaggedToFloat64ConversionType::kNumberOrBoolean
+ return NodeTypeIs(assumed_input_type(), NodeType::kNumberOrBoolean)
? DeoptimizeReason::kNotANumberOrBoolean
: DeoptimizeReason::kNotANumberOrOddball;
}
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- auto options() const { return std::tuple{conversion_type()}; }
+ auto options() const { return std::tuple{assumed_input_type()}; }
private:
- using TaggedToFloat64ConversionTypeOffset =
- Base::template NextBitField<TaggedToFloat64ConversionType, 2>;
+ const NodeType assumed_input_type_;
};
class CheckedNumberOrOddballToHoleyFloat64
: public FixedInputValueNodeT<1, CheckedNumberOrOddballToHoleyFloat64> {
public:
- explicit CheckedNumberOrOddballToHoleyFloat64(
- uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
- : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
- conversion_type)) {
- // CheckedNumberToFloat64 should be used instead for kOnlyNumber.
- DCHECK_NE(conversion_type, TaggedToFloat64ConversionType::kOnlyNumber);
+ explicit CheckedNumberOrOddballToHoleyFloat64(uint64_t bitfield,
+ NodeType assumed_input_type)
+ : Base(bitfield), assumed_input_type_(assumed_input_type) {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ // CheckedNumberToFloat64 should be used instead for kNumber.
+ DCHECK(!NodeTypeIs(assumed_input_type, NodeType::kNumber));
}
static constexpr OpProperties kProperties =
OpProperties::EagerDeopt() | OpProperties::HoleyFloat64();
DECLARE_UNOP(Tagged)
- TaggedToFloat64ConversionType conversion_type() const {
- return TaggedToFloat64ConversionTypeOffset::decode(Base::bitfield());
- }
+ NodeType assumed_input_type() const { return assumed_input_type_; }
DeoptimizeReason deoptimize_reason() const {
- switch (conversion_type()) {
- case TaggedToFloat64ConversionType::kOnlyNumber:
- // CheckedNumberToFloat64 should be used instead for kOnlyNumber.
- UNREACHABLE();
- case TaggedToFloat64ConversionType::kNumberOrBoolean:
- return DeoptimizeReason::kNotANumberOrBoolean;
- case TaggedToFloat64ConversionType::kNumberOrUndefined:
- return DeoptimizeReason::kNotANumberOrUndefined;
- case TaggedToFloat64ConversionType::kNumberOrOddball:
- return DeoptimizeReason::kNotANumberOrOddball;
+ if (NodeTypeIs(assumed_input_type(), NodeType::kNumberOrBoolean)) {
+ return DeoptimizeReason::kNotANumberOrBoolean;
}
- UNREACHABLE();
+ if (NodeTypeIs(assumed_input_type(), NodeType::kNumberOrUndefined)) {
+ return DeoptimizeReason::kNotANumberOrUndefined;
+ }
+ DCHECK(NodeTypeIs(assumed_input_type(), NodeType::kNumberOrOddball));
+ return DeoptimizeReason::kNotANumberOrOddball;
}
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- auto options() const { return std::tuple{conversion_type()}; }
+ auto options() const { return std::tuple{assumed_input_type()}; }
private:
- using TaggedToFloat64ConversionTypeOffset =
- Base::template NextBitField<TaggedToFloat64ConversionType, 2>;
+ const NodeType assumed_input_type_;
};
class UnsafeNumberOrOddballToFloat64
: public FixedInputValueNodeT<1, UnsafeNumberOrOddballToFloat64> {
public:
- explicit UnsafeNumberOrOddballToFloat64(
- uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
- : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
- conversion_type)) {
- // UnsafeNumberToFloat64 should be used instead for kOnlyNumber.
- DCHECK_NE(conversion_type, TaggedToFloat64ConversionType::kOnlyNumber);
+ explicit UnsafeNumberOrOddballToFloat64(uint64_t bitfield,
+ NodeType assumed_input_type)
+ : Base(bitfield), assumed_input_type_(assumed_input_type) {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ // UnsafeNumberToFloat64 should be used instead for kNumber.
+ DCHECK(!NodeTypeIs(assumed_input_type, NodeType::kNumber));
}
static constexpr OpProperties kProperties = OpProperties::Float64();
@@ -4554,26 +4489,24 @@ class UnsafeNumberOrOddballToFloat64
// Not a conversion node since it is not reversible.
static_assert(!kProperties.is_conversion());
- TaggedToFloat64ConversionType conversion_type() const {
- return TaggedToFloat64ConversionTypeOffset::decode(Base::bitfield());
- }
+ NodeType assumed_input_type() const { return assumed_input_type_; }
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- auto options() const { return std::tuple{conversion_type()}; }
+ auto options() const { return std::tuple{assumed_input_type()}; }
private:
- using TaggedToFloat64ConversionTypeOffset =
- Base::template NextBitField<TaggedToFloat64ConversionType, 2>;
+ const NodeType assumed_input_type_;
};
class UnsafeNumberOrOddballToHoleyFloat64
: public FixedInputValueNodeT<1, UnsafeNumberOrOddballToHoleyFloat64> {
public:
- explicit UnsafeNumberOrOddballToHoleyFloat64(
- uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
- : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
- conversion_type)) {}
+ explicit UnsafeNumberOrOddballToHoleyFloat64(uint64_t bitfield,
+ NodeType assumed_input_type)
+ : Base(bitfield), assumed_input_type_(assumed_input_type) {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ }
static constexpr OpProperties kProperties = OpProperties::HoleyFloat64();
DECLARE_UNOP(Tagged)
@@ -4581,15 +4514,12 @@ class UnsafeNumberOrOddballToHoleyFloat64
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- TaggedToFloat64ConversionType conversion_type() const {
- return TaggedToFloat64ConversionTypeOffset::decode(Base::bitfield());
- }
+ NodeType assumed_input_type() const { return assumed_input_type_; }
- auto options() const { return std::tuple{conversion_type()}; }
+ auto options() const { return std::tuple{assumed_input_type()}; }
private:
- using TaggedToFloat64ConversionTypeOffset =
- Base::template NextBitField<TaggedToFloat64ConversionType, 2>;
+ const NodeType assumed_input_type_;
};
class UnsafeHoleyFloat64ToFloat64
@@ -4605,21 +4535,6 @@ class UnsafeHoleyFloat64ToFloat64
void GenerateCode(MaglevAssembler*, const ProcessingState&);
};
-class HoleyFloat64ToSilencedFloat64
- : public FixedInputValueNodeT<1, HoleyFloat64ToSilencedFloat64> {
- public:
- explicit HoleyFloat64ToSilencedFloat64(uint64_t bitfield) : Base(bitfield) {}
-
- static constexpr OpProperties kProperties = OpProperties::Float64();
- DECLARE_UNOP(HoleyFloat64)
-
- int MaxCallStackArgs() const { return 0; }
- void SetValueLocationConstraints();
- void GenerateCode(MaglevAssembler*, const ProcessingState&);
-
- auto options() const { return std::tuple{}; }
-};
-
class Float64ToSilencedFloat64
: public FixedInputValueNodeT<1, Float64ToSilencedFloat64> {
public:
@@ -4644,6 +4559,7 @@ class UnsafeFloat64ToHoleyFloat64
DECLARE_UNOP(Float64)
int MaxCallStackArgs() const { return 0; }
+ void VerifyInputs() const;
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
@@ -4651,20 +4567,6 @@ class UnsafeFloat64ToHoleyFloat64
};
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-class HoleyFloat64ConvertHoleToUndefined
- : public FixedInputValueNodeT<1, HoleyFloat64ConvertHoleToUndefined> {
- public:
- explicit HoleyFloat64ConvertHoleToUndefined(uint64_t bitfield)
- : Base(bitfield) {}
-
- static constexpr OpProperties kProperties = OpProperties::HoleyFloat64();
- DECLARE_UNOP(HoleyFloat64)
-
- int MaxCallStackArgs() const { return 0; }
- void SetValueLocationConstraints();
- void GenerateCode(MaglevAssembler*, const ProcessingState&);
-};
-
class HoleyFloat64IsUndefinedOrHole
: public FixedInputValueNodeT<1, HoleyFloat64IsUndefinedOrHole> {
public:
@@ -4693,10 +4595,12 @@ class HoleyFloat64IsHole : public FixedInputValueNodeT<1, HoleyFloat64IsHole> {
class TruncateUnsafeNumberOrOddballToInt32
: public FixedInputValueNodeT<1, TruncateUnsafeNumberOrOddballToInt32> {
public:
- explicit TruncateUnsafeNumberOrOddballToInt32(
- uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
- : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
- conversion_type)) {}
+ explicit TruncateUnsafeNumberOrOddballToInt32(uint64_t bitfield,
+ NodeType assumed_input_type)
+ : Base(bitfield), assumed_input_type_(assumed_input_type) {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ DCHECK_NE(assumed_input_type, NodeType::kNumberOrUndefined);
+ }
static constexpr OpProperties kProperties = OpProperties::Int32();
DECLARE_UNOP(Tagged)
@@ -4704,15 +4608,12 @@ class TruncateUnsafeNumberOrOddballToInt32
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- TaggedToFloat64ConversionType conversion_type() const {
- return TaggedToFloat64ConversionTypeOffset::decode(bitfield());
- }
+ NodeType assumed_input_type() const { return assumed_input_type_; }
- auto options() const { return std::tuple{conversion_type()}; }
+ auto options() const { return std::tuple{assumed_input_type()}; }
private:
- using TaggedToFloat64ConversionTypeOffset =
- NextBitField<TaggedToFloat64ConversionType, 2>;
+ const NodeType assumed_input_type_;
};
// This node checks that the input is a Number and that it is in the SafeInt
@@ -4783,10 +4684,12 @@ class TruncateHoleyFloat64AsSafeIntToInt32
class TruncateCheckedNumberOrOddballToInt32
: public FixedInputValueNodeT<1, TruncateCheckedNumberOrOddballToInt32> {
public:
- explicit TruncateCheckedNumberOrOddballToInt32(
- uint64_t bitfield, TaggedToFloat64ConversionType conversion_type)
- : Base(TaggedToFloat64ConversionTypeOffset::update(bitfield,
- conversion_type)) {}
+ explicit TruncateCheckedNumberOrOddballToInt32(uint64_t bitfield,
+ NodeType assumed_input_type)
+ : Base(bitfield), assumed_input_type_(assumed_input_type) {
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ DCHECK_NE(assumed_input_type, NodeType::kNumberOrUndefined);
+ }
static constexpr OpProperties kProperties =
OpProperties::EagerDeopt() | OpProperties::Int32();
@@ -4795,15 +4698,12 @@ class TruncateCheckedNumberOrOddballToInt32
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- TaggedToFloat64ConversionType conversion_type() const {
- return TaggedToFloat64ConversionTypeOffset::decode(bitfield());
- }
+ NodeType assumed_input_type() const { return assumed_input_type_; }
- auto options() const { return std::tuple{conversion_type()}; }
+ auto options() const { return std::tuple{assumed_input_type()}; }
private:
- using TaggedToFloat64ConversionTypeOffset =
- NextBitField<TaggedToFloat64ConversionType, 2>;
+ const NodeType assumed_input_type_;
};
class LogicalNot : public FixedInputValueNodeT<1, LogicalNot> {
@@ -5107,40 +5007,6 @@ class GeneratorStore : public VarargsNodeT<2, GeneratorStore> {
const int bytecode_offset_;
};
-class TryOnStackReplacement : public FixedInputNodeT<1, TryOnStackReplacement> {
- public:
- explicit TryOnStackReplacement(uint64_t bitfield, int32_t loop_depth,
- FeedbackSlot feedback_slot,
- BytecodeOffset osr_offset,
- MaglevCompilationUnit* unit)
- : Base(bitfield),
- loop_depth_(loop_depth),
- feedback_slot_(feedback_slot),
- osr_offset_(osr_offset),
- unit_(unit) {}
-
- static constexpr OpProperties kProperties =
- OpProperties::DeferredCall() | OpProperties::EagerDeopt() |
- OpProperties::CanAllocate() | OpProperties::NotIdempotent();
- DECLARE_INPUTS(Closure)
- DECLARE_INPUT_TYPES(Tagged)
-
- Input closure() { return Node::input(0); }
-
- const MaglevCompilationUnit* unit() const { return unit_; }
-
- int MaxCallStackArgs() const;
- void SetValueLocationConstraints();
- void GenerateCode(MaglevAssembler*, const ProcessingState&);
-
- private:
- // For OSR.
- const int32_t loop_depth_;
- const FeedbackSlot feedback_slot_;
- const BytecodeOffset osr_offset_;
- MaglevCompilationUnit* const unit_;
-};
-
class ForInPrepare : public FixedInputValueNodeT<2, ForInPrepare> {
public:
explicit ForInPrepare(uint64_t bitfield, compiler::FeedbackSource& feedback)
@@ -6207,6 +6073,15 @@ struct VirtualJSStringIteratorShape : VirtualJSObjectShape {
#undef FIELD_LIST
};
+struct VirtualJSMapIteratorShape : VirtualJSObjectShape {
+ using T = JSCollectionIterator;
+#define FIELD_LIST(V) \
+ V(table, offsetof(T, table_), vobj::FieldType::kTagged) \
+ V(index, offsetof(T, index_), vobj::FieldType::kTagged)
+ DEF_SHAPE(VirtualJSObjectShape, FIELD_LIST);
+#undef FIELD_LIST
+};
+
struct VirtualJSIteratorResultShape : VirtualJSObjectShape {
using T = JSIteratorResult;
#define FIELD_LIST(V) \
@@ -8227,8 +8102,9 @@ class ProcessWasmArgument
public:
explicit ProcessWasmArgument(uint64_t bitfield) : Base(bitfield) {}
- static constexpr OpProperties kProperties =
- OpProperties::EagerDeopt() | OpProperties::TaggedValue();
+ static constexpr OpProperties kProperties = OpProperties::EagerDeopt() |
+ OpProperties::TaggedValue() |
+ OpProperties::NotIdempotent();
DECLARE_INPUTS(Value)
DECLARE_INPUT_TYPES(Tagged)
@@ -8969,43 +8845,6 @@ class LoadHoleyFixedDoubleArrayElement
void GenerateCode(MaglevAssembler*, const ProcessingState&);
};
-class LoadHoleyFixedDoubleArrayElementCheckedNotHole
- : public FixedInputValueNodeT<
- 2, LoadHoleyFixedDoubleArrayElementCheckedNotHole> {
- public:
- explicit LoadHoleyFixedDoubleArrayElementCheckedNotHole(uint64_t bitfield)
- : Base(bitfield) {}
-
- static constexpr OpProperties kProperties = OpProperties::CanRead() |
- OpProperties::Float64() |
- OpProperties::EagerDeopt();
- DECLARE_INPUTS(Elements, Index)
- DECLARE_INPUT_TYPES(Tagged, Int32)
-
- void SetValueLocationConstraints();
- void GenerateCode(MaglevAssembler*, const ProcessingState&);
-};
-
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-class LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole
- : public FixedInputValueNodeT<
- 2, LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole> {
- public:
- explicit LoadHoleyFixedDoubleArrayElementCheckedNotUndefinedOrHole(
- uint64_t bitfield)
- : Base(bitfield) {}
-
- static constexpr OpProperties kProperties = OpProperties::CanRead() |
- OpProperties::Float64() |
- OpProperties::EagerDeopt();
- DECLARE_INPUTS(Elements, Index)
- DECLARE_INPUT_TYPES(Tagged, Int32)
-
- void SetValueLocationConstraints();
- void GenerateCode(MaglevAssembler*, const ProcessingState&);
-};
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
template <typename Derived, ValueRepresentation value_input_rep>
class StoreFixedDoubleArrayElementT : public FixedInputNodeT<3, Derived> {
public:
@@ -9030,8 +8869,29 @@ class StoreFixedDoubleArrayElement
ValueRepresentation::kFloat64> {
public:
explicit StoreFixedDoubleArrayElement(uint64_t bitfield) : Base(bitfield) {}
+
+ void VerifyInputs() const;
+};
+
+// Writes the hole into an element, marking it absent. This is the only way a
+// hole gets into a double array on purpose, which is what lets
+// StoreFixedDoubleArrayElement mean "stores a number".
+class StoreFixedDoubleArrayHole
+ : public FixedInputNodeT<2, StoreFixedDoubleArrayHole> {
+ public:
+ explicit StoreFixedDoubleArrayHole(uint64_t bitfield) : Base(bitfield) {}
+
+ static constexpr OpProperties kProperties = OpProperties::CanWrite();
+ DECLARE_INPUTS(Elements, Index)
+ DECLARE_INPUT_TYPES(Tagged, Int32)
+
+ void SetValueLocationConstraints();
+ void GenerateCode(MaglevAssembler*, const ProcessingState&);
};
+// Stores a value that can be undefined. HoleyFloat64 spells undefined in two
+// ways, while an element of the array only ever spells it as the undefined
+// NaN, so the store canonicalizes onto that one.
class StoreFixedHoleyDoubleArrayElement
: public StoreFixedDoubleArrayElementT<StoreFixedHoleyDoubleArrayElement,
ValueRepresentation::kHoleyFloat64> {
@@ -9040,14 +8900,23 @@ class StoreFixedHoleyDoubleArrayElement
: Base(bitfield) {}
};
-class LoadSignedIntDataViewElement
- : public FixedInputValueNodeT<4, LoadSignedIntDataViewElement> {
+// LoadInt32DataViewElement handles loads for all integer DataView types whose
+// values fit in a 32-bit signed integer (Int8, Uint8, Uint8Clamped, Int16,
+// Uint16, Int32). Uint32 is handled separately by LoadUint32DataViewElement
+// because the loaded uint32 value range doesn't fit in an int32, so we need to
+// explicitly return a Uint32.
+class LoadInt32DataViewElement
+ : public FixedInputValueNodeT<4, LoadInt32DataViewElement> {
+ using Base = FixedInputValueNodeT<4, LoadInt32DataViewElement>;
+
public:
- explicit LoadSignedIntDataViewElement(uint64_t bitfield,
- ExternalArrayType type)
- : Base(bitfield), type_(type) {
+ explicit LoadInt32DataViewElement(uint64_t bitfield, ExternalArrayType type)
+ : Base(bitfield | ExternalArrayTypeField::encode(type)) {
DCHECK(type == ExternalArrayType::kExternalInt8Array ||
+ type == ExternalArrayType::kExternalUint8Array ||
+ type == ExternalArrayType::kExternalUint8ClampedArray ||
type == ExternalArrayType::kExternalInt16Array ||
+ type == ExternalArrayType::kExternalUint16Array ||
type == ExternalArrayType::kExternalInt32Array);
}
@@ -9059,20 +8928,52 @@ class LoadSignedIntDataViewElement
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- auto options() const { return std::tuple{type_}; }
+ auto options() const { return std::tuple{external_array_type()}; }
- ExternalArrayType external_array_type() const { return type_; }
+ ExternalArrayType external_array_type() const {
+ return ExternalArrayTypeField::decode(bitfield());
+ }
private:
- ExternalArrayType type_;
+ using ExternalArrayTypeField = NextBitField<ExternalArrayType, 4>;
+};
+
+class LoadUint32DataViewElement
+ : public FixedInputValueNodeT<4, LoadUint32DataViewElement> {
+ using Base = FixedInputValueNodeT<4, LoadUint32DataViewElement>;
+
+ public:
+ explicit LoadUint32DataViewElement(
+ uint64_t bitfield,
+ ExternalArrayType type = ExternalArrayType::kExternalUint32Array)
+ : Base(bitfield) {
+ DCHECK_EQ(type, ExternalArrayType::kExternalUint32Array);
+ }
+
+ static constexpr OpProperties kProperties =
+ OpProperties::CanRead() | OpProperties::Uint32();
+ DECLARE_INPUTS(Object, DataPointer, Index, IsLittleEndian)
+ DECLARE_INPUT_TYPES(Tagged, RawPtr, Int32, Tagged)
+
+ void SetValueLocationConstraints();
+ void GenerateCode(MaglevAssembler*, const ProcessingState&);
+
+ auto options() const { return std::tuple{external_array_type()}; }
+
+ ExternalArrayType external_array_type() const {
+ return ExternalArrayType::kExternalUint32Array;
+ }
};
class LoadDoubleDataViewElement
: public FixedInputValueNodeT<4, LoadDoubleDataViewElement> {
+ using Base = FixedInputValueNodeT<4, LoadDoubleDataViewElement>;
+
public:
explicit LoadDoubleDataViewElement(uint64_t bitfield, ExternalArrayType type)
- : Base(bitfield) {
- DCHECK_EQ(type, type_);
+ : Base(bitfield | ExternalArrayTypeField::encode(type)) {
+ DCHECK(type == ExternalArrayType::kExternalFloat32Array ||
+ type == ExternalArrayType::kExternalFloat64Array);
}
static constexpr OpProperties kProperties =
@@ -9083,11 +8984,14 @@ class LoadDoubleDataViewElement
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- auto options() const { return std::tuple{type_}; }
+ auto options() const { return std::tuple{external_array_type()}; }
+
+ ExternalArrayType external_array_type() const {
+ return ExternalArrayTypeField::decode(bitfield());
+ }
private:
- static constexpr ExternalArrayType type_ =
- ExternalArrayType::kExternalFloat64Array;
+ using ExternalArrayTypeField = NextBitField<ExternalArrayType, 4>;
};
#define LOAD_TYPED_ARRAY(name, properties, ...) \
@@ -9237,19 +9141,31 @@ STORE_CONSTANT_TYPED_ARRAY(StoreIntConstantTypedArrayElement,
UINT8_CLAMPED_ELEMENTS, UINT16_ELEMENTS,
UINT16_ELEMENTS, UINT32_ELEMENTS)
STORE_CONSTANT_TYPED_ARRAY(StoreDoubleConstantTypedArrayElement,
- OpProperties::CanWrite(), HoleyFloat64,
- FLOAT32_ELEMENTS, FLOAT64_ELEMENTS)
+ OpProperties::CanWrite(), Float64, FLOAT32_ELEMENTS,
+ FLOAT64_ELEMENTS)
#undef STORE_CONSTANT_TYPED_ARRAY
-class StoreSignedIntDataViewElement
- : public FixedInputNodeT<5, StoreSignedIntDataViewElement> {
+// StoreInt32DataViewElement handles stores for all integer DataView types
+// (Int8, Uint8, Uint8Clamped, Int16, Uint16, Int32, Uint32).
+// In JavaScript, all integer DataView setters (including Uint8/Uint16/Uint32)
+// perform ToNumber and truncate the value to 32 bits (ToInt32 / ToUint32).
+// Since truncation and memory store of the lower 8, 16, or 32 bits write the
+// exact same bit pattern regardless of signedness, a single Int32 store node
+// can represent all integer stores without needing a separate StoreUint32 node.
+class StoreInt32DataViewElement
+ : public FixedInputNodeT<5, StoreInt32DataViewElement> {
+ using Base = FixedInputNodeT<5, StoreInt32DataViewElement>;
+
public:
- explicit StoreSignedIntDataViewElement(uint64_t bitfield,
- ExternalArrayType type)
- : Base(bitfield), type_(type) {
+ explicit StoreInt32DataViewElement(uint64_t bitfield, ExternalArrayType type)
+ : Base(bitfield | ExternalArrayTypeField::encode(type)) {
DCHECK(type == ExternalArrayType::kExternalInt8Array ||
+ type == ExternalArrayType::kExternalUint8Array ||
+ type == ExternalArrayType::kExternalUint8ClampedArray ||
type == ExternalArrayType::kExternalInt16Array ||
- type == ExternalArrayType::kExternalInt32Array);
+ type == ExternalArrayType::kExternalUint16Array ||
+ type == ExternalArrayType::kExternalInt32Array ||
+ type == ExternalArrayType::kExternalUint32Array);
}
static constexpr OpProperties kProperties = OpProperties::CanWrite();
@@ -9259,18 +9175,25 @@ class StoreSignedIntDataViewElement
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
- ExternalArrayType external_array_type() const { return type_; }
+ auto options() const { return std::tuple{external_array_type()}; }
+
+ ExternalArrayType external_array_type() const {
+ return ExternalArrayTypeField::decode(bitfield());
+ }
private:
- ExternalArrayType type_;
+ using ExternalArrayTypeField = NextBitField<ExternalArrayType, 4>;
};
class StoreDoubleDataViewElement
: public FixedInputNodeT<5, StoreDoubleDataViewElement> {
+ using Base = FixedInputNodeT<5, StoreDoubleDataViewElement>;
+
public:
explicit StoreDoubleDataViewElement(uint64_t bitfield, ExternalArrayType type)
- : Base(bitfield) {
- DCHECK_EQ(type, ExternalArrayType::kExternalFloat64Array);
+ : Base(bitfield | ExternalArrayTypeField::encode(type)) {
+ DCHECK(type == ExternalArrayType::kExternalFloat32Array ||
+ type == ExternalArrayType::kExternalFloat64Array);
}
static constexpr OpProperties kProperties = OpProperties::CanWrite();
@@ -9279,6 +9202,15 @@ class StoreDoubleDataViewElement
void SetValueLocationConstraints();
void GenerateCode(MaglevAssembler*, const ProcessingState&);
+
+ auto options() const { return std::tuple{external_array_type()}; }
+
+ ExternalArrayType external_array_type() const {
+ return ExternalArrayTypeField::decode(bitfield());
+ }
+
+ private:
+ using ExternalArrayTypeField = NextBitField<ExternalArrayType, 4>;
};
class StoreInt32 : public FixedInputNodeT<2, StoreInt32> {
@@ -10180,15 +10112,31 @@ class Phi : public ValueNodeT<Phi> {
// TODO(jgruber): More intuitive constructors, if possible.
Phi(uint64_t bitfield, MergePointInterpreterFrameState* merge_state,
interpreter::Register owner)
+ : Phi(bitfield, merge_state, owner, NodeType::kUnknown) {}
+
+ Phi(uint64_t bitfield, MergePointInterpreterFrameState* merge_state,
+ interpreter::Register owner, NodeType type)
: Base(bitfield),
owner_(owner),
merge_state_(merge_state),
- type_(NodeType::kUnknown),
+ type_(type),
post_loop_type_(NodeType::kUnknown) {
DCHECK_NOT_NULL(merge_state);
}
- Input backedge_input() { return input(input_count() - 1); }
+ // The back-edge is always the last input, but not always at index 1: a
+ // resumable loop can be entered through its resume edges alone, leaving its
+ // header without a forward edge.
+ int backedge_index() const {
+ DCHECK(is_loop_phi());
+ return input_count() - 1;
+ }
+ Input backedge_input() { return input(backedge_index()); }
+ ValueNode* backedge() { return backedge_input().node(); }
+ ValueNode* forward_edge() {
+ DCHECK_EQ(backedge_index(), 1);
+ return input_node(0);
+ }
interpreter::Register owner() const { return owner_; }
const MergePointInterpreterFrameState* merge_state() const {
@@ -10204,7 +10152,7 @@ class Phi : public ValueNodeT<Phi> {
bool is_loop_phi() const;
bool is_backedge_offset(int i) const {
- return is_loop_phi() && i == input_count() - 1;
+ return is_loop_phi() && i == backedge_index();
}
void VerifyInputs() const;
@@ -10544,6 +10492,7 @@ class CallBuiltin : public VarargsValueNodeT<0, CallBuiltin> {
V(ArrayPrototypeSplice, NodeType::kJSReceiver) \
V(ArrayUnshift, NodeType::kNumber) \
V(ArrayBufferIsView, NodeType::kBoolean) \
+ V(CloneFastJSArray, NodeType::kJSArray) \
V(ObjectAssign, NodeType::kJSReceiver) \
V(ObjectCreate, NodeType::kAnyHeapObject) \
V(ObjectIs, NodeType::kBoolean) \
@@ -11164,9 +11113,17 @@ class HandleNoHeapWritesInterrupt
class ReduceInterruptBudgetForLoop
: public FixedInputNodeT<1, ReduceInterruptBudgetForLoop> {
public:
- explicit ReduceInterruptBudgetForLoop(uint64_t bitfield, int amount)
- : Base(bitfield), amount_(amount) {
+ explicit ReduceInterruptBudgetForLoop(uint64_t bitfield, int amount,
+ BytecodeOffset osr_offset,
+ int loop_depth,
+ FeedbackSlot feedback_slot)
+ : Base(bitfield),
+ amount_(amount),
+ osr_offset_(osr_offset),
+ loop_depth_(loop_depth),
+ feedback_slot_(feedback_slot) {
DCHECK_GT(amount, 0);
+ DCHECK_EQ(osr_offset == BytecodeOffset::None(), !try_osr());
}
DECLARE_INPUTS(FeedbackCell)
@@ -11174,9 +11131,14 @@ class ReduceInterruptBudgetForLoop
static constexpr OpProperties kProperties =
OpProperties::DeferredCall() | OpProperties::CanAllocate() |
- OpProperties::LazyDeopt() | OpProperties::NotIdempotent();
+ OpProperties::LazyDeopt() | OpProperties::EagerDeopt() |
+ OpProperties::NotIdempotent();
int amount() const { return amount_; }
+ BytecodeOffset osr_offset() const { return osr_offset_; }
+ int loop_depth() const { return loop_depth_; }
+ FeedbackSlot feedback_slot() const { return feedback_slot_; }
+ bool try_osr() const { return !feedback_slot_.IsInvalid(); }
int MaxCallStackArgs() const;
void SetValueLocationConstraints();
@@ -11185,6 +11147,9 @@ class ReduceInterruptBudgetForLoop
private:
const int amount_;
+ const BytecodeOffset osr_offset_;
+ const int loop_depth_;
+ const FeedbackSlot feedback_slot_;
};
class ReduceInterruptBudgetForReturn
diff --git a/deps/v8/src/maglev/maglev-kna-processor.cc b/deps/v8/src/maglev/maglev-kna-processor.cc
index ee5a92cff5f..52edc3d29b6 100644
--- a/deps/v8/src/maglev/maglev-kna-processor.cc
+++ b/deps/v8/src/maglev/maglev-kna-processor.cc
@@ -62,6 +62,20 @@ ProcessResult RecomputeKnownNodeAspectsProcessor::ProcessNode(AssumeMap* node) {
return RecordMaps(node->ObjectInput().node(), node->maps());
}
+namespace {
+
+template <typename NodeT>
+NodeType AssumedOrStaticInputType(NodeT* node, NodeType default_type) {
+ if constexpr (requires { node->assumed_input_type(); }) {
+ DCHECK(NodeTypeIs(node->assumed_input_type(), default_type));
+ return node->assumed_input_type();
+ } else {
+ return default_type;
+ }
+}
+
+} // namespace
+
#define DEFINE_PROCESS_SAFE_CONV(Node, Alt, Type) \
ProcessResult RecomputeKnownNodeAspectsProcessor::ProcessNode(Node* node) { \
NodeInfo* info = GetOrCreateInfoFor(node->input_node(0)); \
@@ -70,7 +84,7 @@ ProcessResult RecomputeKnownNodeAspectsProcessor::ProcessNode(AssumeMap* node) {
* Should we remove this one as well? */ \
info->alternative().set_##Alt(node); \
} \
- info->IntersectType(NodeType::k##Type); \
+ info->IntersectType(AssumedOrStaticInputType(node, NodeType::k##Type)); \
if (info->type() == NodeType::kNone) { \
if constexpr (Node::kProperties.can_eager_deopt()) { \
ReduceResult result = \
@@ -95,8 +109,7 @@ SAFE_CONVERSION_LIST(DEFINE_PROCESS_SAFE_CONV)
ProcessResult RecomputeKnownNodeAspectsProcessor::ProcessNode(
CheckedNumberOrOddballToFloat64* node) {
NodeInfo* info = GetOrCreateInfoFor(node->input_node(0));
- info->IntersectType(
- GetAllowedTypeFromConversionType(node->conversion_type()));
+ info->IntersectType(node->assumed_input_type());
if (!info->alternative().float64() &&
NodeTypeIs(info->type(), NodeType::kNumber)) {
info->alternative().set_float64(node);
@@ -121,7 +134,7 @@ ProcessResult RecomputeKnownNodeAspectsProcessor::ProcessNode(
}
ProcessResult RecomputeKnownNodeAspectsProcessor::ProcessNode(
- HoleyFloat64ToSilencedFloat64* node) {
+ UnsafeHoleyFloat64ToFloat64* node) {
NodeInfo* info = GetOrCreateInfoFor(node->input_node(0));
if (!info->alternative().float64() &&
NodeTypeIs(info->type(), NodeType::kNumber)) {
diff --git a/deps/v8/src/maglev/maglev-kna-processor.h b/deps/v8/src/maglev/maglev-kna-processor.h
index 8460859ae0d..1965a9de1fb 100644
--- a/deps/v8/src/maglev/maglev-kna-processor.h
+++ b/deps/v8/src/maglev/maglev-kna-processor.h
@@ -85,10 +85,10 @@ class RecomputeKnownNodeAspectsProcessor {
// for all loops.
known_node_aspects_ = zone()->New<KnownNodeAspects>(zone());
} else if (block->is_loop()) {
- DCHECK_GT(block->predecessor_count(), 1);
+ DCHECK_EQ(block->predecessor_count(), 2);
known_node_aspects_ = block->state()->TakeKnownNodeAspects();
KnownNodeAspects* backedge_known_node_aspects =
- block->state()->backedge_known_node_aspects();
+ block->state()->AsLoopHeader()->backedge_known_node_aspects();
// Merge saved backedge KNA to the forward one.
TRACE_KNA("Merging KNA at loop header B"
<< block->id() << ":" << TraceNewline{}
@@ -96,8 +96,9 @@ class RecomputeKnownNodeAspectsProcessor {
<< TraceNewline{} << "## Backward KNA:" << TraceNewline{}
<< *backedge_known_node_aspects);
backedge_known_node_aspects->UnwrapIdentitiesAndPhisInKeys(zone());
- known_node_aspects_->MergeForLoop(*backedge_known_node_aspects, zone(),
- block->state()->loop_effects());
+ known_node_aspects_->MergeForLoop(
+ *backedge_known_node_aspects, zone(),
+ block->state()->AsLoopHeader()->loop_effects());
} else if (block->has_state()) {
known_node_aspects_ = block->state()->TakeKnownNodeAspects();
} else if (block->is_edge_split_block()) {
@@ -333,7 +334,7 @@ class RecomputeKnownNodeAspectsProcessor {
ProcessResult ProcessNode(CheckedNumberOrOddballToFloat64* node);
ProcessResult ProcessNode(UnsafeNumberOrOddballToFloat64* node);
- ProcessResult ProcessNode(HoleyFloat64ToSilencedFloat64* node);
+ ProcessResult ProcessNode(UnsafeHoleyFloat64ToFloat64* node);
// TODO(victorgomes): Ideally we would like to check we already know the type,
// but currently we cannot. The issue is that if the GraphBuilder emits a
@@ -363,7 +364,7 @@ class RecomputeKnownNodeAspectsProcessor {
PROCESS_UNSAFE_CONV(ChangeIntPtrToFloat64, float64, Number)
PROCESS_UNSAFE_CONV(UnsafeNumberToFloat64, float64, Number)
// Note: NumberOrOddball->Float64 conversions (such as
- // UnsafeNumberOrOddballToFloat64 and HoleyFloat64ToSilencedFloat64) lose
+ // UnsafeNumberOrOddballToFloat64 and UnsafeHoleyFloat64ToFloat64) lose
// oddball identity and are promoted to float64 alternative by explicit
// handlers if and only if KNA has statically proven the input is strictly
// NodeType::kNumber without oddballs.
@@ -518,6 +519,12 @@ class RecomputeKnownNodeAspectsProcessor {
return RecordType(node->input_node(0), node->asserted_type());
}
+ ProcessResult ProcessNode(CheckInt32IsSmi* node) {
+ NodeInfo* info = GetOrCreateInfoFor(node->input_node(0));
+ info->IntersectType(NodeType::kSmi);
+ return ProcessResult::kContinue;
+ }
+
ProcessResult ProcessNode(Node* node) { return ProcessResult::kContinue; }
};
diff --git a/deps/v8/src/maglev/maglev-known-node-aspects.cc b/deps/v8/src/maglev/maglev-known-node-aspects.cc
index 2c1aa797326..8234a646671 100644
--- a/deps/v8/src/maglev/maglev-known-node-aspects.cc
+++ b/deps/v8/src/maglev/maglev-known-node-aspects.cc
@@ -6,6 +6,7 @@
#include <algorithm>
#include <iostream>
+#include <optional>
#include "include/v8-internal.h"
#include "src/base/logging.h"
@@ -71,36 +72,50 @@ struct DefaultMergeFunc {
}
};
-// Destructively intersects the right map into the left map, such that the
-// left map is mutated to become the result of the intersection. Values that
-// are in both maps are passed to the merging function to be merged with each
-// other -- again, the LHS here is expected to be mutated.
-template <typename Key, typename Value, typename MergeFunc = DefaultMergeFunc>
-void DestructivelyIntersect(ZoneMap<Key, Value>& lhs_map,
- const ZoneMap<Key, Value>& rhs_map,
- MergeFunc&& func = DefaultMergeFunc()) {
+struct NeverKeepLhsOnly {
+ template <typename Key, typename Value>
+ bool operator()(const Key&, Value&) {
+ return false;
+ }
+};
+
+// Destructively merges the right map into the left map, such that the left
+// map is mutated to become the result. Values that are in both maps are
+// passed to `merge` to be merged with each other -- the LHS here is expected
+// to be mutated. Entries only in the left map are passed to `keep_lhs_only`,
+// which may also mutate the value and decides whether the entry survives;
+// entries only in the right map are dropped. Both functors see keys in
+// ascending order.
+template <typename Key, typename Value, typename MergeFunc,
+ typename KeepLhsOnlyFunc>
+void DestructivelyMerge(ZoneMap<Key, Value>& lhs_map,
+ const ZoneMap<Key, Value>& rhs_map, MergeFunc&& merge,
+ KeepLhsOnlyFunc&& keep_lhs_only) {
// Walk the two maps in lock step. This relies on the fact that ZoneMaps are
// sorted.
typename ZoneMap<Key, Value>::iterator lhs_it = lhs_map.begin();
typename ZoneMap<Key, Value>::const_iterator rhs_it = rhs_map.begin();
while (lhs_it != lhs_map.end() && rhs_it != rhs_map.end()) {
if (lhs_it->first < rhs_it->first) {
- // Remove from LHS elements that are not in RHS.
- lhs_it = lhs_map.erase(lhs_it);
+ if (keep_lhs_only(lhs_it->first, lhs_it->second)) {
+ ++lhs_it;
+ } else {
+ lhs_it = lhs_map.erase(lhs_it);
+ }
} else if (rhs_it->first < lhs_it->first) {
// Skip over elements that are only in RHS.
++rhs_it;
} else {
// Apply the merge function to the values of the two iterators. If the
// function returns false, remove the value.
- bool keep_value = func(lhs_it->first, lhs_it->second, rhs_it->second);
+ bool keep_value = merge(lhs_it->first, lhs_it->second, rhs_it->second);
if constexpr (std::is_same_v<decltype(lhs_it->second), ValueNode*>) {
if (!keep_value && lhs_it->second && rhs_it->second) {
auto l = lhs_it->second->UnwrapIdentities();
auto r = rhs_it->second->UnwrapIdentities();
if (l != lhs_it->second || r != rhs_it->second) {
lhs_it->second = l;
- keep_value = func(lhs_it->first, l, r);
+ keep_value = merge(lhs_it->first, l, r);
}
}
}
@@ -112,22 +127,112 @@ void DestructivelyIntersect(ZoneMap<Key, Value>& lhs_map,
++rhs_it;
}
}
- // If we haven't reached the end of LHS by now, then we have reached the end
- // of RHS, and the remaining items are therefore not in RHS. Remove them.
- if (lhs_it != lhs_map.end()) {
- lhs_map.erase(lhs_it, lhs_map.end());
+ // The remaining LHS items have no RHS counterpart.
+ if constexpr (std::is_same_v<std::decay_t<KeepLhsOnlyFunc>,
+ NeverKeepLhsOnly>) {
+ if (lhs_it != lhs_map.end()) {
+ lhs_map.erase(lhs_it, lhs_map.end());
+ }
+ } else {
+ while (lhs_it != lhs_map.end()) {
+ if (keep_lhs_only(lhs_it->first, lhs_it->second)) {
+ ++lhs_it;
+ } else {
+ lhs_it = lhs_map.erase(lhs_it);
+ }
+ }
}
}
+// Destructively intersects the right map into the left map, such that the
+// left map is mutated to become the result of the intersection. Values that
+// are in both maps are passed to the merging function to be merged with each
+// other -- again, the LHS here is expected to be mutated.
+template <typename Key, typename Value, typename MergeFunc = DefaultMergeFunc>
+void DestructivelyIntersect(ZoneMap<Key, Value>& lhs_map,
+ const ZoneMap<Key, Value>& rhs_map,
+ MergeFunc&& func = DefaultMergeFunc()) {
+ DestructivelyMerge(lhs_map, rhs_map, std::forward<MergeFunc>(func),
+ NeverKeepLhsOnly());
+}
+
+// LINT.IfChange(LoopInvariantFacts)
+
+// Membership queries against a sorted ZoneSet, advanced in lock step with a
+// caller iterating its own sorted container: between Resets, keys must be
+// queried in ascending order.
template <typename Key>
-bool NextInIgnoreList(typename ZoneSet<Key>::const_iterator& ignore,
- typename ZoneSet<Key>::const_iterator& ignore_end,
- const Key& cur) {
- while (ignore != ignore_end && *ignore < cur) {
- ++ignore;
+class IgnoreListCursor {
+ public:
+ explicit IgnoreListCursor(const ZoneSet<Key>& set)
+ : set_(set), it_(set.begin()) {}
+
+ bool Contains(const Key& key) {
+#ifdef DEBUG
+ DCHECK_IMPLIES(last_.has_value(), !(key < *last_));
+ last_ = key;
+#endif
+ while (it_ != set_.end() && *it_ < key) {
+ ++it_;
+ }
+ return it_ != set_.end() && *it_ == key;
}
- return ignore != ignore_end && *ignore == cur;
-}
+
+ void Reset() {
+ it_ = set_.begin();
+#ifdef DEBUG
+ last_.reset();
+#endif
+ }
+
+ private:
+ const ZoneSet<Key>& set_;
+ typename ZoneSet<Key>::const_iterator it_;
+#ifdef DEBUG
+ std::optional<Key> last_;
+#endif
+};
+
+// Decides whether a cached property fact provably survives a loop whose
+// writes are summarized by `loop_effects`. StartKey must be called with
+// ascending keys, and ObjectInvariant with ascending objects per key.
+class LoopInvariantPropertyFilter {
+ public:
+ LoopInvariantPropertyFilter(const LoopEffects* loop_effects,
+ const ZoneSet<ValueNode*>& objects_written,
+ const KnownNodeAspects* aspects)
+ : loop_effects_(loop_effects),
+ keys_cleared_(loop_effects->keys_cleared),
+ objects_written_(objects_written),
+ aspects_(aspects) {}
+
+ bool StartKey(PropertyKey key) {
+ key_cleared_ = keys_cleared_.Contains(key);
+ check_elements_transition_ = loop_effects_->elements_kind_transitioned &&
+ key == PropertyKey::Elements();
+ objects_written_.Reset();
+ return !key_cleared_;
+ }
+
+ bool ObjectInvariant(ValueNode* obj) {
+ if (key_cleared_) return false;
+ if (objects_written_.Contains(obj)) return false;
+ if (check_elements_transition_ && !aspects_->TryGetInfoWithFreshMaps(obj)) {
+ return false;
+ }
+ return true;
+ }
+
+ private:
+ const LoopEffects* loop_effects_;
+ IgnoreListCursor<PropertyKey> keys_cleared_;
+ IgnoreListCursor<ValueNode*> objects_written_;
+ const KnownNodeAspects* aspects_;
+ bool key_cleared_ = false;
+ bool check_elements_transition_ = false;
+};
+
+// LINT.ThenChange(:IsCompatibleWithLoopHeader)
// Takes two ordered maps and ensures that every element in `as` is
// * also present in `bs` and
@@ -358,30 +463,56 @@ void KnownNodeAspects::MergeForLoop(const KnownNodeAspects& backedge,
});
return !lhs.empty();
};
- auto entry_invariant = [&](PropertyKey key, ValueNode* obj) {
- if (!keep_invariant_loads) return false;
- if (loop_effects->keys_cleared.contains(key)) return false;
- if (loop_effects->objects_written.contains(obj)) return false;
- if (loop_effects->elements_kind_transitioned &&
- key == PropertyKey::Elements() && !TryGetInfoWithFreshMaps(obj)) {
- return false;
+ ZoneSet<ValueNode*> objects_written(zone);
+ if (keep_invariant_loads) {
+ for (ValueNode* obj : loop_effects->objects_written) {
+ objects_written.insert(obj->UnwrapIdentities());
}
- return true;
+ }
+ std::optional<LoopInvariantPropertyFilter> filter;
+ if (keep_invariant_loads) {
+ filter.emplace(loop_effects, objects_written, this);
+ }
+ auto entry_invariant = [&](ValueNode* obj) {
+ return filter.has_value() && filter->ObjectInvariant(obj);
};
- auto merge_loaded_properties =
+ auto keep_forward_fact = [&](ValueNode* obj, ValueNode*& l) {
+ if (l) l = l->UnwrapIdentities();
+ return l != nullptr && entry_invariant(obj);
+ };
+ auto merge_object_fact = [&](ValueNode* obj, ValueNode*& l, ValueNode* r) {
+ if (l) l = l->UnwrapIdentities();
+ if (r) r = r->UnwrapIdentities();
+ if (!r) return l != nullptr && entry_invariant(obj);
+ return l == r || (entry_invariant(obj) && same_load(l, r));
+ };
+ auto merge_properties_of_key =
[&](PropertyKey key, ZoneMap<ValueNode*, ValueNode*>& lhs,
const ZoneMap<ValueNode*, ValueNode*>& rhs) {
- DestructivelyIntersect(
- lhs, rhs, [&](ValueNode* obj, ValueNode* l, ValueNode* r) {
- return l == r || (entry_invariant(key, obj) && same_load(l, r));
- });
+ if (filter) filter->StartKey(key);
+ DestructivelyMerge(lhs, rhs, merge_object_fact, keep_forward_fact);
+ return !lhs.empty();
+ };
+ auto keep_forward_properties_of_key =
+ [&](PropertyKey key, ZoneMap<ValueNode*, ValueNode*>& lhs) {
+ if (!filter || !filter->StartKey(key)) return false;
+ for (auto it = lhs.begin(); it != lhs.end();) {
+ if (keep_forward_fact(it->first, it->second)) {
+ ++it;
+ } else {
+ it = lhs.erase(it);
+ }
+ }
return !lhs.empty();
};
DestructivelyIntersect(loaded_constant_properties_,
backedge.loaded_constant_properties_,
merge_constant_properties);
- DestructivelyIntersect(loaded_properties_, backedge.loaded_properties_,
- merge_loaded_properties);
+ // The forward predecessor dominates the loop body and the loop effects
+ // summarize every write in the body, so a forward fact provably untouched
+ // by the loop is kept even without a matching backedge entry.
+ DestructivelyMerge(loaded_properties_, backedge.loaded_properties_,
+ merge_properties_of_key, keep_forward_properties_of_key);
DestructivelyIntersect(loaded_tagged_keyed_properties_,
backedge.loaded_tagged_keyed_properties_);
DestructivelyIntersect(loaded_context_constants_,
@@ -391,13 +522,27 @@ void KnownNodeAspects::MergeForLoop(const KnownNodeAspects& backedge,
});
may_have_aliasing_contexts_ = ContextSlotLoadsAliasMerge(
may_have_aliasing_contexts_, backedge.may_have_aliasing_contexts());
+ const bool context_stores_may_alias =
+ may_have_aliasing_contexts_ != ContextSlotLoadsAlias::kNever;
+ std::optional<IgnoreListCursor<LoadedContextSlotsKey>> slot_written;
+ if (keep_invariant_loads && !loop_effects->may_have_aliasing_contexts) {
+ slot_written.emplace(loop_effects->context_slot_written);
+ }
+ auto context_slot_invariant = [&](const LoadedContextSlotsKey& key) {
+ if (!slot_written.has_value()) return false;
+ if (slot_written->Contains(key)) return false;
+ if (context_stores_may_alias &&
+ loop_effects->WritesContextSlotOffset(std::get<int>(key))) {
+ return false;
+ }
+ return true;
+ };
+ // TODO(victorgomes): Like loaded_properties_ above, an invariant forward
+ // context slot could be kept without a backedge witness.
DestructivelyIntersect(
loaded_context_slots_, backedge.loaded_context_slots_,
[&](auto key, ValueNode* l, ValueNode* r) {
- return l == r || (keep_invariant_loads &&
- !loop_effects->may_have_aliasing_contexts &&
- !loop_effects->context_slot_written.contains(key) &&
- same_load(l, r));
+ return l == r || (context_slot_invariant(key) && same_load(l, r));
});
}
@@ -464,7 +609,7 @@ void KnownNodeAspects::UnwrapIdentitiesAndPhisInKeys(Zone* zone) {
void KnownNodeAspects::UpdateMayHaveAliasingContexts(
compiler::JSHeapBroker* broker, LocalIsolate* local_isolate,
ValueNode* context) {
- if (may_have_aliasing_contexts_ == ContextSlotLoadsAlias::kYes) return;
+ if (may_have_aliasing_contexts_ == ContextSlotLoadsAlias::kAlways) return;
while (true) {
if (auto load_prev_ctxt = context->TryCast<LoadContextSlotNoCells>()) {
@@ -501,26 +646,26 @@ void KnownNodeAspects::UpdateMayHaveAliasingContexts(
USE(load);
DCHECK(load->offset() == offsetof(JSFunction, context_) ||
load->offset() == offsetof(JSGeneratorObject, context_));
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kYes;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kAlways;
DCHECK(NodeTypeIs(GetTypeUnchecked(broker, context), NodeType::kContext));
break;
}
case Opcode::kCallRuntime:
DCHECK(NodeTypeIs(GetTypeUnchecked(broker, context), NodeType::kContext));
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kYes;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kAlways;
break;
case Opcode::kGeneratorRestoreRegister:
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kYes;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kAlways;
break;
case Opcode::kPhi:
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kYes;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kAlways;
break;
default:
// This DCHECK only shows which kind of nodes can be a context, even if
// this DCHECK fails, it is always safe to set aliasing context mode to
- // kYes.
+ // kAlways.
DCHECK(false);
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kYes;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kAlways;
break;
}
}
@@ -615,7 +760,7 @@ void KnownNodeAspects::ClearUnstableNodeAspects(bool is_tracing_enabled) {
loaded_properties_.clear();
loaded_tagged_keyed_properties_.clear();
loaded_context_slots_.clear();
- may_have_aliasing_contexts_ = KnownNodeAspects::ContextSlotLoadsAlias::kNone;
+ may_have_aliasing_contexts_ = KnownNodeAspects::ContextSlotLoadsAlias::kNever;
}
KnownNodeAspects* KnownNodeAspects::CloneForLoopHeader(
@@ -634,7 +779,7 @@ KnownNodeAspects::KnownNodeAspects(const KnownNodeAspects& other,
available_expressions_(zone),
side_effects_require_invalidation_(false),
may_have_aliasing_contexts_(
- KnownNodeAspects::ContextSlotLoadsAlias::kNone),
+ KnownNodeAspects::ContextSlotLoadsAlias::kNever),
effect_epoch_(other.effect_epoch_),
node_infos_(zone),
virtual_objects_(other.virtual_objects_) {
@@ -657,6 +802,7 @@ KnownNodeAspects::KnownNodeAspects(const KnownNodeAspects& other,
NodeInfo::ClearUnstableMapsOnCopy{it.second});
}
}
+ // LINT.IfChange(CloneForLoopHeader)
if (optimistic_initial_state && !loop_effects->unstable_aspects_cleared) {
// IMPORTANT: Whatever we clone here needs to be checked for consistency
// in when we try to terminate the loop in `IsCompatibleWithLoopHeader`.
@@ -665,29 +811,15 @@ KnownNodeAspects::KnownNodeAspects(const KnownNodeAspects& other,
!loop_effects->elements_kind_transitioned) {
loaded_properties_ = other.loaded_properties_;
} else {
- auto cleared_key = loop_effects->keys_cleared.begin();
- auto cleared_keys_end = loop_effects->keys_cleared.end();
- auto cleared_obj = loop_effects->objects_written.begin();
- auto cleared_objs_end = loop_effects->objects_written.end();
+ LoopInvariantPropertyFilter filter(loop_effects,
+ loop_effects->objects_written, this);
for (auto loaded_key : other.loaded_properties_) {
- if (NextInIgnoreList(cleared_key, cleared_keys_end, loaded_key.first)) {
- continue;
- }
- const bool check_elements_transition =
- loop_effects->elements_kind_transitioned &&
- loaded_key.first == PropertyKey::Elements();
+ if (!filter.StartKey(loaded_key.first)) continue;
auto& props_for_key =
loaded_properties_.try_emplace(loaded_key.first, zone)
.first->second;
for (auto loaded_obj : loaded_key.second) {
- if (NextInIgnoreList(cleared_obj, cleared_objs_end,
- loaded_obj.first)) {
- continue;
- }
- if (check_elements_transition &&
- !TryGetInfoWithFreshMaps(loaded_obj.first)) {
- continue;
- }
+ if (!filter.ObjectInvariant(loaded_obj.first)) continue;
props_for_key.emplace(loaded_obj);
}
}
@@ -695,25 +827,26 @@ KnownNodeAspects::KnownNodeAspects(const KnownNodeAspects& other,
if (loop_effects->context_slot_written.empty()) {
loaded_context_slots_ = other.loaded_context_slots_;
} else {
- auto slot_written = loop_effects->context_slot_written.begin();
- auto slot_written_end = loop_effects->context_slot_written.end();
+ IgnoreListCursor<LoadedContextSlotsKey> slot_written(
+ loop_effects->context_slot_written);
for (auto loaded : other.loaded_context_slots_) {
if (!loaded.second) continue;
loaded.second = loaded.second->UnwrapIdentities();
- if (!NextInIgnoreList(slot_written, slot_written_end, loaded.first)) {
+ if (!slot_written.Contains(loaded.first)) {
loaded_context_slots_.emplace(loaded);
}
}
}
if (!loaded_context_slots_.empty()) {
if (loop_effects->may_have_aliasing_contexts) {
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kYes;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kAlways;
} else {
- DCHECK_EQ(may_have_aliasing_contexts_, ContextSlotLoadsAlias::kNone);
+ DCHECK_EQ(may_have_aliasing_contexts_, ContextSlotLoadsAlias::kNever);
may_have_aliasing_contexts_ = other.may_have_aliasing_contexts();
}
}
}
+ // LINT.ThenChange(:IsCompatibleWithLoopHeader)
// To account for the back-jump we must not allow effects to be reshuffled
// across loop headers.
@@ -728,16 +861,17 @@ KnownNodeAspects::KnownNodeAspects(const KnownNodeAspects& other,
virtual_objects_.Snapshot();
}
+// LINT.IfChange(IsCompatibleWithLoopHeader)
bool KnownNodeAspects::IsCompatibleWithLoopHeader(
const KnownNodeAspects& loop_header) const {
- // Needs to be in sync with `CloneForLoopHeader(zone, true)`.
// Analysis state can change with loads.
if (!loop_header.loaded_context_slots_.empty() &&
- loop_header.may_have_aliasing_contexts() != ContextSlotLoadsAlias::kYes &&
+ loop_header.may_have_aliasing_contexts() !=
+ ContextSlotLoadsAlias::kAlways &&
loop_header.may_have_aliasing_contexts() !=
may_have_aliasing_contexts() &&
- may_have_aliasing_contexts() != ContextSlotLoadsAlias::kNone) {
+ may_have_aliasing_contexts() != ContextSlotLoadsAlias::kNever) {
if (V8_UNLIKELY(v8_flags.trace_maglev_loop_speeling)) {
std::cout << "KNA after loop has incompatible "
"loop_header.may_have_aliasing_contexts\n";
@@ -824,6 +958,7 @@ bool KnownNodeAspects::IsCompatibleWithLoopHeader(
return true;
}
+// LINT.ThenChange(:LoopInvariantFacts, :CloneForLoopHeader)
SmallZoneVector<KnownNodeAspects::LoadedContextSlotsKey, 8>
KnownNodeAspects::ClearAliasedContextSlotsFor(Graph* graph, ValueNode* context,
@@ -831,7 +966,7 @@ KnownNodeAspects::ClearAliasedContextSlotsFor(Graph* graph, ValueNode* context,
SmallZoneVector<LoadedContextSlotsKey, 8> aliased_slots_(graph->zone());
UpdateMayHaveAliasingContexts(graph->broker(),
graph->broker()->local_isolate(), context);
- if (may_have_aliasing_contexts() == ContextSlotLoadsAlias::kYes) {
+ if (may_have_aliasing_contexts() == ContextSlotLoadsAlias::kAlways) {
for (auto& cache : loaded_context_slots_) {
int cached_offset = std::get<int>(cache.first);
ValueNode* cached_context = std::get<ValueNode*>(cache.first);
diff --git a/deps/v8/src/maglev/maglev-known-node-aspects.h b/deps/v8/src/maglev/maglev-known-node-aspects.h
index 6fdd8ed1020..3534466cdd1 100644
--- a/deps/v8/src/maglev/maglev-known-node-aspects.h
+++ b/deps/v8/src/maglev/maglev-known-node-aspects.h
@@ -24,6 +24,8 @@ class KnownNodeAspects;
class TraceLogger;
enum class EnsureTypeResult { kAlreadyHadType, kTypeUpdated, kContradiction };
+using UpdateTypeOnContradiction =
+ base::StrongAlias<struct UpdateTypeOnContradictionTag, bool>;
using PossibleMaps = compiler::ZoneRefSet<Map>;
@@ -70,6 +72,7 @@ class NodeInfo {
}
NodeType type() const { return type_; }
+ void set_type(NodeType type) { type_ = type; }
NodeType IntersectType(NodeType other) {
return type_ = maglev::IntersectType(type_, other);
}
@@ -449,7 +452,7 @@ class KnownNodeAspects {
loaded_context_slots_.clear();
available_expressions_.clear();
side_effects_require_invalidation_ = false;
- may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kNone;
+ may_have_aliasing_contexts_ = ContextSlotLoadsAlias::kNever;
node_infos_.clear();
virtual_objects_ = {};
}
@@ -548,30 +551,15 @@ class KnownNodeAspects {
EnsureTypeResult EnsureType(compiler::JSHeapBroker* broker, ValueNode* node,
NodeType type, NodeType* old_type = nullptr) {
- NodeType static_type = node->GetStaticType(broker);
- if (old_type) *old_type = static_type;
- if (NodeTypeIs(static_type, type, NodeTypeIsVariant::kAllowNone)) {
- if (static_type == NodeType::kNone) {
- return EnsureTypeResult::kContradiction;
- }
- return EnsureTypeResult::kAlreadyHadType;
- }
- NodeInfo* known_info = GetOrCreateInfoFor(broker, node);
- if (old_type) *old_type = known_info->type();
- if (NodeTypeIs(known_info->type(), type, NodeTypeIsVariant::kAllowNone)) {
- if (known_info->type() == NodeType::kNone) {
- return EnsureTypeResult::kContradiction;
- }
- return EnsureTypeResult::kAlreadyHadType;
- }
- known_info->IntersectType(type);
- if (auto phi = node->TryCast<Phi>()) {
- known_info->IntersectType(phi->type());
- }
- if (known_info->type() == NodeType::kNone) {
- return EnsureTypeResult::kContradiction;
- }
- return EnsureTypeResult::kTypeUpdated;
+ return EnsureTypeHelper(broker, node, type, old_type,
+ UpdateTypeOnContradiction{true});
+ }
+
+ EnsureTypeResult TryEnsureType(compiler::JSHeapBroker* broker,
+ ValueNode* node, NodeType type,
+ NodeType* old_type = nullptr) {
+ return EnsureTypeHelper(broker, node, type, old_type,
+ UpdateTypeOnContradiction{false});
}
void Merge(const KnownNodeAspects& other, Zone* zone);
@@ -723,10 +711,10 @@ class KnownNodeAspects {
}
enum class ContextSlotLoadsAlias : uint8_t {
- kNone,
+ kNever,
kOnlyLoadsRelativeToCurrentContext,
kOnlyLoadsRelativeToConstant,
- kYes,
+ kAlways,
};
ContextSlotLoadsAlias may_have_aliasing_contexts() const {
return may_have_aliasing_contexts_;
@@ -734,9 +722,9 @@ class KnownNodeAspects {
static ContextSlotLoadsAlias ContextSlotLoadsAliasMerge(
ContextSlotLoadsAlias m1, ContextSlotLoadsAlias m2) {
if (m1 == m2) return m1;
- if (m1 == ContextSlotLoadsAlias::kNone) return m2;
- if (m2 == ContextSlotLoadsAlias::kNone) return m1;
- return ContextSlotLoadsAlias::kYes;
+ if (m1 == ContextSlotLoadsAlias::kNever) return m2;
+ if (m2 == ContextSlotLoadsAlias::kNever) return m1;
+ return ContextSlotLoadsAlias::kAlways;
}
struct ContextStoreResult {
enum Type {
@@ -790,6 +778,16 @@ class KnownNodeAspects {
: loaded_context_constants_.empty();
}
+ static bool BuiltinInvalidatesKNA(Builtin builtin) {
+ switch (builtin) {
+ // TODO(victorgomes): Add more builtins to the list!
+ case Builtin::kCloneFastJSArray:
+ return false;
+ default:
+ return true;
+ }
+ }
+
template <typename NodeT>
void MarkPossibleSideEffect(NodeT* node, compiler::JSHeapBroker* broker,
bool is_tracing_enabled) {
@@ -802,6 +800,10 @@ class KnownNodeAspects {
loaded_tagged_keyed_properties_.clear();
}
+ if constexpr (Node::opcode_of<NodeT> == Opcode::kCallBuiltin) {
+ if (!BuiltinInvalidatesKNA(node->builtin())) return;
+ }
+
if constexpr (Node::opcode_of<NodeT> == Opcode::kMaybeGrowFastElements) {
if (ClearLoadedPropertiesForKey(broker->length_string())) {
if (V8_UNLIKELY(v8_flags.trace_maglev_kna && is_tracing_enabled)) {
@@ -850,12 +852,56 @@ class KnownNodeAspects {
loaded_context_slots_(zone),
available_expressions_(zone),
side_effects_require_invalidation_(false),
- may_have_aliasing_contexts_(ContextSlotLoadsAlias::kNone),
+ may_have_aliasing_contexts_(ContextSlotLoadsAlias::kNever),
effect_epoch_(0),
node_infos_(zone),
virtual_objects_() {}
private:
+ EnsureTypeResult EnsureTypeHelper(
+ compiler::JSHeapBroker* broker, ValueNode* node, NodeType type,
+ NodeType* old_type,
+ UpdateTypeOnContradiction update_type_on_contradiction) {
+ NodeType static_type = node->GetStaticType(broker);
+ if (old_type) *old_type = static_type;
+ if (NodeTypeIs(static_type, type, NodeTypeIsVariant::kAllowNone)) {
+ if (static_type == NodeType::kNone) {
+ return EnsureTypeResult::kContradiction;
+ }
+ return EnsureTypeResult::kAlreadyHadType;
+ }
+ NodeInfo* known_info = update_type_on_contradiction
+ ? GetOrCreateInfoFor(broker, node)
+ : TryGetInfoFor(node);
+ NodeType current_type = static_type;
+ if (known_info) {
+ current_type = known_info->type();
+ if (old_type) *old_type = current_type;
+ if (NodeTypeIs(current_type, type, NodeTypeIsVariant::kAllowNone)) {
+ if (current_type == NodeType::kNone) {
+ return EnsureTypeResult::kContradiction;
+ }
+ return EnsureTypeResult::kAlreadyHadType;
+ }
+ }
+ NodeType new_type = IntersectType(current_type, type);
+ if (auto phi = node->TryCast<Phi>()) {
+ new_type = IntersectType(new_type, phi->type());
+ }
+ if (new_type == NodeType::kNone) {
+ if (update_type_on_contradiction) {
+ DCHECK_NOT_NULL(known_info);
+ known_info->set_type(NodeType::kNone);
+ }
+ return EnsureTypeResult::kContradiction;
+ }
+ if (!known_info) {
+ known_info = GetOrCreateInfoFor(broker, node);
+ }
+ known_info->set_type(new_type);
+ return EnsureTypeResult::kTypeUpdated;
+ }
+
bool SetContextCachedValue(ValueNode* context, int offset, ValueNode* value,
MaybeAssignedFlag assigned);
@@ -880,6 +926,7 @@ class KnownNodeAspects {
friend class MaglevReducer;
friend class RecomputeKnownNodeAspectsProcessor;
friend class MergePointInterpreterFrameState;
+ friend class LoopMergePointInterpreterFrameState;
NodeType GetTypeUnchecked(compiler::JSHeapBroker* broker,
ValueNode* node) const {
diff --git a/deps/v8/src/maglev/maglev-loop-peeler.cc b/deps/v8/src/maglev/maglev-loop-peeler.cc
index f4eacbff7a3..12edbec02c0 100644
--- a/deps/v8/src/maglev/maglev-loop-peeler.cc
+++ b/deps/v8/src/maglev/maglev-loop-peeler.cc
@@ -145,8 +145,7 @@ void RemapClonedDeoptInfo(NodeBase* src, NodeBase* clone, const ValueMap& vmap,
}
}
-void RemapClonedExceptionHandlerInfo(NodeBase* src, NodeBase* clone,
- BasicBlock* dst_block) {
+void RemapClonedExceptionHandlerInfo(NodeBase* src, NodeBase* clone) {
if (!clone->properties().can_throw()) return;
ExceptionHandlerInfo* src_info = src->exception_handler_info();
DCHECK(!src_info->HasExceptionHandler() || src_info->ShouldLazyDeopt());
@@ -156,9 +155,6 @@ void RemapClonedExceptionHandlerInfo(NodeBase* src, NodeBase* clone,
} else {
new (clone->exception_handler_info()) ExceptionHandlerInfo();
}
- if (clone->Is<CallKnownJSFunction>()) {
- dst_block->AddExceptionHandler(clone->exception_handler_info());
- }
}
// Clone a single non-phi, non-control Node by raw byte copy; rewires its
@@ -201,7 +197,6 @@ Node* CloneNodeWithRemap(Node* src, const ValueMap& vmap, Zone* zone) {
// loop's back-edge and produce no value used elsewhere.
bool IsSkippableInPeel(Node* node) {
return node->Is<HandleNoHeapWritesInterrupt>() ||
- node->Is<TryOnStackReplacement>() ||
node->Is<ReduceInterruptBudgetForLoop>();
}
@@ -322,8 +317,6 @@ void MaglevLoopPeeler::ResolveLoopHeader() {
// (e.g. it wouldn't count a block reached only via a `break` as in-loop);
// switch to it in a follow-up.
// Bails on:
-// - more than one forward predecessor (Maglev loops have a single back-edge,
-// so predecessor_count > 2 means extra forward edges into the header),
// - a nested loop in the body (a body block that is itself a loop header);
// this is what restricts peeling to innermost loops,
// - a body block with attached exception handlers.
@@ -334,16 +327,10 @@ std::optional<MaglevLoopPeeler::LoopInfo> MaglevLoopPeeler::BuildLoopInfo(
DCHECK(header->is_loop());
DCHECK(!header->state()->is_resumable_loop());
DCHECK(!header->state()->is_unmerged_loop());
- if (header->predecessor_count() != 2) {
- // TODO(victorgomes): a loop header with more than one forward predecessor
- // is peelable in principle; bailing here is conservative.
- TRACE_PEEL_SKIP("@" << header_offset
- << ": skip (header has >1 forward predecessor)");
- return std::nullopt;
- }
+ DCHECK_EQ(header->predecessor_count(), 2);
LoopInfo loop(zone());
- loop.preheader = header->predecessor_at(0);
+ loop.preheader = header->forward_predecessor();
BasicBlock* backedge = header->backedge_predecessor();
// With predecessor_count == 2 and a fully-merged loop, both slots are set.
DCHECK_NOT_NULL(backedge);
@@ -679,7 +666,7 @@ void MaglevLoopPeeler::CloneBodySubgraph(PeelContext& ctx) {
// Header phis resolve to their pre-header input.
if (ctx.loop.header()->has_phi()) {
for (Phi* phi : *ctx.loop.header()->phis()) {
- ctx.value_map[phi] = phi->input(0).node();
+ ctx.value_map[phi] = phi->forward_edge();
}
}
@@ -724,8 +711,8 @@ void MaglevLoopPeeler::CloneBodySubgraph(PeelContext& ctx) {
for (Phi* phi : *block->phis()) {
DCHECK(!phi->is_exception_phi());
int input_count = phi->input_count();
- Phi* clone_phi = NodeBase::New<Phi>(zone(), input_count,
- dst_block->state(), phi->owner());
+ Phi* clone_phi = NodeBase::New<Phi>(
+ zone(), input_count, dst_block->state(), phi->owner(), phi->type());
for (int i = 0; i < input_count; ++i) {
clone_phi->set_input(i, Remap(ctx.value_map, phi->input(i).node()));
}
@@ -761,7 +748,7 @@ void MaglevLoopPeeler::CloneBodySubgraph(PeelContext& ctx) {
}
Node* cloned = CloneNodeWithRemap(node, ctx.value_map, zone());
cloned->set_owner(dst_block);
- RemapClonedExceptionHandlerInfo(node, cloned, dst_block);
+ RemapClonedExceptionHandlerInfo(node, cloned);
dst_block->nodes().push_back(cloned);
if (auto* vn = cloned->TryCast<ValueNode>()) {
ctx.value_map[node->Cast<ValueNode>()] = vn;
@@ -887,11 +874,11 @@ void MaglevLoopPeeler::BuildPeelExitMerge(PeelContext& ctx) {
DCHECK(!phi->is_exception_phi());
// The peeled-path value of a header phi is its pre-header input — exactly
// what CloneBodySubgraph seeds into value_map for the header phis.
- DCHECK_EQ(Remap(ctx.value_map, phi), phi->input(0).node());
+ DCHECK_EQ(Remap(ctx.value_map, phi), phi->forward_edge());
Phi* pem_phi = NodeBase::New<Phi>(zone(), 2 * exit_edge_count, pem_state,
- phi->owner());
+ phi->owner(), phi->type());
for (int idx = 0; idx < exit_edge_count; ++idx) {
- pem_phi->set_input(2 * idx, phi->input(0).node());
+ pem_phi->set_input(2 * idx, phi->forward_edge());
pem_phi->set_input(2 * idx + 1, phi);
}
pem_state->phis()->Add(pem_phi);
@@ -1004,6 +991,7 @@ void MaglevLoopPeeler::CloneLoopBodyControl(PeelContext& ctx) {
clone->set_input(i, Remap(ctx.value_map, control->input(i).node()));
}
RemapClonedDeoptInfo(control, clone, ctx.value_map, zone());
+ RemapClonedExceptionHandlerInfo(control, clone);
return clone;
};
@@ -1257,25 +1245,23 @@ void MaglevLoopPeeler::RewireDownstreamPhiRefs(PeelContext& ctx) {
rewires.reserve(ctx.header_phi_to_pem_phi.size());
PhiMap replacements(zone());
- // After peeling, the loop header has exactly two predecessors regardless of
- // the original phi's arity: a loop can have several forward edges but only
- // one back-edge, so the peeled loop's only predecessors are the peeled
- // back-edge (slot 0) and the original back-edge (slot 1). Every loop phi
- // therefore has two inputs after peeling.
+ // After peeling, the loop header's only predecessors are the peeled back-edge
+ // (slot 0) and the original back-edge (slot 1). Every loop phi therefore has
+ // two inputs after peeling.
static constexpr int kPhiInputCount = 2;
// Create a new loop phi for each header phi and collect the rewires.
for (auto& [old_phi, pem_phi] : ctx.header_phi_to_pem_phi) {
- Phi* loop_phi = NodeBase::New<Phi>(
- zone(), kPhiInputCount, old_phi->merge_state(), old_phi->owner());
+ Phi* loop_phi =
+ NodeBase::New<Phi>(zone(), kPhiInputCount, old_phi->merge_state(),
+ old_phi->owner(), old_phi->type());
// Slot 0 takes the peeled clone of the back-edge value (via value_map);
// slot 1 the original back-edge value. If the back-edge value is itself a
// header phi (a recursive loop phi), slot 1 still points at the old phi
// here; it is rewired to the matching loop phi in the cross-reference pass
// below, once every old->loop phi mapping has been recorded.
- loop_phi->set_input(0,
- Remap(ctx.value_map, old_phi->backedge_input().node()));
- loop_phi->set_input(1, old_phi->backedge_input().node());
+ loop_phi->set_input(0, Remap(ctx.value_map, old_phi->backedge()));
+ loop_phi->set_input(loop_phi->backedge_index(), old_phi->backedge());
RegisterIfLabelled(graph_, loop_phi);
replacements[old_phi] = loop_phi;
rewires.push_back({old_phi, pem_phi, loop_phi});
diff --git a/deps/v8/src/maglev/maglev-phi-representation-selector.cc b/deps/v8/src/maglev/maglev-phi-representation-selector.cc
index c5682cfd804..eff255ed43c 100644
--- a/deps/v8/src/maglev/maglev-phi-representation-selector.cc
+++ b/deps/v8/src/maglev/maglev-phi-representation-selector.cc
@@ -78,6 +78,7 @@ MaglevPhiRepresentationSelector::MaglevPhiRepresentationSelector(Graph* graph)
BlockProcessResult MaglevPhiRepresentationSelector::PreProcessBasicBlock(
BasicBlock* block) {
+ DCHECK(!block->IsUnreachable());
BasicBlock* old_block = reducer_.current_block();
reducer_.set_current_block(block);
PreparePhiTaggings(old_block, block);
@@ -418,8 +419,11 @@ MaglevPhiRepresentationSelector::ProcessPhi(Phi* node) {
} else if (use_reprs.contains(UseRepresentation::kInt32)) {
allowed_inputs_for_uses = {ValueRepresentation::kInt32};
} else if (use_reprs.contains(UseRepresentation::kFloat64)) {
+ // A Float64 use can also consume a HoleyFloat64 input, so a Phi with
+ // HoleyFloat64 inputs need not be kept tagged.
allowed_inputs_for_uses = {ValueRepresentation::kInt32,
- ValueRepresentation::kFloat64};
+ ValueRepresentation::kFloat64,
+ ValueRepresentation::kHoleyFloat64};
} else {
DCHECK(!use_reprs.empty() &&
use_reprs.is_subset_of({UseRepresentation::kHoleyFloat64,
@@ -573,7 +577,7 @@ Opcode GetOpcodeForConversion(ValueRepresentation from, ValueRepresentation to,
// don't have to handle this case.
UNREACHABLE();
case ValueRepresentation::kFloat64:
- return Opcode::kHoleyFloat64ToSilencedFloat64;
+ return Opcode::kUnsafeHoleyFloat64ToFloat64;
case ValueRepresentation::kHoleyFloat64:
case ValueRepresentation::kTagged:
@@ -642,8 +646,8 @@ void MaglevPhiRepresentationSelector::UntagInputWithHoistedUntagging(
DCHECK(NodeTypeIs(input->GetStaticType(graph_->broker()),
NodeType::kNumber));
untagged = AddNewNodeNoInputConversionAtBlockEnd<
- TruncateUnsafeNumberOrOddballToInt32>(
- block, {input}, TaggedToFloat64ConversionType::kOnlyNumber);
+ TruncateUnsafeNumberOrOddballToInt32>(block, {input},
+ NodeType::kNumber);
} else {
DCHECK(NodeTypeIs(input->GetStaticType(graph_->broker()),
NodeType::kSmi));
@@ -653,8 +657,8 @@ void MaglevPhiRepresentationSelector::UntagInputWithHoistedUntagging(
} else {
if (truncating) {
untagged = AddNewNodeNoInputConversionAtBlockEnd<
- TruncateCheckedNumberOrOddballToInt32>(
- block, {input}, TaggedToFloat64ConversionType::kOnlyNumber);
+ TruncateCheckedNumberOrOddballToInt32>(block, {input},
+ NodeType::kNumber);
} else {
// TODO(victorgomes): Why not CheckedNumberToInt32?
untagged =
@@ -741,8 +745,9 @@ void MaglevPhiRepresentationSelector::UntagConstantInput(
Float64 f64 = Float64::FromBits(
base::double_to_uint64(constant->object().AsHeapNumber().value()));
// We need to silence hole and undefined patterns as their
- // interpretation will now change.
- if (f64.has_undefined_or_hole_nan_high_bits()) f64 = f64.to_quiet_nan();
+ // interpretation will now change. Any other signalling NaN has to go too,
+ // so that a HoleyFloat64 only ever carries those two.
+ if (f64.is_signalling_nan()) f64 = f64.to_quiet_nan();
phi->change_input(input_index, graph_->GetHoleyFloat64Constant(f64));
} else if (truncating) {
TRACE_UNTAGGING(TRACE_INPUT_LABEL
@@ -773,20 +778,11 @@ void MaglevPhiRepresentationSelector::UntagConversionInput(
ValueRepresentation from_repr = bypassed_input->value_representation();
ValueNode* new_input;
if (from_repr == repr) {
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- if (input->Is<HoleyFloat64ToTagged>()) {
- DCHECK_EQ(from_repr, ValueRepresentation::kHoleyFloat64);
- // HoleyFloat64ToTagged conversion does convert holes to undefined, so
- // we need to preserve this behavior even if we eliminate that node.
- new_input = GetReplacementForPhiInputConversion<
- HoleyFloat64ConvertHoleToUndefined>(bypassed_input, phi, input_index);
- } else {
-#endif
- TRACE_UNTAGGING(TRACE_INPUT_LABEL << ": Bypassing conversion");
- new_input = bypassed_input;
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- }
-#endif
+ // A HoleyFloat64ToTagged we bypass here converts holes to undefined, but
+ // the two are the same value: only stores tell them apart, and those
+ // canonicalize the bits themselves.
+ TRACE_UNTAGGING(TRACE_INPUT_LABEL << ": Bypassing conversion");
+ new_input = bypassed_input;
} else {
Opcode conv_opcode = GetOpcodeForConversion(from_repr, repr, truncating);
switch (conv_opcode) {
@@ -873,7 +869,8 @@ void MaglevPhiRepresentationSelector::UntagBackedgePhiInput(
DCHECK_EQ(input_phi->value_representation(), ValueRepresentation::kTagged);
- eager_deopt_frame_ = phi->merge_state()->backedge_deopt_frame();
+ eager_deopt_frame_ =
+ phi->merge_state()->AsLoopHeader()->backedge_deopt_frame();
switch (repr) {
case ValueRepresentation::kInt32: {
if (NodeTypeIs(phi->type(), NodeType::kSmi)) {
@@ -905,7 +902,7 @@ void MaglevPhiRepresentationSelector::UntagBackedgePhiInput(
AddNewNodeNoInputConversionAtBlockEnd<
CheckedNumberOrOddballToHoleyFloat64>(
phi->predecessor_at(input_index), {input_phi},
- TaggedToFloat64ConversionType::kNumberOrUndefined));
+ NodeType::kNumberOrUndefined));
break;
}
case ValueRepresentation::kTagged:
@@ -1207,17 +1204,11 @@ ProcessResult MaglevPhiRepresentationSelector::UpdateUntaggingOfPhi(
// A HoleyFloat64 hole really means Undefined rather than the_hole:
// whenever it gets rematerialized, it will always be rematerialized as
// Undefined. So, we can use a truncating conversion as long as the
- // original ConversionType was allowing truncating Undefined.
- switch (truncate->conversion_type()) {
- case TaggedToFloat64ConversionType::kOnlyNumber:
- case TaggedToFloat64ConversionType::kNumberOrBoolean:
- // Need to deopt for Hole/Undefined ==> not truncating.
- break;
- case TaggedToFloat64ConversionType::kNumberOrUndefined:
- case TaggedToFloat64ConversionType::kNumberOrOddball:
- conversion_is_truncating_float64 = true;
- break;
- }
+ // original assumed input type was allowing truncating Undefined.
+ // Assumptions without Undefined need to deopt for Hole/Undefined
+ // ==> not truncating.
+ conversion_is_truncating_float64 = !NodeTypeIs(
+ truncate->assumed_input_type(), NodeType::kNumberOrBoolean);
}
}
@@ -1227,8 +1218,8 @@ ProcessResult MaglevPhiRepresentationSelector::UpdateUntaggingOfPhi(
if (from_repr == ValueRepresentation::kHoleyFloat64) {
if (CheckedNumberOrOddballToFloat64* number_untagging =
old_untagging->TryCast<CheckedNumberOrOddballToFloat64>()) {
- if (number_untagging->conversion_type() !=
- TaggedToFloat64ConversionType::kNumberOrOddball) {
+ if (NodeTypeIs(number_untagging->assumed_input_type(),
+ NodeType::kNumberOrBoolean)) {
// {phi} is a HoleyFloat64 (and thus, it could be a hole), but the
// original untagging did not allow holes.
needed_conversion = Opcode::kCheckedHoleyFloat64ToFloat64;
@@ -1258,9 +1249,22 @@ ProcessResult MaglevPhiRepresentationSelector ::UpdateNodePhiInput(
case ValueRepresentation::kFloat64:
node->OverwriteWith<Float64ToString>();
return ProcessResult::kContinue;
- default:
+ case ValueRepresentation::kHoleyFloat64: {
+ // NumberToString is only emitted for inputs that are known to be numbers.
+ ValueNode* input =
+ AddNewNodeNoInputConversion<UnsafeHoleyFloat64ToFloat64>(
+ reducer_.current_block(), BasicBlockPosition::Start(), {phi});
+ node->OverwriteWith<Float64ToString>();
+ node->change_input(input_index, input);
+ return ProcessResult::kContinue;
+ }
+ case ValueRepresentation::kUint32:
+ case ValueRepresentation::kIntPtr:
+ case ValueRepresentation::kRawPtr:
+ case ValueRepresentation::kNone:
UNREACHABLE();
}
+ UNREACHABLE();
}
ProcessResult MaglevPhiRepresentationSelector::UpdateNodePhiInput(
@@ -1697,8 +1701,8 @@ void MaglevPhiRepresentationSelector::FixLoopPhisBackedge(BasicBlock* block) {
// phis, or at least to go over the loop header twice.
if (!block->has_phi()) return;
for (Phi* phi : *block->phis()) {
- int last_input_idx = phi->input_count() - 1;
- ValueNode* backedge = phi->input(last_input_idx).node();
+ int backedge_index = phi->backedge_index();
+ ValueNode* backedge = phi->backedge();
if (phi->value_representation() == ValueRepresentation::kTagged) {
// If the backedge is a Phi that was untagged, but {phi} is tagged, then
// we need to retag the backedge.
@@ -1714,7 +1718,7 @@ void MaglevPhiRepresentationSelector::FixLoopPhisBackedge(BasicBlock* block) {
// is not tagged means that it's a Phi that we recently untagged.
DCHECK(backedge->Is<Phi>());
phi->change_input(
- last_input_idx,
+ backedge_index,
EnsurePhiTagged(backedge->Cast<Phi>(), reducer_.current_block(),
BasicBlockPosition::End(), /*state*/ nullptr,
/*predecessor_index*/ std::nullopt));
@@ -1733,7 +1737,7 @@ void MaglevPhiRepresentationSelector::FixLoopPhisBackedge(BasicBlock* block) {
ValueRepresentation::kFloat64 &&
phi->value_representation() ==
ValueRepresentation::kHoleyFloat64));
- phi->change_input(last_input_idx, backedge->input(0).node());
+ phi->change_input(backedge_index, backedge->input(0).node());
}
}
}
@@ -1771,14 +1775,42 @@ void MaglevPhiRepresentationSelector::PreparePhiTaggings(
// Setting up new snapshot
predecessors_.clear();
+ bool is_eager_maglev = !graph_->compilation_info()->is_turbolev() &&
+ !v8_flags.maglev_non_eager_inlining;
+ auto get_predecessor_snapshot = [&](BasicBlock* pred) {
+ CHECK_NOT_NULL(pred);
+ CHECK(!pred->is_dead());
+ if (is_eager_maglev) {
+ CHECK_LT(pred->id(), new_block->id());
+ }
+ CHECK(snapshots_.contains(pred->id()));
+ return snapshots_.at(pred->id());
+ };
+
if (!new_block->is_merge_block()) {
- BasicBlock* pred = new_block->predecessor();
- predecessors_.push_back(snapshots_.at(pred->id()));
+ // A single predecessor, no merge required, we just reuse its snapshot.
+ predecessors_.push_back(get_predecessor_snapshot(new_block->predecessor()));
+ } else if (new_block->is_loop()) {
+ if (!new_block->state()->is_resumable_loop()) {
+ // Non-resumable loops have a single forward edge that dominates the loop;
+ // we can thus just use it as the initial snapshot for the loop.
+ DCHECK_EQ(new_block->predecessor_count(), 2);
+ constexpr int kForwardPredecessorIndex = 0;
+ predecessors_.push_back(get_predecessor_snapshot(
+ new_block->predecessor_at(kForwardPredecessorIndex)));
+ } else {
+ // ... while resumable loops can be entered without going through the
+ // header. In that case we don't even attempt to reuse taggings from the
+ // predecessors and just start fresh. We're thus leaving {predecessors_}
+ // empty here.
+ DCHECK(predecessors_.empty());
+ }
} else {
- int skip_backedge = new_block->is_loop();
- for (int i = 0; i < new_block->predecessor_count() - skip_backedge; i++) {
- BasicBlock* pred = new_block->predecessor_at(i);
- predecessors_.push_back(snapshots_.at(pred->id()));
+ // A regular merge, we'll create Phis for Keys that have a value in all
+ // predecessors.
+ for (int i = 0; i < new_block->predecessor_count(); i++) {
+ predecessors_.push_back(
+ get_predecessor_snapshot(new_block->predecessor_at(i)));
}
}
@@ -1796,28 +1828,18 @@ void MaglevPhiRepresentationSelector::PreparePhiTaggings(
}
}
- // Only merge blocks should require Phis.
+ // Only non-loop merge blocks should require Phis.
DCHECK(new_block->is_merge_block());
-
- // Resumable loops are entered through their backedge, so the header
- // doesn't dominate it and the self-reference set below wouldn't be valid.
- if (new_block->state()->is_resumable_loop()) {
- return static_cast<Phi*>(nullptr);
- }
+ DCHECK(!new_block->is_loop());
+ DCHECK_EQ(new_block->predecessor_count(), predecessors.size());
// We create a Phi to merge all of the existing taggings.
int predecessor_count = new_block->predecessor_count();
Phi* phi = Node::New<Phi>(zone(), predecessor_count, new_block->state(),
interpreter::Register());
- for (int i = 0; static_cast<size_t>(i) < predecessors.size(); i++) {
+ for (int i = 0; i < predecessor_count; i++) {
phi->set_input(i, predecessors[i]);
}
- if (predecessors.size() != static_cast<size_t>(predecessor_count)) {
- // The backedge is omitted from {predecessors}. With set the Phi as its
- // own backedge.
- DCHECK(new_block->is_loop());
- phi->set_input(predecessor_count - 1, phi);
- }
if (reducer_.has_graph_labeller()) reducer_.RegisterNode(phi);
new_block->AddPhi(phi);
diff --git a/deps/v8/src/maglev/maglev-post-hoc-optimizations-processors.h b/deps/v8/src/maglev/maglev-post-hoc-optimizations-processors.h
index 464e5ff7ba4..26245b115cb 100644
--- a/deps/v8/src/maglev/maglev-post-hoc-optimizations-processors.h
+++ b/deps/v8/src/maglev/maglev-post-hoc-optimizations-processors.h
@@ -188,7 +188,14 @@ class RecomputePhiUseHintsProcessor {
use_repr = UseRepresentation::kTruncatedInt32;
} else if (node->Is<NumberToString>()) {
use_repr = UseRepresentation::kTaggedForNumberToString;
- } else if (node->Is<CheckedNumberOrOddballToUint8Clamped>()) {
+ } else if (node->Is<CheckedNumberOrOddballToUint8Clamped>() ||
+ node->Is<CheckedNumberOrOddballToHoleyFloat64>() ||
+ node->Is<UnsafeNumberOrOddballToHoleyFloat64>()) {
+ // These consume their input tagged, so is_conversion() is false and
+ // the use would otherwise default to kTagged, pinning the phi boxed.
+ // The two unboxers are how a holey-double element store consumes its
+ // value, so a phi feeding such a store can untag to HoleyFloat64 and
+ // be stored raw instead of being boxed into a HeapNumber.
use_repr = UseRepresentation::kHoleyFloat64;
}
phi->RecordUseReprHint(UseRepresentationSet{use_repr},
@@ -245,7 +252,7 @@ class LoopOptimizationProcessor {
BlockProcessResult PreProcessBasicBlock(BasicBlock* block) {
current_block = block;
if (current_block->is_loop()) {
- loop_effects = current_block->state()->loop_effects();
+ loop_effects = current_block->state()->AsLoopHeader()->loop_effects();
if (loop_effects) return BlockProcessResult::kContinue;
} else {
// TODO(olivf): Some dominance analysis would allow us to keep loop
@@ -271,13 +278,13 @@ class LoopOptimizationProcessor {
ValueNode* input = candidate->input(0).node();
DCHECK(!IsLoopPhi(input));
// For hoisting an instruction we need:
- // * A unique loop entry block.
// * Inputs live before the loop (i.e., not defined inside the loop).
// * No hoisting over checks (done eagerly by clearing loop_effects).
- // TODO(olivf): We should enforce loops having a unique entry block at graph
- // building time.
- if (current_block->predecessor_count() != 2) return false;
- BasicBlock* loop_entry = current_block->predecessor_at(0);
+ // A resumable loop is also entered through resume edges that bypass its
+ // header, so it might not have a forward edge to hoist into at all.
+ if (current_block->state()->is_resumable_loop()) return false;
+ DCHECK_EQ(current_block->predecessor_count(), 2);
+ BasicBlock* loop_entry = current_block->forward_predecessor();
if (loop_entry->successors().size() != 1) {
return false;
}
diff --git a/deps/v8/src/maglev/maglev-range-analysis.h b/deps/v8/src/maglev/maglev-range-analysis.h
index 630f74a9618..51744959af0 100644
--- a/deps/v8/src/maglev/maglev-range-analysis.h
+++ b/deps/v8/src/maglev/maglev-range-analysis.h
@@ -327,6 +327,12 @@ class RangeProcessor {
node, Range::Mul(Get(node->input_node(0)), Get(node->input_node(1))));
return ProcessResult::kContinue;
}
+ ProcessResult Process(Int32ModulusWithOverflow* node,
+ const ProcessingState&) {
+ UnionUpdateInt32(
+ node, Range::Mod(Get(node->input_node(0)), Get(node->input_node(1))));
+ return ProcessResult::kContinue;
+ }
ProcessResult Process(Int32BitwiseAnd* node, const ProcessingState&) {
UnionUpdateInt32(node, Range::BitwiseAnd(Get(node->input_node(0)),
Get(node->input_node(1))));
@@ -543,11 +549,10 @@ class RangeProcessor {
DCHECK_EQ(backedge_pred, block->backedge_predecessor());
ranges_.EnsureMapExistsFor(block); // TODO(victorgomes): not sure if needed
TRACE_RANGE(">>>> Processing backedges for Block b" << block->id());
- int backedge_id = block->state()->predecessor_count() - 1;
bool is_done = true;
for (Phi* phi : *block->phis()) {
Range range = ranges_.Get(block, phi);
- Range backedge = ranges_.Get(backedge_pred, phi->input_node(backedge_id));
+ Range backedge = ranges_.Get(backedge_pred, phi->backedge());
Range widened = Range::Widen(range, backedge);
if (phi->is_int32()) {
// Since phi representation selector promoted this phi to Int32,
diff --git a/deps/v8/src/maglev/maglev-range.h b/deps/v8/src/maglev/maglev-range.h
index 7504e244f3d..dbd6e4ec6f7 100644
--- a/deps/v8/src/maglev/maglev-range.h
+++ b/deps/v8/src/maglev/maglev-range.h
@@ -213,6 +213,26 @@ class Range {
return Range(min, max);
}
+ // [a, b] % [c, d]: the result has the sign of the lhs and a magnitude
+ // strictly smaller than the largest divisor magnitude.
+ static Range Mod(Range r1, Range r2) {
+ if (r1.is_empty() || r2.is_empty()) return Range::Empty();
+ int64_t bound = kInfMax;
+ if (r2.min_ != kInfMin && r2.max_ != kInfMax) {
+ int64_t divisor_max = std::max(std::abs(r2.min_), std::abs(r2.max_));
+ // A zero divisor deopts, so no value flows out of the node.
+ if (divisor_max == 0) return Range::Empty();
+ bound = divisor_max - 1;
+ }
+ int64_t min = r1.min_ == kInfMin ? kInfMin : std::min<int64_t>(r1.min_, 0);
+ int64_t max = r1.max_ == kInfMax ? kInfMax : std::max<int64_t>(r1.max_, 0);
+ if (bound != kInfMax) {
+ min = std::max(min, -bound);
+ max = std::min(max, bound);
+ }
+ return Range(min, max);
+ }
+
static Range BitwiseAnd(Range r1, Range r2) {
// TODO(victorgomes): This is copying OperationTyper::NumberBitwiseAnd. Not
// sure if we need to force both sides to be int32s. I guess a safe int
diff --git a/deps/v8/src/maglev/maglev-reducer-inl.h b/deps/v8/src/maglev/maglev-reducer-inl.h
index 7e3cb806030..2bfe98dbf1d 100644
--- a/deps/v8/src/maglev/maglev-reducer-inl.h
+++ b/deps/v8/src/maglev/maglev-reducer-inl.h
@@ -14,7 +14,10 @@
#include "src/base/division-by-constant.h"
#include "src/base/ieee754.h"
#include "src/base/logging.h"
+#include "src/builtins/builtins.h"
+#include "src/codegen/interface-descriptors.h"
#include "src/common/scoped-modification.h"
+#include "src/compiler/frame-states.h"
#include "src/compiler/processed-feedback.h"
#include "src/maglev/maglev-cse.h"
#include "src/maglev/maglev-ir-inl.h"
@@ -33,7 +36,7 @@
TraceLogger(tracer()) << __VA_ARGS__; \
}
-#define FAIL(...) \
+#define MAGLEV_FAIL(...) \
TRACE("Failed " << __func__ << ":" << __LINE__ << ": " << __VA_ARGS__); \
return {};
@@ -41,6 +44,120 @@ namespace v8 {
namespace internal {
namespace maglev {
+inline void DebugVerifyBuiltinDeoptFrame(
+ const DeoptFrame::FrameData& data,
+ compiler::ContinuationFrameStateMode mode) {
+#ifdef DEBUG
+ DCHECK_EQ(data.tag(), DeoptFrame::FrameType::kBuiltinContinuationFrame);
+ const DeoptFrame::BuiltinContinuationFrameData& frame =
+ data.get<DeoptFrame::BuiltinContinuationFrameData>();
+ if (frame.maybe_js_target) {
+ int stack_parameter_count =
+ Builtins::GetStackParameterCount(frame.builtin_id);
+ DCHECK_EQ(stack_parameter_count,
+ frame.parameters.length() +
+ compiler::DeoptimizerParameterCountFor(mode));
+ } else {
+ CallInterfaceDescriptor descriptor =
+ Builtins::CallInterfaceDescriptorFor(frame.builtin_id);
+ DCHECK_EQ(descriptor.GetParameterCount(),
+ frame.parameters.length() +
+ compiler::DeoptimizerParameterCountFor(mode));
+ }
+#endif
+}
+
+template <typename BaseT>
+MaglevReducer<BaseT>::LazyDeoptFrameScope::LazyDeoptFrameScope(
+ MaglevReducer* reducer, ValueNode* context, Builtin continuation,
+ compiler::OptionalJSFunctionRef maybe_js_target,
+ base::Vector<ValueNode* const> parameters)
+ : reducer_(reducer),
+ data_(DeoptFrame::BuiltinContinuationFrameData{
+ continuation,
+ parameters.empty() ? base::Vector<ValueNode*>{}
+ : reducer->zone()->CloneVector(parameters),
+ context, maybe_js_target}),
+ parent_(reducer->current_lazy_deopt_scope_) {
+ if constexpr (ReducerBaseWithDeoptFrameScopeHooks<BaseT>) {
+ reducer->base_->OnBeginDeoptFrameScope();
+ }
+ if (!parameters.empty()) {
+ if (InlinedAllocation* receiver =
+ parameters[0]->TryCast<InlinedAllocation>()) {
+ // We escape the first argument, since the builtin continuation call can
+ // trigger a stack iteration, which expects the receiver to be a
+ // materialized object.
+ receiver->ForceEscaping();
+ }
+ }
+ DebugVerifyBuiltinDeoptFrame(data_,
+ compiler::ContinuationFrameStateMode::LAZY);
+ reducer->current_lazy_deopt_scope_ = this;
+}
+
+template <typename BaseT>
+MaglevReducer<BaseT>::LazyDeoptFrameScope::LazyDeoptFrameScope(
+ MaglevReducer* reducer, ValueNode* context, ValueNode* receiver,
+ const MaglevCompilationUnit& unit, SourcePosition position)
+ : reducer_(reducer),
+ data_(DeoptFrame::ConstructInvokeStubFrameData{unit, position, receiver,
+ context}),
+ parent_(reducer->current_lazy_deopt_scope_) {
+ if constexpr (ReducerBaseWithDeoptFrameScopeHooks<BaseT>) {
+ reducer->base_->OnBeginDeoptFrameScope();
+ }
+ reducer->current_lazy_deopt_scope_ = this;
+}
+
+template <typename BaseT>
+MaglevReducer<BaseT>::LazyDeoptFrameScope::~LazyDeoptFrameScope() {
+ reducer_->current_lazy_deopt_scope_ = parent_;
+ if constexpr (ReducerBaseWithDeoptFrameScopeHooks<BaseT>) {
+ reducer_->base_->OnEndDeoptFrameScope();
+ }
+}
+
+template <typename BaseT>
+MaglevReducer<BaseT>::EagerDeoptFrameScope::EagerDeoptFrameScope(
+ MaglevReducer* reducer, ValueNode* context, Builtin continuation,
+ compiler::OptionalJSFunctionRef maybe_js_target,
+ base::Vector<ValueNode* const> parameters)
+ : reducer_(reducer),
+ data_(DeoptFrame::BuiltinContinuationFrameData{
+ continuation,
+ parameters.empty() ? base::Vector<ValueNode*>{}
+ : reducer->zone()->CloneVector(parameters),
+ context, maybe_js_target}),
+ parent_(reducer->current_lazy_deopt_scope_) {
+ if constexpr (ReducerBaseWithDeoptFrameScopeHooks<BaseT>) {
+ reducer->base_->OnBeginDeoptFrameScope();
+ }
+ if (!parameters.empty()) {
+ if (InlinedAllocation* receiver =
+ parameters[0]->TryCast<InlinedAllocation>()) {
+ // We escape the first argument, since the builtin continuation call can
+ // trigger a stack iteration, which expects the receiver to be a
+ // materialized object.
+ receiver->ForceEscaping();
+ }
+ }
+ DebugVerifyBuiltinDeoptFrame(data_,
+ compiler::ContinuationFrameStateMode::EAGER);
+ // Eager deopt continuations cannot be nested, so this should always be
+ // null.
+ DCHECK_NULL(reducer->current_eager_deopt_scope_);
+ reducer->current_eager_deopt_scope_ = this;
+}
+
+template <typename BaseT>
+MaglevReducer<BaseT>::EagerDeoptFrameScope::~EagerDeoptFrameScope() {
+ reducer_->current_eager_deopt_scope_ = nullptr;
+ if constexpr (ReducerBaseWithDeoptFrameScopeHooks<BaseT>) {
+ reducer_->base_->OnEndDeoptFrameScope();
+ }
+}
+
template <typename BaseT>
template <typename NodeT, typename Function, typename... Args>
ReduceResult MaglevReducer<BaseT>::AddNewNode(
@@ -198,18 +315,31 @@ void MaglevReducer<BaseT>::AddInitializedNodeToGraph(Node* node) {
// VirtualObjects should never be add to the Maglev graph.
DCHECK(!node->Is<VirtualObject>());
graph_->increment_total_nodes();
- if (current_block_position_.is_at_end()) {
+ // ~Subgraph() restores current_block() to the block before the splice so that
+ // sequential sibling subgraphs within the same reduced node can chain onto
+ // the pending splice (see comment in ~Subgraph()). Therefore, when emitting a
+ // regular node after a subgraph has finished (active_subgraph_ == nullptr),
+ // route it to pending_splice().exit->nodes() so it lands after the splice.
+ // When inside an active subgraph (active_subgraph_ != nullptr), add nodes to
+ // current_block() as usual.
+ if (V8_UNLIKELY(HasPendingSplice() && active_subgraph_ == nullptr)) {
+ BasicBlock* exit = pending_splice().exit;
+ DCHECK_NOT_NULL(exit);
+ exit->nodes().push_back(node);
+ node->set_owner(exit);
+ } else if (current_block_position_.is_at_end()) {
if (V8_UNLIKELY(add_new_node_mode_ == AddNewNodeMode::kUnbuffered)) {
current_block_->nodes().push_back(node);
} else {
new_nodes_at_end_.push_back(node);
}
+ node->set_owner(current_block());
} else {
DCHECK_EQ(add_new_node_mode_, AddNewNodeMode::kBuffered);
new_nodes_at_.push_back(
std::make_pair(current_block_position_.index(), node));
+ node->set_owner(current_block());
}
- node->set_owner(current_block());
if (node->properties().can_throw()) period_added_throwing_node_ = true;
if (V8_UNLIKELY(has_graph_labeller())) RegisterNode(node);
TRACE(TraceNewNode{node});
@@ -478,6 +608,12 @@ ReduceResult MaglevReducer<BaseT>::BuildStoreTaggedField(
ValueNode* object, ValueNode* value, int offset, StoreTaggedMode store_mode,
PropertyKey property_key, MaybeAssignedFlag maybe_assigned) {
DCHECK_IMPLIES(!IsInitializing(store_mode), !value->is_conversion());
+
+ // Unfortunately we need to check for empty types this late. If you think we
+ // can detect them earlier, have a look at
+ // test/mjsunit/maglev/regress-538884561-2.js.
+ ABORT_IF_EMPTY_TYPE(value);
+
if constexpr (ReducerBaseWithAllocationTracking<BaseT>) {
if (!IsInitializing(store_mode)) {
base_->TryBuildStoreTaggedFieldToAllocation(object, value, offset);
@@ -510,6 +646,12 @@ ReduceResult MaglevReducer<BaseT>::BuildStoreTaggedFieldNoWriteBarrier(
ValueNode* object, ValueNode* value, int offset, StoreTaggedMode store_mode,
PropertyKey property_key) {
DCHECK_IMPLIES(!IsInitializing(store_mode), !value->is_conversion());
+
+ // Unfortunately we need to check for empty types this late. If you think we
+ // can detect them earlier, have a look at
+ // test/mjsunit/maglev/regress-538884561-2.js.
+ ABORT_IF_EMPTY_TYPE(value);
+
DCHECK(CanElideWriteBarrier(object, value));
if constexpr (ReducerBaseWithAllocationTracking<BaseT>) {
if (!IsInitializing(store_mode)) {
@@ -661,6 +803,11 @@ ReduceResult MaglevReducer<BaseT>::ConvertForField(
ValueRepresentation::kInt32);
return value;
case vobj::FieldType::kFloat64:
+ if (value->properties().value_representation() ==
+ ValueRepresentation::kHoleyFloat64) {
+ return AddNewNodeNoInputConversion<UnsafeHoleyFloat64ToFloat64>(
+ {value});
+ }
return GetFloat64(value);
case vobj::FieldType::kNone:
UNREACHABLE();
@@ -669,7 +816,7 @@ ReduceResult MaglevReducer<BaseT>::ConvertForField(
}
template <typename BaseT>
-void MaglevReducer<BaseT>::BuildInitializeStore_Tagged(
+ReduceResult MaglevReducer<BaseT>::BuildInitializeStore_Tagged(
vobj::Field desc, InlinedAllocation* object, AllocationType allocation_type,
ValueNode* value, StoreTaggedMode store_mode,
MaybeAssignedFlag maybe_assigned) {
@@ -678,10 +825,8 @@ void MaglevReducer<BaseT>::BuildInitializeStore_Tagged(
// Intercept stores of constant map objects here.
if (desc.offset == offsetof(HeapObject, map_)) {
if (auto map = TryGetConstant<Map>(value)) {
- ReduceResult result = BuildStoreMap(object, map.value(),
- StoreMap::Kind::kInlinedAllocation);
- CHECK(!result.IsDoneWithAbort());
- return;
+ return BuildStoreMap(object, map.value(),
+ StoreMap::Kind::kInlinedAllocation);
}
}
@@ -698,32 +843,25 @@ void MaglevReducer<BaseT>::BuildInitializeStore_Tagged(
inlined_value->AddNonEscapingUses();
}
- // Since `value` is tagged, BuildStoreTaggedField doesn't need to do
- // input conversions and won't abort.
- ReduceResult result =
- BuildStoreTaggedField(object, value, desc.offset, store_mode,
- PropertyKey::None(), maybe_assigned);
- CHECK(!result.IsDoneWithAbort());
+ return BuildStoreTaggedField(object, value, desc.offset, store_mode,
+ PropertyKey::None(), maybe_assigned);
}
template <typename BaseT>
-void MaglevReducer<BaseT>::BuildInitializeStore_TrustedPointer(
+ReduceResult MaglevReducer<BaseT>::BuildInitializeStore_TrustedPointer(
vobj::Field desc, InlinedAllocation* object, AllocationType allocation_type,
ValueNode* value) {
DCHECK_EQ(desc.type, vobj::FieldType::kTrustedPointer);
DCHECK(value->Is<TrustedConstant>());
DCHECK(value->is_tagged());
- // Since `value` is tagged, BuildStoreTaggedField doesn't need to do input
- // conversions and won't abort.
- ReduceResult result = BuildStoreTrustedPointerField(
- object, value, desc.offset, value->Cast<TrustedConstant>()->tag(),
- StoreTaggedMode::kInitializing);
- CHECK(!result.IsDoneWithAbort());
+ return BuildStoreTrustedPointerField(object, value, desc.offset,
+ value->Cast<TrustedConstant>()->tag(),
+ StoreTaggedMode::kInitializing);
}
template <typename BaseT>
-void MaglevReducer<BaseT>::BuildInitializeStore(
+ReduceResult MaglevReducer<BaseT>::BuildInitializeStore(
vobj::Field desc, InlinedAllocation* object, AllocationType allocation_type,
ValueNode* value, StoreTaggedMode store_mode,
MaybeAssignedFlag maybe_assigned) {
@@ -732,18 +870,17 @@ void MaglevReducer<BaseT>::BuildInitializeStore(
switch (desc.type) {
case vobj::FieldType::kTagged:
- BuildInitializeStore_Tagged(desc, object, allocation_type, value,
- store_mode, maybe_assigned);
- break;
+ return BuildInitializeStore_Tagged(desc, object, allocation_type, value,
+ store_mode, maybe_assigned);
case vobj::FieldType::kTrustedPointer:
- BuildInitializeStore_TrustedPointer(desc, object, allocation_type, value);
- break;
+ return BuildInitializeStore_TrustedPointer(desc, object, allocation_type,
+ value);
case vobj::FieldType::kInt32:
- AddNewNodeNoInputConversion<StoreInt32>({object, value}, desc.offset);
- break;
+ return AddNewNodeNoInputConversion<StoreInt32>({object, value},
+ desc.offset);
case vobj::FieldType::kFloat64:
- AddNewNodeNoInputConversion<StoreFloat64>({object, value}, desc.offset);
- break;
+ return AddNewNodeNoInputConversion<StoreFloat64>({object, value},
+ desc.offset);
case vobj::FieldType::kNone:
UNREACHABLE();
}
@@ -819,7 +956,6 @@ ReduceResult MaglevReducer<BaseT>::BuildInlinedAllocation(
}
InlinedAllocation* allocation =
ExtendOrReallocateCurrentAllocationBlock(allocation_type, vobject);
- AddNonEscapingUses(allocation, static_cast<int>(values.size()));
StoreTaggedMode store_mode = StoreTaggedMode::kInitializing;
compiler::OptionalScopeInfoRef scope_info;
if (vobject->has_static_map() && vobject->map()->IsContextMap()) {
@@ -841,8 +977,9 @@ ReduceResult MaglevReducer<BaseT>::BuildInlinedAllocation(
maybe_assigned =
GetContextMaybeAssigned(scope_info.value(), index, &mode);
}
- BuildInitializeStore(desc, allocation, allocation_type, value, store_mode,
- maybe_assigned);
+ RETURN_IF_ABORT(BuildInitializeStore(desc, allocation, allocation_type,
+ value, store_mode, maybe_assigned));
+ AddNonEscapingUses(allocation, 1);
}
if constexpr (ReducerBaseWithLoopEffectTracking<BaseT>) {
if (base_->loop_effects()) {
@@ -914,7 +1051,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryWithFastArrayElements(
MapInference<MaglevReducer<BaseT>> inference(this, receiver);
auto possible_maps = inference.TryGetPossibleMaps();
if (!possible_maps) {
- FAIL("to reduce " << builtin_name << " - receiver map is unknown");
+ MAGLEV_FAIL("to reduce " << builtin_name << " - receiver map is unknown");
}
ElementsKind elements_kind;
@@ -922,15 +1059,15 @@ MaybeReduceResult MaglevReducer<BaseT>::TryWithFastArrayElements(
// together.
if (!CanInlineArrayIteratingBuiltin(broker(), *possible_maps,
&elements_kind)) {
- FAIL("to reduce " << builtin_name
- << " - doesn't support fast array iteration or "
- "incompatible maps");
+ MAGLEV_FAIL("to reduce " << builtin_name
+ << " - doesn't support fast array iteration or "
+ "incompatible maps");
}
if (IsHoleyElementsKind(elements_kind) &&
!broker()->dependencies()->DependOnNoElementsProtector()) {
- FAIL("to reduce " << builtin_name
- << " - invalidated no elements protector");
+ MAGLEV_FAIL("to reduce " << builtin_name
+ << " - invalidated no elements protector");
}
RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
@@ -973,11 +1110,11 @@ MaybeReduceResult MaglevReducer<BaseT>::TryWithArrayIterationArgs(
adjusted, AddNewNode<Int32Add>({length, from_index}));
return BuildInt32Max(adjusted, GetInt32Constant(0));
},
- [&]() -> ReduceResult {
- return BuildInt32Min(from_index, length);
- }));
+ [&]() -> ReduceResult { return from_index; }));
}
+ GET_VALUE_OR_ABORT(from_index, GetSmiValue(from_index));
+
return Reducer(elements_kind, elements, search_element, length,
from_index);
});
@@ -985,7 +1122,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryWithArrayIterationArgs(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayIncludes(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryWithArrayIterationArgs(
"Array.prototype.includes", args,
[&](ElementsKind elements_kind, ValueNode* elements,
@@ -1017,7 +1154,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayIncludes(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayIndexOf(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryWithArrayIterationArgs(
"Array.prototype.indexOf", args,
[&](ElementsKind elements_kind, ValueNode* elements,
@@ -1049,7 +1186,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayIndexOf(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayIsArray(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) return GetBooleanConstant(false);
ValueNode* node = args[0];
@@ -1139,7 +1276,7 @@ ReduceResult MaglevReducer<BaseT>::BuildAssumeMapForElements(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeAt(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryWithFastArrayElements(
"Array.prototype.at", args,
[&](ElementsKind elements_kind, ValueNode* elements, ValueNode* length) {
@@ -1226,7 +1363,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeAt(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeEntries(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
ValueNode* receiver = GetValueOrUndefined(args.receiver());
if (!CheckType(receiver, NodeType::kJSReceiver)) {
@@ -1237,7 +1374,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeEntries(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeKeys(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
ValueNode* receiver = GetValueOrUndefined(args.receiver());
if (!CheckType(receiver, NodeType::kJSReceiver)) {
@@ -1248,7 +1385,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeKeys(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceArrayPrototypeValues(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
ValueNode* receiver = GetValueOrUndefined(args.receiver());
if (!CheckType(receiver, NodeType::kJSReceiver)) {
@@ -1280,9 +1417,8 @@ ReduceResult MaglevReducer<BaseT>::GetTaggedValue(
return graph()->GetSmiConstant(*as_int32_constant);
}
}
- if (auto as_float64_constant = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kHoleyFloat64, value,
- TaggedToFloat64ConversionType::kNumberOrUndefined)) {
+ if (auto as_float64_constant =
+ TryGetHoleyFloat64Constant(value, NodeType::kNumberOrUndefined)) {
if (as_float64_constant->is_undefined_or_hole_nan()) {
return graph()->GetRootConstant(RootIndex::kUndefinedValue);
}
@@ -1591,7 +1727,7 @@ std::optional<intptr_t> MaglevReducer<BaseT>::TryGetIntPtrConstant(
template <typename BaseT>
ReduceResult MaglevReducer<BaseT>::GetTruncatedInt32ForToNumber(
- ValueNode* value, NodeType allowed_input_type) {
+ ValueNode* value, NodeType assumed_input_type) {
value->MaybeRecordUseReprHint(UseRepresentation::kTruncatedInt32);
ValueRepresentation representation =
@@ -1649,7 +1785,7 @@ ReduceResult MaglevReducer<BaseT>::GetTruncatedInt32ForToNumber(
switch (representation) {
case ValueRepresentation::kTagged: {
NodeType old_type;
- RETURN_IF_ABORT(EnsureType(value, allowed_input_type,
+ RETURN_IF_ABORT(EnsureType(value, assumed_input_type,
DeoptimizeReason::kWrongValue, &old_type));
if (NodeTypeIsSmi(old_type)) {
@@ -1659,27 +1795,28 @@ ReduceResult MaglevReducer<BaseT>::GetTruncatedInt32ForToNumber(
GET_VALUE_OR_ABORT(int32_value, BuildSmiUntag(value));
return alternative.set_int32(int32_value);
}
- if (allowed_input_type == NodeType::kSmi) {
+ if (assumed_input_type == NodeType::kSmi) {
return alternative.set_int32(
AddNewNodeNoInputConversion<CheckedSmiUntag>({value}));
}
- if (NodeTypeIs(old_type, allowed_input_type)) {
+ if (NodeTypeIs(old_type, assumed_input_type)) {
return alternative.set_truncated_int32_to_number(
AddNewNodeNoInputConversion<TruncateUnsafeNumberOrOddballToInt32>(
- {value}, GetTaggedToFloat64ConversionType(allowed_input_type)));
+ {value}, assumed_input_type));
}
return alternative.set_truncated_int32_to_number(
AddNewNodeNoInputConversion<TruncateCheckedNumberOrOddballToInt32>(
- {value}, GetTaggedToFloat64ConversionType(allowed_input_type)));
+ {value}, assumed_input_type));
}
case ValueRepresentation::kFloat64:
return alternative.set_truncated_int32_to_number(
AddNewNodeNoInputConversion<TruncateFloat64ToInt32>({value}));
case ValueRepresentation::kHoleyFloat64: {
- // Ignore conversion_type for HoleyFloat64, and treat them like Float64.
- // ToNumber of undefined is anyway a NaN, so we'll simply truncate away
- // the NaN-ness of the hole, and don't need to do extra oddball checks so
- // we can ignore the hint (though we'll miss updating the feedback).
+ // Ignore assumed_input_type for HoleyFloat64, and treat them like
+ // Float64. ToNumber of undefined is anyway a NaN, so we'll simply
+ // truncate away the NaN-ness of the hole, and don't need to do extra
+ // oddball checks so we can ignore the hint (though we'll miss updating
+ // the feedback).
return alternative.set_truncated_int32_to_number(
AddNewNodeNoInputConversion<TruncateHoleyFloat64ToInt32>({value}));
}
@@ -1690,7 +1827,7 @@ ReduceResult MaglevReducer<BaseT>::GetTruncatedInt32ForToNumber(
AddNewNodeNoInputConversion<IntPtrToNumber>({value});
return alternative.set_truncated_int32_to_number(
AddNewNodeNoInputConversion<TruncateUnsafeNumberOrOddballToInt32>(
- {value_to_number}, TaggedToFloat64ConversionType::kOnlyNumber));
+ {value_to_number}, NodeType::kNumber));
}
case ValueRepresentation::kInt32:
case ValueRepresentation::kUint32:
@@ -1702,28 +1839,14 @@ ReduceResult MaglevReducer<BaseT>::GetTruncatedInt32ForToNumber(
}
template <typename BaseT>
-ReduceResult MaglevReducer<BaseT>::GetFloat64OrHoleyFloat64Impl(
- ValueNode* value, UseRepresentation use_rep, NodeType allowed_input_type) {
- DCHECK(use_rep == UseRepresentation::kFloat64 ||
- use_rep == UseRepresentation::kHoleyFloat64);
- ValueRepresentation representation =
- value->properties().value_representation();
- if (representation == ValueRepresentation::kHoleyFloat64 &&
- use_rep == UseRepresentation::kHoleyFloat64) {
- DCHECK_NE(allowed_input_type, NodeType::kNumber);
- return value;
- } else if (representation == ValueRepresentation::kFloat64 &&
- use_rep == UseRepresentation::kFloat64) {
- return value;
- }
+ReduceResult MaglevReducer<BaseT>::GetFloat64ForToNumber(
+ ValueNode* value, NodeType assumed_input_type) {
+ value->MaybeRecordUseReprHint(UseRepresentation::kFloat64);
+
+ if (value->is_float64()) return value;
// Process constants first to avoid allocating NodeInfo for them.
- if (auto cst = TryGetFloat64OrHoleyFloat64Constant(
- use_rep, value,
- GetTaggedToFloat64ConversionType(allowed_input_type))) {
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- return graph()->GetHoleyFloat64Constant(cst.value());
- }
+ if (auto cst = TryGetFloat64Constant(value, assumed_input_type)) {
return graph()->GetFloat64Constant(cst.value());
}
@@ -1734,143 +1857,79 @@ ReduceResult MaglevReducer<BaseT>::GetFloat64OrHoleyFloat64Impl(
known_node_aspects().GetOrCreateInfoFor(broker(), value);
auto& alternative = node_info->alternative();
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- // When we want to use the `holey_float64` alternative, we need to make sure
- // that this doesn't contain any values that are not outside of
- // `allowed_input_type`. We do only set this alternative (see below) when
- // this is a (reversible) conversion, which means that it can only represent
- // numbers and undefined. So for us to use this alternative here, the
- // `allowed_input_type` must at least allow those, too. If we ever decide to
- // allow more narrow types (e.g. kSmi) we need to explicitly check for that
- // range, because the `holey_float64` alternative can contain values outside
- // of smi range.
- if (ValueNode* alt_hf64 = alternative.holey_float64()) {
- if (NodeTypeIs(
- IntersectType(NodeType::kNumberOrUndefined, node_info->type()),
- allowed_input_type)) {
- return alt_hf64;
- }
- }
- } else {
- if (ValueNode* alt_f64 = alternative.float64()) {
- return alt_f64;
- }
+ if (ValueNode* alt_f64 = alternative.float64()) {
+ return alt_f64;
}
+ NodeType known_type = GetType(value);
+
// Check for the empty type first, so that we don't emit unsafe conversion
// nodes below.
- if (IsEmptyNodeType(node_info->type())) {
+ if (IsEmptyNodeType(known_type)) {
return EmitUnconditionalDeopt(DeoptimizeReason::kWrongValue);
}
switch (value->properties().value_representation()) {
case ValueRepresentation::kTagged: {
- auto combined_type = IntersectType(allowed_input_type, node_info->type());
- if (!IsEmptyNodeType(combined_type) &&
- NodeTypeIs(combined_type, NodeType::kSmi)) {
+ // The conversion only has to cope with inputs that the caller allows it
+ // to assume and that the value can actually have, so the arms below pick
+ // their check from the intersection of the two.
+ auto narrowed_input_type = IntersectType(assumed_input_type, known_type);
+ if (IsEmptyNodeType(narrowed_input_type)) {
+ // The value can never be what the caller assumes, so whatever we emit
+ // deopts at runtime. Emitting a plain check keeps the graph as it is,
+ // whereas EmitUnconditionalDeopt aborts the rest of the block and
+ // makes every caller deal with the truncated control flow.
+ // TODO(victorgomes): Do the unconditional deopt anyway.
+ return BuildNumberOrOddballToFloat64(value, assumed_input_type);
+ }
+ if (NodeTypeIs(narrowed_input_type, NodeType::kSmi)) {
// Get the float64 value of a Smi value its int32 representation.
ValueNode* int32_value;
GET_VALUE_OR_ABORT(int32_value, GetInt32(value));
- return GetFloat64OrHoleyFloat64Impl(int32_value, use_rep,
- combined_type);
+ return GetFloat64ForToNumber(int32_value, narrowed_input_type);
}
- if (!IsEmptyNodeType(combined_type) &&
- NodeTypeIs(combined_type, NodeType::kNumber)) {
+ if (NodeTypeIs(narrowed_input_type, NodeType::kNumber)) {
ValueNode* float64_value;
- GET_VALUE_OR_ABORT(float64_value,
- BuildNumberOrOddballToFloat64OrHoleyFloat64(
- value, use_rep, NodeType::kNumber));
- if (use_rep == UseRepresentation::kFloat64) {
- // Number->Float64 conversions are exact alternatives, so they can
- // also become the canonical float64_alternative.
- return alternative.set_float64(float64_value);
- }
- return float64_value;
- }
- if (!IsEmptyNodeType(combined_type) &&
- NodeTypeIs(combined_type, NodeType::kNumberOrOddball)) {
- // NumberOrOddball->Float64 conversions are not exact alternatives,
- // since they lose the information that this is an oddball, so they
- // can only become the canonical float64_alternative if they are a
- // known number (and therefore not oddball).
- return BuildNumberOrOddballToFloat64OrHoleyFloat64(value, use_rep,
- combined_type);
+ GET_VALUE_OR_ABORT(float64_value, BuildNumberOrOddballToFloat64(
+ value, NodeType::kNumber));
+ // Number->Float64 conversions are exact alternatives, so they can
+ // also become the canonical float64_alternative.
+ return alternative.set_float64(float64_value);
}
- // The type is impossible. We could generate an unconditional deopt here,
- // but it's too invasive. So we just generate a check which will always
- // deopt.
- return BuildNumberOrOddballToFloat64OrHoleyFloat64(value, use_rep,
- allowed_input_type);
+ // NumberOrOddball->Float64 conversions are not exact alternatives, since
+ // they lose the information that this is an oddball, so they can only
+ // become the canonical float64_alternative if they are a known number
+ // (and therefore not oddball).
+ DCHECK(NodeTypeIs(narrowed_input_type, NodeType::kNumberOrOddball));
+ return BuildNumberOrOddballToFloat64(value, narrowed_input_type);
}
- case ValueRepresentation::kInt32: {
- ValueNode* float64 =
- AddNewNodeNoInputConversion<ChangeInt32ToFloat64>({value});
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- // We only set the holey_float64 alternative if all feasible values are
- // allowed according to `allowed_input_type`.
- return alternative.set_holey_float64(
- AddNewNodeNoInputConversion<UnsafeFloat64ToHoleyFloat64>(
- {float64}));
- }
- return alternative.set_float64(float64);
- }
- case ValueRepresentation::kUint32: {
- ValueNode* float64 =
- AddNewNodeNoInputConversion<ChangeUint32ToFloat64>({value});
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- // We only set the holey_float64 alternative if all feasible values are
- // allowed according to `allowed_input_type`.
- return alternative.set_holey_float64(
- AddNewNodeNoInputConversion<UnsafeFloat64ToHoleyFloat64>(
- {float64}));
- }
- return alternative.set_float64(float64);
- }
- case ValueRepresentation::kFloat64:
- DCHECK_EQ(use_rep, UseRepresentation::kHoleyFloat64);
- // We only set the holey_float64 alternative if all feasible values are
- // allowed according to `allowed_input_type`.
- return alternative.set_holey_float64(
- AddNewNodeNoInputConversion<ChangeFloat64ToHoleyFloat64>({value}));
+ case ValueRepresentation::kInt32:
+ return alternative.set_float64(
+ AddNewNodeNoInputConversion<ChangeInt32ToFloat64>({value}));
+ case ValueRepresentation::kUint32:
+ return alternative.set_float64(
+ AddNewNodeNoInputConversion<ChangeUint32ToFloat64>({value}));
+ case ValueRepresentation::kIntPtr:
+ return alternative.set_float64(
+ AddNewNodeNoInputConversion<ChangeIntPtrToFloat64>({value}));
case ValueRepresentation::kHoleyFloat64: {
- DCHECK_EQ(use_rep, UseRepresentation::kFloat64);
- switch (allowed_input_type) {
- case NodeType::kSmi:
- case NodeType::kNumber:
- case NodeType::kNumberOrBoolean:
- // Number->Float64 conversions are exact alternatives, so they can
- // also become the canonical float64_alternative. The HoleyFloat64
- // representation can represent undefined but no other oddballs, so
- // booleans cannot occur here and kNumberOrBoolean can be grouped with
- // kNumber.
- return alternative.set_float64(
- AddNewNodeNoInputConversion<CheckedHoleyFloat64ToFloat64>(
- {value}));
- case NodeType::kNumberOrUndefined:
- return AddNewNodeNoInputConversion<UnsafeHoleyFloat64ToFloat64>(
- {value});
- case NodeType::kNumberOrOddball:
- // NumberOrOddball->Float64 conversions are not exact alternatives,
- // since they lose the information that this is an oddball, so they
- // cannot become the canonical float64_alternative.
- return AddNewNodeNoInputConversion<HoleyFloat64ToSilencedFloat64>(
- {value});
- default:
- UNREACHABLE();
- }
- }
- case ValueRepresentation::kIntPtr: {
- ValueNode* float64 =
- AddNewNodeNoInputConversion<ChangeIntPtrToFloat64>({value});
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- // We only set the holey_float64 alternative if all feasible values are
- // allowed according to `allowed_input_type`.
- return alternative.set_holey_float64(
- AddNewNodeNoInputConversion<UnsafeFloat64ToHoleyFloat64>(
- {float64}));
+ if (NodeTypeIs(assumed_input_type, NodeType::kNumberOrBoolean)) {
+ // Number->Float64 conversions are exact alternatives, so they can
+ // also become the canonical float64_alternative. The HoleyFloat64
+ // representation can represent undefined but no other oddballs, so
+ // booleans cannot occur here and kNumberOrBoolean can be grouped with
+ // kNumber.
+ return alternative.set_float64(
+ AddNewNodeNoInputConversion<CheckedHoleyFloat64ToFloat64>({value}));
}
- return alternative.set_float64(float64);
+ DCHECK(NodeTypeIs(assumed_input_type, NodeType::kNumberOrOddball));
+ // NumberOrOddball->Float64 conversions are not exact alternatives,
+ // since they lose the information that this is an oddball, so they
+ // cannot become the canonical float64_alternative.
+ return AddNewNodeNoInputConversion<UnsafeHoleyFloat64ToFloat64>({value});
}
+ case ValueRepresentation::kFloat64:
case ValueRepresentation::kNone:
case ValueRepresentation::kRawPtr:
UNREACHABLE();
@@ -1878,14 +1937,85 @@ ReduceResult MaglevReducer<BaseT>::GetFloat64OrHoleyFloat64Impl(
UNREACHABLE();
}
+template <typename BaseT>
+ReduceResult MaglevReducer<BaseT>::GetHoleyFloat64ForToNumber(
+ ValueNode* value, NodeType assumed_input_type) {
+ value->MaybeRecordUseReprHint(UseRepresentation::kHoleyFloat64);
+
+ if (value->is_holey_float64()) {
+ // The value is returned as it is, keeping whatever hole or undefined it
+ // carries, so a caller assuming a number would not get what it asked for.
+ DCHECK_NE(assumed_input_type, NodeType::kNumber);
+ return value;
+ }
+
+ // Process constants first to avoid allocating NodeInfo for them.
+ if (auto cst = TryGetHoleyFloat64Constant(value, assumed_input_type)) {
+ return graph()->GetHoleyFloat64Constant(cst.value());
+ }
+
+ NodeInfo* node_info =
+ known_node_aspects().GetOrCreateInfoFor(broker(), value);
+ auto& alternative = node_info->alternative();
+
+ NodeType known_type = GetType(value);
+
+ // When we want to use the `holey_float64` alternative, we need to make sure
+ // that this doesn't contain any values that are not outside of
+ // `assumed_input_type`. We do only set this alternative (see below) when
+ // this is a (reversible) conversion, which means that it can only represent
+ // numbers and undefined. So for us to use this alternative here, the
+ // `assumed_input_type` must at least allow those, too. If we ever decide to
+ // allow more narrow types (e.g. kSmi) we need to explicitly check for that
+ // range, because the `holey_float64` alternative can contain values outside
+ // of smi range.
+ if (ValueNode* alt_hf64 = alternative.holey_float64()) {
+ if (NodeTypeIs(IntersectType(NodeType::kNumberOrUndefined, known_type),
+ assumed_input_type)) {
+ return alt_hf64;
+ }
+ }
+
+ // Check for the empty type first, so that we don't emit unsafe conversion
+ // nodes below.
+ if (IsEmptyNodeType(known_type)) {
+ return EmitUnconditionalDeopt(DeoptimizeReason::kWrongValue);
+ }
+
+ // An oddball is the only input that is not already a number, so it is the
+ // only one that cannot be converted and widened below. It is unboxed into
+ // HoleyFloat64 directly, which is what keeps undefined undefined.
+ if (value->is_tagged()) {
+ auto narrowed_input_type = IntersectType(assumed_input_type, known_type);
+ if (IsEmptyNodeType(narrowed_input_type)) {
+ // The input cannot be what the caller expects, so a conversion of it
+ // could only ever deopt.
+ return EmitUnconditionalDeopt(DeoptimizeReason::kWrongValue);
+ }
+ if (!NodeTypeIs(narrowed_input_type, NodeType::kNumber)) {
+ DCHECK(NodeTypeIs(narrowed_input_type, NodeType::kNumberOrOddball));
+ return BuildNumberOrOddballToHoleyFloat64(value, narrowed_input_type);
+ }
+ }
+
+ ValueNode* float64;
+ GET_VALUE_OR_ABORT(float64, GetFloat64ForToNumber(value, assumed_input_type));
+ if (float64->MayBeHoleOrUndefinedNan()) {
+ // The value is a number, so its bits must not start meaning the hole or
+ // undefined in the wider representation.
+ return alternative.set_holey_float64(
+ AddNewNodeNoInputConversion<ChangeFloat64ToHoleyFloat64>({float64}));
+ }
+ return alternative.set_holey_float64(
+ AddNewNodeNoInputConversion<UnsafeFloat64ToHoleyFloat64>({float64}));
+}
+
template <typename BaseT>
ValueNode* MaglevReducer<BaseT>::TryGetFloat64ForToNumber(
- ValueNode* value, NodeType allowed_input_type) {
+ ValueNode* value, NodeType assumed_input_type) {
if (value->is_float64()) return value;
- if (auto cst = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, value,
- GetTaggedToFloat64ConversionType(allowed_input_type))) {
+ if (auto cst = TryGetFloat64Constant(value, assumed_input_type)) {
return graph()->GetFloat64Constant(cst.value());
}
@@ -1904,31 +2034,12 @@ ValueNode* MaglevReducer<BaseT>::TryGetFloat64(ValueNode* value) {
template <typename BaseT>
ReduceResult MaglevReducer<BaseT>::GetFloat64(ValueNode* value) {
- value->MaybeRecordUseReprHint(UseRepresentation::kFloat64);
return GetFloat64ForToNumber(value, NodeType::kNumber);
}
-template <typename BaseT>
-ReduceResult MaglevReducer<BaseT>::GetFloat64ForToNumber(
- ValueNode* value, NodeType allowed_input_type) {
- value->MaybeRecordUseReprHint(UseRepresentation::kFloat64);
- return GetFloat64OrHoleyFloat64Impl(value, UseRepresentation::kFloat64,
- allowed_input_type);
-}
-
template <typename BaseT>
ReduceResult MaglevReducer<BaseT>::GetHoleyFloat64(ValueNode* value) {
- value->MaybeRecordUseReprHint(UseRepresentation::kHoleyFloat64);
- return GetFloat64OrHoleyFloat64Impl(value, UseRepresentation::kHoleyFloat64,
- NodeType::kNumberOrUndefined);
-}
-
-template <typename BaseT>
-ReduceResult MaglevReducer<BaseT>::GetHoleyFloat64ForToNumber(
- ValueNode* value, NodeType allowed_input_type) {
- value->MaybeRecordUseReprHint(UseRepresentation::kHoleyFloat64);
- return GetFloat64OrHoleyFloat64Impl(value, UseRepresentation::kHoleyFloat64,
- allowed_input_type);
+ return GetHoleyFloat64ForToNumber(value, NodeType::kNumberOrUndefined);
}
template <typename BaseT>
@@ -1940,12 +2051,11 @@ ReduceResult MaglevReducer<BaseT>::EnsureInt32(ValueNode* value,
}
template <typename BaseT>
-std::optional<Float64>
-MaglevReducer<BaseT>::TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation use_repr, ValueNode* value,
- TaggedToFloat64ConversionType conversion_type) {
- DCHECK(use_repr == UseRepresentation::kFloat64 ||
- use_repr == UseRepresentation::kHoleyFloat64);
+template <UseRepresentation kUseRepr>
+std::optional<Float64> MaglevReducer<BaseT>::TryGetFloatConstantImpl(
+ ValueNode* value, NodeType assumed_input_type) {
+ static_assert(kUseRepr == UseRepresentation::kFloat64 ||
+ kUseRepr == UseRepresentation::kHoleyFloat64);
switch (value->opcode()) {
case Opcode::kHeapConstant: {
compiler::ObjectRef object = value->Cast<HeapConstant>()->object();
@@ -1970,32 +2080,33 @@ MaglevReducer<BaseT>::TryGetFloat64OrHoleyFloat64Constant(
return Float64{
static_cast<double>(value->Cast<SmiConstant>()->value().value())};
case Opcode::kFloat64Constant: {
- Float64 cst = value->Cast<Float64Constant>()->value();
- if (use_repr == UseRepresentation::kFloat64) return cst;
+ if constexpr (kUseRepr == UseRepresentation::kFloat64) {
+ return value->Cast<Float64Constant>()->value();
+ }
// TODO(nicohartmann): We could optimize the HoleyFloat64 case here, too.
return {};
}
case Opcode::kHoleyFloat64Constant: {
- Float64 cst = value->Cast<HoleyFloat64Constant>()->value();
- if (use_repr == UseRepresentation::kHoleyFloat64) return cst;
+ if constexpr (kUseRepr == UseRepresentation::kHoleyFloat64) {
+ return value->Cast<HoleyFloat64Constant>()->value();
+ }
// TODO(nicohartmann): We could optimize the Float64 case here, too.
return {};
}
case Opcode::kRootConstant: {
Tagged<Object> root_object =
broker()->local_isolate()->root(value->Cast<RootConstant>()->index());
- if (conversion_type == TaggedToFloat64ConversionType::kNumberOrBoolean &&
+ if (NodeTypeIs(NodeType::kBoolean, assumed_input_type) &&
IsBoolean(root_object)) {
return Float64{Cast<Oddball>(root_object)->to_number_raw()};
}
- if (conversion_type ==
- TaggedToFloat64ConversionType::kNumberOrUndefined &&
+ if (NodeTypeIs(NodeType::kUndefined, assumed_input_type) &&
IsUndefined(root_object)) {
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
// We use the undefined nan and silence it to produce the same result
// as a computation from non-constants would.
auto ud = Float64::undefined_nan();
- if (use_repr != UseRepresentation::kHoleyFloat64) {
+ if constexpr (kUseRepr != UseRepresentation::kHoleyFloat64) {
ud = ud.to_quiet_nan();
}
return ud;
@@ -2004,19 +2115,8 @@ MaglevReducer<BaseT>::TryGetFloat64OrHoleyFloat64Constant(
Cast<Oddball>(root_object)->to_number_raw()));
#endif
}
- if (conversion_type == TaggedToFloat64ConversionType::kNumberOrOddball &&
- IsOddball(root_object)) {
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- if (IsUndefined(root_object)) {
- // We use the undefined nan and silence it to produce the same result
- // as a computation from non-constants would.
- auto ud = Float64::undefined_nan();
- if (use_repr != UseRepresentation::kHoleyFloat64) {
- ud = ud.to_quiet_nan();
- }
- return ud;
- }
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
+ if (NodeTypeIs(NodeType::kNull, assumed_input_type) &&
+ IsNull(root_object)) {
return Float64::FromBits(base::double_to_uint64(
Cast<Oddball>(root_object)->to_number_raw()));
}
@@ -2033,7 +2133,7 @@ MaglevReducer<BaseT>::TryGetFloat64OrHoleyFloat64Constant(
break;
}
if (auto c = TryGetConstantAlternative(value)) {
- return TryGetFloat64OrHoleyFloat64Constant(use_repr, *c, conversion_type);
+ return TryGetFloatConstantImpl<kUseRepr>(*c, assumed_input_type);
}
return {};
}
@@ -2578,18 +2678,20 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastHasInPrototypeChain(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastOrdinaryHasInstance(
ValueNode* context, ValueNode* object, compiler::JSObjectRef callable,
- ValueNode* callable_node_if_not_constant) {
+ ValueNode* callable_node_if_not_constant, int max_depth) {
const bool is_constant = callable_node_if_not_constant == nullptr;
if (!is_constant) return {};
if (callable.IsJSBoundFunction()) {
+ if (max_depth == 0) return {};
compiler::JSBoundFunctionRef function = callable.AsJSBoundFunction();
compiler::JSReceiverRef bound_target_function =
function.bound_target_function(broker());
if (bound_target_function.IsJSObject()) {
- RETURN_IF_DONE(TryBuildFastInstanceOf(
- context, object, bound_target_function.AsJSObject(), nullptr));
+ RETURN_IF_DONE(TryBuildFastInstanceOf(context, object,
+ bound_target_function.AsJSObject(),
+ nullptr, max_depth - 1));
}
return BuildCallBuiltinWithTaggedInputs<Builtin::kInstanceOf>(
@@ -2616,9 +2718,9 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastOrdinaryHasInstance(
template <typename BaseT>
ReduceResult MaglevReducer<BaseT>::BuildOrdinaryHasInstance(
ValueNode* context, ValueNode* object, compiler::JSObjectRef callable,
- ValueNode* callable_node_if_not_constant) {
+ ValueNode* callable_node_if_not_constant, int max_depth) {
RETURN_IF_DONE(TryBuildFastOrdinaryHasInstance(
- context, object, callable, callable_node_if_not_constant));
+ context, object, callable, callable_node_if_not_constant, max_depth));
return BuildCallBuiltinWithTaggedInputs<Builtin::kOrdinaryHasInstance>(
context, {callable_node_if_not_constant ? callable_node_if_not_constant
@@ -2638,7 +2740,7 @@ ReduceResult MaglevReducer<BaseT>::BuildToBoolean(ValueNode* value) {
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
ValueNode* context, ValueNode* object, compiler::JSObjectRef callable,
- ValueNode* callable_node_if_not_constant) {
+ ValueNode* callable_node_if_not_constant, int max_depth) {
compiler::MapRef receiver_map = callable.map(broker());
compiler::NameRef name = broker()->has_instance_symbol();
compiler::PropertyAccessInfo access_info = broker()->GetPropertyAccessInfo(
@@ -2670,7 +2772,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
}
return BuildOrdinaryHasInstance(context, object, callable,
- callable_node_if_not_constant);
+ callable_node_if_not_constant, max_depth);
}
if constexpr (!ReducerBaseCanBuildCall<BaseT>) {
@@ -2723,7 +2825,8 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
// {callable}, so we can treat the callable as a compile-time constant
// from here on, which lets BuildOrdinaryHasInstance take its fast
// path instead of calling the OrdinaryHasInstance builtin.
- return BuildOrdinaryHasInstance(context, object, callable, nullptr);
+ return BuildOrdinaryHasInstance(context, object, callable, nullptr,
+ max_depth);
}
}
@@ -2733,8 +2836,8 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOf(
ConvertReceiverMode::kNotNullOrUndefined, {callable_node, object});
ValueNode* call_result;
{
- typename BaseT::LazyDeoptFrameScope continuation_scope(
- base_, Builtin::kToBooleanLazyDeoptContinuation);
+ LazyDeoptFrameScope continuation_scope(
+ this, context, Builtin::kToBooleanLazyDeoptContinuation);
if (has_instance_field->IsJSFunction()) {
GET_VALUE_OR_ABORT(call_result,
@@ -2787,7 +2890,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildFastInstanceOfWithFeedback(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceFunctionPrototypeHasInstance(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
// We can't reduce Function#hasInstance when there is no receiver function.
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
return {};
@@ -2810,7 +2913,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceFunctionPrototypeHasInstance(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceObjectPrototypeIsPrototypeOf(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
return {};
}
@@ -2864,9 +2967,7 @@ ReduceResult MaglevReducer<BaseT>::BuildTaggedEqual(ValueNode* lhs,
template <typename BaseT>
bool MaglevReducer<BaseT>::IsNeitherNaNNorZero(ValueNode* node) {
- if (auto constant = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, node,
- TaggedToFloat64ConversionType::kOnlyNumber)) {
+ if (auto constant = TryGetFloat64Constant(node, NodeType::kNumber)) {
double value = constant->get_scalar();
// Note that `value != 0` rules out both +0 and -0.
return !std::isnan(value) && value != 0;
@@ -2946,7 +3047,7 @@ ReduceResult MaglevReducer<BaseT>::BuildSameValue(ValueNode* lhs,
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceObjectIs(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return BuildSameValue(GetValueOrUndefined(args[0]),
GetValueOrUndefined(args[1]));
}
@@ -3018,6 +3119,19 @@ ReduceResult MaglevReducer<BaseT>::BuildCheckString(ValueNode* object) {
return AddNewNode<CheckString>({object}, GetCheckType(known_type));
}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryFoldCheckNotHole(ValueNode* node) {
+ if (!node->is_tagged()) return ReduceResult::Done();
+ switch (node->IsTheHole()) {
+ case Tribool::kTrue:
+ return EmitUnconditionalDeopt(DeoptimizeReason::kHole);
+ case Tribool::kFalse:
+ return ReduceResult::Done();
+ case Tribool::kMaybe:
+ return MaybeReduceResult::Fail();
+ }
+}
+
namespace detail {
inline bool CheckConditionIn32(int32_t lhs, int32_t rhs,
AssertCondition condition) {
@@ -3071,56 +3185,42 @@ compiler::OptionalObjectRef MaglevReducer<BaseT>::TryFoldLoadConstantDataField(
}
template <typename BaseT>
-ReduceResult MaglevReducer<BaseT>::BuildNumberOrOddballToFloat64OrHoleyFloat64(
- ValueNode* node, UseRepresentation use_rep, NodeType allowed_input_type) {
- DCHECK(use_rep == UseRepresentation::kFloat64 ||
- use_rep == UseRepresentation::kHoleyFloat64);
+ReduceResult MaglevReducer<BaseT>::BuildNumberOrOddballToFloat64(
+ ValueNode* node, NodeType assumed_input_type) {
NodeType old_type;
- TaggedToFloat64ConversionType conversion_type =
- GetTaggedToFloat64ConversionType(allowed_input_type);
EnsureTypeResult ensure_res = known_node_aspects().EnsureType(
- broker(), node, allowed_input_type, &old_type);
+ broker(), node, assumed_input_type, &old_type);
+ if (ensure_res == EnsureTypeResult::kContradiction) {
+ return EmitUnconditionalDeopt(DeoptimizeReason::kWrongValue);
+ }
+ bool needs_check = ensure_res != EnsureTypeResult::kAlreadyHadType;
+ DCHECK_IMPLIES(!needs_check, old_type != NodeType::kSmi);
+ if (NodeTypeIs(assumed_input_type, NodeType::kNumber)) {
+ if (needs_check) return AddNewNode<CheckedNumberToFloat64>({node});
+ return AddNewNode<UnsafeNumberToFloat64>({node});
+ }
+ if (needs_check) {
+ return AddNewNode<CheckedNumberOrOddballToFloat64>({node},
+ assumed_input_type);
+ }
+ return AddNewNode<UnsafeNumberOrOddballToFloat64>({node}, assumed_input_type);
+}
+
+template <typename BaseT>
+ReduceResult MaglevReducer<BaseT>::BuildNumberOrOddballToHoleyFloat64(
+ ValueNode* node, NodeType assumed_input_type) {
+ DCHECK(!NodeTypeIs(assumed_input_type, NodeType::kNumber));
+ EnsureTypeResult ensure_res =
+ known_node_aspects().EnsureType(broker(), node, assumed_input_type);
if (ensure_res == EnsureTypeResult::kContradiction) {
return EmitUnconditionalDeopt(DeoptimizeReason::kWrongValue);
}
if (ensure_res == EnsureTypeResult::kAlreadyHadType) {
- if (old_type == NodeType::kSmi) {
- ValueNode* untagged_smi;
- GET_VALUE_OR_ABORT(untagged_smi, BuildSmiUntag(node));
- ValueNode* float64;
- GET_VALUE_OR_ABORT(float64,
- AddNewNode<ChangeInt32ToFloat64>({untagged_smi}));
- if (use_rep == UseRepresentation::kFloat64) return float64;
- return AddNewNode<UnsafeFloat64ToHoleyFloat64>({float64});
- }
- if (conversion_type == TaggedToFloat64ConversionType::kOnlyNumber) {
- ValueNode* float64;
- GET_VALUE_OR_ABORT(float64, AddNewNode<UnsafeNumberToFloat64>({node}));
- if (use_rep == UseRepresentation::kFloat64) return float64;
- return AddNewNode<ChangeFloat64ToHoleyFloat64>({float64});
- } else {
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- return AddNewNode<UnsafeNumberOrOddballToHoleyFloat64>({node},
- conversion_type);
- }
- return AddNewNode<UnsafeNumberOrOddballToFloat64>({node},
- conversion_type);
- }
- } else {
- if (conversion_type == TaggedToFloat64ConversionType::kOnlyNumber) {
- ValueNode* float64;
- GET_VALUE_OR_ABORT(float64, AddNewNode<CheckedNumberToFloat64>({node}));
- if (use_rep == UseRepresentation::kFloat64) return float64;
- return AddNewNode<ChangeFloat64ToHoleyFloat64>({node});
- } else {
- if (use_rep == UseRepresentation::kHoleyFloat64) {
- return AddNewNode<CheckedNumberOrOddballToHoleyFloat64>(
- {node}, conversion_type);
- }
- return AddNewNode<CheckedNumberOrOddballToFloat64>({node},
- conversion_type);
- }
+ return AddNewNode<UnsafeNumberOrOddballToHoleyFloat64>({node},
+ assumed_input_type);
}
+ return AddNewNode<CheckedNumberOrOddballToHoleyFloat64>({node},
+ assumed_input_type);
}
template <typename BaseT>
@@ -3718,9 +3818,8 @@ bool MaglevReducer<BaseT>::TryFoldUint32CompareOperation(Operation op,
template <typename BaseT>
std::optional<bool> MaglevReducer<BaseT>::TryFoldFloat64CompareOperation(
Operation op, ValueNode* left, ValueNode* right) {
- if (auto cst_right = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, right,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst_right =
+ TryGetFloat64Constant(right, NodeType::kNumberOrOddball)) {
return TryFoldFloat64CompareOperation(op, left, cst_right->get_scalar());
}
return {};
@@ -3729,9 +3828,7 @@ std::optional<bool> MaglevReducer<BaseT>::TryFoldFloat64CompareOperation(
template <typename BaseT>
std::optional<bool> MaglevReducer<BaseT>::TryFoldFloat64CompareOperation(
Operation op, ValueNode* left, double cst_right) {
- if (auto cst_left = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, left,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst_left = TryGetFloat64Constant(left, NodeType::kNumberOrOddball)) {
return TryFoldFloat64CompareOperation(op, cst_left->get_scalar(),
cst_right);
}
@@ -3762,9 +3859,8 @@ bool MaglevReducer<BaseT>::TryFoldFloat64CompareOperation(Operation op,
template <typename BaseT>
template <Operation kOperation>
MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64UnaryOperationForToNumber(
- TaggedToFloat64ConversionType conversion_type, ValueNode* value) {
- auto cst = TryGetFloat64OrHoleyFloat64Constant(UseRepresentation::kFloat64,
- value, conversion_type);
+ NodeType assumed_input_type, ValueNode* value) {
+ auto cst = TryGetFloat64Constant(value, assumed_input_type);
if (!cst.has_value()) return {};
const double scalar = cst->get_scalar();
switch (kOperation) {
@@ -3794,23 +3890,19 @@ template <typename BaseT>
template <Operation kOperation>
MaybeReduceResult
MaglevReducer<BaseT>::TryFoldFloat64BinaryOperationForToNumber(
- TaggedToFloat64ConversionType conversion_type, ValueNode* left,
- ValueNode* right) {
- auto cst_right = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, right, conversion_type);
+ NodeType assumed_input_type, ValueNode* left, ValueNode* right) {
+ auto cst_right = TryGetFloat64Constant(right, assumed_input_type);
if (!cst_right.has_value()) return {};
return TryFoldFloat64BinaryOperationForToNumber<kOperation>(
- conversion_type, left, cst_right->get_scalar());
+ assumed_input_type, left, cst_right->get_scalar());
}
template <typename BaseT>
template <Operation kOperation>
MaybeReduceResult
MaglevReducer<BaseT>::TryFoldFloat64BinaryOperationForToNumber(
- TaggedToFloat64ConversionType conversion_type, ValueNode* left,
- double cst_right) {
- auto cst_left = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, left, conversion_type);
+ NodeType assumed_input_type, ValueNode* left, double cst_right) {
+ auto cst_left = TryGetFloat64Constant(left, assumed_input_type);
if (!cst_left.has_value()) {
if (details::Float64Equal(cst_right, Float64Identity<kOperation>())) {
// This needs to return a Float64.
@@ -3820,6 +3912,9 @@ MaglevReducer<BaseT>::TryFoldFloat64BinaryOperationForToNumber(
} else {
GET_VALUE_OR_ABORT(left, GetFloat64(left));
}
+ if (left->MayBeHoleOrUndefinedNan()) {
+ GET_VALUE_OR_ABORT(left, AddNewNode<Float64ToSilencedFloat64>({left}));
+ }
return left->Unwrap();
}
// TODO(dmercadier): we could still do strength reduction, like
@@ -3860,16 +3955,17 @@ MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64Min(ValueNode* lhs,
DCHECK(ValueRepresentationIs(rhs->value_representation(),
ValueRepresentation::kFloat64));
if (lhs == rhs) {
+ if (lhs->MayBeHoleOrUndefinedNan()) {
+ GET_VALUE_OR_ABORT(lhs, AddNewNode<Float64ToSilencedFloat64>({lhs}));
+ }
return lhs->Unwrap();
}
- std::optional<Float64> lhs_const = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, lhs,
- TaggedToFloat64ConversionType::kNumberOrOddball);
+ std::optional<Float64> lhs_const =
+ TryGetFloat64Constant(lhs, NodeType::kNumberOrOddball);
if (!lhs_const) return {};
- std::optional<Float64> rhs_const = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, rhs,
- TaggedToFloat64ConversionType::kNumberOrOddball);
+ std::optional<Float64> rhs_const =
+ TryGetFloat64Constant(rhs, NodeType::kNumberOrOddball);
if (!rhs_const) return {};
const double lhs_scalar = lhs_const->get_scalar();
@@ -3900,17 +3996,18 @@ MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64Max(ValueNode* lhs,
DCHECK(ValueRepresentationIs(rhs->value_representation(),
ValueRepresentation::kFloat64));
if (lhs == rhs) {
+ if (lhs->MayBeHoleOrUndefinedNan()) {
+ GET_VALUE_OR_ABORT(lhs, AddNewNode<Float64ToSilencedFloat64>({lhs}));
+ }
return lhs->Unwrap();
}
- std::optional<Float64> lhs_const = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, lhs,
- TaggedToFloat64ConversionType::kNumberOrOddball);
+ std::optional<Float64> lhs_const =
+ TryGetFloat64Constant(lhs, NodeType::kNumberOrOddball);
if (!lhs_const) return {};
- std::optional<Float64> rhs_const = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, rhs,
- TaggedToFloat64ConversionType::kNumberOrOddball);
+ std::optional<Float64> rhs_const =
+ TryGetFloat64Constant(rhs, NodeType::kNumberOrOddball);
if (!rhs_const) return {};
const double lhs_scalar = lhs_const->get_scalar();
@@ -3955,9 +4052,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64Max(ValueNode* lhs,
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64Ieee754Unary(
Float64Ieee754Unary::Ieee754Function ieee_function, ValueNode* input) {
- if (auto cst = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, input,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = TryGetFloat64Constant(input, NodeType::kNumberOrOddball)) {
double value = cst.value().get_scalar();
double result;
switch (ieee_function) {
@@ -3977,12 +4072,8 @@ template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64Ieee754Binary(
Float64Ieee754Binary::Ieee754Function ieee_function, ValueNode* left,
ValueNode* right) {
- if (auto lhs = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, left,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
- if (auto rhs = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, right,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto lhs = TryGetFloat64Constant(left, NodeType::kNumberOrOddball)) {
+ if (auto rhs = TryGetFloat64Constant(right, NodeType::kNumberOrOddball)) {
double lhs_val = lhs.value().get_scalar();
double rhs_val = rhs.value().get_scalar();
double result;
@@ -4012,9 +4103,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryFoldInt32CountLeadingZeros(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryFoldFloat64CountLeadingZeros(
ValueNode* input) {
- if (auto cst = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, input,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = TryGetFloat64Constant(input, NodeType::kNumberOrOddball)) {
uint32_t value = DoubleToUint32(cst.value().get_scalar());
return GetInt32Constant(base::bits::CountLeadingZeros32(value));
}
@@ -4385,7 +4474,7 @@ ReduceResult MaglevReducer<BaseT>::BuildFloat64Sign(ValueNode* value) {
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathSqrt(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() < 1) {
return GetRootConstant(RootIndex::kNanValue);
}
@@ -4400,7 +4489,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathSqrt(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathMax(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) {
return GetConstant(broker()->minus_infinity_value());
}
@@ -4423,7 +4512,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathMax(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathMin(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) {
return GetConstant(broker()->infinity_value());
}
@@ -4484,7 +4573,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathMinMax(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathAbs(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) {
return GetRootConstant(RootIndex::kNanValue);
}
@@ -4529,15 +4618,13 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathAbs(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathSign(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) {
return GetRootConstant(RootIndex::kNanValue);
}
ValueNode* arg = args[0];
- if (auto cst = TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation::kFloat64, arg,
- TaggedToFloat64ConversionType::kNumberOrOddball)) {
+ if (auto cst = TryGetFloat64Constant(arg, NodeType::kNumberOrOddball)) {
double value = cst.value().get_scalar();
// NaN, +0 and -0 are returned unchanged.
return GetFloat64Constant(value > 0 ? 1.0 : (value < 0 ? -1.0 : value));
@@ -4579,25 +4666,25 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathSign(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathCeil(
- compiler::JSFunctionRef target, CallArguments& args) {
- return DoTryReduceMathRound(args, Float64Round::Kind::kCeil);
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return DoTryReduceMathRound(context, args, Float64Round::Kind::kCeil);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathFloor(
- compiler::JSFunctionRef target, CallArguments& args) {
- return DoTryReduceMathRound(args, Float64Round::Kind::kFloor);
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return DoTryReduceMathRound(context, args, Float64Round::Kind::kFloor);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathRound(
- compiler::JSFunctionRef target, CallArguments& args) {
- return DoTryReduceMathRound(args, Float64Round::Kind::kNearest);
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return DoTryReduceMathRound(context, args, Float64Round::Kind::kNearest);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::DoTryReduceMathRound(
- CallArguments& args, Float64Round::Kind kind) {
+ ValueNode* context, CallArguments& args, Float64Round::Kind kind) {
if (args.count() == 0) {
return GetRootConstant(RootIndex::kNanValue);
}
@@ -4627,26 +4714,22 @@ MaybeReduceResult MaglevReducer<BaseT>::DoTryReduceMathRound(
return AddNewNode<Float64Round>({float64_value}, kind);
}
if (!CanSpeculateCall()) return {};
- if constexpr (ReducerBaseWithLazyDeoptScope<BaseT>) {
- typename BaseT::LazyDeoptFrameScope continuation_scope(
- base_, Float64Round::continuation(kind));
- ToNumberOrNumeric* conversion;
- GET_VALUE_OR_ABORT(conversion, AddNewNode<ToNumberOrNumeric>(
- {arg}, Object::Conversion::kToNumber));
- // TODO(victorgomes): rely on automatic input conversion here rather than
- // calling UncheckedNumberToFloat64 manually.
- ValueNode* float64_value;
- GET_VALUE_OR_ABORT(float64_value,
- AddNewNode<UnsafeNumberToFloat64>({conversion}));
- return AddNewNode<Float64Round>({float64_value}, kind);
- } else {
- return {};
- }
+ LazyDeoptFrameScope continuation_scope(this, context,
+ Float64Round::continuation(kind));
+ ToNumberOrNumeric* conversion;
+ GET_VALUE_OR_ABORT(conversion, AddNewNode<ToNumberOrNumeric>(
+ {arg}, Object::Conversion::kToNumber));
+ // TODO(victorgomes): rely on automatic input conversion here rather than
+ // calling UncheckedNumberToFloat64 manually.
+ ValueNode* float64_value;
+ GET_VALUE_OR_ABORT(float64_value,
+ AddNewNode<UnsafeNumberToFloat64>({conversion}));
+ return AddNewNode<Float64Round>({float64_value}, kind);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathTrunc(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() < 1) {
return GetRootConstant(RootIndex::kNanValue);
}
@@ -4667,7 +4750,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathTrunc(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathClz32(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() < 1) {
return GetInt32Constant(32);
}
@@ -4706,26 +4789,22 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathClz32(
return {};
}
- if constexpr (ReducerBaseWithLazyDeoptScope<BaseT>) {
- typename BaseT::LazyDeoptFrameScope continuation_scope(
- base_, Float64CountLeadingZeros::continuation());
- ToNumberOrNumeric* conversion;
- GET_VALUE_OR_ABORT(conversion, AddNewNode<ToNumberOrNumeric>(
- {arg}, Object::Conversion::kToNumber));
- // TODO(victorgomes): rely on automatic input conversion here rather than
- // calling UnsafeNumberToFloat64 manually.
- ValueNode* float64_value;
- GET_VALUE_OR_ABORT(float64_value,
- AddNewNode<UnsafeNumberToFloat64>({conversion}));
- return AddNewNode<Float64CountLeadingZeros>({float64_value});
- } else {
- return {};
- }
+ LazyDeoptFrameScope continuation_scope(
+ this, context, Float64CountLeadingZeros::continuation());
+ ToNumberOrNumeric* conversion;
+ GET_VALUE_OR_ABORT(conversion, AddNewNode<ToNumberOrNumeric>(
+ {arg}, Object::Conversion::kToNumber));
+ // TODO(victorgomes): rely on automatic input conversion here rather than
+ // calling UnsafeNumberToFloat64 manually.
+ ValueNode* float64_value;
+ GET_VALUE_OR_ABORT(float64_value,
+ AddNewNode<UnsafeNumberToFloat64>({conversion}));
+ return AddNewNode<Float64CountLeadingZeros>({float64_value});
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathImul(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) {
return GetInt32Constant(0);
}
@@ -4746,7 +4825,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathImul(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathFround(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() < 1) {
return GetRootConstant(RootIndex::kNanValue);
}
@@ -4761,6 +4840,23 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceMathFround(
return AddNewNode<Float64RoundToFloat32>({value});
}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::BuildSpeculativeCheckInstanceType(
+ ValueNode* object, NodeType target_type, InstanceType first,
+ InstanceType last) {
+ NodeType known_type;
+ EnsureTypeResult ensure_res = known_node_aspects().TryEnsureType(
+ broker(), object, target_type, &known_type);
+ if (ensure_res == EnsureTypeResult::kAlreadyHadType) {
+ return ReduceResult::Done();
+ }
+ if (ensure_res == EnsureTypeResult::kContradiction) {
+ return {};
+ }
+ return AddNewNode<CheckInstanceType>({object}, GetCheckType(known_type),
+ first, last);
+}
+
template <typename BaseT>
ReduceResult MaglevReducer<BaseT>::BuildCheckInstanceType(ValueNode* object,
NodeType target_type,
@@ -4945,20 +5041,136 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringLength(
return MaybeReduceResult::Fail();
}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceConstantStringAt(
+ ValueNode* receiver, ValueNode* index, StringAtOOBMode oob_mode) {
+ auto constant_receiver = TryGetConstant<HeapObject>(receiver);
+ if (!constant_receiver) return {};
+ if (!constant_receiver->IsString()) {
+ return EmitUnconditionalDeopt(DeoptimizeReason::kNotAString);
+ }
+ compiler::StringRef string = constant_receiver->AsString();
+ auto maybe_constant_index = TryGetInt32Constant(index);
+ if (!maybe_constant_index) return {};
+ int32_t constant_index = *maybe_constant_index;
+
+ if (static_cast<uint32_t>(constant_index) >= string.length()) {
+ switch (oob_mode) {
+ case StringAtOOBMode::kElement:
+ // For element access, a negative index triggers a named lookup rather
+ // than an element lookup; when this is the case, we shouldn't be trying
+ // to optimize an elements access at all, so deopt.
+ if (constant_index < 0) {
+ return EmitUnconditionalDeopt(DeoptimizeReason::kOutOfBounds);
+ }
+ // Otherwise, this is hole-like access, so guard against elements on the
+ // prototype to return undefined.
+ if (broker()->dependencies()->DependOnNoElementsProtector()) {
+ return GetRootConstant(RootIndex::kUndefinedValue);
+ }
+ // If the no elements protector is invalidated, unconditionally deopt.
+ // This shouldn't trigger a deopt look because the feedback should
+ // transition to megamorphic.
+ return EmitUnconditionalDeopt(DeoptimizeReason::kOutOfBounds);
+ case StringAtOOBMode::kCharAt: {
+ // OOB for charAt is always the empty string.
+ return GetRootConstant(RootIndex::kempty_string);
+ }
+ }
+ UNREACHABLE();
+ }
+
+ if (std::optional<uint16_t> value =
+ string.GetChar(broker(), constant_index)) {
+ return GetConstantSingleCharacterStringFromCode(*value);
+ }
+ return {};
+}
+
+template <typename BaseT>
+MaybeReduceResult
+MaglevReducer<BaseT>::GetConstantSingleCharacterStringFromCode(uint16_t code) {
+ // Only handle the one-byte character case, which accesses roots.
+ if (code <= String::kMaxOneByteCharCode) {
+ return GetRootConstant(RootsTable::SingleCharacterStringIndex(code));
+ }
+ return {};
+}
+
+template <typename BaseT>
+ReduceResult MaglevReducer<BaseT>::BuildLoadStringLength(ValueNode* string) {
+ RETURN_IF_DONE(TryReduceStringLength(string));
+ ValueNode* result;
+ GET_VALUE_OR_ABORT(result, AddNewNode<StringLength>({string}));
+ RecordKnownProperty(string, PropertyKey::StringLength(), result, true,
+ compiler::AccessMode::kLoad);
+ return result;
+}
+
+template <typename BaseT>
+ReduceResult MaglevReducer<BaseT>::BuildGetCharCodeAt(ValueNode* string,
+ ValueNode* index) {
+ return AddNewNode<BuiltinStringPrototypeCharCodeOrCodePointAt>(
+ {string, index},
+ BuiltinStringPrototypeCharCodeOrCodePointAt::kCharCodeAt);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeIndexOfIncludes(
+ CallArguments& args, bool is_includes) {
+ if (!CanSpeculateCall()) return {};
+
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+
+ ValueNode* search_element =
+ args.count() > 0 ? args[0]
+ : GetRootConstant(RootIndex::kundefined_string);
+ RETURN_IF_ABORT(BuildCheckString(search_element));
+
+ ValueNode* start = args.count() > 1 ? args[1] : GetInt32Constant(0);
+ ValueNode* receiver_length;
+ GET_VALUE_OR_ABORT(receiver_length, BuildLoadStringLength(receiver));
+
+ // min(max(start, 0), receiver_length)
+ ValueNode* max_value;
+ GET_VALUE_OR_ABORT(max_value, BuildInt32Max(start, GetInt32Constant(0)));
+ ValueNode* clamped_start;
+ GET_VALUE_OR_ABORT(clamped_start, BuildInt32Min(max_value, receiver_length));
+
+ // TODO(496266449): Change StringIndexOf value representation type to
+ // kSmi and remove this GetSmiValue call.
+ ValueNode* clamped_start_smi;
+ GET_VALUE_OR_ABORT(clamped_start_smi, GetSmiValue(clamped_start));
+
+ ValueNode* result;
+ GET_VALUE_OR_ABORT(result,
+ (AddNewNode<StringIndexOf>(
+ {receiver, search_element, clamped_start_smi})));
+
+ if (is_includes) {
+ return (AddNewNode<Int32Compare>({result, GetInt32Constant(0)},
+ Operation::kGreaterThanOrEqual));
+ }
+
+ return result;
+}
+
template <typename BaseT>
template <typename LoadNode>
MaybeReduceResult MaglevReducer<BaseT>::TryBuildLoadDataView(
const CallArguments& args, ExternalArrayType type) {
if (!CanSpeculateCall()) return {};
- if (!broker()->dependencies()->DependOnArrayBufferDetachingProtector()) {
- // TODO(victorgomes): Add checks whether the array has been detached or is
- // immutable.
- return {};
- }
ValueNode* receiver = GetValueOrUndefined(args.receiver());
- RETURN_IF_ABORT(BuildCheckInstanceType(receiver, NodeType::kJSDataView,
- JS_DATA_VIEW_TYPE, JS_DATA_VIEW_TYPE));
- // TODO(v8:11111): Optimize for JS_RAB_GSAB_DATA_VIEW_TYPE too.
+ RETURN_IF_NOT_DONE_WITHOUT_ABORT(BuildSpeculativeCheckInstanceType(
+ receiver, NodeType::kJSDataView, JS_DATA_VIEW_TYPE, JS_DATA_VIEW_TYPE));
+ bool depend_on_detaching =
+ broker()->dependencies()->DependOnArrayBufferDetachingProtector();
+ if (!depend_on_detaching) {
+ RETURN_IF_ABORT(AddNewNode<CheckTypedArrayValid>(
+ {receiver}, TypedArrayAccessMode::kRead));
+ }
+ // TODO(555676855): Optimize for JS_RAB_GSAB_DATA_VIEW_TYPE too.
ValueNode* offset;
if (args[0]) {
GET_VALUE_OR_ABORT(offset, GetInt32ElementIndex(args[0]));
@@ -4985,15 +5197,18 @@ template <typename StoreNode, typename Function>
MaybeReduceResult MaglevReducer<BaseT>::TryBuildStoreDataView(
const CallArguments& args, ExternalArrayType type, Function&& getValue) {
if (!CanSpeculateCall()) return {};
- if (!broker()->dependencies()->DependOnArrayBufferDetachingProtector() ||
- !broker()->dependencies()->DependOnArrayBufferMutableProtector()) {
- // TODO(victorgomes): Add checks whether the array has been detached.
- return {};
- }
ValueNode* receiver = GetValueOrUndefined(args.receiver());
- RETURN_IF_ABORT(BuildCheckInstanceType(receiver, NodeType::kJSDataView,
- JS_DATA_VIEW_TYPE, JS_DATA_VIEW_TYPE));
- // TODO(v8:11111): Optimize for JS_RAB_GSAB_DATA_VIEW_TYPE too.
+ RETURN_IF_NOT_DONE_WITHOUT_ABORT(BuildSpeculativeCheckInstanceType(
+ receiver, NodeType::kJSDataView, JS_DATA_VIEW_TYPE, JS_DATA_VIEW_TYPE));
+ bool depend_on_detaching =
+ broker()->dependencies()->DependOnArrayBufferDetachingProtector();
+ bool depend_on_mutable =
+ broker()->dependencies()->DependOnArrayBufferMutableProtector();
+ if (!depend_on_detaching || !depend_on_mutable) {
+ RETURN_IF_ABORT(AddNewNode<CheckTypedArrayValid>(
+ {receiver}, TypedArrayAccessMode::kWrite));
+ }
+ // TODO(555676855): Optimize for JS_RAB_GSAB_DATA_VIEW_TYPE too.
ValueNode* offset;
if (args[0]) {
GET_VALUE_OR_ABORT(offset, GetInt32ElementIndex(args[0]));
@@ -5019,52 +5234,131 @@ MaybeReduceResult MaglevReducer<BaseT>::TryBuildStoreDataView(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetInt8(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryBuildLoadDataView<LoadSignedIntDataViewElement>(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadInt32DataViewElement>(
args, ExternalArrayType::kExternalInt8Array);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetInt8(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryBuildStoreDataView<StoreSignedIntDataViewElement>(
- args, ExternalArrayType::kExternalInt8Array,
- [&](ValueNode* value) { return value ? value : GetInt32Constant(0); });
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreInt32DataViewElement>(
+ args, ExternalArrayType::kExternalInt8Array, [&](ValueNode* value) {
+ return value ? GetTruncatedInt32ForToNumber(value,
+ NodeType::kNumberOrOddball)
+ : GetInt32Constant(0);
+ });
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetUint8(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadInt32DataViewElement>(
+ args, ExternalArrayType::kExternalUint8Array);
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetUint8(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreInt32DataViewElement>(
+ args, ExternalArrayType::kExternalUint8Array, [&](ValueNode* value) {
+ return value ? GetTruncatedInt32ForToNumber(value,
+ NodeType::kNumberOrOddball)
+ : GetInt32Constant(0);
+ });
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetInt16(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryBuildLoadDataView<LoadSignedIntDataViewElement>(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadInt32DataViewElement>(
args, ExternalArrayType::kExternalInt16Array);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetInt16(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryBuildStoreDataView<StoreSignedIntDataViewElement>(
- args, ExternalArrayType::kExternalInt16Array,
- [&](ValueNode* value) { return value ? value : GetInt32Constant(0); });
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreInt32DataViewElement>(
+ args, ExternalArrayType::kExternalInt16Array, [&](ValueNode* value) {
+ return value ? GetTruncatedInt32ForToNumber(value,
+ NodeType::kNumberOrOddball)
+ : GetInt32Constant(0);
+ });
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetUint16(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadInt32DataViewElement>(
+ args, ExternalArrayType::kExternalUint16Array);
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetUint16(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreInt32DataViewElement>(
+ args, ExternalArrayType::kExternalUint16Array, [&](ValueNode* value) {
+ return value ? GetTruncatedInt32ForToNumber(value,
+ NodeType::kNumberOrOddball)
+ : GetInt32Constant(0);
+ });
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetInt32(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryBuildLoadDataView<LoadSignedIntDataViewElement>(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadInt32DataViewElement>(
args, ExternalArrayType::kExternalInt32Array);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetInt32(
- compiler::JSFunctionRef target, CallArguments& args) {
- return TryBuildStoreDataView<StoreSignedIntDataViewElement>(
- args, ExternalArrayType::kExternalInt32Array,
- [&](ValueNode* value) { return value ? value : GetInt32Constant(0); });
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreInt32DataViewElement>(
+ args, ExternalArrayType::kExternalInt32Array, [&](ValueNode* value) {
+ return value ? GetTruncatedInt32ForToNumber(value,
+ NodeType::kNumberOrOddball)
+ : GetInt32Constant(0);
+ });
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetUint32(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadUint32DataViewElement>(
+ args, ExternalArrayType::kExternalUint32Array);
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetUint32(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreInt32DataViewElement>(
+ args, ExternalArrayType::kExternalUint32Array, [&](ValueNode* value) {
+ return value ? GetTruncatedInt32ForToNumber(value,
+ NodeType::kNumberOrOddball)
+ : GetInt32Constant(0);
+ });
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetFloat32(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildLoadDataView<LoadDoubleDataViewElement>(
+ args, ExternalArrayType::kExternalFloat32Array);
+}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetFloat32(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryBuildStoreDataView<StoreDoubleDataViewElement>(
+ args, ExternalArrayType::kExternalFloat32Array, [&](ValueNode* value) {
+#ifdef V8_ENABLE_UNDEFINED_DOUBLE
+ // Produce the same bit pattern we would get through computation.
+ auto ud = Float64::FromBits(kUndefinedNanInt64);
+ const double silenced_nan = ud.to_quiet_nan().get_scalar();
+#else
+ const double silenced_nan = std::numeric_limits<double>::quiet_NaN();
+#endif // V8_ENABLE_UNDEFINED_DOUBLE
+ return value ? GetFloat64ForToNumber(value, NodeType::kNumberOrOddball)
+ : GetFloat64Constant(silenced_nan);
+ });
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeGetFloat64(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryBuildLoadDataView<LoadDoubleDataViewElement>(
args, ExternalArrayType::kExternalFloat64Array);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetFloat64(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryBuildStoreDataView<StoreDoubleDataViewElement>(
args, ExternalArrayType::kExternalFloat64Array, [&](ValueNode* value) {
#ifdef V8_ENABLE_UNDEFINED_DOUBLE
@@ -5082,7 +5376,8 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceDataViewPrototypeSetFloat64(
#define MATH_UNARY_IEEE_BUILTIN_REDUCER(MathName, ExtName, EnumName) \
template <typename BaseT> \
MaybeReduceResult MaglevReducer<BaseT>::TryReduce##MathName( \
- compiler::JSFunctionRef target, CallArguments& args) { \
+ ValueNode* context, compiler::JSFunctionRef target, \
+ CallArguments& args) { \
if (args.count() < 1) { \
return GetRootConstant(RootIndex::kNanValue); \
} \
@@ -5103,7 +5398,8 @@ IEEE_754_UNARY_LIST(MATH_UNARY_IEEE_BUILTIN_REDUCER)
#define MATH_BINARY_IEEE_BUILTIN_REDUCER(MathName, ExtName, EnumName) \
template <typename BaseT> \
MaybeReduceResult MaglevReducer<BaseT>::TryReduce##MathName( \
- compiler::JSFunctionRef target, CallArguments& args) { \
+ ValueNode* context, compiler::JSFunctionRef target, \
+ CallArguments& args) { \
if (args.count() < 2) { \
if (args.count() == 1 && !CheckType(args[0], NodeType::kNumber)) { \
return {}; \
@@ -5199,7 +5495,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetField(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetTime(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
auto prologue_result = TryReduceDatePrototypeGetFieldPrologue(target, args);
if (!prologue_result.IsDoneWithoutPayload()) return prologue_result;
@@ -5211,37 +5507,37 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetTime(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetFullYear(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kYear);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetMonth(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kMonth);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetDate(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kDay);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetDay(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kWeekday);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetHours(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kHour);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetMinutes(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kMinute);
}
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetSeconds(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return TryReduceDatePrototypeGetField(target, args, JSDate::kSecond);
}
@@ -5249,7 +5545,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceDatePrototypeGetSeconds(
template <typename BaseT>
MaybeReduceResult
MaglevReducer<BaseT>::TryReduceStringPrototypeLocaleCompareIntl(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() < 1 || args.count() > 3) return {};
LocalFactory* factory = local_isolate()->factory();
@@ -5304,14 +5600,14 @@ MaglevReducer<BaseT>::TryReduceStringPrototypeLocaleCompareIntl(
template <typename BaseT>
MaybeReduceResult
MaglevReducer<BaseT>::TryReduceGetContinuationPreservedEmbedderData(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
return AddNewNode<GetContinuationPreservedEmbedderData>({});
}
template <typename BaseT>
MaybeReduceResult
MaglevReducer<BaseT>::TryReduceSetContinuationPreservedEmbedderData(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (args.count() == 0) return {};
RETURN_IF_ABORT(AddNewNode<SetContinuationPreservedEmbedderData>({args[0]}));
@@ -5884,13 +6180,32 @@ VirtualObject* MaglevReducer<BaseT>::CreateJSStringIterator(
}
template <typename BaseT>
-MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeThen(
- compiler::JSFunctionRef target, CallArguments& args) {
+VirtualObject* MaglevReducer<BaseT>::CreateJSMapIterator(compiler::MapRef map,
+ ValueNode* table) {
+ using Shape = VirtualJSMapIteratorShape;
+ static_assert(sizeof(JSMapIterator) == 5 * kTaggedSize);
+ int slot_count = Shape::header_slot_count;
+ VirtualObject* vobj = NodeBase::New<VirtualObject>(
+ zone(), 0, NewObjectId(), zone(), &Shape::kObjectLayout, map, slot_count);
+ vobj->set(offsetof(HeapObject, map_), GetConstant(map));
+ vobj->set(offsetof(JSCollectionIterator, properties_or_hash_),
+ GetRootConstant(RootIndex::kEmptyFixedArray));
+ vobj->set(offsetof(JSCollectionIterator, elements_),
+ GetRootConstant(RootIndex::kEmptyFixedArray));
+ vobj->set(offsetof(JSCollectionIterator, table_), table);
+ vobj->set(offsetof(JSCollectionIterator, index_), GetInt32Constant(0));
+ return vobj;
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReducePromiseThenImpl(
+ const char* trace_name, CallArguments& args, ValueNode* on_fulfilled,
+ ValueNode* on_rejected, bool needs_then_protector) {
+ DCHECK(args.mode() == CallArguments::kDefault);
if (!CanSpeculateCall()) return {};
- if (args.mode() != CallArguments::kDefault) return {};
if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
- TRACE(TraceColor::kRed
- << "! Failed to reduce Promise.prototype.then - no receiver");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - no receiver");
return {};
}
ValueNode* receiver = GetValueOrUndefined(args.receiver());
@@ -5900,8 +6215,8 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeThen(
MapInference<MaglevReducer<BaseT>> inference(this, receiver);
auto possible_maps = inference.TryGetPossibleMaps();
if (!possible_maps) {
- TRACE(TraceColor::kRed << "! Failed to reduce Promise.prototype.then - "
- "unknown receiver map");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - unknown receiver map");
return {};
}
if (possible_maps->is_empty()) {
@@ -5910,8 +6225,8 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeThen(
for (compiler::MapRef map : *possible_maps) {
if (!map.IsJSPromiseMap() ||
!map.prototype(broker()).equals(promise_prototype)) {
- TRACE(TraceColor::kRed << "! Failed to reduce Promise.prototype.then - "
- "not an initial-prototype JSPromise map");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - not an initial-prototype JSPromise map");
return {};
}
}
@@ -5919,37 +6234,37 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeThen(
// Non-callable reactions behave like undefined; the fast path only covers
// arguments that are statically callable or undefined.
ValueNode* undefined_value = GetRootConstant(RootIndex::kUndefinedValue);
- ValueNode* on_fulfilled =
- args.count() > 0 ? args[0]->UnwrapIdentities() : undefined_value;
- ValueNode* on_rejected =
- args.count() > 1 ? args[1]->UnwrapIdentities() : undefined_value;
auto is_callable_or_undefined = [&](ValueNode* value) {
return value == undefined_value || CheckType(value, NodeType::kCallable);
};
if (!is_callable_or_undefined(on_fulfilled)) {
- TRACE(TraceColor::kRed << "! Failed to reduce Promise.prototype.then - "
- "on_fulfilled not callable");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - on_fulfilled not callable");
return {};
}
if (!is_callable_or_undefined(on_rejected)) {
- TRACE(TraceColor::kRed << "! Failed to reduce Promise.prototype.then - "
- "on_rejected not callable");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - on_rejected not callable");
return {};
}
- // No PromiseThenProtector needed here: unlike Promise.prototype.catch/finally
- // (which desugar to a `then` lookup), this builtin never reads the "then"
- // property, so a monkeypatched `then` dispatches elsewhere and never reaches
- // this reduction. The map checks above only establish an initial-prototype
- // JSPromise for the species/hook assumptions below.
+ // PromiseThenProtector is only required when the caller desugars to a
+ // dynamic `then` lookup (e.g. catch/finally); direct Promise.prototype.then
+ // invocations dispatch elsewhere if monkeypatched.
+ if (needs_then_protector &&
+ !broker()->dependencies()->DependOnPromiseThenProtector()) {
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - promise then protector");
+ return {};
+ }
if (!broker()->dependencies()->DependOnPromiseHookProtector()) {
- TRACE(TraceColor::kRed << "! Failed to reduce Promise.prototype.then - "
- "promise hook protector");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - promise hook protector");
return {};
}
if (!broker()->dependencies()->DependOnPromiseSpeciesProtector()) {
- TRACE(TraceColor::kRed << "! Failed to reduce Promise.prototype.then - "
- "species protector");
+ TRACE(TraceColor::kRed << "! Failed to reduce " << trace_name
+ << " - species protector");
return {};
}
@@ -5960,9 +6275,34 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeThen(
GET_VALUE_OR_ABORT(result_promise, BuildInlinedAllocation(
result_vobj, AllocationType::kYoung));
- ValueNode* context = GetConstant(broker()->target_native_context());
+ ValueNode* native_context = GetConstant(broker()->target_native_context());
return BuildCallBuiltin<Builtin::kPerformPromiseThen>(
- context, {receiver, on_fulfilled, on_rejected, result_promise});
+ native_context, {receiver, on_fulfilled, on_rejected, result_promise});
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeCatch(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (args.mode() != CallArguments::kDefault) return {};
+ ValueNode* undefined_value = GetRootConstant(RootIndex::kUndefinedValue);
+ ValueNode* on_fulfilled = undefined_value;
+ ValueNode* on_rejected =
+ args.count() > 0 ? args[0]->UnwrapIdentities() : undefined_value;
+ return TryReducePromiseThenImpl("Promise.prototype.catch", args, on_fulfilled,
+ on_rejected, /*needs_then_protector=*/true);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReducePromisePrototypeThen(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (args.mode() != CallArguments::kDefault) return {};
+ ValueNode* undefined_value = GetRootConstant(RootIndex::kUndefinedValue);
+ ValueNode* on_fulfilled =
+ args.count() > 0 ? args[0]->UnwrapIdentities() : undefined_value;
+ ValueNode* on_rejected =
+ args.count() > 1 ? args[1]->UnwrapIdentities() : undefined_value;
+ return TryReducePromiseThenImpl("Promise.prototype.then", args, on_fulfilled,
+ on_rejected, /*needs_then_protector=*/false);
}
// Like JSNativeContextSpecialization::ReduceJSResolvePromise: returns true
@@ -6023,7 +6363,7 @@ bool MaglevReducer<BaseT>::CanElideResolvePromiseThenLookup(ValueNode* value) {
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceRegExpPrototypeTest(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
if (!CanSpeculateCall()) return {};
if (v8_flags.force_slow_path) return {};
@@ -6121,7 +6461,7 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceRegExpPrototypeTest(
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReducePromiseResolveTrampoline(
- compiler::JSFunctionRef target, CallArguments& args) {
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
// Ports JSCallReducer::ReducePromiseResolveTrampoline combined with
// JSNativeContextSpecialization::ReduceJSPromiseResolve: Promise.resolve
// on the %Promise% constructor itself, with a value that provably has no
@@ -6185,10 +6525,407 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReducePromiseResolveTrampoline(
return BuildInlinedAllocation(promise, AllocationType::kYoung);
}
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceTypedArrayConstructor(
+ ValueNode* context, compiler::JSFunctionRef target, ValueNode* new_target,
+ CallArguments& args) {
+ DCHECK_NOT_NULL(new_target);
+ ValueNode* target_node = GetConstant(target);
+ ValueNode* arg0 =
+ args[0] ? args[0] : GetRootConstant(RootIndex::kUndefinedValue);
+ ValueNode* arg1 =
+ args[1] ? args[1] : GetRootConstant(RootIndex::kUndefinedValue);
+ ValueNode* arg2 =
+ args[2] ? args[2] : GetRootConstant(RootIndex::kUndefinedValue);
+
+ // The caller (the construct dispatch) is responsible for pushing the
+ // construct-stub deopt frame scope.
+ DCHECK_NOT_NULL(current_lazy_deopt_scope());
+ LazyDeoptFrameScope continuation(
+ this, context, Builtin::kGenericLazyDeoptContinuation, target,
+ base::VectorOf<ValueNode* const>(
+ {GetRootConstant(RootIndex::kTheHoleValue)}));
+ return BuildCallBuiltinWithTaggedInputs<Builtin::kCreateTypedArray>(
+ GetConstant(broker()->target_native_context()),
+ {target_node, new_target, arg0, arg1, arg2});
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceMapIteratorCreation(
+ CallArguments& args, IterationKind iteration_kind) {
+ if (!CanSpeculateCall()) return {};
+ if (args.receiver_mode() == ConvertReceiverMode::kNullOrUndefined) {
+ return {};
+ }
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ MapInference<MaglevReducer<BaseT>> inference(this, receiver);
+ auto possible_receiver_maps = inference.TryGetPossibleMaps();
+ if (!possible_receiver_maps || possible_receiver_maps->is_empty()) {
+ return {};
+ }
+ if (!std::all_of(possible_receiver_maps->begin(),
+ possible_receiver_maps->end(), [](compiler::MapRef map) {
+ return map.instance_type() == JS_MAP_TYPE;
+ })) {
+ return {};
+ }
+ RETURN_IF_ABORT(inference.InsertMapChecks(zone()));
+
+ ValueNode* table;
+ GET_VALUE_OR_ABORT(
+ table, BuildLoadTaggedField(receiver, offsetof(JSCollection, table_),
+ NodeType::kAnyHeapObject));
+
+ compiler::NativeContextRef nc = broker()->target_native_context();
+ compiler::MapRef iterator_map =
+ iteration_kind == IterationKind::kEntries
+ ? nc.map_key_value_iterator_map(broker())
+ : (iteration_kind == IterationKind::kKeys
+ ? nc.map_key_iterator_map(broker())
+ : nc.map_value_iterator_map(broker()));
+ VirtualObject* iterator = CreateJSMapIterator(iterator_map, table);
+ return BuildInlinedAllocation(iterator, AllocationType::kYoung);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceMapPrototypeEntries(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceMapIteratorCreation(args, IterationKind::kEntries);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceMapPrototypeKeys(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceMapIteratorCreation(args, IterationKind::kKeys);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceMapPrototypeValues(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceMapIteratorCreation(args, IterationKind::kValues);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceReturnReceiver(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return GetValueOrUndefined(args.receiver());
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringFromCharCode(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall()) return {};
+ if (args.count() != 1) return {};
+ ValueNode* value;
+ GET_VALUE_OR_ABORT(
+ value, GetTruncatedInt32ForToNumber(args[0], NodeType::kNumberOrOddball));
+ return AddNewNode<BuiltinStringFromCharCode>({value});
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeCharAt(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall({SpeculationMode::kDisallowBoundsCheckSpeculation})) {
+ return {};
+ }
+
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ ValueNode* index;
+ if (args.count() == 0) {
+ // Index is the undefined object. ToIntegerOrInfinity(undefined) = 0.
+ index = GetInt32Constant(0);
+ } else {
+ GET_VALUE_OR_ABORT(index, GetInt32ElementIndex(args[0]));
+ }
+ // Any other argument is ignored.
+
+ RETURN_IF_DONE(
+ TryReduceConstantStringAt(receiver, index, StringAtOOBMode::kCharAt));
+
+ // Ensure that {receiver} is actually a String.
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+ // And index is below length.
+ ValueNode* length;
+ GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
+
+ auto GetCharAt = [&]() -> ReduceResult {
+ return AddNewNode<StringAt>({receiver, index});
+ };
+ if (current_speculation_mode_ ==
+ SpeculationMode::kDisallowBoundsCheckSpeculation) {
+ return Select(
+ [&](BranchBuilder& builder) {
+ // Do unsafe conversions of length and index into uint32, to do an
+ // unsigned comparison. The index might actually be a negative signed
+ // value, but this "unsafe" cast will still work, converting it into a
+ // large unsigned value which compares greater than the length.
+ return BuildBranchIfUint32Compare(
+ builder, Operation::kLessThan,
+ // 'index' and 'length' are both int32, so no input conversion is
+ // needed.
+ AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({index}),
+ AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({length}));
+ },
+ [&]() -> ReduceResult { return GetCharAt(); },
+ [&]() -> ReduceResult {
+ return GetRootConstant(RootIndex::kempty_string);
+ });
+ }
+
+ DCHECK_EQ(current_speculation_mode_, SpeculationMode::kAllowSpeculation);
+ RETURN_IF_ABORT(TryBuildCheckInt32Condition(
+ index, length, AssertCondition::kUnsignedLessThan,
+ DeoptimizeReason::kOutOfBounds));
+ return GetCharAt();
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeCharCodeAt(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall({SpeculationMode::kDisallowBoundsCheckSpeculation})) {
+ return {};
+ }
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ ValueNode* index;
+ if (args.count() == 0) {
+ // Index is the undefined object. ToIntegerOrInfinity(undefined) = 0.
+ index = GetInt32Constant(0);
+ } else {
+ GET_VALUE_OR_ABORT(index, GetInt32ElementIndex(args[0]));
+ }
+ // Any other argument is ignored.
+
+ // Try to constant-fold if receiver and index are constant
+ if (auto cst = TryGetConstant<String>(receiver)) {
+ if (index->template Is<Int32Constant>()) {
+ int idx = index->template Cast<Int32Constant>()->value();
+ if (idx >= 0 && static_cast<uint32_t>(idx) < cst->length()) {
+ if (std::optional<uint16_t> value = cst->GetChar(broker(), idx)) {
+ return GetSmiConstant(*value);
+ }
+ }
+ }
+ }
+
+ // Ensure that {receiver} is actually a String.
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+ // And index is below length.
+ ValueNode* length;
+ GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
+
+ if (current_speculation_mode_ ==
+ SpeculationMode::kDisallowBoundsCheckSpeculation) {
+ return Select(
+ [&](BranchBuilder& builder) {
+ // Do unsafe conversions of length and index into uint32, to do an
+ // unsigned comparison. The index might actually be a negative signed
+ // value, but this "unsafe" cast will still work, converting it into a
+ // large unsigned value which compares greater than the length.
+ return BuildBranchIfUint32Compare(
+ builder, Operation::kLessThan,
+ // 'index' and 'length' are both int32, so no input conversion is
+ // needed.
+ AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({index}),
+ AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({length}));
+ },
+ [&]() -> ReduceResult { return BuildGetCharCodeAt(receiver, index); },
+ [&]() -> ReduceResult {
+ return GetRootConstant(RootIndex::kNanValue);
+ });
+ }
+
+ RETURN_IF_ABORT(TryBuildCheckInt32Condition(
+ index, length, AssertCondition::kUnsignedLessThan,
+ DeoptimizeReason::kOutOfBounds));
+ return BuildGetCharCodeAt(receiver, index);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeCodePointAt(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall({SpeculationMode::kDisallowBoundsCheckSpeculation})) {
+ return {};
+ }
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ ValueNode* index;
+ if (args.count() == 0) {
+ // Index is the undefined object. ToIntegerOrInfinity(undefined) = 0.
+ index = GetInt32Constant(0);
+ } else {
+ GET_VALUE_OR_ABORT(index, GetInt32ElementIndex(args[0]));
+ }
+ // Any other argument is ignored.
+ // Ensure that {receiver} is actually a String.
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+ // And index is below length.
+ ValueNode* length;
+ GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
+
+ auto GetCodePointAt = [&]() -> ReduceResult {
+ return AddNewNode<BuiltinStringPrototypeCharCodeOrCodePointAt>(
+ {receiver, index},
+ BuiltinStringPrototypeCharCodeOrCodePointAt::kCodePointAt);
+ };
+
+ if (current_speculation_mode_ ==
+ SpeculationMode::kDisallowBoundsCheckSpeculation) {
+ return Select(
+ [&](BranchBuilder& builder) {
+ // Do unsafe conversions of length and index into uint32, to do an
+ // unsigned comparison. The index might actually be a negative signed
+ // value, but this "unsafe" cast will still work, converting it into a
+ // large unsigned value which compares greater than the length.
+ return BuildBranchIfUint32Compare(
+ builder, Operation::kLessThan,
+ // 'index' and 'length' are both int32, so no input conversion is
+ // needed.
+ AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({index}),
+ AddNewNodeNoInputConversion<UnsafeInt32ToUint32>({length}));
+ },
+ [&]() -> ReduceResult { return GetCodePointAt(); },
+ [&]() -> ReduceResult {
+ return GetRootConstant(RootIndex::kUndefinedValue);
+ });
+ }
+
+ RETURN_IF_ABORT(TryBuildCheckInt32Condition(
+ index, length, AssertCondition::kUnsignedLessThan,
+ DeoptimizeReason::kOutOfBounds));
+ return GetCodePointAt();
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeSlice(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall()) return {};
+
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ // Ensure that {receiver} is actually a String.
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+
+ if (args.count() == 1) {
+ // Reduce slice(-1).
+ if (std::optional<int32_t> index_const = TryGetInt32Constant(args[0]);
+ index_const && *index_const == -1) {
+ ValueNode* receiver_length;
+ GET_VALUE_OR_ABORT(receiver_length, BuildLoadStringLength(receiver));
+
+ return Select(
+ [&](BranchBuilder& builder) {
+ return BuildBranchIfInt32Compare(builder, Operation::kEqual,
+ receiver_length,
+ GetInt32Constant(0));
+ },
+ [&] { return GetRootConstant(RootIndex::kempty_string); },
+ [&] {
+ ValueNode* index_last;
+ // TODO(marja): Consider TryReduceConstantStringAt.
+ GET_VALUE_OR_ABORT(index_last,
+ (AddNewNode<Int32Subtract>(
+ {receiver_length, GetInt32Constant(1)})));
+ return AddNewNode<StringAt>({receiver, index_last});
+ });
+ }
+ }
+
+ ValueNode* start_index;
+ bool start_is_undefined = false;
+ if (args.count() >= 1) {
+ if (RootConstant* root_cst = args[0]->template TryCast<RootConstant>()) {
+ start_is_undefined = (root_cst->index() == RootIndex::kUndefinedValue);
+ }
+ }
+ if (args.count() == 0 || start_is_undefined) {
+ start_index = GetInt32Constant(0);
+ } else {
+ GET_VALUE_OR_ABORT(start_index, GetInt32(args[0]));
+ }
+
+ ValueNode* end_index;
+ bool end_is_undefined = false;
+ if (args.count() >= 2) {
+ if (RootConstant* root_cst = args[1]->template TryCast<RootConstant>()) {
+ end_is_undefined = (root_cst->index() == RootIndex::kUndefinedValue);
+ }
+ }
+ if (args.count() < 2 || end_is_undefined) {
+ // Use String::kMaxLength as sentinel, as it is >= receiver.length it
+ // will be set to receiver.length when the node is lowered. This avoids
+ // loading the string length here.
+ end_index = GetInt32Constant(String::kMaxLength);
+ } else {
+ GET_VALUE_OR_ABORT(end_index, GetInt32(args[1]));
+ }
+
+ return AddNewNode<StringSlice>({receiver, start_index, end_index});
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeSubstring(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall()) return {};
+
+ if (args.count() != 1 && args.count() != 2) return {};
+
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+
+ ValueNode* start_index = args[0];
+ ValueNode* end_index;
+ if (args.count() > 1) {
+ end_index = args[1];
+ } else {
+ GET_VALUE_OR_ABORT(end_index, BuildLoadStringLength(receiver));
+ }
+
+ ValueNode* zero = GetInt32Constant(0);
+ ValueNode* length;
+ GET_VALUE_OR_ABORT(length, BuildLoadStringLength(receiver));
+
+ ValueNode* clamped_start;
+ GET_VALUE_OR_ABORT(clamped_start, BuildInt32Max(start_index, zero));
+ GET_VALUE_OR_ABORT(clamped_start, BuildInt32Min(clamped_start, length));
+
+ ValueNode* clamped_end;
+ GET_VALUE_OR_ABORT(clamped_end, BuildInt32Max(end_index, zero));
+ GET_VALUE_OR_ABORT(clamped_end, BuildInt32Min(clamped_end, length));
+
+ ValueNode* from;
+ GET_VALUE_OR_ABORT(from, BuildInt32Min(clamped_start, clamped_end));
+ ValueNode* to;
+ GET_VALUE_OR_ABORT(to, BuildInt32Max(clamped_start, clamped_end));
+ return AddNewNode<StringSubstring>({receiver, from, to});
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeIndexOf(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceStringPrototypeIndexOfIncludes(args, false);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeIncludes(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ return TryReduceStringPrototypeIndexOfIncludes(args, true);
+}
+
+template <typename BaseT>
+MaybeReduceResult MaglevReducer<BaseT>::TryReduceStringPrototypeIterator(
+ ValueNode* context, compiler::JSFunctionRef target, CallArguments& args) {
+ if (!CanSpeculateCall()) return {};
+ ValueNode* receiver = GetValueOrUndefined(args.receiver());
+ // Ensure that {receiver} is actually a String.
+ RETURN_IF_ABORT(BuildCheckString(receiver));
+ compiler::MapRef map =
+ broker()->target_native_context().initial_string_iterator_map(broker());
+ VirtualObject* string_iterator = CreateJSStringIterator(map, receiver);
+ return BuildInlinedAllocation(string_iterator, AllocationType::kYoung);
+}
+
template <typename BaseT>
MaybeReduceResult MaglevReducer<BaseT>::TryReduceBuiltin(
- Builtin builtin_id, compiler::JSFunctionRef target, CallArguments& args,
- const compiler::FeedbackSource& feedback_source) {
+ Builtin builtin_id, ValueNode* context, compiler::JSFunctionRef target,
+ CallArguments& args, const compiler::FeedbackSource& feedback_source) {
if (args.mode() != CallArguments::kDefault) {
// TODO(victorgomes): Maybe inline the spread stub? Or call known function
// directly if arguments list is an array.
@@ -6215,9 +6952,9 @@ MaybeReduceResult MaglevReducer<BaseT>::TryReduceBuiltin(
MaybeReduceResult result;
switch (builtin_id) {
-#define CASE(Name, ...) \
- case Builtin::k##Name: \
- result = TryReduce##Name(target, args); \
+#define CASE(Name, ...) \
+ case Builtin::k##Name: \
+ result = TryReduce##Name(context, target, args); \
break;
MAGLEV_REDUCER_BUILTIN(CASE)
#undef CASE
@@ -6330,6 +7067,6 @@ inline bool IsSmallFunction(int bytecode_length,
} // namespace v8
#undef TRACE
-#undef FAIL
+#undef MAGLEV_FAIL
#endif // V8_MAGLEV_MAGLEV_REDUCER_INL_H_
diff --git a/deps/v8/src/maglev/maglev-reducer.h b/deps/v8/src/maglev/maglev-reducer.h
index 8c8faaa35d8..7320e7c18a6 100644
--- a/deps/v8/src/maglev/maglev-reducer.h
+++ b/deps/v8/src/maglev/maglev-reducer.h
@@ -6,6 +6,7 @@
#define V8_MAGLEV_MAGLEV_REDUCER_H_
#include <algorithm>
+#include <concepts>
#include <initializer_list>
#include <optional>
#include <utility>
@@ -51,6 +52,8 @@ enum class CpuOperation {
// TODO(leszeks): Add a generic mechanism for marking nodes as optionally
// supported.
+enum class StringAtOOBMode { kElement, kCharAt };
+
inline bool IsSupported(CpuOperation op) {
switch (op) {
case CpuOperation::kFloat64Round:
@@ -203,6 +206,14 @@ inline ReduceResult MaybeReduceResult::Checked() { return ReduceResult(*this); }
} \
} while (false)
+#define RETURN_IF_NOT_DONE_WITHOUT_ABORT(result) \
+ do { \
+ auto res = (result); \
+ if (!res.IsDoneWithoutAbort()) { \
+ return res; \
+ } \
+ } while (false)
+
#define PROCESS_AND_RETURN_IF_DONE(result, value_processor) \
do { \
auto res = (result); \
@@ -280,6 +291,11 @@ inline ReduceResult MaybeReduceResult::Checked() { return ReduceResult(*this); }
DCHECK_NOT_NULL(variable); \
} while (false)
+#define ABORT_IF_EMPTY_TYPE(node) \
+ if (IsEmptyNodeType(GetType(node))) { \
+ return BuildAbort(AbortReason::kUnreachable); \
+ }
+
template <typename BaseT>
concept ReducerBaseWithKNA = requires(BaseT* b) { b->known_node_aspects(); };
@@ -304,8 +320,10 @@ concept ReducerBaseWithLazyDeopt = requires(BaseT* b) {
};
template <typename BaseT>
-concept ReducerBaseWithLazyDeoptScope =
- requires { typename BaseT::LazyDeoptFrameScope; };
+concept ReducerBaseWithDeoptFrameScopeHooks = requires(BaseT* b) {
+ b->OnBeginDeoptFrameScope();
+ b->OnEndDeoptFrameScope();
+};
template <typename NodeT, typename BaseT>
concept ReducerBaseWithEffectTracking = requires(BaseT* b) {
@@ -671,6 +689,63 @@ inline bool operator==(const BasicBlockPosition& lhs,
template <typename BaseT>
class MaglevReducer {
public:
+ // Pushes a continuation deopt frame onto the current lazy deopt frame
+ // chain: nodes created while the scope is live get their lazy deopt frame
+ // wrapped with this continuation. The frame data construction is shared
+ // across reducer bases; the caller passes everything the frame needs (bases
+ // may additionally implement the ReducerBaseWithDeoptFrameScopeHooks
+ // hooks).
+ class V8_NODISCARD LazyDeoptFrameScope {
+ public:
+ LazyDeoptFrameScope(MaglevReducer* reducer, ValueNode* context,
+ Builtin continuation,
+ compiler::OptionalJSFunctionRef maybe_js_target = {},
+ base::Vector<ValueNode* const> parameters = {});
+ LazyDeoptFrameScope(MaglevReducer* reducer, ValueNode* context,
+ ValueNode* receiver, const MaglevCompilationUnit& unit,
+ SourcePosition position);
+ ~LazyDeoptFrameScope();
+
+ LazyDeoptFrameScope* parent() const { return parent_; }
+ const DeoptFrame::FrameData& data() const { return data_; }
+
+ private:
+ MaglevReducer* reducer_;
+ DeoptFrame::FrameData data_;
+ LazyDeoptFrameScope* parent_;
+ };
+
+ // Pushes an eager deopt continuation frame: eager deopts of nodes created
+ // while the scope is live resume in the continuation instead of
+ // re-executing the current bytecode.
+ class V8_NODISCARD EagerDeoptFrameScope {
+ public:
+ EagerDeoptFrameScope(MaglevReducer* reducer, ValueNode* context,
+ Builtin continuation,
+ compiler::OptionalJSFunctionRef maybe_js_target = {},
+ base::Vector<ValueNode* const> parameters = {});
+ ~EagerDeoptFrameScope();
+
+ LazyDeoptFrameScope* parent() const { return parent_; }
+ const DeoptFrame::FrameData& data() const { return data_; }
+
+ private:
+ MaglevReducer* reducer_;
+ DeoptFrame::FrameData data_;
+ // An eager deopt continuation's parent has to be a lazy deopt
+ // continuation, because we want to continue _after_ the eager deopt
+ // continuation completes.
+ LazyDeoptFrameScope* parent_;
+ };
+
+ LazyDeoptFrameScope* current_lazy_deopt_scope() const {
+ return current_lazy_deopt_scope_;
+ }
+
+ EagerDeoptFrameScope* current_eager_deopt_scope() const {
+ return current_eager_deopt_scope_;
+ }
+
MaglevReducer(BaseT* base, Graph* graph,
MaglevCompilationUnit* compilation_unit = nullptr)
: base_(base),
@@ -763,9 +838,16 @@ class MaglevReducer {
std::optional<int32_t> TryGetInt32Constant(ValueNode* value);
std::optional<uint32_t> TryGetUint32Constant(ValueNode* value);
std::optional<intptr_t> TryGetIntPtrConstant(ValueNode* value);
- std::optional<Float64> TryGetFloat64OrHoleyFloat64Constant(
- UseRepresentation use_repr, ValueNode* value,
- TaggedToFloat64ConversionType conversion_type);
+ std::optional<Float64> TryGetFloat64Constant(ValueNode* value,
+ NodeType assumed_input_type) {
+ return TryGetFloatConstantImpl<UseRepresentation::kFloat64>(
+ value, assumed_input_type);
+ }
+ std::optional<Float64> TryGetHoleyFloat64Constant(
+ ValueNode* value, NodeType assumed_input_type) {
+ return TryGetFloatConstantImpl<UseRepresentation::kHoleyFloat64>(
+ value, assumed_input_type);
+ }
template <typename MapContainer>
MaybeReduceResult TryFoldCheckConstantMaps(ValueNode* object,
@@ -790,13 +872,16 @@ class MaglevReducer {
ValueNode* receiver, compiler::HeapObjectRef prototype);
MaybeReduceResult TryBuildFastHasInPrototypeChain(
ValueNode* object, compiler::HeapObjectRef prototype);
+ // Bound functions are unwrapped recursively; cap how deep we follow the
+ // bound_target_function chain to bound both graph size and stack usage.
+ static constexpr int kMaxBoundFunctionDepth = 5;
MaybeReduceResult TryBuildFastOrdinaryHasInstance(
ValueNode* context, ValueNode* object, compiler::JSObjectRef callable,
- ValueNode* callable_node_if_not_constant);
- MaybeReduceResult TryBuildFastInstanceOf(ValueNode* context,
- ValueNode* object,
- compiler::JSObjectRef callable_ref,
- ValueNode* callable_node);
+ ValueNode* callable_node_if_not_constant,
+ int max_depth = kMaxBoundFunctionDepth);
+ MaybeReduceResult TryBuildFastInstanceOf(
+ ValueNode* context, ValueNode* object, compiler::JSObjectRef callable_ref,
+ ValueNode* callable_node, int max_depth = kMaxBoundFunctionDepth);
MaybeReduceResult TryBuildFastInstanceOfWithFeedback(
ValueNode* context, ValueNode* object, ValueNode* callable,
compiler::FeedbackSource feedback_source);
@@ -805,6 +890,7 @@ class MaglevReducer {
ReduceResult BuildSmiUntag(ValueNode* node);
ReduceResult BuildCheckSmi(ValueNode* object);
ReduceResult BuildCheckString(ValueNode* object);
+ MaybeReduceResult TryFoldCheckNotHole(ValueNode* node);
ReduceResult BuildTaggedEqual(ValueNode* lhs, ValueNode* rhs);
ReduceResult BuildTaggedEqual(ValueNode* lhs, RootIndex rhs_index);
@@ -821,12 +907,15 @@ class MaglevReducer {
compiler::JSObjectRef holder,
compiler::PropertyAccessInfo const& access_info);
- ReduceResult BuildNumberOrOddballToFloat64OrHoleyFloat64(
- ValueNode* node, UseRepresentation use_rep, NodeType allowed_input_type);
+ ReduceResult BuildNumberOrOddballToFloat64(ValueNode* node,
+ NodeType assumed_input_type);
+ ReduceResult BuildNumberOrOddballToHoleyFloat64(ValueNode* node,
+ NodeType assumed_input_type);
ReduceResult BuildOrdinaryHasInstance(
ValueNode* context, ValueNode* object, compiler::JSObjectRef callable,
- ValueNode* callable_node_if_not_constant);
+ ValueNode* callable_node_if_not_constant,
+ int max_depth = kMaxBoundFunctionDepth);
template <bool flip = false>
ReduceResult BuildToBoolean(ValueNode* value);
@@ -935,6 +1024,7 @@ class MaglevReducer {
ValueNode* done);
VirtualObject* CreateJSStringIterator(compiler::MapRef map,
ValueNode* string);
+ VirtualObject* CreateJSMapIterator(compiler::MapRef map, ValueNode* table);
VirtualObject* CreateJSStringWrapper(ValueNode* value);
VirtualObject* CreateJSPromiseObject();
VirtualObject* CreateAsyncResumeTask(ValueNode* generator, ValueNode* value,
@@ -999,11 +1089,7 @@ class MaglevReducer {
//
// Deopts if the ToNumber is non-trivial.
ReduceResult GetTruncatedInt32ForToNumber(ValueNode* value,
- NodeType allowed_input_type);
-
- ReduceResult GetFloat64OrHoleyFloat64Impl(ValueNode* value,
- UseRepresentation use_rep,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
// Get a Float64 representation node whose value is equivalent to the given
// node.
@@ -1015,16 +1101,16 @@ class MaglevReducer {
ValueNode* TryGetFloat64(ValueNode* value);
ReduceResult GetFloat64ForToNumber(ValueNode* value,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
// This does not emit any conversion.
ValueNode* TryGetFloat64ForToNumber(ValueNode* value,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
ReduceResult GetHoleyFloat64(ValueNode* value);
ReduceResult GetHoleyFloat64ForToNumber(ValueNode* value,
- NodeType allowed_input_type);
+ NodeType assumed_input_type);
ReduceResult EnsureInt32(ValueNode* value, bool can_be_heap_number = false);
@@ -1124,14 +1210,22 @@ class MaglevReducer {
V(ArrayPrototypeEntries) \
V(ArrayPrototypeKeys) \
V(ArrayPrototypeValues) \
+ V(DataViewPrototypeGetFloat32) \
V(DataViewPrototypeGetFloat64) \
V(DataViewPrototypeGetInt16) \
V(DataViewPrototypeGetInt32) \
V(DataViewPrototypeGetInt8) \
+ V(DataViewPrototypeGetUint16) \
+ V(DataViewPrototypeGetUint32) \
+ V(DataViewPrototypeGetUint8) \
+ V(DataViewPrototypeSetFloat32) \
V(DataViewPrototypeSetFloat64) \
V(DataViewPrototypeSetInt16) \
V(DataViewPrototypeSetInt32) \
V(DataViewPrototypeSetInt8) \
+ V(DataViewPrototypeSetUint16) \
+ V(DataViewPrototypeSetUint32) \
+ V(DataViewPrototypeSetUint8) \
V(DatePrototypeGetDate) \
V(DatePrototypeGetDay) \
V(DatePrototypeGetFullYear) \
@@ -1141,6 +1235,9 @@ class MaglevReducer {
V(DatePrototypeGetSeconds) \
V(DatePrototypeGetTime) \
V(FunctionPrototypeHasInstance) \
+ V(MapPrototypeEntries) \
+ V(MapPrototypeKeys) \
+ V(MapPrototypeValues) \
V(MathAbs) \
V(MathCeil) \
V(MathClz32) \
@@ -1155,20 +1252,47 @@ class MaglevReducer {
V(MathTrunc) \
V(ObjectIs) \
V(ObjectPrototypeIsPrototypeOf) \
+ V(PromisePrototypeCatch) \
V(PromisePrototypeThen) \
V(PromiseResolveTrampoline) \
V(RegExpPrototypeTest) \
+ V(ReturnReceiver) \
+ V(StringFromCharCode) \
+ V(StringPrototypeCharAt) \
+ V(StringPrototypeCharCodeAt) \
+ V(StringPrototypeCodePointAt) \
+ V(StringPrototypeSlice) \
+ V(StringPrototypeSubstring) \
+ V(StringPrototypeIndexOf) \
+ V(StringPrototypeIncludes) \
+ V(StringPrototypeIterator) \
IEEE_754_UNARY_LIST(V) \
IEEE_754_BINARY_LIST(V) \
IF_INTL(V, StringPrototypeLocaleCompareIntl) \
CONTINUATION_PRESERVED_EMBEDDER_DATA_LIST(V)
#define DECLARE_BUILTIN_REDUCER(Name, ...) \
- MaybeReduceResult TryReduce##Name(compiler::JSFunctionRef target, \
+ MaybeReduceResult TryReduce##Name(ValueNode* context, \
+ compiler::JSFunctionRef target, \
CallArguments& args);
MAGLEV_REDUCER_BUILTIN(DECLARE_BUILTIN_REDUCER)
#undef DECLARE_BUILTIN_REDUCER
+ MaybeReduceResult TryReduceMapIteratorCreation(CallArguments& args,
+ IterationKind iteration_kind);
+
+ MaybeReduceResult TryReducePromiseThenImpl(const char* trace_name,
+ CallArguments& args,
+ ValueNode* on_fulfilled,
+ ValueNode* on_rejected,
+ bool needs_then_protector);
+
+ // Reduces a TypedArray construct (not call — calling a TypedArray
+ // constructor without new throws) to Builtin::kCreateTypedArray.
+ MaybeReduceResult TryReduceTypedArrayConstructor(
+ ValueNode* context, compiler::JSFunctionRef target, ValueNode* new_target,
+ CallArguments& args);
+
// Returns kDoneWithoutPayload if checks passed successfully.
MaybeReduceResult TryReduceDatePrototypeGetFieldPrologue(
compiler::JSFunctionRef target, CallArguments& args);
@@ -1176,15 +1300,16 @@ class MaglevReducer {
compiler::JSFunctionRef target, CallArguments& args,
JSDate::FieldIndex field);
- MaybeReduceResult DoTryReduceMathRound(CallArguments& args,
+ MaybeReduceResult DoTryReduceMathRound(ValueNode* context,
+ CallArguments& args,
Float64Round::Kind kind);
template <typename Int32Binop, typename Float64Binop>
MaybeReduceResult TryReduceMathMinMax(CallArguments& args,
Int32Binop&& int32_case,
Float64Binop&& float64_case);
MaybeReduceResult TryReduceBuiltin(
- Builtin builtin_id, compiler::JSFunctionRef target, CallArguments& args,
- const compiler::FeedbackSource& feedback_source);
+ Builtin builtin_id, ValueNode* context, compiler::JSFunctionRef target,
+ CallArguments& args, const compiler::FeedbackSource& feedback_source);
template <typename LoadNode>
MaybeReduceResult TryBuildLoadDataView(const CallArguments& args,
@@ -1215,7 +1340,19 @@ class MaglevReducer {
ElementsKind kind);
MaybeReduceResult TryReduceStringLength(ValueNode* string);
-
+ MaybeReduceResult TryReduceConstantStringAt(ValueNode* receiver,
+ ValueNode* index,
+ StringAtOOBMode oob_mode);
+ MaybeReduceResult GetConstantSingleCharacterStringFromCode(uint16_t code);
+ ReduceResult BuildLoadStringLength(ValueNode* string);
+ ReduceResult BuildGetCharCodeAt(ValueNode* string, ValueNode* index);
+ MaybeReduceResult TryReduceStringPrototypeIndexOfIncludes(CallArguments& args,
+ bool is_includes);
+
+ MaybeReduceResult BuildSpeculativeCheckInstanceType(ValueNode* object,
+ NodeType target_type,
+ InstanceType first,
+ InstanceType last);
ReduceResult BuildCheckInstanceType(ValueNode* object, NodeType target_type,
InstanceType first, InstanceType last);
ReduceResult GetInt32ElementIndex(ValueNode* index_object);
@@ -1457,15 +1594,13 @@ class MaglevReducer {
template <Operation kOperation>
MaybeReduceResult TryFoldFloat64UnaryOperationForToNumber(
- TaggedToFloat64ConversionType conversion_type, ValueNode* value);
+ NodeType assumed_input_type, ValueNode* value);
template <Operation kOperation>
MaybeReduceResult TryFoldFloat64BinaryOperationForToNumber(
- TaggedToFloat64ConversionType conversion_type, ValueNode* left,
- ValueNode* right);
+ NodeType assumed_input_type, ValueNode* left, ValueNode* right);
template <Operation kOperation>
MaybeReduceResult TryFoldFloat64BinaryOperationForToNumber(
- TaggedToFloat64ConversionType conversion_type, ValueNode* left,
- double cst_right);
+ NodeType assumed_input_type, ValueNode* left, double cst_right);
MaybeReduceResult TryFoldFloat64Min(ValueNode* left, ValueNode* right);
MaybeReduceResult TryFoldFloat64Max(ValueNode* left, ValueNode* right);
@@ -1654,23 +1789,29 @@ class MaglevReducer {
AllocationType allocation_type, VirtualObject* value);
ReduceResult ConvertForField(ValueNode* value, const vobj::Field& desc,
AllocationType allocation_type);
- void BuildInitializeStore(vobj::Field desc, InlinedAllocation* alloc,
- AllocationType allocation_type, ValueNode* value,
- StoreTaggedMode store_mode,
- MaybeAssignedFlag maybe_assigned = kMaybeAssigned);
- void BuildInitializeStore_Tagged(vobj::Field desc, InlinedAllocation* alloc,
- AllocationType allocation_type,
- ValueNode* value, StoreTaggedMode store_mode,
- MaybeAssignedFlag maybe_assigned);
- void BuildInitializeStore_TrustedPointer(vobj::Field desc,
+ ReduceResult BuildInitializeStore(
+ vobj::Field desc, InlinedAllocation* alloc,
+ AllocationType allocation_type, ValueNode* value,
+ StoreTaggedMode store_mode,
+ MaybeAssignedFlag maybe_assigned = kMaybeAssigned);
+ ReduceResult BuildInitializeStore_Tagged(vobj::Field desc,
InlinedAllocation* alloc,
AllocationType allocation_type,
- ValueNode* value);
+ ValueNode* value,
+ StoreTaggedMode store_mode,
+ MaybeAssignedFlag maybe_assigned);
+ ReduceResult BuildInitializeStore_TrustedPointer(
+ vobj::Field desc, InlinedAllocation* alloc,
+ AllocationType allocation_type, ValueNode* value);
template <typename T>
friend class MapInference;
private:
+ template <UseRepresentation kUseRepr>
+ std::optional<Float64> TryGetFloatConstantImpl(ValueNode* value,
+ NodeType assumed_input_type);
+
template <typename NodeT, typename... Args>
ReduceResult EmitAbruptBlockEnd(std::initializer_list<ValueNode*> inputs,
Args&&... args);
@@ -1705,6 +1846,8 @@ class MaglevReducer {
bool period_added_throwing_node_ = false;
+ LazyDeoptFrameScope* current_lazy_deopt_scope_ = nullptr;
+ EagerDeoptFrameScope* current_eager_deopt_scope_ = nullptr;
compiler::FeedbackSource current_speculation_feedback_ = {};
SpeculationMode current_speculation_mode_ =
SpeculationMode::kDisallowSpeculation;
diff --git a/deps/v8/src/maglev/maglev-regalloc.cc b/deps/v8/src/maglev/maglev-regalloc.cc
index 636c74fd912..9bec10cd9fd 100644
--- a/deps/v8/src/maglev/maglev-regalloc.cc
+++ b/deps/v8/src/maglev/maglev-regalloc.cc
@@ -482,7 +482,7 @@ void StraightForwardRegisterAllocator::AllocateRegisters() {
} else if (control->Is<Return>()) {
printing_visitor_->os() << " " << control->id() << ".";
break;
- } else if (control->Is<Deopt>() || control->Is<Abort>()) {
+ } else if (control->Is<TerminalControlNode>()) {
printing_visitor_->os() << " " << control->id() << "✖️";
break;
}
@@ -2293,8 +2293,9 @@ void StraightForwardRegisterAllocator::HoistLoopSpills(BasicBlock* target) {
void StraightForwardRegisterAllocator::InitializeBranchTargetRegisterValues(
ControlNode* source, BasicBlock* target) {
- MergePointRegisterState& target_state = target->state()->register_state();
- DCHECK(!target_state.is_initialized());
+ DCHECK(!target->state()->has_register_state());
+ MergePointRegisterState* target_state =
+ compilation_info_->zone()->New<MergePointRegisterState>();
auto init = [&](auto& registers, auto reg, RegisterState& state) {
ValueNode* node = nullptr;
DCHECK(registers.blocked().is_empty());
@@ -2307,7 +2308,8 @@ void StraightForwardRegisterAllocator::InitializeBranchTargetRegisterValues(
HoistLoopReloads(target, general_registers_);
HoistLoopReloads(target, double_registers_);
HoistLoopSpills(target);
- ForEachMergePointRegisterState(target_state, init);
+ ForEachMergePointRegisterState(*target_state, init);
+ target->state()->set_register_state(target_state);
}
void StraightForwardRegisterAllocator::InitializeEmptyBlockRegisterValues(
@@ -2316,7 +2318,6 @@ void StraightForwardRegisterAllocator::InitializeEmptyBlockRegisterValues(
MergePointRegisterState* register_state =
compilation_info_->zone()->New<MergePointRegisterState>();
- DCHECK(!register_state->is_initialized());
auto init = [&](auto& registers, auto reg, RegisterState& state) {
ValueNode* node = nullptr;
DCHECK(registers.blocked().is_empty());
@@ -2338,11 +2339,11 @@ void StraightForwardRegisterAllocator::MergeRegisterValues(ControlNode* control,
return InitializeEmptyBlockRegisterValues(control, target);
}
- MergePointRegisterState& target_state = target->state()->register_state();
- if (!target_state.is_initialized()) {
+ if (!target->state()->has_register_state()) {
// This is the first block we're merging, initialize the values.
return InitializeBranchTargetRegisterValues(control, target);
}
+ MergePointRegisterState& target_state = target->state()->register_state();
if (v8_flags.trace_maglev_regalloc) {
printing_visitor_->os() << "Merging registers...\n";
diff --git a/deps/v8/src/maglev/maglev-truncation.h b/deps/v8/src/maglev/maglev-truncation.h
index b72601b84e8..ff7c82b2b6c 100644
--- a/deps/v8/src/maglev/maglev-truncation.h
+++ b/deps/v8/src/maglev/maglev-truncation.h
@@ -5,9 +5,12 @@
#ifndef V8_MAGLEV_MAGLEV_TRUNCATION_H_
#define V8_MAGLEV_MAGLEV_TRUNCATION_H_
+#include <algorithm>
+#include <cmath>
#include <type_traits>
#include "src/base/logging.h"
+#include "src/base/small-vector.h"
#include "src/common/scoped-modification.h"
#include "src/flags/flags.h"
#include "src/maglev/maglev-basic-block.h"
@@ -29,6 +32,73 @@ namespace maglev {
template <typename T>
concept IsValueNodeT = std::is_base_of_v<ValueNode, T>;
+// Truncating an operation to Int32 replaces a rounded Number result by an
+// exact wrapping one, so it is only value equivalent while every intermediate
+// it is computed from stays exactly representable as a double. One past
+// Number.MAX_SAFE_INTEGER: 2^53 is still exactly representable.
+constexpr int64_t kMaxExactlyRepresentableValue =
+ static_cast<int64_t>(kMaxSafeIntegerUint64) + 1;
+constexpr int64_t kMaxSaturatedValue = kMaxExactlyRepresentableValue + 1;
+
+inline Range RefinedInputRange(ValueNode* node) {
+ node = node->UnwrapIdentities();
+ Range refined = Range::All();
+ switch (node->opcode()) {
+ case Opcode::kInt32BitwiseAnd:
+ for (int i = 0; i < 2; ++i) {
+ if (auto mask = node->TryGetInt32ConstantInput(i); mask && *mask >= 0) {
+ refined = Range(0, *mask);
+ break;
+ }
+ }
+ break;
+ case Opcode::kInt32ShiftRight:
+ if (auto shift = node->TryGetInt32ConstantInput(1)) {
+ int32_t s = *shift & 0x1f;
+ refined = Range(int64_t{INT32_MIN} >> s, int64_t{INT32_MAX} >> s);
+ }
+ break;
+ case Opcode::kInt32ShiftRightLogical:
+ if (auto shift = node->TryGetInt32ConstantInput(1)) {
+ int32_t s = *shift & 0x1f;
+ refined = Range(0, int64_t{UINT32_MAX} >> s);
+ }
+ break;
+ default:
+ break;
+ }
+ return Range::Intersect(refined, node->GetStaticRange());
+}
+
+inline int64_t GetMaxExactValueOfRange(Range range) {
+ if (range.is_empty()) return kMaxSaturatedValue;
+ std::optional<int64_t> min = range.min();
+ std::optional<int64_t> max = range.max();
+ if (!min.has_value() || !max.has_value()) {
+ return kMaxSaturatedValue;
+ }
+ if (*min < -kMaxExactlyRepresentableValue ||
+ *max > kMaxExactlyRepresentableValue) {
+ return kMaxSaturatedValue;
+ }
+ return std::max(-*min, *max);
+}
+
+constexpr bool IsAdditiveOperation(Opcode opcode) {
+ switch (opcode) {
+ case Opcode::kFloat64Add:
+ case Opcode::kFloat64Subtract:
+ case Opcode::kFloat64SpeculateSafeAdd:
+ case Opcode::kInt32Add:
+ case Opcode::kInt32Subtract:
+ case Opcode::kInt32AddWithOverflow:
+ case Opcode::kInt32SubtractWithOverflow:
+ return true;
+ default:
+ return false;
+ }
+}
+
// This pass propagates updates for the `CanTruncateToInt32` flag.
// At the end of the pass, if a node has `CanTruncateToInt32` then all its uses
// can handle the node's output being truncated to an int32. IMPORTANT: This is
@@ -36,6 +106,9 @@ concept IsValueNodeT = std::is_base_of_v<ValueNode, T>;
// occur if all of the node's inputs can be truncated.
class PropagateTruncationProcessor {
public:
+ explicit PropagateTruncationProcessor(Graph* graph)
+ : max_exact_value_(graph->zone()) {}
+
void PreProcessGraph(Graph* graph) {}
BlockProcessResult PostProcessBasicBlock(BasicBlock* block) {
return BlockProcessResult::kContinue;
@@ -66,38 +139,38 @@ class PropagateTruncationProcessor {
return ProcessResult::kContinue;
}
- // Int32-representation inputs hold integral values, so wrapping composes
- // exactly through int32 add/subtract: a truncatable result makes the
- // inputs truncatable too. This includes the WithOverflow variants, since
- // TruncationProcessor overwrites truncatable ones with the plain
- // operation.
- if constexpr (std::is_same_v<NodeT, Int32Add> ||
- std::is_same_v<NodeT, Int32Subtract> ||
- std::is_same_v<NodeT, Int32AddWithOverflow> ||
- std::is_same_v<NodeT, Int32SubtractWithOverflow>) {
+ // An addition composes linearly with its operands, so a truncatable result
+ // makes them truncatable too, as long as the value it stands for stays
+ // exactly representable. This covers the Int32 forms as well, including the
+ // WithOverflow variants, since TruncationProcessor overwrites truncatable
+ // ones with the plain operation.
+ if constexpr (IsAdditiveOperation(Node::opcode_of<NodeT>)) {
if (node->can_truncate_to_int32()) {
+ if (GetMaxExactValue(node) > kMaxExactlyRepresentableValue) {
+ node->set_can_truncate_to_int32(false);
+ UnsetCanTruncateToInt32Inputs(node);
+ return ProcessResult::kContinue;
+ }
+ CheckOperandsFit(node);
+ // Otherwise don't unset truncation...
return ProcessResult::kContinue;
}
+ UnsetCanTruncateToInt32Inputs(node);
+ return ProcessResult::kContinue;
}
// TODO(marja): We can add a limited version of that, to support cases where
// one of the operands is a constant and thus we can be sure the result
// stays in the safe range.
- // If the output is not a Float64, then it cannot (or doesn't need)
- // to be truncated. Just propagate that all inputs should not be
- // truncated.
- if constexpr (NodeT::kProperties.value_representation() !=
- ValueRepresentation::kFloat64) {
- UnsetCanTruncateToInt32Inputs(node);
- return ProcessResult::kContinue;
- }
- // If the output node is a Float64 and cannot be truncated, then
- // its inputs cannot be truncated.
+ UnsetCanTruncateToInt32Inputs(node);
+ return ProcessResult::kContinue;
+ }
+
+ ProcessResult Process(ChangeInt32ToFloat64* node) {
if (!node->can_truncate_to_int32()) {
UnsetCanTruncateToInt32Inputs(node);
}
- // Otherwise don't unset truncation...
return ProcessResult::kContinue;
}
@@ -152,6 +225,121 @@ class PropagateTruncationProcessor {
void PostProcessGraph(Graph* graph) {}
private:
+ // Memoised GetMaxExactValue of every node it has been asked about.
+ ZoneAbslFlatHashMap<ValueNode*, int64_t> max_exact_value_;
+
+ static ValueNode* UnwrapForTruncation(ValueNode* node) {
+ node = node->UnwrapIdentities();
+ if (node->Is<ChangeInt32ToFloat64>()) {
+ return node->input_node(0)->UnwrapIdentities();
+ }
+ return node;
+ }
+
+ static bool IsTruncatableAdditiveOperation(ValueNode* node) {
+ return node->can_truncate_to_int32() && IsAdditiveOperation(node->opcode());
+ }
+
+ // Largest absolute value an input can hold, as an operand of `user_opcode`.
+ static int64_t GetMaxExactInputValue(Opcode user_opcode, ValueNode* node) {
+ node = UnwrapForTruncation(node);
+ if (auto constant = node->TryCast<Float64Constant>()) {
+ double value = std::abs(constant->value().get_scalar());
+ if (!(value <= static_cast<double>(kMaxExactlyRepresentableValue))) {
+ return kMaxSaturatedValue;
+ }
+ return static_cast<int64_t>(std::ceil(value));
+ }
+ // A multiply this pass truncates keeps only the low 32 bits of a product
+ // that its own safe integer check bounds by 2^53, so charge the product.
+ if ((node->opcode() == Opcode::kInt32MultiplyWithOverflow ||
+ node->opcode() == Opcode::kFloat64Multiply) &&
+ node->can_truncate_to_int32()) {
+ return GetMaxExactValueOfRange(
+ Range::Mul(RefinedInputRange(node->input_node(0)),
+ RefinedInputRange(node->input_node(1))));
+ }
+ if (node->is_int32() || node->is_uint32()) {
+ return int64_t{kMaxUInt32};
+ }
+ // An operand the pass leaves untruncated has nothing truncated below it
+ // either, since refusing a node also refuses everything it is computed
+ // from, so its static range still describes the value it holds.
+ int64_t max_abs_value = GetMaxExactValueOfRange(node->GetStaticRange());
+ if (user_opcode == Opcode::kFloat64SpeculateSafeAdd) {
+ // Speculative truncation reaches a Float64 operand through a conversion
+ // that range checks it against the additive safe integer feedback range,
+ // so that check bounds it too.
+ max_abs_value = std::min(max_abs_value, -kMinAdditiveSafeIntegerFeedback);
+ }
+ return max_abs_value;
+ }
+
+ // Largest absolute value this node can reach before truncation wraps it.
+ // Addition composes linearly, so looking through every truncatable
+ // addition down to the operands they are built from, and summing those,
+ // bounds the whole subgraph and with it every intermediate the pass never
+ // checks.
+ int64_t GetMaxExactValue(ValueNode* root) {
+ // Anything above the largest exactly representable value is
+ // indistinguishable for our purposes, so saturate there rather than risk
+ // overflowing the sum.
+ auto add_saturated = [](int64_t a, int64_t b) {
+ if (a > kMaxExactlyRepresentableValue - b) {
+ return kMaxSaturatedValue;
+ }
+ return a + b;
+ };
+ // The additions walked here are acyclic: a value cycle passes through a
+ // Phi, and a Phi is not an additive operation, so it ends the walk as an
+ // operand.
+ base::SmallVector<ValueNode*, 16> stack{root};
+ while (!stack.empty()) {
+ ValueNode* node = stack.back();
+ if (max_exact_value_.contains(node)) {
+ stack.pop_back();
+ continue;
+ }
+ // Resolve first: queue up every operand still missing a bound, and come
+ // back to this node once they all have one.
+ bool has_pending_input = false;
+ for (int i = 0; i < node->input_count(); i++) {
+ ValueNode* input = UnwrapForTruncation(node->input_node(i));
+ if (IsTruncatableAdditiveOperation(input) &&
+ !max_exact_value_.contains(input)) {
+ stack.push_back(input);
+ has_pending_input = true;
+ }
+ }
+ if (has_pending_input) continue;
+ // Every operand is bounded now, so this node's bound is their sum.
+ int64_t max_abs_value = 0;
+ for (int i = 0; i < node->input_count(); i++) {
+ ValueNode* input = UnwrapForTruncation(node->input_node(i));
+ max_abs_value = add_saturated(
+ max_abs_value, IsTruncatableAdditiveOperation(input)
+ ? max_exact_value_.at(input)
+ : GetMaxExactInputValue(node->opcode(), input));
+ }
+ stack.pop_back();
+ max_exact_value_.emplace(node, max_abs_value);
+ }
+ return max_exact_value_.at(root);
+ }
+
+ // Accepting a node commits to accepting every truncatable addition below it,
+ // since refusing one later would strand the rest already truncated. Only
+ // reads the memo, which GetMaxExactValue has just filled in for them all.
+ void CheckOperandsFit(ValueNode* node) {
+#ifdef DEBUG
+ for (int i = 0; i < node->input_count(); i++) {
+ ValueNode* input = UnwrapForTruncation(node->input_node(i));
+ if (!IsTruncatableAdditiveOperation(input)) continue;
+ DCHECK_LE(max_exact_value_.at(input), kMaxExactlyRepresentableValue);
+ }
+#endif // DEBUG
+ }
+
template <typename NodeT, int I>
void UnsetCanTruncateToInt32ForFixedInputNodes(NodeT* node) {
if constexpr (I < static_cast<int>(NodeT::kInputCount)) {
@@ -406,40 +594,6 @@ class TruncationProcessor {
// reason about ranges.
}
- // Refined int32 bound of a value from its defining bit operation, intersected
- // with the value's static range; falls back to the static range alone when
- // the defining operation tells us nothing better.
- static Range RefinedInputRange(ValueNode* node) {
- node = node->UnwrapIdentities();
- Range refined = Range::All();
- switch (node->opcode()) {
- case Opcode::kInt32BitwiseAnd:
- for (int i = 0; i < 2; ++i) {
- if (auto mask = node->TryGetInt32ConstantInput(i);
- mask && *mask >= 0) {
- refined = Range(0, *mask);
- break;
- }
- }
- break;
- case Opcode::kInt32ShiftRight:
- if (auto shift = node->TryGetInt32ConstantInput(1)) {
- int32_t s = *shift & 0x1f;
- refined = Range(int64_t{INT32_MIN} >> s, int64_t{INT32_MAX} >> s);
- }
- break;
- case Opcode::kInt32ShiftRightLogical:
- if (auto shift = node->TryGetInt32ConstantInput(1)) {
- int32_t s = *shift & 0x1f;
- refined = Range(0, int64_t{UINT32_MAX} >> s);
- }
- break;
- default:
- break;
- }
- return Range::Intersect(refined, node->GetStaticRange());
- }
-
// The product provably fits the safe-integer range, so the wrapping Int32
// multiply matches Number multiplication followed by ToInt32 (which is how a
// truncatable result is consumed, also erasing the minus-zero distinction).
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 130910c4dea..a14e55d0bdc 100644
--- a/deps/v8/src/maglev/ppc/maglev-assembler-ppc-inl.h
+++ b/deps/v8/src/maglev/ppc/maglev-assembler-ppc-inl.h
@@ -228,8 +228,9 @@ inline Condition MaglevAssembler::TrySmiTagInt32(Register dst, Register src) {
inline void MaglevAssembler::CheckInt32IsSmi(Register obj, Label* fail,
Register scratch) {
DCHECK(!SmiValuesAre32Bits());
+ TemporaryRegisterScope temps(this);
if (scratch == Register::no_reg()) {
- scratch = r0;
+ scratch = temps.AcquireScratch();
}
Condition cond = TrySmiTagInt32(scratch, obj);
JumpIf(NegateCondition(cond), fail);
@@ -358,6 +359,14 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, element_address, element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MemOperand element_address = MemOperand(data_pointer, index);
+ LoadUnsignedField(result, element_address, element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
@@ -383,7 +392,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -400,7 +411,9 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
void MaglevAssembler::LoadFixedArrayElementWithoutDecompressing(
Register result, Register array, Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -543,6 +556,19 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ if (size == 2) {
+ ByteReverseU16(value, value);
+ ZeroExtend<uint16_t>(value, value);
+ } else if (size == 4) {
+ ByteReverseU32(value, value);
+ ZeroExtend<uint32_t>(value, value);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline void MaglevAssembler::IncrementInt32(Register reg) {
AddS32(reg, reg, Operand(1));
}
@@ -747,6 +773,39 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
MacroAssembler::StoreF64(src, dst);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ LoadFloat32(dst, MemOperand(base, index));
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ TemporaryRegisterScope scope(this);
+ Register scratch = scope.AcquireScratch();
+ LoadU32(scratch, MemOperand(base, index));
+ ByteReverseU32(scratch, scratch);
+ subi(sp, sp, Operand(kSystemPointerSize));
+ StoreU32(scratch, MemOperand(sp));
+ LoadFloat32(dst, MemOperand(sp));
+ addi(sp, sp, Operand(kSystemPointerSize));
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ StoreFloat32(MemOperand(base, index), src);
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ TemporaryRegisterScope scope(this);
+ Register scratch = scope.AcquireScratch();
+ subi(sp, sp, Operand(kSystemPointerSize));
+ StoreFloat32(MemOperand(sp), src);
+ LoadU32(scratch, MemOperand(sp));
+ addi(sp, sp, Operand(kSystemPointerSize));
+ ByteReverseU32(scratch, scratch);
+ StoreU32(scratch, MemOperand(base, index));
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -1519,7 +1578,7 @@ inline Condition MaglevAssembler::FunctionEntryStackCheck(
LoadStackLimit(interrupt_stack_limit, StackLimitKind::kInterruptStackLimit);
Register stack_cmp_reg = sp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = r0;
AddS64(stack_cmp_reg, sp, Operand(-stack_check_offset));
}
@@ -1582,6 +1641,8 @@ inline void MaglevAssembler::MaybeEmitPlaceHolderForDeopt() {
// Implemented only for x64.
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) { sync(); }
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/ppc/maglev-ir-ppc.cc b/deps/v8/src/maglev/ppc/maglev-ir-ppc.cc
index 1909e116ab3..6c9f0d9d437 100644
--- a/deps/v8/src/maglev/ppc/maglev-ir-ppc.cc
+++ b/deps/v8/src/maglev/ppc/maglev-ir-ppc.cc
@@ -93,14 +93,16 @@ void Int32IncrementWithOverflow::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register value = ToRegister(ValueInput());
Register out = ToRegister(result());
- __ li(r0, Operand(1));
- __ add(out, value, r0, SetOE);
- __ MoveToCrFromXer(cr0);
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ Register scratch = temps.AcquireScratch();
+ __ li(scratch, Operand(1));
+ __ add(out, value, scratch, SetOE);
+ __ MoveToCrFromXer(cr0);
- // Output register must not be a register input into the eager deopt info.
- DCHECK_REGLIST_EMPTY(RegList{out} &
- GetGeneralRegistersUsedAsInputs(eager_deopt_info()));
- __ EmitEagerDeoptIf(overflow32, DeoptimizeReason::kOverflow, this);
+ // Output register must not be a register input into the eager deopt info.
+ DCHECK_REGLIST_EMPTY(RegList{out} &
+ GetGeneralRegistersUsedAsInputs(eager_deopt_info()));
+ __ EmitEagerDeoptIf(overflow32, DeoptimizeReason::kOverflow, this);
__ extsw(out, out);
}
@@ -114,14 +116,16 @@ void Int32DecrementWithOverflow::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register value = ToRegister(ValueInput());
Register out = ToRegister(result());
- __ li(r0, Operand(-1));
- __ add(out, value, r0, SetOE);
- __ MoveToCrFromXer(cr0);
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ Register scratch = temps.AcquireScratch();
+ __ li(scratch, Operand(-1));
+ __ add(out, value, scratch, SetOE);
+ __ MoveToCrFromXer(cr0);
- // Output register must not be a register input into the eager deopt info.
- DCHECK_REGLIST_EMPTY(RegList{out} &
- GetGeneralRegistersUsedAsInputs(eager_deopt_info()));
- __ EmitEagerDeoptIf(overflow32, DeoptimizeReason::kOverflow, this);
+ // Output register must not be a register input into the eager deopt info.
+ DCHECK_REGLIST_EMPTY(RegList{out} &
+ GetGeneralRegistersUsedAsInputs(eager_deopt_info()));
+ __ EmitEagerDeoptIf(overflow32, DeoptimizeReason::kOverflow, this);
__ extsw(out, out);
}
@@ -501,8 +505,10 @@ void Int32DivideWithOverflow::GenerateCode(MaglevAssembler* masm,
__ EmitEagerDeoptIf(overflow, DeoptimizeReason::kNotInt32, this);
// Check that the remainder is zero.
- __ mullw(r0, out, right);
- __ sub(r0, left, r0, LeaveOE, SetRC);
+ MaglevAssembler::TemporaryRegisterScope temps(masm);
+ Register scratch = temps.AcquireScratch();
+ __ mullw(scratch, out, right);
+ __ sub(scratch, left, scratch, LeaveOE, SetRC);
__ EmitEagerDeoptIf(ne, DeoptimizeReason::kNotInt32, this);
__ extsw(out, out);
@@ -587,8 +593,9 @@ void Int32ModulusWithOverflow::GenerateCode(MaglevAssembler* masm,
Label rhs_not_power_of_2;
MaglevAssembler::TemporaryRegisterScope temps(masm);
Register mask = temps.AcquireScratch();
+ Register scratch = temps.AcquireScratch();
__ addi(mask, rhs, Operand(-1));
- __ and_(r0, mask, rhs, SetRC);
+ __ and_(scratch, mask, rhs, SetRC);
__ JumpIf(ne, &rhs_not_power_of_2);
// {rhs} is power of 2.
@@ -968,18 +975,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
__ CanonicalizeNaN(value, value);
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- // The hole value is a signalling NaN, so just silence it to get the
- // float64 value.
- __ CanonicalizeNaN(ToDoubleRegister(this->result()),
- ToDoubleRegister(ValueInput()));
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -999,25 +994,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
- set_temporaries_needed(1);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
-
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch = temps.Acquire();
- __ JumpIfNotHoleNan(value, scratch, &done);
- __ Move(value, UndefinedNan());
- __ bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1030,49 +1006,28 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- {
- Register stack_limit = scratch0;
- __ LoadStackLimit(stack_limit, StackLimitKind::kInterruptStackLimit);
- __ CmpU64(sp, stack_limit);
- __ bgt(&next);
- }
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- Register function = scratch0;
- __ LoadU64(function,
- MemOperand(fp, StandardFrameConstants::kFunctionOffset));
- __ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ b(*done); // All done, continue.
- __ bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
Register function = scratch0;
__ LoadU64(function,
MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
+ __ Push(Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
+ Register function = scratch0;
+ __ LoadU64(function,
+ MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ Push(function);
__ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
@@ -1101,14 +1056,17 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
+ set_temporaries_needed(try_osr() ? 3 : 1);
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
diff --git a/deps/v8/src/maglev/riscv/maglev-assembler-riscv-inl.h b/deps/v8/src/maglev/riscv/maglev-assembler-riscv-inl.h
index c81ca0214dd..cc6e4499c23 100644
--- a/deps/v8/src/maglev/riscv/maglev-assembler-riscv-inl.h
+++ b/deps/v8/src/maglev/riscv/maglev-assembler-riscv-inl.h
@@ -347,12 +347,15 @@ inline Condition MaglevAssembler::TrySmiTagInt32(Register dst, Register src) {
CHECK(!SmiValuesAre32Bits());
// NB: JumpIf expects the result in dedicated "flag" register.
Register overflow_flag = MaglevAssembler::GetFlagsRegister();
- // Smi is shifted left by 1, so double incoming integer using 64- and 32-bit
- // addition operations and then compare the results to detect overflow. The
- // order matters because the dst and src registers may be the same.
- Add64(overflow_flag, src, src);
- Add32(dst, src, src);
- Sne(overflow_flag, overflow_flag, Operand(dst));
+ // Smi is shifted left by 1.
+ if (src == dst) {
+ Move(overflow_flag, src);
+ src = overflow_flag;
+ }
+ // overflow_flag = (bits[31] ^ bits[30]) >> 31
+ Sll32(dst, src, 1);
+ Xor(overflow_flag, src, dst);
+ Srl32(overflow_flag, overflow_flag, 31);
return kNoOverflow;
}
@@ -364,12 +367,12 @@ inline void MaglevAssembler::CheckInt32IsSmi(Register maybe_smi, Label* fail,
if (scratch == Register::no_reg()) {
scratch = temps.AcquireScratch();
}
- Register sum32 = scratch;
- Register sum64 = temps.AcquireScratch();
- Add32(sum32, maybe_smi, Operand(maybe_smi));
- Add64(sum64, maybe_smi, Operand(maybe_smi));
- // Overflow happened if sum64 != sum32.
- MacroAssembler::Branch(fail, ne, sum64, Operand(sum32));
+ Register bit31 = scratch;
+ Register bit30 = temps.AcquireScratch();
+ Srl32(bit30, maybe_smi, 30);
+ Srl32(bit31, maybe_smi, 31);
+ And(bit30, bit30, Operand(1));
+ MacroAssembler::Branch(fail, ne, bit30, Operand(bit31));
}
inline void MaglevAssembler::SmiAddConstant(Register dst, Register src,
@@ -512,10 +515,13 @@ inline void MaglevAssembler::BuildTypedArrayDataPointer(Register data_pointer,
inline MemOperand MaglevAssembler::TypedArrayElementOperand(
Register data_pointer, Register index, int element_size) {
const int shift = ShiftFromScale(element_size);
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ ZeroExtendWord(scratch, index);
if (shift == 0) {
- AddWord(data_pointer, data_pointer, index);
+ AddWord(data_pointer, data_pointer, scratch);
} else {
- CalcScaledAddress(data_pointer, data_pointer, index, shift);
+ CalcScaledAddress(data_pointer, data_pointer, scratch, shift);
}
return MemOperand(data_pointer);
}
@@ -540,15 +546,28 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, MemOperand(addr), element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register addr = temps.AcquireScratch();
+ AddWord(addr, data_pointer, index);
+ LoadUnsignedField(result, MemOperand(addr), element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
int offset) {
const int shift = ShiftFromScale(scale);
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ ZeroExtendWord(scratch, index);
if (shift == 0) {
- AddWord(result, object, index);
+ AddWord(result, object, scratch);
} else {
- CalcScaledAddress(result, object, index, shift);
+ CalcScaledAddress(result, object, scratch, shift);
}
LoadTaggedField(result, FieldMemOperand(result, offset));
}
@@ -574,7 +593,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -591,11 +612,16 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
void MaglevAssembler::LoadFixedArrayElementWithoutDecompressing(
Register result, Register array, Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
- CalcScaledAddress(result, array, index, kTaggedSizeLog2);
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(result, array, scratch, kTaggedSizeLog2);
MacroAssembler::LoadTaggedFieldWithoutDecompressing(
result, FieldMemOperand(result, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -611,7 +637,8 @@ void MaglevAssembler::LoadFixedDoubleArrayElement(DoubleRegister result,
}
MaglevAssembler::TemporaryRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
- CalcScaledAddress(scratch, array, index, kDoubleSizeLog2);
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(scratch, array, scratch, kDoubleSizeLog2);
LoadDouble(result,
FieldMemOperand(scratch, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -620,7 +647,8 @@ inline void MaglevAssembler::StoreFixedDoubleArrayElement(
Register array, Register index, DoubleRegister value) {
MaglevAssembler::TemporaryRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
- CalcScaledAddress(scratch, array, index, kDoubleSizeLog2);
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(scratch, array, scratch, kDoubleSizeLog2);
StoreDouble(value,
FieldMemOperand(scratch, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -645,7 +673,7 @@ inline void MaglevAssembler::LoadUnsignedField(Register result,
Lhu(result, operand);
} else {
DCHECK_EQ(size, 4);
- Lwu(result, operand);
+ Lw(result, operand);
}
}
@@ -657,8 +685,11 @@ inline void MaglevAssembler::SetSlotAddressForTaggedField(Register slot_reg,
inline void MaglevAssembler::SetSlotAddressForFixedArrayElement(
Register slot_reg, Register object, Register index) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
Add64(slot_reg, object, OFFSET_OF_DATA_START(FixedArray) - kHeapObjectTag);
- CalcScaledAddress(slot_reg, slot_reg, index, kTaggedSizeLog2);
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(slot_reg, slot_reg, scratch, kTaggedSizeLog2);
}
inline void MaglevAssembler::StoreTaggedFieldNoWriteBarrier(Register object,
@@ -671,7 +702,8 @@ inline void MaglevAssembler::StoreFixedArrayElementNoWriteBarrier(
Register array, Register index, Register value) {
MaglevAssembler::TemporaryRegisterScope temps(this);
Register scratch = temps.AcquireScratch();
- CalcScaledAddress(scratch, array, index, kTaggedSizeLog2);
+ ZeroExtendWord(scratch, index);
+ CalcScaledAddress(scratch, array, scratch, kTaggedSizeLog2);
MacroAssembler::StoreTaggedField(
value, FieldMemOperand(scratch, OFFSET_OF_DATA_START(FixedArray)));
}
@@ -736,6 +768,20 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ if (size == 2) {
+ ByteSwap(value, value, 4, scratch);
+ srli(value, value, 16);
+ } else if (size == 4) {
+ ByteSwap(value, value, 4, scratch);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline void MaglevAssembler::IncrementInt32(Register reg) {
Add32(reg, reg, Operand(1));
}
@@ -757,19 +803,14 @@ inline void MaglevAssembler::AddInt32(Register dst, Register src, int amount) {
}
inline void MaglevAssembler::AndInt32(Register dst, Register src, int mask) {
- Add32(dst, src, Operand(mask));
+ And(dst, src, Operand(mask));
}
inline void MaglevAssembler::AndInt32(Register reg, int mask) {
- // check if size of immediate exceeds 32 bits
- if constexpr (sizeof(intptr_t) > sizeof(mask)) {
- // set the upper bits of the immediate and so make sure that AND operation
- // won't touch the upper part of target register
- static constexpr intptr_t lsb_mask = 0xFFFFFFFF;
- And(reg, reg, Operand(~lsb_mask | mask));
- } else {
- And(reg, reg, Operand(mask));
- }
+ // Operand(mask) sign-extends the mask, so that ANDing a canonical
+ // (sign-extended) Word32 register with it yields a canonical result:
+ // the upper 32 bits of the result are always a copy of its bit 31.
+ And(reg, reg, Operand(mask));
}
inline void MaglevAssembler::OrInt32(Register reg, int mask) {
@@ -898,7 +939,7 @@ void MaglevAssembler::MoveTagged(Register dst, Handle<HeapObject> obj) {
}
inline void MaglevAssembler::LoadInt32(Register dst, MemOperand src) {
- Load32U(dst, src);
+ Lw(dst, src);
}
inline void MaglevAssembler::StoreInt32(MemOperand dst, Register src) {
Sw(src, dst);
@@ -923,6 +964,46 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
StoreDouble(src, dst);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register address = temps.AcquireScratch();
+ Add64(address, base, index);
+ LoadFloat32(dst, MemOperand(address));
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register address = temps.AcquireScratch();
+ Register scratch = temps.AcquireScratch();
+ Add64(address, base, index);
+ LoadWord(scratch, MemOperand(address));
+ ByteSwap(scratch, scratch, 4, address);
+ fmv_w_x(dst, scratch);
+ fcvt_d_s(dst, dst);
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register address = temps.AcquireScratch();
+ Add64(address, base, index);
+ StoreFloat32(MemOperand(address), src);
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ MaglevAssembler::TemporaryRegisterScope temps(this);
+ Register scratch = temps.AcquireScratch();
+ DoubleRegister scratch_double = temps.AcquireScratchDouble();
+ Register address = temps.AcquireScratch();
+ fcvt_s_d(scratch_double, src);
+ MacroAssembler::Move(scratch, scratch_double);
+ ByteSwap(scratch, scratch, 4, address);
+ Add64(address, base, index);
+ Sw(scratch, MemOperand(address));
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -935,8 +1016,8 @@ inline void MaglevAssembler::LoadUnalignedFloat64AndReverseByteOrder(
DoubleRegister dst, Register base, Register index) {
MaglevAssembler::TemporaryRegisterScope temps(this);
Register address = temps.AcquireScratch();
+ Register scratch = temps.AcquireScratch();
Add64(address, base, index);
- Register scratch = base; // reuse base as scratch register
LoadWord(scratch, MemOperand(address));
ByteSwap(scratch, scratch, 8, address);
MacroAssembler::Move(dst, scratch);
@@ -1670,8 +1751,6 @@ inline void MaglevAssembler::CompareIntPtrAndBranch(
UNREACHABLE(); // not expected
}
- MaglevAssembler::TemporaryRegisterScope temps(this);
- Register lhs = temps.AcquireScratch();
if (fallthrough_when_false) {
if (fallthrough_when_true) {
// If both paths are a fallthrough, do nothing.
@@ -1679,10 +1758,10 @@ inline void MaglevAssembler::CompareIntPtrAndBranch(
return;
}
// Jump over the false block if true, otherwise fall through into it.
- MacroAssembler::Branch(if_true, cond, lhs, Operand(value), true_distance);
+ MacroAssembler::Branch(if_true, cond, r1, Operand(value), true_distance);
} else {
// Jump to the false block if true.
- MacroAssembler::Branch(if_false, NegateCondition(cond), lhs, Operand(value),
+ MacroAssembler::Branch(if_false, NegateCondition(cond), r1, Operand(value),
false_distance);
// Jump to the true block if it's not the next block.
if (!fallthrough_when_true) {
@@ -2033,7 +2112,7 @@ inline void MaglevAssembler::LoadContextCellState(Register state,
inline void MaglevAssembler::LoadContextCellInt32Value(Register value,
Register cell) {
AssertContextCellState(cell, ContextCell::kInt32);
- Lwu(value, FieldMemOperand(cell, offsetof(ContextCell, double_value_)));
+ Lw(value, FieldMemOperand(cell, offsetof(ContextCell, double_value_)));
}
inline void MaglevAssembler::LoadContextCellFloat64Value(DoubleRegister value,
Register cell) {
@@ -2090,7 +2169,7 @@ inline Condition MaglevAssembler::FunctionEntryStackCheck(
int stack_check_offset) {
MaglevAssembler::TemporaryRegisterScope temps(this);
Register stack_cmp_reg = sp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = temps.AcquireScratch();
Sub64(stack_cmp_reg, sp, stack_check_offset);
}
@@ -2156,6 +2235,8 @@ inline void MaglevAssembler::MaybeEmitPlaceHolderForDeopt() {
// Implemented only for x64.
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) { sync(); }
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc b/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc
index 67a3652cbf4..95a3717a0f8 100644
--- a/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc
+++ b/deps/v8/src/maglev/riscv/maglev-assembler-riscv.cc
@@ -584,7 +584,6 @@ void MaglevAssembler::TruncateDoubleToInt32(Register dst, DoubleRegister src) {
TryInlineTruncateDoubleToI(dst, src, *done);
Jump(slow_path);
bind(*done);
- ZeroExtendWord(dst, dst); // FIXME: is zero extension really needed here?
}
void MaglevAssembler::TryTruncateDoubleToInt32(Register dst, DoubleRegister src,
diff --git a/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc b/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc
index 5ecf8e0e9f0..85498270ad8 100644
--- a/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc
+++ b/deps/v8/src/maglev/riscv/maglev-ir-riscv.cc
@@ -145,7 +145,7 @@ void BuiltinStringFromCharCode::SetValueLocationConstraints() {
if (CharCodeInput().node()->Is<Int32Constant>()) {
UseAny(CharCodeInput());
} else {
- UseRegister(CharCodeInput());
+ UseAndClobberRegister(CharCodeInput());
}
set_temporaries_needed(2);
DefineAsRegister(this);
@@ -676,21 +676,29 @@ void Int32ModulusWithOverflow::GenerateCode(MaglevAssembler* masm,
__ bind(*done);
}
-#define DEF_BITWISE_BINOP(Instruction, opcode) \
- void Instruction::SetValueLocationConstraints() { \
- UseRegister(LeftInput()); \
- UseRegister(RightInput()); \
- DefineAsRegister(this); \
- } \
- \
- void Instruction::GenerateCode(MaglevAssembler* masm, \
- const ProcessingState& state) { \
- Register lhs = ToRegister(LeftInput()); \
- Register rhs = ToRegister(RightInput()); \
- Register out = ToRegister(result()); \
- __ opcode(out, lhs, Operand(rhs)); \
- /* TODO: is zero extension really needed here? */ \
- __ ZeroExtendWord(out, out); \
+#define DEF_BITWISE_BINOP(Instruction, opcode) \
+ void Instruction::SetValueLocationConstraints() { \
+ UseRegister(LeftInput()); \
+ if (TryGetInt12ConstantInput(this, kRightIndex)) { \
+ UseAny(RightInput()); \
+ } else { \
+ UseRegister(RightInput()); \
+ } \
+ DefineAsRegister(this); \
+ } \
+ \
+ void Instruction::GenerateCode(MaglevAssembler* masm, \
+ const ProcessingState& state) { \
+ Register left = ToRegister(LeftInput()); \
+ Register out = ToRegister(result()); \
+ if (!RightInput().operand().IsRegister()) { \
+ auto right_const = TryGetInt12ConstantInput(this, kRightIndex); \
+ DCHECK(right_const); \
+ __ opcode(out, left, Operand(*right_const)); \
+ } else { \
+ Register right = ToRegister(RightInput()); \
+ __ opcode(out, left, right); \
+ } \
}
DEF_BITWISE_BINOP(Int32BitwiseAnd, And)
DEF_BITWISE_BINOP(Int32BitwiseOr, Or)
@@ -715,10 +723,6 @@ DEF_BITWISE_BINOP(Int32BitwiseXor, Xor)
if (Int32Constant* constant = \
RightInput().node()->TryCast<Int32Constant>()) { \
uint32_t shift = constant->value() & 31; \
- if (shift == 0) { \
- __ ZeroExtendWord(out, lhs); \
- return; \
- } \
__ opcode(out, lhs, Operand(shift)); \
} else { \
Register rhs = ToRegister(RightInput()); \
@@ -740,7 +744,6 @@ void Int32BitwiseNot::GenerateCode(MaglevAssembler* masm,
Register value = ToRegister(ValueInput());
Register out = ToRegister(result());
__ not_(out, value);
- __ ZeroExtendWord(out, out); // TODO(Yuri Gaevsky): is it really needed?
}
void Float64Add::SetValueLocationConstraints() {
@@ -1040,19 +1043,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
ToDoubleRegister(ValueInput()));
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- // The hole value is a signalling NaN, so just silence it to get the
- // float64 value.
- __ FPUCanonicalizeNaN(ToDoubleRegister(this->result()),
- ToDoubleRegister(ValueInput()));
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -1074,25 +1064,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
- set_temporaries_needed(1);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
-
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch = temps.Acquire();
- __ JumpIfNotHoleNan(value, scratch, &done);
- __ Move(value, UndefinedNan());
- __ bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1105,49 +1076,28 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- {
- Register stack_limit = scratch0;
- __ LoadStackLimit(stack_limit, StackLimitKind::kInterruptStackLimit);
- __ MacroAssembler::Branch(&next, ugt, sp, Operand(stack_limit),
- Label::Distance::kNear);
- }
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- Register function = scratch0;
- __ LoadWord(function,
- MemOperand(fp, StandardFrameConstants::kFunctionOffset));
- __ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ MacroAssembler::Branch(*done); // All done, continue.
- __ bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
Register function = scratch0;
__ LoadWord(function,
MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
+ __ Push(Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
+ Register function = scratch0;
+ __ LoadWord(function,
+ MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ Push(function);
__ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
@@ -1183,15 +1133,17 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
- set_temporaries_needed(1);
+ set_temporaries_needed(try_osr() ? 3 : 1);
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
diff --git a/deps/v8/src/maglev/s390/maglev-assembler-s390-inl.h b/deps/v8/src/maglev/s390/maglev-assembler-s390-inl.h
index b2206169f3c..04cb566abfd 100644
--- a/deps/v8/src/maglev/s390/maglev-assembler-s390-inl.h
+++ b/deps/v8/src/maglev/s390/maglev-assembler-s390-inl.h
@@ -347,6 +347,14 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, element_address, element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MemOperand element_address = MemOperand(data_pointer, index);
+ LoadUnsignedField(result, element_address, element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
@@ -372,7 +380,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -391,7 +401,9 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
void MaglevAssembler::LoadFixedArrayElementWithoutDecompressing(
Register result, Register array, Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -537,6 +549,22 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ if (size == 2) {
+ lay(sp, MemOperand(sp, -kSystemPointerSize));
+ StoreU16(value, MemOperand(sp));
+ lrvh(value, MemOperand(sp));
+ LoadU16(value, value);
+ lay(sp, MemOperand(sp, kSystemPointerSize));
+ } else if (size == 4) {
+ lrvr(value, value);
+ LoadU32(value, value);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline void MaglevAssembler::IncrementInt32(Register reg) {
AddS32(reg, Operand(1));
}
@@ -737,6 +765,39 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
MacroAssembler::StoreF64(src, dst);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ LoadFloat32(dst, MemOperand(base, index));
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ TemporaryRegisterScope scope(this);
+ Register scratch = r0;
+ LoadU32(scratch, MemOperand(base, index));
+ lrvr(scratch, scratch);
+ lay(sp, MemOperand(sp, -kSystemPointerSize));
+ StoreU32(scratch, MemOperand(sp));
+ LoadFloat32(dst, MemOperand(sp));
+ lay(sp, MemOperand(sp, kSystemPointerSize));
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ StoreFloat32(MemOperand(base, index), src);
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ TemporaryRegisterScope scope(this);
+ Register scratch = r0;
+ lay(sp, MemOperand(sp, -kSystemPointerSize));
+ StoreFloat32(MemOperand(sp), src);
+ LoadU32(scratch, MemOperand(sp));
+ lay(sp, MemOperand(sp, kSystemPointerSize));
+ lrvr(scratch, scratch);
+ StoreU32(scratch, MemOperand(base, index));
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -1489,7 +1550,7 @@ inline Condition MaglevAssembler::FunctionEntryStackCheck(
LoadStackLimit(interrupt_stack_limit, StackLimitKind::kInterruptStackLimit);
Register stack_cmp_reg = sp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = r0;
AddS64(stack_cmp_reg, sp, Operand(-stack_check_offset));
}
@@ -1552,6 +1613,10 @@ inline void MaglevAssembler::MaybeEmitPlaceHolderForDeopt() {
// Implemented only for x64.
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) {
+ // S390 is TSO.
+}
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/s390/maglev-ir-s390.cc b/deps/v8/src/maglev/s390/maglev-ir-s390.cc
index 069795fe6cc..6e898604a41 100644
--- a/deps/v8/src/maglev/s390/maglev-ir-s390.cc
+++ b/deps/v8/src/maglev/s390/maglev-ir-s390.cc
@@ -941,19 +941,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
__ SubF64(value, value, kDoubleRegZero);
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- // The hole value is a signalling NaN, so just silence it to get the
- // float64 value.
- __ lzdr(kDoubleRegZero);
- __ SubF64(ToDoubleRegister(this->result()), ToDoubleRegister(ValueInput()),
- kDoubleRegZero);
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -974,25 +961,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
- set_temporaries_needed(1);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
-
- MaglevAssembler::TemporaryRegisterScope temps(masm);
- Register scratch = temps.Acquire();
- __ JumpIfNotHoleNan(value, scratch, &done);
- __ Move(value, UndefinedNan());
- __ bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1005,49 +973,28 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- {
- Register stack_limit = scratch0;
- __ LoadStackLimit(stack_limit, StackLimitKind::kInterruptStackLimit);
- __ CmpU64(sp, stack_limit);
- __ bgt(&next);
- }
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- Register function = scratch0;
- __ LoadU64(function,
- MemOperand(fp, StandardFrameConstants::kFunctionOffset));
- __ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
- __ Move(kContextRegister, masm->native_context().object());
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ b(*done); // All done, continue.
- __ bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
Register function = scratch0;
__ LoadU64(function,
MemOperand(fp, StandardFrameConstants::kFunctionOffset));
__ Push(function);
- // Move into kContextRegister after the load into scratch0, just in case
- // scratch0 happens to be kContextRegister.
+ __ Push(Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
+ __ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
+ Register function = scratch0;
+ __ LoadU64(function,
+ MemOperand(fp, StandardFrameConstants::kFunctionOffset));
+ __ Push(function);
__ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
@@ -1075,14 +1022,17 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
+ set_temporaries_needed(try_osr() ? 3 : 1);
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
diff --git a/deps/v8/src/maglev/turbolev-escape-analysis.cc b/deps/v8/src/maglev/turbolev-escape-analysis.cc
index 634212d4d78..5a32a92cc2e 100644
--- a/deps/v8/src/maglev/turbolev-escape-analysis.cc
+++ b/deps/v8/src/maglev/turbolev-escape-analysis.cc
@@ -34,7 +34,7 @@ ValueNode* EscapeAnalysisData::Get(InlinedAllocation* base, int offset) {
ObjectField addr = ObjectField{base, offset};
Key key = TryGetKeyFor(addr);
DCHECK(key.valid());
- return field_values.Get(key);
+ return GetFieldValue(key);
}
Key EscapeAnalysisData::GetOrCreateKey(InlinedAllocation* base, int offset) {
@@ -133,9 +133,9 @@ ValueNode* EscapeAnalysisData::ResolveLoadBase(ValueNode* base, int offset,
return fallback;
}
DCHECK(key.valid());
- ValueNode* val = predecessor_index == -1 ? field_values.Get(key)
- : field_values.GetPredecessorValue(
- key, predecessor_index);
+ ValueNode* val = predecessor_index == -1
+ ? GetFieldValue(key)
+ : GetPredecessorFieldValue(key, predecessor_index);
if (val == nullptr) {
// The key is valid, but the value is nullptr (e.g. because it is
// uninitialized on this path, or merged to nullptr due to predecessor
@@ -873,7 +873,7 @@ class CandidateAnalyzer {
// flow into Phis.
// When visiting a loop header for the 1st time, the backedge predecessor
// has no snapshot yet, and thus no value to look up: its inputs are handled
- // by CheckLoopPhiInvalidation when reaching the JumpLoop instead.
+ // by MarkEscapingLoopPhiBackedges when reaching the JumpLoop instead.
DCHECK_LE(data_.merged_predecessor_count, phi->input_count());
for (int i = 0; i < data_.merged_predecessor_count; i++) {
ValueNode* input = phi->input_node(i);
@@ -1005,7 +1005,8 @@ class FieldValuesTracker : public CandidateAnalyzer {
return BlockProcessResult::kContinue;
}
- bool CreateSnapshotFor(BasicBlock* block) {
+ bool CreateSnapshotFor(BasicBlock* block,
+ bool is_loop_fixpoint_check = false) {
TRACE("> CreateSnapshotFor " << BLOCK_ID(block));
DCHECK(field_values().IsSealed());
base::SmallVector<Snapshot, 4> predecessors_snapshots;
@@ -1057,6 +1058,21 @@ class FieldValuesTracker : public CandidateAnalyzer {
if (all_predecessors_equal) {
// All of the predecessors have the same value recorded for {key}, so
// there is no need to insert a Phi.
+ for (auto [phi, other_key] : old_phis_) {
+ if (other_key == key) {
+ // If there was already a Phi in {old_phis_} for {key}, then it
+ // might be referenced within the loop. We thus overwrite it with an
+ // Identity so that those references remain valid. Note that there
+ // is no need to trigger a loop revisit in such a case, since loop
+ // phis are anyways treated as opaque (which means that replacing a
+ // Phi with a non-phi doesn't invalidate any previous decisions).
+ // Also note that {phi} will not be added to the graph, but that's
+ // fine: the MaglevGraphOptimizer that runs after this phase will
+ // take care of rewiring the users to bypass this Identity.
+ phi->OverwriteWithIdentityTo(predecessors[0]);
+ break;
+ }
+ }
return predecessors[0];
}
@@ -1087,25 +1103,35 @@ class FieldValuesTracker : public CandidateAnalyzer {
// Trying to find an already-created Phi for this field. If we find it, we
// reuse it, for 2 reasons:
//
- // - termination: if there is already a Phi for this field, then it's
- // guaranteed to already have the right values (cf comment below), and
- // thus we don't need to trigger a revisit of the loop. Creating a
- // branch new phi would trigger loop revisits for ever (since it
- // always set {need_revisit} to true).
+ // - performance (always): we avoid reallocating a new phi.
//
- // - performance: we avoid reallocating a new phi.
+ // - correctness / termination (when {is_loop_fixpoint_check} is true):
+ // if there is already a Phi for this field, we reuse it and do not
+ // trigger a revisit of the loop. Creating a brand new phi would
+ // trigger loop revisits forever (since it always sets {need_revisit}
+ // to true).
+ //
+ // Note that when {is_loop_fixpoint_check} is false (for example, when an
+ // outer loop revisits an inner loop), the forward-edge predecessor of
+ // the inner loop header may have changed across outer-loop iterations.
+ // Therefore, we update any changed inputs on the reused Phi to match the
+ // incoming predecessors.
for (auto [phi, other_key] : old_phis_) {
if (other_key != key) continue;
-#ifdef DEBUG
- // Forward edges shouldn't have changed, and PatchLoopPhisBackedges
- // should have already patched the backedge. So, if we find a phi, its
- // inputs should already have the correct values.
DCHECK_EQ(phi->input_count(), predecessors.size());
+ bool any_input_changed = false;
for (int i = 0; i < phi->input_count(); i++) {
- DCHECK_EQ(phi->input_node(i), predecessors[i]);
+ if (phi->input_node(i) != predecessors[i]) {
+ DCHECK(!is_loop_fixpoint_check);
+ phi->change_input(i, predecessors[i]);
+ any_input_changed = true;
+ }
}
-#endif
+ DCHECK_IMPLIES(is_loop_fixpoint_check, !any_input_changed);
RegisterNewPhi(phi, block, key);
+ if (any_input_changed) {
+ CandidateAnalyzer::ProcessPhi(phi);
+ }
return phi;
}
@@ -1118,18 +1144,18 @@ class FieldValuesTracker : public CandidateAnalyzer {
constexpr interpreter::Register kFakeOwner =
interpreter::Register::invalid_value();
- // When visiting a loop with multiple forward edge for the 1st time, we
- // may need to insert a phi to merge the forward values but we won't have
- // a backedge value yet. Still, we'll create a valid loop phi with enough
- // inputs and we'll set itself as backedge input.
- int phi_input_count =
- block->is_loop() ? block->predecessor_count() : predecessor_count;
+ // A loop header has a single forward edge, so its first visit merges a
+ // single predecessor and returns above without reaching this point. By
+ // the time a loop phi is created here, the backedge has been visited too.
+ DCHECK_IMPLIES(
+ block->is_loop(),
+ predecessor_count == static_cast<int>(block->predecessor_count()));
// TODO(dmercadier): instead of creating a proper Phi (which are 64 bytes
// long + inputs!), we could have a custom "PseudoPhi" (name tbd)
// structure that contains the bare minimum and would basically just be a
// vector of Union(ValueNodes, PseudoPhi)., and only create real Phis in
// the elider once we're sure that we're going to need them.
- Phi* phi = NodeBase::New<Phi>(zone(), phi_input_count, state.value(),
+ Phi* phi = NodeBase::New<Phi>(zone(), predecessor_count, state.value(),
kFakeOwner);
#ifdef V8_ENABLE_MAGLEV_GRAPH_PRINTER
// TODO(dmercadier): should we register Phis only once we're sure that
@@ -1140,10 +1166,6 @@ class FieldValuesTracker : public CandidateAnalyzer {
for (int i = 0; i < predecessor_count; i++) {
phi->set_input(i, predecessors[i]);
}
- if (block->is_loop() && predecessor_count < phi_input_count) {
- DCHECK_EQ(predecessor_count, phi_input_count - 1);
- phi->set_input(phi_input_count - 1, predecessors[0]);
- }
phi->change_representation(predecessors[0]->value_representation());
TRACE(">> Created new phi: " << PRINT_NODE(phi));
need_revisit = true;
@@ -1170,17 +1192,18 @@ class FieldValuesTracker : public CandidateAnalyzer {
if (JumpLoop* jump_loop = block->control_node()->TryCast<JumpLoop>()) {
BasicBlock* loop_header = jump_loop->target();
- // Loop phis backedges need to be patched in 2 situations:
- //
- // - this is a loop with multiple forward edges that was requiring Phis
- // to merge forward values. In that case, during the first visit of
- // the loop, this Phi was created with itself as backedge (because it
- // needs a backedge value to be a valid loop phi); and we're now
- // patching this with the correct value of the backedge.
- //
- // - we have just revisited the loop, and when creating the loop phis
- // initially we were using the old backedge value (since it's the only
- // one that we had); and we're now patching it with the correct value.
+ // Any candidate flowing into a backedge need to be invalidated. When this
+ // happens, MarkAsEscaped will be called, which might set
+ // has_escaped_candidate for the current loop, which could trigger a
+ // revisit of the current loop. This means that it's important to run
+ // MarkEscapingLoopPhiBackedges before popping the current loop from
+ // `data_.loop_stack`.
+ MarkEscapingLoopPhiBackedges(loop_header);
+
+ // Loop phis backedges need to be patched when we have just revisited the
+ // loop: when creating the loop phis initially we were using the old
+ // backedge value (since it's the only one that we had), and we're now
+ // patching it with the correct value.
//
// Note that the fact that a loop phi needs to be patched isn't a reason
// to revisit the loop: while visiting the loop, phis are treated as
@@ -1189,10 +1212,10 @@ class FieldValuesTracker : public CandidateAnalyzer {
// will not lead to making any different decision when revisiting the
// loop.
//
- // Also note that PatchLoopPhisBackedges needs to be called before popping
- // the current loop from `data_.loop_stack` to ensure that if
- // `MarkAsEscaped(alloc)` is called inside it, it will find the current
- // loop on the stack if needed.
+ // Similarly to MarkEscapingLoopPhiBackedges above, PatchLoopPhisBackedges
+ // needs to be called before popping the current loop from
+ // `data_.loop_stack` to ensure that if `MarkAsEscaped(alloc)` is called
+ // inside it, it will find the current loop on the stack if needed.
PatchLoopPhisBackedges(loop_header, snapshot);
DCHECK_GT(data_.loop_stack.size(), 1);
@@ -1203,16 +1226,15 @@ class FieldValuesTracker : public CandidateAnalyzer {
auto prev_header_phis = new_phis().find(loop_header);
if (prev_header_phis != new_phis().end()) {
- old_phis_.swap(*prev_header_phis->second);
- DCHECK(prev_header_phis->second->empty());
+ old_phis_ = std::move(*prev_header_phis->second);
+ prev_header_phis->second->clear();
}
// TODO(dmercadier): we could try to reuse the snapshot created by
// CreateSnapshotFor when revisiting the loop, instead of discarding it
// and recomputing it afterwards.
bool needs_revisit = has_escaped_candidate ||
- CheckLoopPhiInvalidation(loop_header) ||
- CreateSnapshotFor(loop_header);
+ CreateSnapshotFor(loop_header, true);
if (needs_revisit) {
TRACE("> Will revisit loop");
// Discarding temporary snapshot.
@@ -1224,9 +1246,6 @@ class FieldValuesTracker : public CandidateAnalyzer {
} else {
// Discarding temporary snapshot.
if (!field_values().IsSealed()) field_values().Seal();
- // Discarding the backedge's snapshot, so that if we're currently in a
- // nested loop, we can still revisit it if we revisit the outer loop.
- block_snapshots_.erase(block);
}
}
@@ -1242,7 +1261,6 @@ class FieldValuesTracker : public CandidateAnalyzer {
// VariableReducer creates in Turboshaft.
field_values().StartNewSnapshot({backedge_snapshot});
- int backedge_index = header->predecessor_count() - 1;
for (auto& [phi, key] : *new_phis().at(header)) {
InlinedAllocation* alloc = key.data().base;
if (data_.HasEscaped(alloc)) {
@@ -1252,7 +1270,7 @@ class FieldValuesTracker : public CandidateAnalyzer {
continue;
}
- ValueNode* backedge_val = field_values().Get(key);
+ ValueNode* backedge_val = data_.GetFieldValue(key);
if (InlinedAllocation* backedge_alloc =
data_.TryGetCandidateInlinedAllocation(backedge_val)) {
@@ -1265,50 +1283,40 @@ class FieldValuesTracker : public CandidateAnalyzer {
// decisions based on the inputs of Phis, so the fact that the backedge
// of {phi} is now escaping doesn't invalidate any decision made in the
// loop.
-#ifdef DEBUG
- bool needed_revisit_before =
- data_.loop_stack.back().has_escaped_candidate;
-#endif
data_.MarkAsEscaped(backedge_alloc);
- // Calling MarkAsEscaped should not have marked the current loop as
- // needing to be revisited.
- DCHECK_EQ(needed_revisit_before,
- data_.loop_stack.back().has_escaped_candidate);
}
DCHECK_NOT_NULL(backedge_val);
TRACE(">> Updating loop phi backedge: "
- << PRINT_NODE(phi) << " backedge "
- << PRINT_NODE(phi->input(backedge_index).node()) << " -> "
- << PRINT_NODE(backedge_val));
- phi->change_input(backedge_index, backedge_val);
+ << PRINT_NODE(phi) << " backedge " << PRINT_NODE(phi->backedge())
+ << " -> " << PRINT_NODE(backedge_val));
+ phi->change_input(phi->backedge_index(), backedge_val);
}
field_values().Seal();
}
- // Returns true if a candidate for eliding flows into a loop phi. In that
- // case, we'll invalidate it and reprocess the loop.
+ // Invalidates any candidate that flows into a loop phi. This might trigger a
+ // loop revisit via has_escaped_candidate if the allocation was defined
+ // outside the current loop.
// TODO(dmercadier): try to merge objects in that case, instead of
- // invalidating.
- bool CheckLoopPhiInvalidation(BasicBlock* loop_header) {
- TRACE("CheckLoopPhiInvalidation");
+ // marking them as escaping.
+ void MarkEscapingLoopPhiBackedges(BasicBlock* loop_header) {
+ TRACE("MarkEscapingLoopPhiBackedges");
if (!loop_header->has_phi()) {
TRACE("> no phis");
- return false;
+ return;
}
- bool invalidated = false;
for (Phi* phi : *loop_header->phis()) {
if (InlinedAllocation* alloc =
- data_.TryGetCandidateInlinedAllocation(phi->backedge_input())) {
- TRACE("> Marking " << NODE_ID(alloc) << " as escaping, will revisit");
+ data_.TryGetCandidateInlinedAllocation(phi->backedge())) {
+ TRACE("> Marking " << NODE_ID(alloc) << " as escaping");
data_.MarkAsEscaped(alloc);
- invalidated = true;
}
}
- return invalidated;
}
+
ProcessResult Process(InlinedAllocation* node, const ProcessingState& state) {
BasicBlock* current_loop = data_.loop_stack.back().header;
data_.alloc_definition_loop[node] = current_loop;
@@ -1829,7 +1837,7 @@ class Elider {
}
DCHECK(keys_mappings().contains(addr));
Key key = keys_mappings().at(addr);
- ValueNode* replacement = field_values().Get(key);
+ ValueNode* replacement = data_.GetFieldValue(key);
if (replacement == nullptr || (replacement->value_representation() !=
node->value_representation())) {
diff --git a/deps/v8/src/maglev/turbolev-escape-analysis.h b/deps/v8/src/maglev/turbolev-escape-analysis.h
index 0b6b348bfc8..f32e63721d9 100644
--- a/deps/v8/src/maglev/turbolev-escape-analysis.h
+++ b/deps/v8/src/maglev/turbolev-escape-analysis.h
@@ -216,7 +216,7 @@ struct EscapeAnalysisData {
ObjectField addr = ObjectField{alloc, 0};
Key key = TryGetKeyFor(addr);
DCHECK(key.valid());
- return field_values.Get(key) != nullptr;
+ return GetFieldValue(key) != nullptr;
}
// {value} is being stored into {base}. As a result, if {base} is not
@@ -230,6 +230,30 @@ struct EscapeAnalysisData {
bool HasEscaped(InlinedAllocation* alloc);
+ // Reads the value of a field, unwrapping any Identity nodes.
+ //
+ // Identity nodes can appear here because LoadFloat64 and
+ // LoadFixedDoubleArrayElement are not eagerly resolved during the
+ // CandidateAnalyzer phase (unlike LoadTaggedField) and are instead
+ // overwritten with Identity by the Elider. When an elided object's field
+ // stores the result of such a load, its field_values entry holds the raw
+ // load node, which turns into an Identity when the load is elided.
+ //
+ // Note: An alternative approach of eagerly resolving LoadFloat64 and
+ // LoadFixedDoubleArrayElement in CandidateAnalyzer (similar to
+ // LoadTaggedField) was explored in https://crrev.com/c/8287966, but
+ // unwrapping identities here is significantly simpler and avoids having to
+ // track additional load opcodes in loaded_values.
+ ValueNode* GetFieldValue(Key key) {
+ ValueNode* value = field_values.Get(key);
+ return value ? value->UnwrapIdentities() : nullptr;
+ }
+ ValueNode* GetPredecessorFieldValue(Key key, int predecessor_index) {
+ DCHECK_GE(predecessor_index, 0);
+ ValueNode* value = field_values.GetPredecessorValue(key, predecessor_index);
+ return value ? value->UnwrapIdentities() : nullptr;
+ }
+
ValueNode* Get(InlinedAllocation* base, int field);
Key GetOrCreateKey(InlinedAllocation* base, int field);
};
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 0cfcdfb8d2e..36c482fccd1 100644
--- a/deps/v8/src/maglev/x64/maglev-assembler-x64-inl.h
+++ b/deps/v8/src/maglev/x64/maglev-assembler-x64-inl.h
@@ -367,6 +367,14 @@ inline void MaglevAssembler::LoadDataViewElement(Register result,
LoadSignedField(result, element_address, element_size);
}
+inline void MaglevAssembler::LoadUnsignedDataViewElement(Register result,
+ Register data_pointer,
+ Register index,
+ int element_size) {
+ MemOperand element_address = Operand(data_pointer, index, times_1, 0);
+ LoadUnsignedField(result, element_address, element_size);
+}
+
inline void MaglevAssembler::LoadTaggedFieldByIndex(Register result,
Register object,
Register index, int scale,
@@ -396,7 +404,9 @@ inline void MaglevAssembler::LoadExternalPointerField(Register result,
void MaglevAssembler::LoadFixedArrayElement(Register result, Register array,
Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -413,7 +423,9 @@ inline void MaglevAssembler::LoadTaggedFieldWithoutDecompressing(
void MaglevAssembler::LoadFixedArrayElementWithoutDecompressing(
Register result, Register array, Register index) {
if (v8_flags.debug_code) {
- AssertObjectType(array, FIXED_ARRAY_TYPE, AbortReason::kUnexpectedValue);
+ AssertObjectTypeInRange(array, FIRST_FIXED_ARRAY_TYPE,
+ LAST_FIXED_ARRAY_TYPE,
+ AbortReason::kUnexpectedValue);
CompareInt32AndAssert(index, 0, kUnsignedGreaterThanEqual,
AbortReason::kUnexpectedNegativeValue);
}
@@ -540,6 +552,18 @@ inline void MaglevAssembler::ReverseByteOrder(Register value, int size) {
}
}
+inline void MaglevAssembler::ReverseByteOrderUnsigned(Register value,
+ int size) {
+ if (size == 2) {
+ bswapl(value);
+ shrl(value, Immediate(16));
+ } else if (size == 4) {
+ bswapl(value);
+ } else {
+ DCHECK_EQ(size, 1);
+ }
+}
+
inline MemOperand MaglevAssembler::StackSlotOperand(StackSlot stack_slot) {
return MemOperand(rbp, stack_slot.index);
}
@@ -717,6 +741,31 @@ inline void MaglevAssembler::StoreFloat64(MemOperand dst, DoubleRegister src) {
Movsd(dst, src);
}
+inline void MaglevAssembler::LoadUnalignedFloat32(DoubleRegister dst,
+ Register base,
+ Register index) {
+ LoadFloat32(dst, Operand(base, index, times_1, 0));
+}
+inline void MaglevAssembler::LoadUnalignedFloat32AndReverseByteOrder(
+ DoubleRegister dst, Register base, Register index) {
+ movl(kScratchRegister, Operand(base, index, times_1, 0));
+ bswapl(kScratchRegister);
+ Movd(dst, kScratchRegister);
+ Cvtss2sd(dst, dst);
+}
+inline void MaglevAssembler::StoreUnalignedFloat32(Register base,
+ Register index,
+ DoubleRegister src) {
+ StoreFloat32(Operand(base, index, times_1, 0), src);
+}
+inline void MaglevAssembler::ReverseByteOrderAndStoreUnalignedFloat32(
+ Register base, Register index, DoubleRegister src) {
+ Cvtsd2ss(kScratchDoubleReg, src);
+ Movd(kScratchRegister, kScratchDoubleReg);
+ bswapl(kScratchRegister);
+ movl(Operand(base, index, times_1, 0), kScratchRegister);
+}
+
inline void MaglevAssembler::LoadUnalignedFloat64(DoubleRegister dst,
Register base,
Register index) {
@@ -1066,7 +1115,7 @@ inline void MaglevAssembler::JumpIfNotSmi(Register src, Label* on_not_smi,
void MaglevAssembler::JumpIfByte(Condition cc, Register value, int32_t byte,
Label* target, Label::Distance distance) {
- cmpb(value, Immediate(byte));
+ Cmpb(value, byte);
j(cc, target, distance);
}
@@ -1241,7 +1290,7 @@ inline void MaglevAssembler::CompareInt32AndJumpIf(Register r1, int32_t value,
void MaglevAssembler::CompareIntPtrAndJumpIf(Register r1, int32_t value,
Condition cond, Label* target,
Label::Distance distance) {
- cmpq(r1, Immediate(value));
+ Cmpq(r1, value);
JumpIf(cond, target, distance);
}
@@ -1267,7 +1316,7 @@ inline void MaglevAssembler::CompareIntPtrAndBranch(
Register r1, int32_t value, Condition cond, Label* if_true,
Label::Distance true_distance, bool fallthrough_when_true, Label* if_false,
Label::Distance false_distance, bool fallthrough_when_false) {
- cmpq(r1, Immediate(value));
+ Cmpq(r1, value);
Branch(cond, if_true, true_distance, fallthrough_when_true, if_false,
false_distance, fallthrough_when_false);
}
@@ -1464,7 +1513,7 @@ inline void MaglevAssembler::AssertStackSizeCorrect() {
inline Condition MaglevAssembler::FunctionEntryStackCheck(
int stack_check_offset) {
Register stack_cmp_reg = rsp;
- if (stack_check_offset >= kStackLimitSlackForDeoptimizationInBytes) {
+ if (stack_check_offset > kStackLimitSlackForDeoptimizationInBytes) {
stack_cmp_reg = kScratchRegister;
leaq(stack_cmp_reg, Operand(rsp, -stack_check_offset));
}
@@ -1503,6 +1552,14 @@ inline void MaglevAssembler::MaybeEmitPlaceHolderForDeopt() {
}
}
+inline void MaglevAssembler::MemoryBarrier(AtomicMemoryOrder order) {
+ // x64 is no weaker than release-acquire and only needs to emit an
+ // instruction for SeqCst memory barriers.
+ if (order == AtomicMemoryOrder::kSeqCst) {
+ mfence();
+ }
+}
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/maglev/x64/maglev-assembler-x64.cc b/deps/v8/src/maglev/x64/maglev-assembler-x64.cc
index 99494be280b..61ea0e75948 100644
--- a/deps/v8/src/maglev/x64/maglev-assembler-x64.cc
+++ b/deps/v8/src/maglev/x64/maglev-assembler-x64.cc
@@ -452,14 +452,14 @@ void MaglevAssembler::TryTruncateDoubleToInt32(Register dst, DoubleRegister src,
// Check if {input} is -0.
Label check_done;
- cmpl(dst, Immediate(0));
- j(not_equal, &check_done);
+ Cmp(dst, 0);
+ j(not_zero, &check_done);
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
Register high_word32_of_input = kScratchRegister;
Pextrd(high_word32_of_input, src, 1);
- cmpl(high_word32_of_input, Immediate(0));
- JumpIf(less, fail);
+ Cmp(high_word32_of_input, 0);
+ JumpIf(negative, fail);
bind(&check_done);
}
@@ -483,14 +483,14 @@ void MaglevAssembler::TryTruncateDoubleToUint32(Register dst,
// Check if {input} is -0.
Label check_done;
- cmpl(dst, Immediate(0));
- j(not_equal, &check_done);
+ Cmp(dst, 0);
+ j(not_zero, &check_done);
// In case of 0, we need to check the high bits for the IEEE -0 pattern.
Register high_word32_of_input = kScratchRegister;
Pextrd(high_word32_of_input, src, 1);
- cmpl(high_word32_of_input, Immediate(0));
- JumpIf(less, fail);
+ Cmp(high_word32_of_input, 0);
+ JumpIf(negative, fail);
bind(&check_done);
}
diff --git a/deps/v8/src/maglev/x64/maglev-ir-x64.cc b/deps/v8/src/maglev/x64/maglev-ir-x64.cc
index 5df05b94fb6..54d55f926bf 100644
--- a/deps/v8/src/maglev/x64/maglev-ir-x64.cc
+++ b/deps/v8/src/maglev/x64/maglev-ir-x64.cc
@@ -422,16 +422,16 @@ void Int32MultiplyWithOverflow::GenerateCode(MaglevAssembler* masm,
// If the result is zero, check if either lhs or rhs is negative.
Label end;
- __ cmpl(result, Immediate(0));
+ __ Cmp(result, 0);
__ j(not_zero, &end);
{
__ orl(saved_left, right);
- __ cmpl(saved_left, Immediate(0));
+ __ Cmp(saved_left, 0);
// If one of them is negative, we must have a -0 result, which is non-int32,
// so deopt.
// TODO(leszeks): Consider splitting these deopts to have distinct deopt
// reasons. Otherwise, the reason has to match the above.
- __ EmitEagerDeoptIf(less, DeoptimizeReason::kOverflow, this);
+ __ EmitEagerDeoptIf(negative, DeoptimizeReason::kOverflow, this);
}
__ bind(&end);
}
@@ -489,7 +489,7 @@ void Int32ModulusWithOverflow::GenerateCode(MaglevAssembler* masm,
ZoneLabelRef done(masm);
ZoneLabelRef rhs_checked(masm);
- __ cmpl(rhs, Immediate(0));
+ __ Cmp(rhs, 0);
__ JumpToDeferredIf(
less_equal,
[](MaglevAssembler* masm, ZoneLabelRef rhs_checked, Register rhs,
@@ -501,7 +501,7 @@ void Int32ModulusWithOverflow::GenerateCode(MaglevAssembler* masm,
rhs_checked, rhs, this);
__ bind(*rhs_checked);
- __ cmpl(lhs, Immediate(0));
+ __ Cmp(lhs, 0);
__ JumpToDeferredIf(
less,
[](MaglevAssembler* masm, ZoneLabelRef done, Register lhs, Register rhs,
@@ -568,7 +568,7 @@ void Int32DivideWithOverflow::GenerateCode(MaglevAssembler* masm,
// REDUCE(WordBinopDeoptOnOverflow) in machine-lowering-reducer-inl.h
// Check if {right} is positive (and not zero).
- __ cmpl(right, Immediate(0));
+ __ Cmp(right, 0);
ZoneLabelRef done(masm);
__ JumpToDeferredIf(
less_equal,
@@ -586,9 +586,9 @@ void Int32DivideWithOverflow::GenerateCode(MaglevAssembler* masm,
// Check if {left} is zero, as that would produce minus zero. Left is in
// rax already.
- __ cmpl(rax, Immediate(0));
+ __ Cmp(rax, 0);
// TODO(leszeks): Better DeoptimizeReason = kMinusZero.
- __ EmitEagerDeoptIf(equal, DeoptimizeReason::kNotInt32, node);
+ __ EmitEagerDeoptIf(zero, DeoptimizeReason::kNotInt32, node);
// Check if {left} is kMinInt and {right} is -1, in which case we'd have
// to return -kMinInt, which is not representable as Int32.
@@ -607,12 +607,12 @@ void Int32DivideWithOverflow::GenerateCode(MaglevAssembler* masm,
__ idivl(right);
// Check that the remainder is zero.
- __ cmpl(rdx, Immediate(0));
+ __ Cmp(rdx, 0);
// None of the mutated input registers should be a register input into the
// eager deopt info.
DCHECK_REGLIST_EMPTY(RegList{rax, rdx} &
GetGeneralRegistersUsedAsInputs(eager_deopt_info()));
- __ EmitEagerDeoptIf(not_equal, DeoptimizeReason::kNotInt32, this);
+ __ EmitEagerDeoptIf(not_zero, DeoptimizeReason::kNotInt32, this);
DCHECK_EQ(ToRegister(result()), rax);
}
@@ -736,7 +736,7 @@ void Int32AbsWithOverflow::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
Register value = ToRegister(result());
Label done;
- __ cmpl(value, Immediate(0));
+ __ Cmp(value, 0);
__ j(greater_equal, &done);
__ negl(value);
__ EmitEagerDeoptIf(overflow, DeoptimizeReason::kOverflow, this);
@@ -1054,19 +1054,6 @@ void ChangeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
__ Subsd(value, kScratchDoubleReg);
}
-void HoleyFloat64ToSilencedFloat64::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-void HoleyFloat64ToSilencedFloat64::GenerateCode(MaglevAssembler* masm,
- const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- // The hole value is a signalling NaN, so just silence it to get the
- // float64 value.
- __ Xorpd(kScratchDoubleReg, kScratchDoubleReg);
- __ Subsd(value, kScratchDoubleReg);
-}
-
void Float64ToSilencedFloat64::SetValueLocationConstraints() {
UseRegister(ValueInput());
DefineSameAsFirst(this);
@@ -1087,21 +1074,6 @@ void UnsafeFloat64ToHoleyFloat64::SetValueLocationConstraints() {
void UnsafeFloat64ToHoleyFloat64::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {}
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
-void HoleyFloat64ConvertHoleToUndefined::SetValueLocationConstraints() {
- UseRegister(ValueInput());
- DefineSameAsFirst(this);
-}
-void HoleyFloat64ConvertHoleToUndefined::GenerateCode(
- MaglevAssembler* masm, const ProcessingState& state) {
- DoubleRegister value = ToDoubleRegister(ValueInput());
- Label done;
- __ JumpIfNotHoleNan(value, kScratchRegister, &done);
- __ Move(value, UndefinedNan());
- __ bind(&done);
-}
-#endif // V8_ENABLE_UNDEFINED_DOUBLE
-
namespace {
enum class ReduceInterruptBudgetType { kLoop, kReturn };
@@ -1113,38 +1085,23 @@ void HandleInterruptsAndTiering(MaglevAssembler* masm, ZoneLabelRef done,
__ ResetLastYoungAllocation();
}
- // For loops, first check for interrupts. Don't do this for returns, as we
- // can't lazy deopt to the end of a return.
+ // Call into the TieringManager. For loops, pass the OSR bytecode offset and
+ // define a lazy deopt point since they double as interrupt checks.
if (type == ReduceInterruptBudgetType::kLoop) {
- Label next;
-
- // Here, we only care about interrupts since we've already guarded against
- // real stack overflows on function entry.
- __ cmpq(rsp, __ StackLimitAsOperand(StackLimitKind::kInterruptStackLimit));
- __ j(above, &next);
-
- // An interrupt has been requested and we must call into runtime to handle
- // it; since we already pay the call cost, combine with the TieringManager
- // call.
- {
- SaveRegisterStateForCall save_register_state(masm,
- node->register_snapshot());
- __ Move(kContextRegister, masm->native_context().object());
- __ Push(MemOperand(rbp, StandardFrameConstants::kFunctionOffset));
- __ CallRuntime(Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev, 1);
- save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
- }
- __ jmp(*done); // All done, continue.
-
- __ bind(&next);
- }
-
- // No pending interrupts. Call into the TieringManager if needed.
- {
SaveRegisterStateForCall save_register_state(masm,
node->register_snapshot());
+ __ Push(MemOperand(rbp, StandardFrameConstants::kFunctionOffset));
+ __ Push(Smi::FromInt(
+ node->Cast<ReduceInterruptBudgetForLoop>()->osr_offset().ToInt()));
__ Move(kContextRegister, masm->native_context().object());
+ __ CallRuntime(Runtime::kBytecodeBudgetLoopInterrupt_Maglev, 2);
+ save_register_state.DefineSafepointWithLazyDeopt(node->lazy_deopt_info());
+ } else {
+ DCHECK_EQ(type, ReduceInterruptBudgetType::kReturn);
+ SaveRegisterStateForCall save_register_state(masm,
+ node->register_snapshot());
__ Push(MemOperand(rbp, StandardFrameConstants::kFunctionOffset));
+ __ Move(kContextRegister, masm->native_context().object());
// Note: must not cause a lazy deopt!
__ CallRuntime(Runtime::kBytecodeBudgetInterrupt_Maglev, 1);
save_register_state.DefineSafepoint();
@@ -1166,14 +1123,19 @@ void GenerateReduceInterruptBudget(MaglevAssembler* masm, Node* node,
} // namespace
-int ReduceInterruptBudgetForLoop::MaxCallStackArgs() const { return 1; }
void ReduceInterruptBudgetForLoop::SetValueLocationConstraints() {
UseRegister(FeedbackCellInput());
+ if (try_osr()) {
+ set_temporaries_needed(2);
+ }
}
void ReduceInterruptBudgetForLoop::GenerateCode(MaglevAssembler* masm,
const ProcessingState& state) {
GenerateReduceInterruptBudget(masm, this, ToRegister(FeedbackCellInput()),
ReduceInterruptBudgetType::kLoop, amount());
+ if (try_osr()) {
+ masm->TryOnStackReplacement(this, feedback_slot());
+ }
}
int ReduceInterruptBudgetForReturn::MaxCallStackArgs() const { return 1; }
@@ -1296,8 +1258,7 @@ void LoadDictionaryField::GenerateCode(MaglevAssembler* masm,
entry_index + NameDictionary::kEntryDetailsIndex));
__ SmiUntag(scratch);
__ andl(scratch, Immediate(PropertyDetails::KindField::kMask));
- __ cmpl(scratch,
- Immediate(PropertyDetails::KindField::encode(PropertyKind::kData)));
+ __ Cmp(scratch, PropertyDetails::KindField::encode(PropertyKind::kData));
__ j(not_equal, deferred_fallback);
__ LoadTaggedField(result_reg, properties,
diff --git a/deps/v8/src/objects/abstract-code.h b/deps/v8/src/objects/abstract-code.h
index 585d2a9de37..79a35dd1bbf 100644
--- a/deps/v8/src/objects/abstract-code.h
+++ b/deps/v8/src/objects/abstract-code.h
@@ -23,6 +23,8 @@ class Code;
// profiling. Perhaps methods should be specialized instead of this wrapper
// class?
class AbstractCode : public HeapObject {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
int SourcePosition(Isolate* isolate, int offset);
int SourceStatementPosition(Isolate* isolate, int offset);
diff --git a/deps/v8/src/objects/all-objects-inl.h b/deps/v8/src/objects/all-objects-inl.h
index 5501cf2b320..f78c50656e0 100644
--- a/deps/v8/src/objects/all-objects-inl.h
+++ b/deps/v8/src/objects/all-objects-inl.h
@@ -5,9 +5,11 @@
#ifndef V8_OBJECTS_ALL_OBJECTS_INL_H_
#define V8_OBJECTS_ALL_OBJECTS_INL_H_
-// This file includes all inline headers from src/objects, which is handy for
-// compilation units that need it like object printing or verification.
-// New inline headers should be added here.
+#include "src/objects/all-objects.h"
+
+// Inline definitions for compilation units that operate on every heap object,
+// such as object printing and verification. Add new object declarations to
+// all-objects.h. Add an inline header here when these consumers need it.
#include "src/objects/allocation-site-inl.h"
#include "src/objects/allocation-site-scopes-inl.h"
@@ -99,6 +101,7 @@
#include "src/objects/turboshaft-types-inl.h"
#if V8_ENABLE_WEBASSEMBLY
+#include "src/debug/debug-wasm-objects-inl.h"
#include "src/wasm/wasm-objects-inl.h"
#endif // V8_ENABLE_WEBASSEMBLY
diff --git a/deps/v8/src/objects/all-objects.h b/deps/v8/src/objects/all-objects.h
new file mode 100644
index 00000000000..76b8392e4d1
--- /dev/null
+++ b/deps/v8/src/objects/all-objects.h
@@ -0,0 +1,129 @@
+// 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_OBJECTS_ALL_OBJECTS_H_
+#define V8_OBJECTS_ALL_OBJECTS_H_
+
+// This file reaches the declaration of every heap object. 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.
+
+#include "src/ic/handler-configuration.h"
+#include "src/objects/abstract-code.h"
+#include "src/objects/allocation-site-scopes.h"
+#include "src/objects/allocation-site.h"
+#include "src/objects/api-callbacks.h"
+#include "src/objects/arguments.h"
+#include "src/objects/bigint.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-object-wrapper.h"
+#include "src/objects/data-handler.h"
+#include "src/objects/debug-objects.h"
+#include "src/objects/descriptor-array.h"
+#include "src/objects/dictionary.h"
+#include "src/objects/elements.h"
+#include "src/objects/embedder-data-array.h"
+#include "src/objects/embedder-data-slot.h"
+#include "src/objects/feedback-cell.h"
+#include "src/objects/feedback-vector.h"
+#include "src/objects/field-index.h"
+#include "src/objects/fixed-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/instance-type.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.h"
+#include "src/objects/js-disposable-stack.h"
+#include "src/objects/js-function.h"
+#include "src/objects/js-generator.h"
+#include "src/objects/js-interceptor-map.h"
+#include "src/objects/js-iterator-helpers.h"
+#include "src/objects/js-objects.h"
+#include "src/objects/js-promise.h"
+#include "src/objects/js-proxy.h"
+#include "src/objects/js-raw-json.h"
+#include "src/objects/js-regexp-string-iterator.h"
+#include "src/objects/js-regexp.h"
+#include "src/objects/js-shadow-realm.h"
+#include "src/objects/js-shared-array.h"
+#ifdef V8_TEMPORAL_SUPPORT
+#include "src/objects/js-temporal-objects.h"
+#endif // V8_TEMPORAL_SUPPORT
+#include "src/objects/js-weak-refs.h"
+#include "src/objects/literal-objects.h"
+#include "src/objects/lookup-cache.h"
+#include "src/objects/lookup.h"
+#include "src/objects/map.h"
+#include "src/objects/maybe-object.h"
+#include "src/objects/megadom-handler.h"
+#include "src/objects/microtask.h"
+#include "src/objects/module.h"
+#include "src/objects/name.h"
+#include "src/objects/number-string-cache.h"
+#include "src/objects/objects.h"
+#include "src/objects/oddball.h"
+#include "src/objects/ordered-hash-table.h"
+#include "src/objects/promise.h"
+#include "src/objects/property-array.h"
+#include "src/objects/property-cell.h"
+#include "src/objects/property-descriptor-object.h"
+#include "src/objects/prototype-info.h"
+#include "src/objects/regexp-match-info.h"
+#include "src/objects/scope-info.h"
+#include "src/objects/script.h"
+#include "src/objects/shared-function-info.h"
+#include "src/objects/slots.h"
+#include "src/objects/sort-state.h"
+#include "src/objects/source-text-module.h"
+#include "src/objects/string-forwarding-table.h"
+#include "src/objects/string-set.h"
+#include "src/objects/string-table.h"
+#include "src/objects/string.h"
+#include "src/objects/struct.h"
+#include "src/objects/swiss-name-dictionary.h"
+#include "src/objects/synthetic-module.h"
+#include "src/objects/tagged-field.h"
+#include "src/objects/tagged-impl.h"
+#include "src/objects/tagged-value.h"
+#include "src/objects/template-objects.h"
+#include "src/objects/templates.h"
+#include "src/objects/transitions.h"
+#include "src/objects/trusted-object.h"
+#include "src/objects/turbofan-types.h"
+#include "src/objects/turboshaft-types.h"
+
+#if V8_ENABLE_WEBASSEMBLY
+#include "src/debug/debug-wasm-objects.h"
+#include "src/wasm/wasm-objects.h"
+#endif // V8_ENABLE_WEBASSEMBLY
+
+#ifdef V8_INTL_SUPPORT
+#include "src/objects/js-break-iterator.h"
+#include "src/objects/js-collator.h"
+#include "src/objects/js-date-time-format.h"
+#include "src/objects/js-display-names.h"
+#include "src/objects/js-duration-format.h"
+#include "src/objects/js-list-format.h"
+#include "src/objects/js-locale.h"
+#include "src/objects/js-number-format.h"
+#include "src/objects/js-plural-rules.h"
+#include "src/objects/js-relative-time-format.h"
+#include "src/objects/js-segment-iterator.h"
+#include "src/objects/js-segmenter.h"
+#include "src/objects/js-segments.h"
+#endif // V8_INTL_SUPPORT
+
+#endif // V8_OBJECTS_ALL_OBJECTS_H_
diff --git a/deps/v8/src/objects/allocation-site-inl.h b/deps/v8/src/objects/allocation-site-inl.h
index 9fdaba85e17..c0dbebecb68 100644
--- a/deps/v8/src/objects/allocation-site-inl.h
+++ b/deps/v8/src/objects/allocation-site-inl.h
@@ -14,6 +14,7 @@
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/dependent-code-inl.h"
#include "src/objects/js-objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
diff --git a/deps/v8/src/objects/allocation-site.h b/deps/v8/src/objects/allocation-site.h
index f4b266931e8..291002908fb 100644
--- a/deps/v8/src/objects/allocation-site.h
+++ b/deps/v8/src/objects/allocation-site.h
@@ -19,6 +19,9 @@ namespace internal {
enum InstanceType : uint16_t;
V8_OBJECT class AllocationSite : public HeapObject {
+ V8_IT_OWN_TYPE;
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
static const uint32_t kMaximumArrayBytesToPretransition = 8 * 1024;
@@ -152,6 +155,8 @@ V8_OBJECT class AllocationSite : public HeapObject {
} V8_OBJECT_END;
V8_OBJECT class AllocationSiteWithWeakNext : public AllocationSite {
+ V8_IT_REUSE_PARENT;
+
public:
// heap->allocation_site_list() points to the last AllocationSite which form
// a linked list through the weak_next property. The GC might remove elements
diff --git a/deps/v8/src/objects/arguments.h b/deps/v8/src/objects/arguments.h
index 2973650d354..e76baae75d8 100644
--- a/deps/v8/src/objects/arguments.h
+++ b/deps/v8/src/objects/arguments.h
@@ -21,6 +21,7 @@ class StructBodyDescriptor;
// Superclass for all objects with instance type {JS_ARGUMENTS_OBJECT_TYPE}
V8_OBJECT class JSArgumentsObject : public JSObject {
public:
+ V8_IT_OWN_TYPE;
DECL_VERIFIER(JSArgumentsObject)
DECL_PRINTER(JSArgumentsObject)
@@ -38,6 +39,7 @@ inline constexpr int JSArgumentsObject::kHeaderSize = sizeof(JSArgumentsObject);
// JSArgumentsObject::kHeaderSize.
class JSSloppyArgumentsObject : public JSArgumentsObject {
public:
+ V8_IT_REUSE_PARENT;
// Slot indices of the in-object properties, relative to the parent's
// kHeaderSize.
static constexpr int kLengthSlotIndex = 0;
@@ -58,6 +60,8 @@ class JSSloppyArgumentsObject : public JSArgumentsObject {
// JSStrictArgumentsObject is just a JSArgumentsObject with specific initial
// map. This initial map adds an in-object property for "length".
class JSStrictArgumentsObject : public JSArgumentsObject {
+ V8_IT_REUSE_PARENT;
+
public:
static constexpr int kLengthSlotIndex = 0;
static constexpr int kInObjectPropertyCount = 1;
diff --git a/deps/v8/src/objects/backing-store.cc b/deps/v8/src/objects/backing-store.cc
index beab4e44b29..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;
@@ -584,15 +584,6 @@ std::optional<size_t> BackingStore::GrowWasmMemoryInPlace(Isolate* isolate,
return {old_length / wasm::kWasmPageSize};
}
-void BackingStore::AttachSharedWasmMemoryObject(
- Isolate* isolate, DirectHandle<WasmMemoryObject> memory_object) {
- DCHECK(is_wasm_memory());
- DCHECK(is_shared());
- // We need to take the global registry lock for this operation.
- GlobalBackingStoreRegistry::AddSharedWasmMemoryObject(isolate, this,
- memory_object);
-}
-
void BackingStore::BroadcastSharedWasmMemoryGrow(Isolate* isolate) const {
GlobalBackingStoreRegistry::BroadcastSharedWasmMemoryGrow(isolate, this);
}
@@ -804,23 +795,6 @@ DEFINE_LAZY_LEAKY_OBJECT_GETTER(GlobalBackingStoreRegistryImpl,
GetGlobalBackingStoreRegistryImpl)
} // namespace
-void GlobalBackingStoreRegistry::Register(
- std::shared_ptr<BackingStore> backing_store) {
- if (!backing_store || !backing_store->buffer_start()) return;
- // Only wasm memory backing stores need to be registered globally.
- CHECK(backing_store->is_wasm_memory());
-
- GlobalBackingStoreRegistryImpl* impl = GetGlobalBackingStoreRegistryImpl();
- base::MutexGuard scope_lock(&impl->mutex_);
- if (backing_store->globally_registered()) return;
- TRACE_BS("BS:reg bs=%p mem=%p (length=%zu, capacity=%zu)\n",
- backing_store.get(), backing_store->buffer_start(),
- backing_store->byte_length(), backing_store->byte_capacity());
- std::weak_ptr<BackingStore> weak = backing_store;
- auto result = impl->map_.insert({backing_store->buffer_start(), weak});
- CHECK(result.second);
- backing_store->set_flag(BackingStore::kGloballyRegistered);
-}
void GlobalBackingStoreRegistry::Unregister(BackingStore* backing_store) {
if (!backing_store->globally_registered()) return;
@@ -871,14 +845,29 @@ void GlobalBackingStoreRegistry::Purge(Isolate* isolate) {
#if V8_ENABLE_WEBASSEMBLY
void GlobalBackingStoreRegistry::AddSharedWasmMemoryObject(
- Isolate* isolate, BackingStore* backing_store,
+ Isolate* isolate, std::shared_ptr<BackingStore> backing_store,
DirectHandle<WasmMemoryObject> memory_object) {
+ DCHECK(backing_store->is_wasm_memory());
+ DCHECK(backing_store->is_shared());
+
// Add to the weak array list of shared memory objects in the isolate.
isolate->AddSharedWasmMemory(memory_object);
- // Add the isolate to the list of isolates sharing this backing store.
GlobalBackingStoreRegistryImpl* impl = GetGlobalBackingStoreRegistryImpl();
base::MutexGuard scope_lock(&impl->mutex_);
+
+ // Register this backing store globally.
+ if (!backing_store->globally_registered() && backing_store->buffer_start()) {
+ TRACE_BS("BS:reg bs=%p mem=%p (length=%zu, capacity=%zu)\n",
+ backing_store.get(), backing_store->buffer_start(),
+ backing_store->byte_length(), backing_store->byte_capacity());
+ std::weak_ptr<BackingStore> weak = backing_store;
+ auto result = impl->map_.insert({backing_store->buffer_start(), weak});
+ CHECK(result.second);
+ backing_store->set_flag(BackingStore::kGloballyRegistered);
+ }
+
+ // Add the isolate to the list of isolates sharing this backing store.
SharedWasmMemoryData* shared_data =
backing_store->get_shared_wasm_memory_data();
auto& isolates = shared_data->isolates_;
diff --git a/deps/v8/src/objects/backing-store.h b/deps/v8/src/objects/backing-store.h
index bf2ffb573a1..6e2eebcf10c 100644
--- a/deps/v8/src/objects/backing-store.h
+++ b/deps/v8/src/objects/backing-store.h
@@ -12,6 +12,7 @@
#include "include/v8-internal.h"
#include "src/base/bit-field.h"
#include "src/handles/handles.h"
+#include "src/objects/managed-type-id.h"
#include "src/sandbox/sandbox.h"
namespace v8::internal {
@@ -56,7 +57,7 @@ struct SharedWasmMemoryData;
// and the destructor frees the memory (and page allocation if necessary).
class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
public:
- static constexpr ExternalPointerTag kManagedTag = kBackingStoreTag;
+ static constexpr ManagedTypeId kTypeID = ManagedTypeId::kBackingStore;
~BackingStore();
@@ -178,11 +179,6 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
size_t max_pages,
WasmMemoryFlag wasm_memory);
- // Attach the given memory object to this backing store. The memory object
- // will be updated if this backing store is grown.
- void AttachSharedWasmMemoryObject(
- Isolate* isolate, DirectHandle<WasmMemoryObject> memory_object);
-
// Send asynchronous updates to attached memory objects in other isolates
// after the backing store has been grown. Memory objects in this
// isolate are updated synchronously.
@@ -337,23 +333,18 @@ class V8_EXPORT_PRIVATE BackingStore : public BackingStoreBase {
// of wasm memory objects.
class GlobalBackingStoreRegistry {
public:
- // Register a backing store in the global registry. A mapping from the
- // {buffer_start} to the backing store object will be added. The backing
- // store will automatically unregister itself upon destruction.
- // Only wasm memory backing stores are supported.
- static void Register(std::shared_ptr<BackingStore> backing_store);
+ // Adds the given memory object to the backing store's weak list
+ // of memory objects and registers the backing store if not yet registered
+ // (under the registry lock).
+ static void AddSharedWasmMemoryObject(
+ Isolate* isolate, std::shared_ptr<BackingStore> backing_store,
+ DirectHandle<WasmMemoryObject> memory_object);
private:
friend class BackingStore;
// Unregister a backing store in the global registry.
static void Unregister(BackingStore* backing_store);
- // Adds the given memory object to the backing store's weak list
- // of memory objects (under the registry lock).
- static void AddSharedWasmMemoryObject(
- Isolate* isolate, BackingStore* backing_store,
- DirectHandle<WasmMemoryObject> memory_object);
-
// Purge any shared wasm memory lists that refer to this isolate.
static void Purge(Isolate* isolate);
diff --git a/deps/v8/src/objects/bigint.h b/deps/v8/src/objects/bigint.h
index 40d33b3ccdc..3ff1cfd5b46 100644
--- a/deps/v8/src/objects/bigint.h
+++ b/deps/v8/src/objects/bigint.h
@@ -88,6 +88,9 @@ class ValueSerializer;
// BigIntBase is just the raw data object underlying a BigInt. Use with care!
// Most code should be using BigInts instead.
V8_OBJECT class BigIntBase : public PrimitiveHeapObject {
+ V8_IT_OWN_TYPE;
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
inline uint32_t length() const {
return LengthBits::decode(bitfield_.load(std::memory_order_relaxed));
@@ -170,6 +173,7 @@ V8_OBJECT class BigIntBase : public PrimitiveHeapObject {
} V8_OBJECT_END;
V8_OBJECT class FreshlyAllocatedBigInt : public BigIntBase {
+ V8_IT_REUSE_PARENT;
// This class is essentially the publicly accessible abstract version of
// MutableBigInt (which is a hidden implementation detail). It serves as
// the return type of Factory::NewBigInt, and makes it possible to enforce
@@ -192,6 +196,9 @@ V8_OBJECT class FreshlyAllocatedBigInt : public BigIntBase {
// Arbitrary precision integers in JavaScript.
V8_OBJECT class BigInt : public BigIntBase {
+ V8_IT_REUSE_PARENT;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
// Implementation of the Spec methods, see:
// https://tc39.es/proposal-bigint/#sec-numeric-types
diff --git a/deps/v8/src/objects/call-site-info.cc b/deps/v8/src/objects/call-site-info.cc
index a76617d88e2..2df21415440 100644
--- a/deps/v8/src/objects/call-site-info.cc
+++ b/deps/v8/src/objects/call-site-info.cc
@@ -117,7 +117,7 @@ bool CallSiteInfo::IsNative() const {
bool CallSiteInfo::IsEval() const {
if (auto script = GetScript()) {
- return script.value()->compilation_type() == Script::CompilationType::kEval;
+ return script.value()->has_eval_origin();
}
return false;
}
@@ -288,7 +288,7 @@ MaybeHandle<String> FormatEvalOrigin(Isolate* isolate,
DirectHandle<Script> eval_script(Cast<Script>(eval_shared->script()),
isolate);
builder.AppendCStringLiteral(" (");
- if (eval_script->compilation_type() == Script::CompilationType::kEval) {
+ if (eval_script->has_eval_origin()) {
// Eval script originated from another eval.
DirectHandle<String> str;
ASSIGN_RETURN_ON_EXCEPTION(isolate, str,
@@ -328,7 +328,7 @@ Handle<PrimitiveHeapObject> CallSiteInfo::GetEvalOrigin(
auto isolate = Isolate::Current();
DirectHandle<Script> script;
if (!GetScript(isolate, info).ToHandle(&script) ||
- script->compilation_type() != Script::CompilationType::kEval) {
+ !script->has_eval_origin()) {
return isolate->factory()->undefined_value();
}
return FormatEvalOrigin(isolate, script).ToHandleChecked();
diff --git a/deps/v8/src/objects/code.h b/deps/v8/src/objects/code.h
index ce0e11a4588..3f9ac591e9a 100644
--- a/deps/v8/src/objects/code.h
+++ b/deps/v8/src/objects/code.h
@@ -63,6 +63,8 @@ enum class LazyDeoptimizeReason : uint8_t;
// and referenced through indirect pointers, so they need to inherit from
// ExposedTrustedObject.
V8_OBJECT class Code : public ExposedTrustedObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
// When V8_EXTERNAL_CODE_SPACE is enabled, InstructionStream objects are
// allocated in a separate pointer compression cage instead of the cage where
@@ -536,6 +538,8 @@ V8_OBJECT class Code : public ExposedTrustedObject {
// InstructionStream may be forwarding pointers, thus type checks and normal
// (checked) casts do not work on GcSafeCode.
V8_OBJECT class GcSafeCode : public HeapObject {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
// Safe accessors (these just forward to Code methods).
inline Address instruction_start() const;
@@ -578,6 +582,8 @@ V8_OBJECT class GcSafeCode : public HeapObject {
// for example when a reference to a Code needs to be stored along other tagged
// pointers inside an array or similar container datastructure.
V8_OBJECT class CodeWrapper : public Struct {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
DECL_CODE_POINTER_ACCESSORS(code)
diff --git a/deps/v8/src/objects/compilation-cache-table-inl.h b/deps/v8/src/objects/compilation-cache-table-inl.h
index 794788f5877..4e421b94ccf 100644
--- a/deps/v8/src/objects/compilation-cache-table-inl.h
+++ b/deps/v8/src/objects/compilation-cache-table-inl.h
@@ -11,6 +11,7 @@
#include <optional>
#include "src/objects/name-inl.h"
+#include "src/objects/object-conversions-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/compilation-cache-table.h b/deps/v8/src/objects/compilation-cache-table.h
index b22d577a2c6..d2c1b5401b9 100644
--- a/deps/v8/src/objects/compilation-cache-table.h
+++ b/deps/v8/src/objects/compilation-cache-table.h
@@ -112,6 +112,8 @@ EXTERN_DECLARE_HASH_TABLE(CompilationCacheTable, CompilationCacheShape)
class CompilationCacheTable
: public HashTable<CompilationCacheTable, CompilationCacheShape> {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
// The 'script' cache contains SharedFunctionInfos. Once a root
// SharedFunctionInfo has become old enough that its bytecode is flushed, the
diff --git a/deps/v8/src/objects/contexts-inl.h b/deps/v8/src/objects/contexts-inl.h
index 94365b35b39..718f953280e 100644
--- a/deps/v8/src/objects/contexts-inl.h
+++ b/deps/v8/src/objects/contexts-inl.h
@@ -304,7 +304,6 @@ Tagged<Map> Context::GetInitialJSArrayMap(ElementsKind kind) const {
return Cast<Map>(initial_js_array_map);
}
-#ifdef V8_CPPGC_MICROTASK_QUEUE
MicrotaskQueue* NativeContext::microtask_queue() const {
i::IsolateForPointerCompression isolate = Isolate::Current();
return microtask_queue(isolate);
@@ -335,11 +334,6 @@ void NativeContext::init_microtask_queue(IsolateForPointerCompression isolate,
set_microtask_queue(isolate, queue);
}
}
-#else
-EXTERNAL_POINTER_ACCESSORS(NativeContext, microtask_queue, MicrotaskQueue*,
- kMicrotaskQueueOffset,
- kNativeContextMicrotaskQueueTag)
-#endif // V8_CPPGC_MICROTASK_QUEUE
bool NativeContext::HasSameSecurityTokenAs(Tagged<NativeContext> that) const {
return this == that || this->security_token() == that->security_token();
diff --git a/deps/v8/src/objects/contexts.h b/deps/v8/src/objects/contexts.h
index f07eeee7a68..e22720c8efd 100644
--- a/deps/v8/src/objects/contexts.h
+++ b/deps/v8/src/objects/contexts.h
@@ -194,7 +194,6 @@ enum ContextLookupFlags {
initial_disposable_stack_prototype) \
V(INITIAL_MAP_ITERATOR_PROTOTYPE_INDEX, JSObject, \
initial_map_iterator_prototype) \
- V(INITIAL_MAP_PROTOTYPE_INDEX, JSObject, initial_map_prototype) \
V(INITIAL_MAP_PROTOTYPE_MAP_INDEX, Map, initial_map_prototype_map) \
V(INITIAL_OBJECT_PROTOTYPE_INDEX, JSObject, initial_object_prototype) \
V(INITIAL_SET_ITERATOR_PROTOTYPE_INDEX, JSObject, \
@@ -205,7 +204,6 @@ enum ContextLookupFlags {
V(INITIAL_STRING_ITERATOR_PROTOTYPE_INDEX, JSObject, \
initial_string_iterator_prototype) \
V(INITIAL_STRING_PROTOTYPE_INDEX, JSObject, initial_string_prototype) \
- V(INITIAL_WEAKMAP_PROTOTYPE_INDEX, JSObject, initial_weakmap_prototype) \
V(INITIAL_WEAKMAP_PROTOTYPE_MAP_INDEX, Map, initial_weakmap_prototype_map) \
V(INITIAL_WEAKSET_PROTOTYPE_MAP_INDEX, Map, initial_weakset_prototype_map) \
V(INTL_COLLATOR_FUNCTION_INDEX, JSFunction, intl_collator_function) \
@@ -498,6 +496,7 @@ enum ContextLookupFlags {
V8_OBJECT class Context : public HeapObject {
public:
+ V8_IT_ABSTRACT;
inline int length() const;
inline void set_length(int value);
inline int length(RelaxedLoadTag) const;
@@ -790,6 +789,8 @@ V8_OBJECT class FunctionContext : public Context {
} V8_OBJECT_END;
V8_OBJECT class NativeContext : public Context {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
// TODO(neis): Move some stuff from Context here.
@@ -805,13 +806,8 @@ V8_OBJECT class NativeContext : public Context {
ReleaseStoreTag);
// [microtask_queue]: pointer to the MicrotaskQueue object.
-#ifdef V8_CPPGC_MICROTASK_QUEUE
static constexpr int kMicrotaskQueueSlotSize = kCppHeapPointerSlotSize;
DECL_CPP_POINTER_ACCESSORS(microtask_queue, MicrotaskQueue*)
-#else
- static constexpr int kMicrotaskQueueSlotSize = kExternalPointerSlotSize;
- DECL_EXTERNAL_POINTER_ACCESSORS(microtask_queue, MicrotaskQueue*)
-#endif // V8_CPPGC_MICROTASK_QUEUE
inline void synchronized_set_script_context_table(
Tagged<ScriptContextTable> script_context_table);
diff --git a/deps/v8/src/objects/cpp-heap-object-wrapper-inl.h b/deps/v8/src/objects/cpp-heap-object-wrapper-inl.h
index fc0a71e7ee0..0b790da1301 100644
--- a/deps/v8/src/objects/cpp-heap-object-wrapper-inl.h
+++ b/deps/v8/src/objects/cpp-heap-object-wrapper-inl.h
@@ -11,6 +11,7 @@
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/heap-object-field-inl.h"
#include "src/objects/heap-object-inl.h"
+#include "src/objects/managed.h"
#include "src/objects/objects-inl.h"
namespace v8::internal {
@@ -22,6 +23,9 @@ CppHeapObjectWrapper CppHeapObjectWrapper::From(
if (IsCppHeapExternalObject(object)) {
return CppHeapObjectWrapper(Cast<CppHeapExternalObject>(object));
}
+ if (IsCppGCManagedBase(object)) {
+ return CppHeapObjectWrapper(Cast<CppGCManagedBase>(object));
+ }
DCHECK(IsJSObject(object));
return CppHeapObjectWrapper(Cast<JSObject>(object));
}
@@ -32,6 +36,11 @@ CppHeapObjectWrapper::CppHeapObjectWrapper(Tagged<CppHeapExternalObject> object)
DCHECK(IsCppHeapPointerWrapperObject(object));
}
+CppHeapObjectWrapper::CppHeapObjectWrapper(Tagged<CppGCManagedBase> object)
+ : object_(object), offset_(offsetof(CppGCManagedBase, cpp_gc_wrapper_)) {
+ DCHECK(IsCppHeapPointerWrapperObject(object));
+}
+
CppHeapObjectWrapper::CppHeapObjectWrapper(Tagged<JSObject> object)
: object_(object),
offset_(offsetof(JSAPIObjectWithEmbedderSlots, cpp_heap_wrappable_)) {
diff --git a/deps/v8/src/objects/cpp-heap-object-wrapper.h b/deps/v8/src/objects/cpp-heap-object-wrapper.h
index 71840b9b060..7d8424426cf 100644
--- a/deps/v8/src/objects/cpp-heap-object-wrapper.h
+++ b/deps/v8/src/objects/cpp-heap-object-wrapper.h
@@ -12,11 +12,14 @@
namespace v8::internal {
+class CppGCManagedBase;
+class EmbedderDataArray;
class NativeContext;
// Object types that can have a cpp heap object pointer field.
using CppHeapPointerWrapperObjectT =
- UnionOf<JSObject, CppHeapExternalObject, NativeContext>;
+ UnionOf<JSObject, CppHeapExternalObject, NativeContext, CppGCManagedBase,
+ EmbedderDataArray>;
// Helper union that doesn't actually exist as type. Used to get and set the cpp
// heap pointer for objects that are associated with one. Use by value.
@@ -27,6 +30,7 @@ class CppHeapObjectWrapper {
V8_INLINE explicit CppHeapObjectWrapper(Tagged<JSObject> object);
V8_INLINE explicit CppHeapObjectWrapper(Tagged<CppHeapExternalObject> object);
+ V8_INLINE explicit CppHeapObjectWrapper(Tagged<CppGCManagedBase> object);
V8_INLINE void InitializeCppHeapWrapper();
diff --git a/deps/v8/src/objects/data-handler.h b/deps/v8/src/objects/data-handler.h
index 4da79c3c0c7..647b6536724 100644
--- a/deps/v8/src/objects/data-handler.h
+++ b/deps/v8/src/objects/data-handler.h
@@ -16,6 +16,8 @@ namespace internal {
// DataHandler is a base class for load and store handlers that can't be
// encoded in one Smi. Kind of a handler can be deduced from instance type.
V8_OBJECT class DataHandler : public Struct {
+ V8_IT_ABSTRACT;
+
public:
static constexpr int OffsetOf(int index);
static constexpr int SizeFor(int count);
diff --git a/deps/v8/src/objects/debug-objects-inl.h b/deps/v8/src/objects/debug-objects-inl.h
index 4e36b7ed07a..1137d91e06f 100644
--- a/deps/v8/src/objects/debug-objects-inl.h
+++ b/deps/v8/src/objects/debug-objects-inl.h
@@ -261,6 +261,22 @@ void ErrorStackData::set_stack_trace(Tagged<StackTraceInfo> value,
stack_trace_.store(this, value, mode);
}
+Tagged<ByteArray> DebugScriptScopeInfo::numeric_data() const {
+ return numeric_data_.load();
+}
+void DebugScriptScopeInfo::set_numeric_data(Tagged<ByteArray> value,
+ WriteBarrierMode mode) {
+ numeric_data_.store(this, value, mode);
+}
+
+Tagged<FixedArray> DebugScriptScopeInfo::string_table() const {
+ return string_table_.load();
+}
+void DebugScriptScopeInfo::set_string_table(Tagged<FixedArray> value,
+ WriteBarrierMode mode) {
+ string_table_.store(this, value, mode);
+}
+
// CoverageInfo.
int32_t CoverageInfo::slot_count() const { return slot_count_; }
void CoverageInfo::set_slot_count(int32_t value) { slot_count_ = value; }
diff --git a/deps/v8/src/objects/debug-objects.h b/deps/v8/src/objects/debug-objects.h
index 7c6fb5db754..ce560b5d531 100644
--- a/deps/v8/src/objects/debug-objects.h
+++ b/deps/v8/src/objects/debug-objects.h
@@ -27,6 +27,7 @@ class BreakPoint;
class BreakPointInfo;
class StackFrameInfo;
class StackTraceInfo;
+class DebugScriptScopeInfo;
class BytecodeArray;
class StructBodyDescriptor;
@@ -429,6 +430,31 @@ V8_OBJECT class ErrorStackData : public Struct {
TaggedMember<StackTraceInfo> stack_trace_;
} V8_OBJECT_END;
+// DebugScriptScopeInfo holds the serialized scope tree of a Script for the
+// debugger. It caches lexical scope information (scopes, variables, positions)
+// to avoid reparsing the script on every pause or inspection step.
+//
+// The exact encoding of the data in `numeric_data` is described in
+// src/debug/debug-scope-info.cc.
+V8_OBJECT class DebugScriptScopeInfo : public Struct {
+ public:
+ inline Tagged<ByteArray> numeric_data() const;
+ inline void set_numeric_data(Tagged<ByteArray> value,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
+ inline Tagged<FixedArray> string_table() const;
+ inline void set_string_table(Tagged<FixedArray> value,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
+ DECL_VERIFIER(DebugScriptScopeInfo)
+ DECL_PRINTER(DebugScriptScopeInfo)
+
+ using BodyDescriptor = StructBodyDescriptor;
+
+ TaggedMember<ByteArray> numeric_data_;
+ TaggedMember<FixedArray> string_table_;
+} V8_OBJECT_END;
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/debug-objects.tq b/deps/v8/src/objects/debug-objects.tq
index 00a23021ab8..1ca08caea12 100644
--- a/deps/v8/src/objects/debug-objects.tq
+++ b/deps/v8/src/objects/debug-objects.tq
@@ -119,3 +119,18 @@ extern class ErrorStackData extends Struct {
// This holds the StackTraceInfo for inspector stack trace.
stack_trace: StackTraceInfo;
}
+
+// DebugScriptScopeInfo holds the serialized scope tree of a Script for the
+// debugger. It caches lexical scope information (scopes, variables, positions)
+// to avoid reparsing the script on every pause or debug evaluate.
+//
+// By default, V8 does not create instances of `DebugScriptScopeInfo`. Only
+// when the debugger is turned on AND we pause in a script the first time.
+//
+// The exact encoding of the data in `numeric_data` is described in
+// src/debug/debug-scope-info.cc.
+@cppObjectLayoutDefinition
+extern class DebugScriptScopeInfo extends Struct {
+ numeric_data: ByteArray;
+ string_table: FixedArray;
+}
diff --git a/deps/v8/src/objects/deoptimization-data.cc b/deps/v8/src/objects/deoptimization-data.cc
index 7e8165f1f2e..7a24f4c57a6 100644
--- a/deps/v8/src/objects/deoptimization-data.cc
+++ b/deps/v8/src/objects/deoptimization-data.cc
@@ -14,10 +14,6 @@
#include "src/objects/deoptimization-data-inl.h"
#include "src/objects/shared-function-info.h"
-#ifdef V8_USE_ZLIB
-#include "third_party/zlib/google/compression_utils_portable.h"
-#endif // V8_USE_ZLIB
-
namespace v8 {
namespace internal {
@@ -189,11 +185,6 @@ Tagged<SharedFunctionInfo> DeoptimizationData::GetInlinedFunction(int index) {
#ifdef DEBUG
void DeoptimizationData::Verify(Handle<BytecodeArray> bytecode) const {
-#ifdef V8_USE_ZLIB
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- return;
- }
-#endif // V8_USE_ZLIB
for (uint32_t i = 0; i < DeoptCount(); ++i) {
// Check the frame count and identify the bailout id of the top compilation
// unit.
@@ -296,30 +287,6 @@ void DeoptimizationData::PrintDeoptimizationData(std::ostream& os) const {
DeoptTranslationIterator::DeoptTranslationIterator(
base::Vector<const uint8_t> buffer, int index)
: buffer_(buffer), index_(index) {
-#ifdef V8_USE_ZLIB
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- const int size =
- base::ReadUnalignedValue<uint32_t>(reinterpret_cast<Address>(
- &buffer_[DeoptimizationFrameTranslation::kUncompressedSizeOffset]));
- uncompressed_contents_.insert(uncompressed_contents_.begin(), size, 0);
-
- uLongf uncompressed_size = size *
- DeoptimizationFrameTranslation::
- kDeoptimizationFrameTranslationElementSize;
-
- CHECK_EQ(zlib_internal::UncompressHelper(
- zlib_internal::ZRAW,
- reinterpret_cast<Bytef*>(uncompressed_contents_.data()),
- &uncompressed_size,
- buffer_.begin() +
- DeoptimizationFrameTranslation::kCompressedDataOffset,
- buffer_.length()),
- Z_OK);
- DCHECK(index >= 0 && index < size);
- return;
- }
-#endif // V8_USE_ZLIB
- DCHECK(!v8_flags.turbo_compress_frame_translations);
DCHECK(index >= 0 && index < buffer_.length());
// Starting at a location other than a BEGIN would make
// MATCH_PREVIOUS_TRANSLATION instructions not work.
@@ -334,9 +301,7 @@ DeoptimizationFrameTranslation::Iterator::Iterator(
index) {}
int32_t DeoptTranslationIterator::NextOperand() {
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- return uncompressed_contents_[index_++];
- } else if (remaining_ops_to_use_from_previous_translation_) {
+ if (remaining_ops_to_use_from_previous_translation_) {
int32_t value = base::VLQDecode(buffer_.begin(), &previous_index_);
DCHECK_LT(previous_index_, index_);
return value;
@@ -363,9 +328,7 @@ uint32_t DeoptTranslationIterator::NextUnsignedOperandAtPreviousIndex() {
}
uint32_t DeoptTranslationIterator::NextOperandUnsigned() {
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- return uncompressed_contents_[index_++];
- } else if (remaining_ops_to_use_from_previous_translation_) {
+ if (remaining_ops_to_use_from_previous_translation_) {
return NextUnsignedOperandAtPreviousIndex();
} else {
uint32_t value = base::VLQDecodeUnsigned(buffer_.begin(), &index_);
@@ -375,9 +338,6 @@ uint32_t DeoptTranslationIterator::NextOperandUnsigned() {
}
TranslationOpcode DeoptTranslationIterator::NextOpcode() {
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- return static_cast<TranslationOpcode>(NextOperandUnsigned());
- }
if (remaining_ops_to_use_from_previous_translation_) {
--remaining_ops_to_use_from_previous_translation_;
}
@@ -473,12 +433,8 @@ TranslationOpcode DeoptTranslationIterator::SeekNextFrame() {
}
bool DeoptTranslationIterator::HasNextOpcode() const {
- if (V8_UNLIKELY(v8_flags.turbo_compress_frame_translations)) {
- return index_ < static_cast<int>(uncompressed_contents_.size());
- } else {
- return index_ < buffer_.length() ||
- remaining_ops_to_use_from_previous_translation_ > 1;
- }
+ return index_ < buffer_.length() ||
+ remaining_ops_to_use_from_previous_translation_ > 1;
}
void DeoptTranslationIterator::SkipOpcodeAndItsOperandsAtPreviousIndex() {
diff --git a/deps/v8/src/objects/deoptimization-data.h b/deps/v8/src/objects/deoptimization-data.h
index f6a7547d6a1..bd956028244 100644
--- a/deps/v8/src/objects/deoptimization-data.h
+++ b/deps/v8/src/objects/deoptimization-data.h
@@ -22,6 +22,8 @@ namespace internal {
// This class holds data required during deoptimization. It does not have its
// own instance type.
class DeoptimizationLiteralArray : public TrustedWeakFixedArray {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
// Getters for literals. These include runtime checks that the pointer was not
// cleared, if the literal was held weakly.
@@ -186,6 +188,8 @@ class DeoptimizationLiteral {
// transform an optimized frame back into one or more unoptimized frames.
enum class TranslationOpcode;
class DeoptimizationFrameTranslation : public TrustedByteArray {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
struct FrameCount {
int total_frame_count;
@@ -194,17 +198,6 @@ class DeoptimizationFrameTranslation : public TrustedByteArray {
class Iterator;
-#ifdef V8_USE_ZLIB
- // Constants describing compressed DeoptimizationFrameTranslation layout. Only
- // relevant if
- // --turbo-compress-frame-translation is enabled.
- static constexpr int kUncompressedSizeOffset = 0;
- static constexpr int kUncompressedSizeSize = kInt32Size;
- static constexpr int kCompressedDataOffset =
- kUncompressedSizeOffset + kUncompressedSizeSize;
- static constexpr int kDeoptimizationFrameTranslationElementSize = kInt32Size;
-#endif // V8_USE_ZLIB
-
#ifdef ENABLE_DISASSEMBLER
void PrintFrameTranslation(
std::ostream& os, int index,
@@ -239,7 +232,6 @@ class DeoptTranslationIterator {
uint32_t NextUnsignedOperandAtPreviousIndex();
void SkipOpcodeAndItsOperandsAtPreviousIndex();
- std::vector<int32_t> uncompressed_contents_;
const base::Vector<const uint8_t> buffer_;
int index_;
@@ -271,6 +263,8 @@ class DeoptimizationFrameTranslation::Iterator
//
// It can be empty.
class DeoptimizationData : public ProtectedFixedArray {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
using SharedFunctionInfoWrapperOrSmi =
UnionOf<Smi, SharedFunctionInfoWrapper>;
diff --git a/deps/v8/src/objects/dependent-code.h b/deps/v8/src/objects/dependent-code.h
index a79d1cbf5b4..a17a728e4cb 100644
--- a/deps/v8/src/objects/dependent-code.h
+++ b/deps/v8/src/objects/dependent-code.h
@@ -31,6 +31,8 @@ using DependableObject =
// contents may shrink).
// TODO(jgruber): Consider adding physical shrinking.
class DependentCode : public WeakArrayList {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
enum DependencyGroup {
// Group of code objects that embed a transition to this map, and depend on
diff --git a/deps/v8/src/objects/descriptor-array.h b/deps/v8/src/objects/descriptor-array.h
index 4a9be39f70a..8e020a8b467 100644
--- a/deps/v8/src/objects/descriptor-array.h
+++ b/deps/v8/src/objects/descriptor-array.h
@@ -84,6 +84,8 @@ V8_OBJECT class EnumCache : public Struct {
// FieldType::None(), FieldType::Any() or a weak reference to a Map. All other
// references are strong.
V8_OBJECT class DescriptorArray : public HeapObject {
+ V8_IT_OWN_TYPE;
+
public:
// Do linear search for small arrays, and for searches in the background
// thread.
diff --git a/deps/v8/src/objects/dictionary-inl.h b/deps/v8/src/objects/dictionary-inl.h
index 4efbc70303a..b7c37e1bca2 100644
--- a/deps/v8/src/objects/dictionary-inl.h
+++ b/deps/v8/src/objects/dictionary-inl.h
@@ -12,7 +12,7 @@
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/hash-table-inl.h"
-#include "src/objects/objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-cell-inl.h"
// Has to be the last include (doesn't have include guards):
diff --git a/deps/v8/src/objects/elements.cc b/deps/v8/src/objects/elements.cc
index 22375d60c95..410bd48dc1a 100644
--- a/deps/v8/src/objects/elements.cc
+++ b/deps/v8/src/objects/elements.cc
@@ -23,6 +23,7 @@
#include "src/objects/js-array-inl.h"
#include "src/objects/js-shared-array.h"
#include "src/objects/keys.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/slots-atomic-inl.h"
#include "src/objects/slots.h"
@@ -2099,12 +2100,67 @@ class DictionaryElementsAccessor
return Just(false);
}
+ static bool IndexOfValueFastPath(Isolate* isolate,
+ DirectHandle<JSObject> receiver,
+ DirectHandle<Object> value,
+ size_t start_from, size_t length,
+ Maybe<int64_t>* result) {
+ DisallowGarbageCollection no_gc;
+ Tagged<NumberDictionary> dictionary =
+ Cast<NumberDictionary>(receiver->elements());
+ Tagged<Object> the_hole = ReadOnlyRoots(isolate).the_hole_value();
+ Tagged<Object> undefined = ReadOnlyRoots(isolate).undefined_value();
+
+ // Iterate the dictionary's entries directly (O(entries)) instead of
+ // probing every index in [start_from, length) (O(length)). This is
+ // unobservable as long as no entry is an accessor: reading data values
+ // and comparing them with StrictEquals has no side effects, and indexOf
+ // skips holes (HasProperty gates the Get in the spec), so the smallest
+ // matching entry index is exactly the spec's answer. If accessors are
+ // present, elements must be accessed in order via the slow path.
+ bool found = false;
+ uint32_t found_index = 0;
+ for (InternalIndex i : dictionary->IterateEntries()) {
+ Tagged<Object> k = dictionary->KeyAt(i);
+ if (k == the_hole) continue;
+ if (k == undefined) continue;
+
+ uint32_t index;
+ if (!Object::ToArrayIndex(k, &index) || index < start_from ||
+ index >= length) {
+ continue;
+ }
+
+ if (dictionary->DetailsAt(i).kind() == PropertyKind::kAccessor) {
+ // Restart from the beginning in the slow path, otherwise we may
+ // observably access getters out of order.
+ return false;
+ } else if (!found || index < found_index) {
+ Tagged<Object> element_k = dictionary->ValueAt(i);
+ if (Object::StrictEquals(*value, element_k)) {
+ found = true;
+ found_index = index;
+ }
+ }
+ }
+
+ *result = found ? Just(static_cast<int64_t>(found_index))
+ : Just(static_cast<int64_t>(-1));
+ return true;
+ }
+
static Maybe<int64_t> IndexOfValueImpl(Isolate* isolate,
DirectHandle<JSObject> receiver,
DirectHandle<Object> value,
size_t start_from, size_t length) {
DCHECK(JSObject::PrototypeHasNoElements(isolate, *receiver));
+ Maybe<int64_t> fast_result = Nothing<int64_t>();
+ if (DictionaryElementsAccessor::IndexOfValueFastPath(
+ isolate, receiver, value, start_from, length, &fast_result)) {
+ return fast_result;
+ }
+
ElementsKind original_elements_kind = receiver->GetElementsKind();
USE(original_elements_kind);
DirectHandle<NumberDictionary> dictionary(
@@ -2853,9 +2909,10 @@ class FastSmiOrObjectElementsAccessor
Subclass::EnsureFillRangeCapacity(isolate, receiver, start, end));
if (IsSmi(*obj_value)) {
- MemsetTagged(Cast<FixedArray>(receiver->elements())
- ->RawFieldOfElementAt(static_cast<uint32_t>(start)),
- *obj_value, end - start);
+ Relaxed_MemsetTagged(
+ Cast<FixedArray>(receiver->elements())
+ ->RawFieldOfElementAt(static_cast<uint32_t>(start)),
+ *obj_value, end - start);
return MaybeDirectHandle<Object>(receiver);
}
diff --git a/deps/v8/src/objects/embedder-data-array.cc b/deps/v8/src/objects/embedder-data-array.cc
index 470adad0863..e646bde5830 100644
--- a/deps/v8/src/objects/embedder-data-array.cc
+++ b/deps/v8/src/objects/embedder-data-array.cc
@@ -10,17 +10,11 @@
namespace v8 {
namespace internal {
-#ifdef V8_ENABLE_SANDBOX
+#ifdef V8_COMPRESS_POINTERS
namespace {
-ExternalPointerHandle LoadExternalPointerHandle(const EmbedderDataSlot& slot) {
- Address loc = slot.address() + EmbedderDataSlot::kExternalPointerOffset;
- return ExternalPointerSlot(loc, kAnyExternalPointerTagRange)
- .Relaxed_LoadHandle();
-}
-void StoreTaggedWithoutBarrier(const EmbedderDataSlot& slot,
- Tagged<Object> value) {
- Address loc = slot.address() + EmbedderDataSlot::kTaggedPayloadOffset;
- ObjectSlot(loc).Relaxed_Store(value);
+CppHeapPointerHandle LoadCppHeapPointerHandle(const EmbedderDataSlot& slot) {
+ Address loc = slot.address() + EmbedderDataSlot::kCppHeapPointerOffset;
+ return CppHeapPointerSlot(loc).Relaxed_LoadHandle();
}
} // namespace
#endif
@@ -34,22 +28,22 @@ DirectHandle<EmbedderDataArray> EmbedderDataArray::EnsureCapacity(
isolate->factory()->NewEmbedderDataArray(index + 1);
DisallowGarbageCollection no_gc;
// Last new space allocation does not require any write barriers.
-#ifdef V8_ENABLE_SANDBOX
+#ifdef V8_COMPRESS_POINTERS
for (int i = 0; i < array->length(); i++) {
EmbedderDataSlot src(*array, i);
EmbedderDataSlot dest(*new_array, i);
- ExternalPointerHandle src_handle = LoadExternalPointerHandle(src);
- if (src_handle != kNullExternalPointerHandle) {
- CHECK(dest.store_handle(isolate, *new_array, src_handle));
+ CppHeapPointerHandle src_handle = LoadCppHeapPointerHandle(src);
+ if (src_handle != kNullCppHeapPointerHandle) {
+ CHECK(dest.store_handle_without_barrier(isolate, src_handle));
} else {
- StoreTaggedWithoutBarrier(dest, src.load_tagged());
+ dest.store_tagged_without_barrier(src.load_tagged());
}
}
#else
size_t size = array->length() * kEmbedderDataSlotSize;
MemCopy(reinterpret_cast<void*>(new_array->slots_start()),
reinterpret_cast<void*>(array->slots_start()), size);
-#endif // V8_ENABLE_SANDBOX
+#endif // V8_COMPRESS_POINTERS
return new_array;
}
diff --git a/deps/v8/src/objects/embedder-data-array.h b/deps/v8/src/objects/embedder-data-array.h
index 3c8e209af9d..3164c34bddb 100644
--- a/deps/v8/src/objects/embedder-data-array.h
+++ b/deps/v8/src/objects/embedder-data-array.h
@@ -56,7 +56,8 @@ V8_OBJECT class EmbedderDataArray : public HeapObject {
} V8_OBJECT_END;
constexpr int EmbedderDataArray::SizeFor(int length) {
- static_assert(kEmbedderDataSlotSize == sizeof(Address));
+ static_assert(kEmbedderDataSlotSize >= sizeof(Address));
+ static_assert(kEmbedderDataSlotSize % sizeof(Address) == 0);
return OFFSET_OF_DATA_START(EmbedderDataArray) +
length * kEmbedderDataSlotSize;
}
diff --git a/deps/v8/src/objects/embedder-data-slot-inl.h b/deps/v8/src/objects/embedder-data-slot-inl.h
index 2e30d07ac0f..34c8b8fa955 100644
--- a/deps/v8/src/objects/embedder-data-slot-inl.h
+++ b/deps/v8/src/objects/embedder-data-slot-inl.h
@@ -8,13 +8,17 @@
#include "src/objects/embedder-data-slot.h"
// Include the non-inl header before the rest of the headers.
+#include "include/v8-cppgc.h"
+#include "include/v8-isolate.h"
#include "src/base/memory.h"
#include "src/common/globals.h"
+#include "src/handles/handles.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/embedder-data-array.h"
#include "src/objects/heap-object-field-inl.h"
#include "src/objects/heap-object-inl.h"
#include "src/objects/js-objects-inl.h"
+#include "src/sandbox/cppheap-pointer-inl.h"
#include "src/sandbox/external-pointer-inl.h"
#include "src/sandbox/isolate.h"
@@ -40,9 +44,7 @@ void EmbedderDataSlot::Initialize(Tagged<Object> initial_value) {
DCHECK(IsSmi(initial_value) ||
ReadOnlyHeap::Contains(Cast<HeapObject>(initial_value)));
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(initial_value);
-#ifdef V8_COMPRESS_POINTERS
- ObjectSlot(address() + kRawPayloadOffset).Relaxed_Store(Smi::zero());
-#endif
+ clear_cpp_heap_pointer_field(address());
}
Tagged<Object> EmbedderDataSlot::load_tagged() const {
@@ -51,10 +53,8 @@ Tagged<Object> EmbedderDataSlot::load_tagged() const {
void EmbedderDataSlot::store_smi(Tagged<Smi> value) {
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(value);
-#ifdef V8_COMPRESS_POINTERS
- // See gc_safe_store() for the reasons behind two stores.
- ObjectSlot(address() + kRawPayloadOffset).Relaxed_Store(Smi::zero());
-#endif
+ // See store_raw() for the reasons behind two stores.
+ clear_cpp_heap_pointer_field(address());
}
// static
@@ -70,11 +70,8 @@ void EmbedderDataSlot::store_tagged(Tagged<EmbedderDataArray> array,
ObjectSlot(tagged_addr).Relaxed_Store(value);
WriteBarrier::ForValue(&*array, MaybeObjectSlot(tagged_addr), value,
UPDATE_WRITE_BARRIER);
-#ifdef V8_COMPRESS_POINTERS
- // See gc_safe_store() for the reasons behind two stores.
- ObjectSlot(FIELD_ADDR(array, slot_offset + kRawPayloadOffset))
- .Relaxed_Store(Smi::zero());
-#endif
+ // See store_raw() for the reasons behind two stores.
+ clear_cpp_heap_pointer_field(FIELD_ADDR(array, slot_offset));
}
// static
@@ -90,111 +87,173 @@ void EmbedderDataSlot::store_tagged(Tagged<JSObject> object,
ObjectSlot(FIELD_ADDR(object, slot_offset + kTaggedPayloadOffset))
.Relaxed_Store(value);
WRITE_BARRIER(object, slot_offset + kTaggedPayloadOffset, value);
+ // See store_raw() for the reasons behind two stores.
+ clear_cpp_heap_pointer_field(FIELD_ADDR(object, slot_offset));
+}
+
+// static
+void EmbedderDataSlot::clear_cpp_heap_pointer_field(Address slot_address) {
#ifdef V8_COMPRESS_POINTERS
- // See gc_safe_store() for the reasons behind two stores.
- ObjectSlot(FIELD_ADDR(object, slot_offset + kRawPayloadOffset))
- .Relaxed_Store(Smi::zero());
+ CppHeapPointerSlot(slot_address + kCppHeapPointerOffset)
+ .Relaxed_StoreHandle(kNullCppHeapPointerHandle);
+#else
+ base::WriteUnalignedValue<Address>(slot_address + kCppHeapPointerOffset,
+ kNullAddress);
#endif
}
bool EmbedderDataSlot::ToAlignedPointer(
- IsolateForSandbox isolate, void** out_pointer,
- ExternalPointerTagRange tag_range) const {
+ IsolateForPointerCompression isolate, void** out_pointer,
+ CppHeapPointerTagRange tag_range) const {
// We don't care about atomicity of access here because embedder slots
// are accessed this way only from the main thread via API during "mutator"
- // phase which is propely synched with GC (concurrent marker may still look
+ // phase which is properly synched with GC (concurrent marker may still look
// at the tagged part of the embedder slot but read-only access is ok).
-#ifdef V8_ENABLE_SANDBOX
- // The raw part must always contain a valid external pointer table index.
- *out_pointer = reinterpret_cast<void*>(ReadExternalPointerField(
- address() + kExternalPointerOffset, isolate, tag_range));
+#ifdef V8_COMPRESS_POINTERS
+ CppHeapPointerSlot slot(address() + kCppHeapPointerOffset);
+ CppHeapPointerHandle handle = slot.Relaxed_LoadHandle();
+ if (handle == kNullCppHeapPointerHandle) {
+ *out_pointer = nullptr;
+ return true;
+ }
+ Address wrapper_addr =
+ isolate.GetCppHeapPointerTable().Get(handle, tag_range);
+ if (wrapper_addr == kNullAddress) {
+ *out_pointer = nullptr;
+ return true;
+ }
+ *out_pointer = reinterpret_cast<void*>(wrapper_addr);
return true;
#else
- Address raw_value;
- if (COMPRESS_POINTERS_BOOL) {
- // TODO(ishell, v8:8875): When pointer compression is enabled 8-byte size
- // fields (external pointers, doubles and BigInt data) are only kTaggedSize
- // aligned so we have to use unaligned pointer friendly way of accessing
- // them in order to avoid undefined behavior in C++ code.
- raw_value = base::ReadUnalignedValue<Address>(address());
- } else {
- raw_value = *location();
- }
+ Address raw_value =
+ base::ReadUnalignedValue<Address>(address() + kCppHeapPointerOffset);
*out_pointer = reinterpret_cast<void*>(raw_value);
- return HAS_SMI_TAG(raw_value);
-#endif // V8_ENABLE_SANDBOX
+ return true;
+#endif // V8_COMPRESS_POINTERS
}
-bool EmbedderDataSlot::ToGenericAlignedPointer(IsolateForSandbox isolate,
- void** out_pointer) const {
+bool EmbedderDataSlot::ToAlignedPointer(
+ IsolateForPointerCompression isolate, void** out_pointer,
+ ExternalPointerTagRange tag_range) const {
+ void* raw_ptr = nullptr;
+ if (!ToAlignedPointer(isolate, &raw_ptr,
+ {CppHeapPointerTag::kEmbedderDataSlotTag})) {
+ *out_pointer = nullptr;
+ return false;
+ }
+ if (!raw_ptr) {
+ *out_pointer = nullptr;
+ return true;
+ }
+ auto* wrapper = reinterpret_cast<EmbedderDataSlotWrapper*>(raw_ptr);
+ if (tag_range.Contains(wrapper->tag())) {
+ *out_pointer = wrapper->pointer();
+ return true;
+ }
+ *out_pointer = nullptr;
+ return true;
+}
+
+bool EmbedderDataSlot::ToGenericAlignedPointer(
+ IsolateForPointerCompression isolate, void** out_pointer) const {
return ToAlignedPointer(
isolate, out_pointer, {kFirstEmbedderDataTag, kLastEmbedderDataTag});
}
-bool EmbedderDataSlot::DeprecatedToAlignedPointer(IsolateForSandbox isolate,
- void** out_pointer) const {
+bool EmbedderDataSlot::DeprecatedToAlignedPointer(
+ IsolateForPointerCompression isolate, void** out_pointer) const {
return ToAlignedPointer(
isolate, out_pointer, {kFirstEmbedderDataTag, kLastEmbedderDataTag});
}
-bool EmbedderDataSlot::store_aligned_pointer(IsolateForSandbox isolate,
+bool EmbedderDataSlot::store_aligned_pointer(Isolate* isolate,
Tagged<HeapObject> host, void* ptr,
- ExternalPointerTag tag) {
+ CppHeapPointerTag tag) {
Address value = reinterpret_cast<Address>(ptr);
- if (!HAS_SMI_TAG(value)) return false;
-#ifdef V8_ENABLE_SANDBOX
- // When the sandbox is enabled, the external pointer handles in
- // EmbedderDataSlots are lazily initialized: initially they contain the null
- // external pointer handle (see EmbedderDataSlot::Initialize), and only once
- // an external pointer is stored in them are they properly initialized.
- // TODO(saelo): here we currently have to use the accessor on the host object
- // as we may need a write barrier. This is a bit awkward. Maybe we should
- // introduce helper methods on the ExternalPointerSlot class that allow us to
- // determine whether the slot needs to be initialized, in which case a write
- // barrier can be performed here.
- size_t offset = address() - host.address() + kExternalPointerOffset;
- host->WriteLazilyInitializedExternalPointerField(offset, isolate, value, tag);
+#ifdef V8_COMPRESS_POINTERS
+ CppHeapPointerSlot slot(address() + kCppHeapPointerOffset);
+ CppHeapPointerHandle handle = slot.Relaxed_LoadHandle();
+ CppHeapPointerTable& table =
+ IsolateForPointerCompression(isolate).GetCppHeapPointerTable();
+
+ if (ptr == nullptr) {
+ if (handle != kNullCppHeapPointerHandle) {
+ table.Set(handle, kNullAddress, tag);
+ }
+ } else {
+ if (handle == kNullCppHeapPointerHandle) {
+ CppHeapPointerTable::Space* space =
+ IsolateForPointerCompression(isolate).GetCppHeapPointerTableSpace();
+ handle = table.AllocateAndInitializeEntry(space, value, tag);
+ slot.Relaxed_StoreHandle(handle);
+ } else {
+ table.Set(handle, value, tag);
+ }
+ WriteBarrier::ForCppHeapPointer(Cast<CppHeapPointerWrapperObjectT>(host),
+ slot, ptr);
+ }
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(Smi::zero());
return true;
#else
- gc_safe_store(isolate, value);
+ base::WriteUnalignedValue<Address>(address() + kCppHeapPointerOffset, value);
+ ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(Smi::zero());
+ if (ptr != nullptr) {
+ CppHeapPointerSlot slot(address() + kCppHeapPointerOffset);
+ WriteBarrier::ForCppHeapPointer(Cast<CppHeapPointerWrapperObjectT>(host),
+ slot, ptr);
+ }
return true;
-#endif // V8_ENABLE_SANDBOX
+#endif // V8_COMPRESS_POINTERS
+}
+
+// static
+template <typename T>
+ requires std::is_same_v<EmbedderDataArray, T> ||
+ std::is_same_v<JSObject, T>
+bool EmbedderDataSlot::store_aligned_pointer(
+ Isolate* isolate, DirectHandle<T> host, int entry_or_embedder_field_index,
+ void* ptr, ExternalPointerTag tag) {
+ EmbedderDataSlotWrapper* wrapper = nullptr;
+ if (ptr != nullptr) {
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
+ cppgc::AllocationHandle& alloc_handle =
+ v8_isolate->GetCppHeap()->GetAllocationHandle();
+ wrapper = cppgc::MakeGarbageCollected<EmbedderDataSlotWrapper>(alloc_handle,
+ ptr, tag);
+ }
+ DisallowGarbageCollection no_gc;
+ EmbedderDataSlot slot(*host, entry_or_embedder_field_index);
+ return slot.store_aligned_pointer(isolate, *host, wrapper,
+ CppHeapPointerTag::kEmbedderDataSlotTag);
+}
+
+#ifdef V8_COMPRESS_POINTERS
+void EmbedderDataSlot::store_tagged_without_barrier(Tagged<Object> value) {
+ ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(value);
+ clear_cpp_heap_pointer_field(address());
}
-#ifdef V8_ENABLE_SANDBOX
-bool EmbedderDataSlot::store_handle(IsolateForSandbox isolate,
- Tagged<HeapObject> host,
- ExternalPointerHandle handle) {
- DCHECK_NE(handle, kNullExternalPointerHandle);
- // The actual type tag does not matter here, as it is only used to load the
- // correct external pointer table and space, both here and in the write
- // barrier code below. It only has to be in the range of embedder data tags.
- constexpr ExternalPointerTag kAnyTag = kFirstEmbedderDataTag;
- ExternalPointerTable& table = isolate.GetExternalPointerTableFor(kAnyTag);
- ExternalPointerTable::Space* space =
- isolate.GetExternalPointerTableSpaceFor(kAnyTag, host.address());
-
- ExternalPointerHandle new_handle = table.DuplicateEntry(space, handle);
- if (new_handle == kNullExternalPointerHandle) return false;
-
- auto location = reinterpret_cast<ExternalPointerHandle*>(
- address() + kExternalPointerOffset);
- DCHECK_EQ(base::AsAtomic32::Relaxed_Load(location),
- kNullExternalPointerHandle);
- base::AsAtomic32::Release_Store(location, new_handle);
- size_t offset = address() - host.address() + kExternalPointerOffset;
- // Use `offset` to avoid compilation issues for gn arg
- // `v8_disable_write_barriers = true`.
- USE(offset);
- EXTERNAL_POINTER_WRITE_BARRIER(host, static_cast<int>(offset), kAnyTag);
+bool EmbedderDataSlot::store_handle_without_barrier(
+ IsolateForPointerCompression isolate, CppHeapPointerHandle handle) {
+ DCHECK_NE(handle, kNullCppHeapPointerHandle);
+ CppHeapPointerTable& table = isolate.GetCppHeapPointerTable();
+ CppHeapPointerTable::Space* space = isolate.GetCppHeapPointerTableSpace();
+
+ CppHeapPointerHandle new_handle = table.DuplicateEntry(space, handle);
+ if (new_handle == kNullCppHeapPointerHandle) return false;
+
+ CppHeapPointerSlot slot(address() + kCppHeapPointerOffset);
+ DCHECK_EQ(slot.Relaxed_LoadHandle(), kNullCppHeapPointerHandle);
+ slot.Relaxed_StoreHandle(new_handle);
+
ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Store(Smi::zero());
return true;
}
-#endif // V8_ENABLE_SANDBOX
+#endif // V8_COMPRESS_POINTERS
EmbedderDataSlot::RawData EmbedderDataSlot::load_raw(
- IsolateForSandbox isolate, const DisallowGarbageCollection& no_gc) const {
+ IsolateForPointerCompression isolate,
+ const DisallowGarbageCollection& no_gc) const {
// We don't care about atomicity of access here because embedder slots
// are accessed this way only by serializer from the main thread when
// GC is not active (concurrent marker may still look at the tagged part
@@ -206,17 +265,15 @@ EmbedderDataSlot::RawData EmbedderDataSlot::load_raw(
// in order to avoid undefined behavior in C++ code.
return base::ReadUnalignedValue<EmbedderDataSlot::RawData>(address());
#else
- return *location();
+ return RawData{
+ base::ReadUnalignedValue<Address>(address() + kCppHeapPointerOffset),
+ ObjectSlot(address() + kTaggedPayloadOffset).Relaxed_Load().ptr()};
#endif
}
-void EmbedderDataSlot::store_raw(IsolateForSandbox isolate,
- EmbedderDataSlot::RawData data,
+void EmbedderDataSlot::store_raw(IsolateForPointerCompression isolate,
+ EmbedderDataSlot::RawData value,
const DisallowGarbageCollection& no_gc) {
- gc_safe_store(isolate, data);
-}
-
-void EmbedderDataSlot::gc_safe_store(IsolateForSandbox isolate, Address value) {
#ifdef V8_COMPRESS_POINTERS
static_assert(kSmiShiftSize == 0);
static_assert(SmiValuesAre31Bits());
@@ -236,10 +293,12 @@ void EmbedderDataSlot::gc_safe_store(IsolateForSandbox isolate, Address value) {
// The raw part of the payload does not contain a valid tagged value, so we
// need to use a raw store operation for it here.
AsAtomicTagged::Relaxed_Store(
- reinterpret_cast<AtomicTagged_t*>(address() + kRawPayloadOffset), hi);
+ reinterpret_cast<AtomicTagged_t*>(address() + kCppHeapPointerOffset), hi);
#else
ObjectSlot(address() + kTaggedPayloadOffset)
- .Relaxed_Store(Tagged<Smi>(value));
+ .Relaxed_Store(Tagged<Object>(value.tagged));
+ base::WriteUnalignedValue<Address>(address() + kCppHeapPointerOffset,
+ value.pointer);
#endif
}
@@ -250,13 +309,15 @@ bool EmbedderDataSlot::MustClearDuringSerialization(
// as a dangling pointer. For consistency it would be nice to avoid writing
// external pointers also in the wide-pointer case, but as we can't
// distinguish between Smi values and pointers we just leave them be.
-#ifdef V8_ENABLE_SANDBOX
- auto* location = reinterpret_cast<ExternalPointerHandle*>(
- address() + kExternalPointerOffset);
- return base::AsAtomic32::Relaxed_Load(location) != kNullExternalPointerHandle;
-#else // !V8_ENABLE_SANDBOX
- return false;
-#endif // !V8_ENABLE_SANDBOX
+#ifdef V8_COMPRESS_POINTERS
+ auto* location = reinterpret_cast<CppHeapPointerHandle*>(
+ address() + kCppHeapPointerOffset);
+ return base::AsAtomic32::Relaxed_Load(location) != kNullCppHeapPointerHandle;
+#else // !V8_COMPRESS_POINTERS
+ Address raw_value =
+ base::ReadUnalignedValue<Address>(address() + kCppHeapPointerOffset);
+ return raw_value != kNullAddress;
+#endif // !V8_COMPRESS_POINTERS
}
} // namespace internal
diff --git a/deps/v8/src/objects/embedder-data-slot.h b/deps/v8/src/objects/embedder-data-slot.h
index d3c3e595eaa..3a12b5e7771 100644
--- a/deps/v8/src/objects/embedder-data-slot.h
+++ b/deps/v8/src/objects/embedder-data-slot.h
@@ -5,8 +5,12 @@
#ifndef V8_OBJECTS_EMBEDDER_DATA_SLOT_H_
#define V8_OBJECTS_EMBEDDER_DATA_SLOT_H_
+#include <type_traits>
#include <utility>
+#include "include/cppgc/allocation.h"
+#include "include/cppgc/garbage-collected.h"
+#include "include/cppgc/visitor.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/objects/slots.h"
@@ -22,6 +26,24 @@ class EmbedderDataArray;
class JSObject;
class Object;
+// A wrapper CppGC object referenced by the CppHeapPointerTable for entries in
+// EmbedderDataSlot that store arbitrary C++ pointers.
+class EmbedderDataSlotWrapper final
+ : public cppgc::GarbageCollected<EmbedderDataSlotWrapper> {
+ public:
+ EmbedderDataSlotWrapper(void* pointer, ExternalPointerTag tag)
+ : pointer_(pointer), tag_(tag) {}
+
+ void* pointer() const { return pointer_; }
+ ExternalPointerTag tag() const { return tag_; }
+
+ void Trace(cppgc::Visitor*) const {}
+
+ private:
+ void* const pointer_;
+ const ExternalPointerTag tag_;
+};
+
// An EmbedderDataSlot instance describes a kEmbedderDataSlotSize field ("slot")
// holding an embedder data which may contain raw aligned pointer or a tagged
// pointer (smi or heap object).
@@ -33,60 +55,22 @@ class Object;
class EmbedderDataSlot
: public SlotBase<EmbedderDataSlot, Address, kTaggedSize> {
public:
-#ifdef V8_ENABLE_SANDBOX
// When the sandbox is enabled, an EmbedderDataSlot always contains a valid
- // external pointer table index (initially, zero) in it's "raw" part and a
+ // CppHeap pointer table index (initially, zero) in its "raw" part and a
// valid tagged value in its 32-bit "tagged" part.
+ // When pointer compression is disabled, an EmbedderDataSlot similarly
+ // contains two separate fields: a tagged value in its "tagged" part and a
+ // raw external pointer in its "raw" part.
//
- // Layout (sandbox):
+ // Layout (sandbox or no pointer compression):
// +-----------------------------------+-----------------------------------+
- // | Tagged (Smi/CompressedPointer) | External Pointer Table Index |
+ // | Tagged (Smi/Pointer) | CppHeap Pointer Table Index / |
+ // | | CppHeap Pointer |
// +-----------------------------------+-----------------------------------+
// ^ ^
- // kTaggedPayloadOffset kRawPayloadOffset
- // kExternalPointerOffset
+ // kTaggedPayloadOffset kCppHeapPointerOffset
static constexpr int kTaggedPayloadOffset = 0;
- static constexpr int kRawPayloadOffset = kTaggedSize;
- static constexpr int kExternalPointerOffset = kRawPayloadOffset;
-#elif defined(V8_COMPRESS_POINTERS) && defined(V8_TARGET_BIG_ENDIAN)
- // The raw payload is located in the other "tagged" part of the full pointer
- // and cotains the upper part of an aligned address. The raw part is not
- // expected to look like a tagged value.
- //
- // Layout (big endian pointer compression):
- // +-----------------------------------+-----------------------------------+
- // | External Pointer (high word) | Tagged (Smi/CompressedPointer) |
- // | | OR External Pointer (low word) |
- // +-----------------------------------+-----------------------------------+
- // ^ ^
- // kRawPayloadOffset kTaggedayloadOffset
- // kExternalPointerOffset
- static constexpr int kExternalPointerOffset = 0;
- static constexpr int kRawPayloadOffset = 0;
- static constexpr int kTaggedPayloadOffset = kTaggedSize;
-#elif defined(V8_COMPRESS_POINTERS) && defined(V8_TARGET_LITTLE_ENDIAN)
- // Layout (little endian pointer compression):
- // +-----------------------------------+-----------------------------------+
- // | Tagged (Smi/CompressedPointer) | External Pointer (high word) |
- // | OR External Pointer (low word) | |
- // +-----------------------------------+-----------------------------------+
- // ^ ^
- // kTaggedPayloadOffset kRawPayloadOffset
- // kExternalPointerOffset
- static constexpr int kExternalPointerOffset = 0;
- static constexpr int kTaggedPayloadOffset = 0;
- static constexpr int kRawPayloadOffset = kTaggedSize;
-#else
- // Layout (no pointer compression):
- // +-----------------------------------------------------------------------+
- // | Tagged (Smi/Pointer) OR External Pointer |
- // +-----------------------------------------------------------------------+
- // ^
- // kTaggedPayloadOffset
- // kExternalPointerOffset
- static constexpr int kTaggedPayloadOffset = 0;
- static constexpr int kExternalPointerOffset = 0;
-#endif // V8_ENABLE_SANDBOX
+ static constexpr int kCppHeapPointerOffset = kTaggedSize;
static constexpr int kRequiredPtrAlignment = kSmiTagSize;
@@ -95,7 +79,18 @@ class EmbedderDataSlot
V8_INLINE EmbedderDataSlot(Tagged<JSObject> object, int embedder_field_index);
// Opaque type used for storing raw embedder data.
- using RawData = Address;
+#ifdef V8_COMPRESS_POINTERS
+ using RawData = uint64_t;
+#else
+ struct RawData {
+ Address pointer;
+ Address tagged;
+ constexpr RawData() : pointer(0), tagged(0) {}
+ constexpr RawData(Address pointer, Address tagged)
+ : pointer(pointer), tagged(tagged) {}
+ constexpr RawData(Address addr) : pointer(addr), tagged(0) {}
+ };
+#endif
V8_INLINE void Initialize(Tagged<Object> initial_value);
@@ -118,41 +113,63 @@ class EmbedderDataSlot
// When the sandbox is enabled, calling this method when the raw part of the
// slot does not contain valid external pointer table index is undefined
// behaviour and most likely result in crashes.
- V8_INLINE bool ToAlignedPointer(IsolateForSandbox isolate, void** out_result,
+ V8_INLINE bool ToAlignedPointer(IsolateForPointerCompression isolate,
+ void** out_result,
ExternalPointerTagRange tag_range) const;
+ V8_INLINE bool ToAlignedPointer(IsolateForPointerCompression isolate,
+ void** out_result,
+ CppHeapPointerTagRange tag_range) const;
- V8_INLINE bool ToGenericAlignedPointer(IsolateForSandbox isolate,
+ V8_INLINE bool ToGenericAlignedPointer(IsolateForPointerCompression isolate,
void** out_result) const;
// Deprecated, either use ToAlignedPointer with a `tag_range`, or use
// `ToGenericAlignedPointer to indicate that the read pointer will not be
// dereferenced.
- V8_INLINE bool DeprecatedToAlignedPointer(IsolateForSandbox isolate,
- void** out_result) const;
+ V8_INLINE bool DeprecatedToAlignedPointer(
+ IsolateForPointerCompression isolate, void** out_result) const;
- // Returns true if the pointer was successfully stored or false it the pointer
+ // Returns true if the pointer was successfully stored or false if the pointer
// was improperly aligned.
V8_INLINE V8_WARN_UNUSED_RESULT bool store_aligned_pointer(
- IsolateForSandbox isolate, Tagged<HeapObject> host, void* ptr,
- ExternalPointerTag tag);
+ Isolate* isolate, Tagged<HeapObject> host, void* ptr,
+ CppHeapPointerTag tag);
+ template <typename T>
+ requires std::is_same_v<EmbedderDataArray, T> || std::is_same_v<JSObject, T>
+ static V8_INLINE V8_WARN_UNUSED_RESULT bool store_aligned_pointer(
+ Isolate* isolate, DirectHandle<T> host, int entry_or_embedder_field_index,
+ void* ptr, ExternalPointerTag tag);
+
+#ifdef V8_COMPRESS_POINTERS
+ V8_INLINE void store_tagged_without_barrier(Tagged<Object> value);
-#ifdef V8_ENABLE_SANDBOX
- V8_INLINE V8_WARN_UNUSED_RESULT bool store_handle(
- IsolateForSandbox isolate, Tagged<HeapObject> host,
- ExternalPointerHandle handle);
-#endif // V8_ENABLE_SANDBOX
+ V8_INLINE V8_WARN_UNUSED_RESULT bool store_handle_without_barrier(
+ IsolateForPointerCompression isolate, CppHeapPointerHandle handle);
+#endif // V8_COMPRESS_POINTERS
V8_INLINE bool MustClearDuringSerialization(
const DisallowGarbageCollection& no_gc);
- V8_INLINE RawData load_raw(IsolateForSandbox isolate,
+
+ // IMPORTANT: load_raw and store_raw are strictly intended for temporary
+ // in-place save-and-restore of an object's embedder slots during snapshot
+ // serialization (see ContextSerializer::SerializeObjectWithEmbedderFields).
+ // They must NEVER be used to copy or duplicate embedder slot contents across
+ // different objects or slots, as doing so would duplicate raw
+ // CppHeapPointerHandles without updating the CppHeapPointerTable.
+ V8_INLINE RawData load_raw(IsolateForPointerCompression isolate,
const DisallowGarbageCollection& no_gc) const;
- V8_INLINE void store_raw(IsolateForSandbox isolate, RawData data,
+
+ // IMPORTANT: load_raw and store_raw are strictly intended for temporary
+ // in-place save-and-restore of an object's embedder slots during snapshot
+ // serialization (see ContextSerializer::SerializeObjectWithEmbedderFields).
+ // They must NEVER be used to copy or duplicate embedder slot contents across
+ // different objects or slots, as doing so would duplicate raw
+ // CppHeapPointerHandles without updating the CppHeapPointerTable.
+ V8_INLINE void store_raw(IsolateForPointerCompression isolate, RawData data,
const DisallowGarbageCollection& no_gc);
private:
- // Stores given value to the embedder data slot in a concurrent-marker
- // friendly manner (tagged part of the slot is written atomically).
- V8_INLINE void gc_safe_store(IsolateForSandbox isolate, Address value);
+ static V8_INLINE void clear_cpp_heap_pointer_field(Address slot_address);
};
} // namespace internal
diff --git a/deps/v8/src/objects/feedback-vector-inl.h b/deps/v8/src/objects/feedback-vector-inl.h
index 1e2f548eff3..b0179811c49 100644
--- a/deps/v8/src/objects/feedback-vector-inl.h
+++ b/deps/v8/src/objects/feedback-vector-inl.h
@@ -11,6 +11,7 @@
#include <optional>
#include "src/common/globals.h"
+#include "src/execution/isolate.h"
#include "src/heap/heap-write-barrier-inl.h"
#include "src/objects/code-inl.h"
#include "src/objects/feedback-cell-inl.h"
@@ -266,22 +267,30 @@ bool FeedbackVector::tiering_in_progress() const {
std::optional<Tagged<Code>> FeedbackVector::GetOptimizedOsrCode(
Isolate* isolate, Handle<BytecodeArray> bytecode, FeedbackSlot slot) {
+ DCHECK_EQ(ThreadId::Current(), isolate->thread_id());
+
+ // Since this is only called in the main thread, we don't need to take the
+ // mutex for reading.
Tagged<MaybeObject> maybe_code = Get(slot);
if (maybe_code.IsCleared()) return {};
Tagged<Code> code =
Cast<CodeWrapper>(maybe_code.GetHeapObject())->code(isolate);
- if (code->marked_for_deoptimization()) {
+ if (!code->marked_for_deoptimization()) return code;
+
+ {
// Clear the cached Code object if deoptimized.
// TODO(jgruber): Add tracing.
+ base::MutexGuard mutex_guard(isolate->feedback_vector_access());
Set(slot, ClearedValue());
- if (!bytecode.is_null()) {
- RecomputeOptimizedOsrCodeFlags(isolate, bytecode);
- }
- return {};
}
- return code;
+ // RecomputeOptimizedOsrCodeFlags can take the mutex again, so it has to run
+ // after releasing it above.
+ if (!bytecode.is_null()) {
+ RecomputeOptimizedOsrCodeFlags(isolate, bytecode);
+ }
+ return {};
}
void FeedbackVector::RecomputeOptimizedOsrCodeFlags(
@@ -292,7 +301,7 @@ void FeedbackVector::RecomputeOptimizedOsrCodeFlags(
for (; !it.done(); it.Advance()) {
if (it.current_bytecode() != interpreter::Bytecode::kJumpLoop) continue;
if (auto code = GetOptimizedOsrCode(isolate, {}, it.GetSlotOperand(2))) {
- if ((*code)->marked_for_deoptimization()) continue;
+ DCHECK(!(*code)->marked_for_deoptimization());
turbofan |= (*code)->is_turbofanned();
maglev |= (*code)->is_maglevved();
}
diff --git a/deps/v8/src/objects/feedback-vector.cc b/deps/v8/src/objects/feedback-vector.cc
index 71c4285d8b6..7b3a481bd77 100644
--- a/deps/v8/src/objects/feedback-vector.cc
+++ b/deps/v8/src/objects/feedback-vector.cc
@@ -15,6 +15,7 @@
#include "src/heap/local-factory-inl.h"
#include "src/ic/handler-configuration-inl.h"
#include "src/ic/ic-inl.h"
+#include "src/objects/code-inl.h"
#include "src/objects/data-handler-inl.h"
#include "src/objects/feedback-cell.h"
#include "src/objects/feedback-vector-inl.h"
@@ -405,10 +406,17 @@ void FeedbackVector::SetOptimizedOsrCode(Isolate* isolate, FeedbackSlot slot,
Tagged<Code> code) {
DCHECK(CodeKindIsOptimizedJSFunction(code->kind()));
DCHECK(!slot.IsInvalid());
+
+ // The synchronization mechanism to use here depends on the slot size:
+ DCHECK_EQ(GetKind(slot), FeedbackSlotKind::kJumpLoop);
+ DCHECK_GT(FeedbackMetadata::GetSlotSize(FeedbackSlotKind::kJumpLoop), 1);
+
auto current = GetOptimizedOsrCode(isolate, {}, slot);
if (V8_UNLIKELY(current && current.value()->kind() > code->kind())) {
return;
}
+
+ base::MutexGuard mutex_guard(isolate->feedback_vector_access());
Set(slot, MakeWeak(code->wrapper()));
set_maybe_has_optimized_osr_code(true, code->kind());
}
@@ -1097,6 +1105,21 @@ SpeculationMode FeedbackNexus::GetSpeculationMode() {
return SpeculationModeField::decode(value);
}
+std::optional<Tagged<Code>> FeedbackNexus::GetOptimizedOsrCode(
+ IsolateForSandbox isolate) const {
+ DCHECK_EQ(kind(), FeedbackSlotKind::kJumpLoop);
+ Tagged<MaybeObject> maybe_code = GetFeedback();
+ Tagged<HeapObject> heap_object;
+ if (maybe_code.GetHeapObjectIfWeak(&heap_object)) {
+ Tagged<CodeWrapper> code_wrapper = Cast<CodeWrapper>(heap_object);
+ Tagged<Code> code = code_wrapper->code(isolate, kAcquireLoad);
+ if (!code->marked_for_deoptimization()) {
+ return code;
+ }
+ }
+ return {};
+}
+
CallFeedbackContent FeedbackNexus::GetCallFeedbackContent() {
DCHECK(IsCallICKind(kind()));
diff --git a/deps/v8/src/objects/feedback-vector.h b/deps/v8/src/objects/feedback-vector.h
index 2ca26741f48..079645e33e8 100644
--- a/deps/v8/src/objects/feedback-vector.h
+++ b/deps/v8/src/objects/feedback-vector.h
@@ -304,10 +304,10 @@ V8_OBJECT class FeedbackVector : public HeapObject {
public:
// Bit positions in |osr_state|.
using OsrUrgencyBits = base::BitField<uint32_t, 0, 3, uint8_t>;
- using MaybeHasMaglevOsrCodeBit = OsrUrgencyBits::Next<bool, 1>;
- using MaybeHasTurbofanOsrCodeBit = MaybeHasMaglevOsrCodeBit::Next<bool, 1>;
+ using MaybeHasTurbofanOsrCodeBit = OsrUrgencyBits::Next<bool, 1>;
+ using MaybeHasMaglevOsrCodeBit = MaybeHasTurbofanOsrCodeBit::Next<bool, 1>;
using DontUseTheseBitsUnlessBeneficialBits =
- MaybeHasTurbofanOsrCodeBit::Next<uint32_t, 3>;
+ MaybeHasMaglevOsrCodeBit::Next<uint32_t, 3>;
// Bit positions in |flags|.
using TieringInProgressBit = base::BitField<bool, 0, 1, uint16_t>;
using OsrTieringInProgressBit = TieringInProgressBit::Next<bool, 1>;
@@ -386,11 +386,20 @@ V8_OBJECT class FeedbackVector : public HeapObject {
// Optimized OSR'd code is cached in JumpLoop feedback vector slots. The
// slots either contain a Code object or the ClearedValue.
+ //
+ // These all run on the main thread only, which is the sole writer of feedback
+ // slots, so reading a slot needs no synchronization. Writing one does:
+ // background compilation threads read JumpLoop slots as a pair under
+ // feedback_vector_access (NexusConfig::GetFeedbackPair), so every write has
+ // to hold that mutex. Note that GetOptimizedOsrCode writes too: it clears the
+ // slot if the cached code was deoptimized.
inline std::optional<Tagged<Code>> GetOptimizedOsrCode(
Isolate* isolate, Handle<BytecodeArray> bytecode_array,
FeedbackSlot slot);
void SetOptimizedOsrCode(Isolate* isolate, FeedbackSlot slot,
Tagged<Code> code);
+ // Acquires feedback_vector_access whenever it has to clear a slot, so it must
+ // not be called while holding it.
inline void RecomputeOptimizedOsrCodeFlags(
Isolate* isolate, Handle<BytecodeArray> bytecode_array);
@@ -1087,6 +1096,10 @@ class V8_EXPORT_PRIVATE FeedbackNexus final {
SpeculationModeField::Next<CallFeedbackContent, 1>;
using CallCountField = CallFeedbackContentField::Next<uint32_t, 29>;
+ // For JumpLoop.
+ std::optional<Tagged<Code>> GetOptimizedOsrCode(
+ IsolateForSandbox isolate) const;
+
// For InstanceOf ICs.
MaybeDirectHandle<JSObject> GetConstructorFeedback() const;
diff --git a/deps/v8/src/objects/feedback-vector.tq b/deps/v8/src/objects/feedback-vector.tq
index 3be2910b10e..a116ed20ef3 100644
--- a/deps/v8/src/objects/feedback-vector.tq
+++ b/deps/v8/src/objects/feedback-vector.tq
@@ -18,8 +18,8 @@ bitfield struct OsrState extends uint8 {
// maybe_has_(maglev|turbofan)_osr_code can be loaded with a single load
// (i.e. no masking required).
osr_urgency: uint32: 3 bit;
- maybe_has_maglev_osr_code: bool: 1 bit;
maybe_has_turbofan_osr_code: bool: 1 bit;
+ maybe_has_maglev_osr_code: bool: 1 bit;
// In order to have fast OSR checks in Ignition and Sparkplug, these bits
// should remain 0. That way, the OSR check can be implemented as a single
// comparison.
diff --git a/deps/v8/src/objects/fixed-array-base.h b/deps/v8/src/objects/fixed-array-base.h
index 0db0fb7a955..e0d27d33608 100644
--- a/deps/v8/src/objects/fixed-array-base.h
+++ b/deps/v8/src/objects/fixed-array-base.h
@@ -20,13 +20,15 @@ namespace v8::internal {
// This could be larger, but the next power of two up would push the maximum
// byte size of FixedDoubleArray out of int32 range.
static constexpr uint32_t kMaxFixedArrayCapacity =
- V8_LOWER_LIMITS_MODE_BOOL ? (16 * 1024 * 1024) : (128 * 1024 * 1024);
+ V8_LOWER_LIMITS_MODE_BOOL ? (1 * 1024 * 1024) : (128 * 1024 * 1024);
// Common superclass for the FixedArray family of heap classes. Owns the
// length_ field (and optional_padding_ for TAGGED_SIZE_8_BYTES); concrete
// subclasses get them via inheritance and append their own fields after
// kHeaderSize.
V8_OBJECT class FixedArrayBase : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
static constexpr int kLengthOffset = sizeof(HeapObject);
#if TAGGED_SIZE_8_BYTES
@@ -63,6 +65,8 @@ V8_OBJECT class FixedArrayBase : public HeapObject {
// optional_padding_ fields but extends TrustedObject so its concrete
// subclasses live in trusted space.
V8_OBJECT class TrustedFixedArrayBase : public TrustedObject {
+ V8_IT_ABSTRACT;
+
public:
static constexpr int kLengthOffset = sizeof(TrustedObject);
#if TAGGED_SIZE_8_BYTES
diff --git a/deps/v8/src/objects/fixed-array.h b/deps/v8/src/objects/fixed-array.h
index d23a609e3d8..b9519556b33 100644
--- a/deps/v8/src/objects/fixed-array.h
+++ b/deps/v8/src/objects/fixed-array.h
@@ -225,8 +225,10 @@ constexpr int TaggedArrayBase<Derived, ElementT, Super>::MaxRegularCapacity() {
}
// FixedArray describes fixed-sized arrays with element type Object.
-V8_OBJECT class FixedArray : public TaggedArrayBase<FixedArray, Object> {
- using Super = TaggedArrayBase<FixedArray, Object>;
+V8_OBJECT class FixedArray
+ : public TaggedArrayBase<FixedArray, Object, FixedArrayBase> {
+ V8_IT_OWN_TYPE;
+ using Super = TaggedArrayBase<FixedArray, Object, FixedArrayBase>;
public:
static constexpr RootIndex kMapRootIndex = RootIndex::kFixedArrayMap;
@@ -402,13 +404,15 @@ V8_OBJECT class ProtectedFixedArray
// check: [FIRST_FIXED_ARRAY_TYPE, LAST_FIXED_ARRAY_TYPE].
V8_OBJECT
class FixedArrayExact final : public FixedArray {
+ V8_IT_NO_AUTO_CHECKER;
} V8_OBJECT_END;
// WeakFixedArray describes fixed-sized arrays with element type
// Tagged<MaybeObject>.
V8_OBJECT class WeakFixedArray
- : public TaggedArrayBase<WeakFixedArray, MaybeObject> {
- using Super = TaggedArrayBase<WeakFixedArray, MaybeObject>;
+ : public TaggedArrayBase<WeakFixedArray, MaybeObject, FixedArrayBase> {
+ V8_IT_OWN_TYPE;
+ using Super = TaggedArrayBase<WeakFixedArray, MaybeObject, FixedArrayBase>;
public:
static constexpr RootIndex kMapRootIndex = RootIndex::kWeakFixedArrayMap;
@@ -436,8 +440,10 @@ V8_OBJECT class WeakFixedArray
// It acts as a fixed-size lossy hashmap-based cache, where collisions
// overwrite existing entries.
V8_OBJECT class WeakHomomorphicFixedArray
- : public TaggedArrayBase<WeakHomomorphicFixedArray, MaybeObject> {
- using Super = TaggedArrayBase<WeakHomomorphicFixedArray, MaybeObject>;
+ : public TaggedArrayBase<WeakHomomorphicFixedArray, MaybeObject,
+ FixedArrayBase> {
+ using Super =
+ TaggedArrayBase<WeakHomomorphicFixedArray, MaybeObject, FixedArrayBase>;
public:
static constexpr RootIndex kMapRootIndex =
@@ -512,6 +518,7 @@ V8_OBJECT class ProtectedWeakFixedArray
DECL_VERIFIER(ProtectedWeakFixedArray)
class BodyDescriptor;
+
public:
// length_ / optional_padding_ live in TrustedFixedArrayBase.
FLEXIBLE_ARRAY_MEMBER(ElementMemberT, objects);
@@ -524,6 +531,7 @@ V8_OBJECT class ProtectedWeakFixedArray
// dynamically with O(1) amortized insertion.
V8_OBJECT class WeakArrayList
: public TaggedArrayBase<WeakArrayList, MaybeObject, HeapObject> {
+ V8_IT_OWN_TYPE;
using Super = TaggedArrayBase<WeakArrayList, MaybeObject, HeapObject>;
public:
@@ -654,7 +662,6 @@ class WeakArrayList::Iterator {
DISALLOW_GARBAGE_COLLECTION(no_gc_)
};
-
// A generic array that grows dynamically with O(1) amortized insertion.
V8_OBJECT class ArrayList
: public TaggedArrayBase<ArrayList, Object, HeapObject> {
diff --git a/deps/v8/src/objects/fixed-primitive-array.h b/deps/v8/src/objects/fixed-primitive-array.h
index 7669b8a62e1..528c63e9e04 100644
--- a/deps/v8/src/objects/fixed-primitive-array.h
+++ b/deps/v8/src/objects/fixed-primitive-array.h
@@ -164,6 +164,7 @@ V8_OBJECT class FixedDoubleArray
// ByteArray represents fixed sized arrays containing raw bytes that will not
// be scanned by the garbage collector.
V8_OBJECT class ByteArray : public PrimitiveArrayBase<ByteArray, uint8_t> {
+ V8_IT_OWN_TYPE;
using Super = PrimitiveArrayBase<ByteArray, uint8_t>;
public:
@@ -200,6 +201,7 @@ V8_OBJECT class ByteArray : public PrimitiveArrayBase<ByteArray, uint8_t> {
V8_OBJECT
class TrustedByteArray : public PrimitiveArrayBase<TrustedByteArray, uint8_t,
TrustedFixedArrayBase> {
+ V8_IT_OWN_TYPE;
using Super =
PrimitiveArrayBase<TrustedByteArray, uint8_t, TrustedFixedArrayBase>;
@@ -273,6 +275,7 @@ using FixedUInt64Array = FixedIntegerArrayBase<uint64_t, ByteArray>;
V8_OBJECT
class TrustedFixedAddressArray
: public FixedIntegerArrayBase<Address, TrustedByteArray> {
+ V8_IT_REUSE_PARENT;
using Underlying = FixedIntegerArrayBase<Address, TrustedByteArray>;
public:
diff --git a/deps/v8/src/objects/foreign.h b/deps/v8/src/objects/foreign.h
index 1037d217447..8070899991c 100644
--- a/deps/v8/src/objects/foreign.h
+++ b/deps/v8/src/objects/foreign.h
@@ -15,6 +15,8 @@ namespace v8::internal {
// Foreign describes objects pointing from JavaScript to C structures.
V8_OBJECT class Foreign : public HeapObject {
+ V8_IT_FIXED_VALUE(0xcc);
+
public:
// [foreign_address]: field containing the address.
template <ExternalPointerTag tag>
@@ -49,6 +51,8 @@ V8_OBJECT class Foreign : public HeapObject {
// TrustedForeign is similar to Foreign but lives in trusted space.
V8_OBJECT class TrustedForeign : public TrustedObject {
+ V8_IT_OWN_TYPE;
+
public:
// [foreign_address]: field containing the address of a C object.
inline Address foreign_address() const;
diff --git a/deps/v8/src/objects/free-space.h b/deps/v8/src/objects/free-space.h
index 90893415a57..173ab431273 100644
--- a/deps/v8/src/objects/free-space.h
+++ b/deps/v8/src/objects/free-space.h
@@ -32,6 +32,8 @@ namespace internal {
// b) it's independent of the pointer compression base and pointer compression
// scheme.
V8_OBJECT class FreeSpace : public HeapObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
static constexpr uint32_t kMaxSizeInBytes =
uint32_t{Smi::kMaxValue} * kTaggedSize;
diff --git a/deps/v8/src/objects/hash-seed-wrapper.h b/deps/v8/src/objects/hash-seed-wrapper.h
index a5ae30f8a4d..7301423a24f 100644
--- a/deps/v8/src/objects/hash-seed-wrapper.h
+++ b/deps/v8/src/objects/hash-seed-wrapper.h
@@ -16,6 +16,8 @@ namespace v8 {
namespace internal {
V8_OBJECT class HashSeedWrapper : public HeapObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
inline const HashSeed::Data& data() const;
inline void set_data(const HashSeed::Data& value);
diff --git a/deps/v8/src/objects/hash-table.h b/deps/v8/src/objects/hash-table.h
index b005a25a769..e11548d5d5e 100644
--- a/deps/v8/src/objects/hash-table.h
+++ b/deps/v8/src/objects/hash-table.h
@@ -66,6 +66,8 @@ class V8_EXPORT_PRIVATE BaseShape {
};
class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
// Returns the number of elements in the hash table.
inline uint32_t NumberOfElements() const;
@@ -124,6 +126,8 @@ class V8_EXPORT_PRIVATE HashTableBase : public NON_EXPORTED_BASE(FixedArray) {
V8_OBJECT template <typename Derived, typename ShapeT>
class EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE) HashTable
: public HashTableBase {
+ V8_IT_OWN_TYPE;
+
public:
// TODO(jgruber): Derive from TaggedArrayBase instead of FixedArray, and
// merge with TaggedArrayBase's Shape class. Once the naming conflict is
@@ -461,6 +465,8 @@ EXTERN_DECLARE_OBJECT_BASE_HASH_TABLE(ObjectHashTable, ObjectHashTableShape)
// using the identity hash of the key for hashing purposes.
class V8_EXPORT_PRIVATE ObjectHashTable
: public ObjectHashTableBase<ObjectHashTable, ObjectHashTableShape> {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
DECL_PRINTER(ObjectHashTable)
};
@@ -504,6 +510,8 @@ class ObjectMultiHashTableShape : public ObjectHashTableShape {
template <typename Derived, int N>
class ObjectMultiHashTableBase
: public HashTable<Derived, ObjectMultiHashTableShape<N>> {
+ V8_IT_REUSE_PARENT;
+
public:
static_assert(N > 1, "use ObjectHashTable instead if N = 1");
@@ -528,7 +536,9 @@ class ObjectMultiHashTableBase
};
class ObjectTwoHashTable
- : public ObjectMultiHashTableBase<ObjectTwoHashTable, 2> {};
+ : public ObjectMultiHashTableBase<ObjectTwoHashTable, 2> {
+ V8_IT_NO_AUTO_CHECKER;
+};
class ObjectHashSetShape : public ObjectHashTableShape {
public:
@@ -540,6 +550,8 @@ EXTERN_DECLARE_HASH_TABLE(ObjectHashSet, ObjectHashSetShape)
class V8_EXPORT_PRIVATE ObjectHashSet
: public HashTable<ObjectHashSet, ObjectHashSetShape> {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
static Handle<ObjectHashSet> Add(Isolate* isolate, Handle<ObjectHashSet> set,
DirectHandle<Object> key);
diff --git a/deps/v8/src/objects/heap-object-set-map-inl.h b/deps/v8/src/objects/heap-object-set-map-inl.h
index 593726fcb54..e6a705cfcd5 100644
--- a/deps/v8/src/objects/heap-object-set-map-inl.h
+++ b/deps/v8/src/objects/heap-object-set-map-inl.h
@@ -83,7 +83,8 @@ void HeapObject::set_map(IsolateT* isolate, Tagged<Map> value,
#if V8_ENABLE_WEBASSEMBLY
// In {WasmGraphBuilder::SetMap} and {WasmGraphBuilder::LoadMap}, we treat
// maps as immutable. Therefore we are not allowed to mutate them here.
- DCHECK(!IsWasmStructMap(value) && !IsWasmArrayMap(value));
+ DCHECK(!IsWasmStructMap(value) && !IsWasmArrayMap(value) &&
+ !IsWasmCustomMapMap(value));
#endif
if (v8_flags.verify_heap) {
if (mode == VerificationMode::kSafeMapTransition) {
diff --git a/deps/v8/src/objects/heap-object.h b/deps/v8/src/objects/heap-object.h
index 481b3cd3862..0983cce69f6 100644
--- a/deps/v8/src/objects/heap-object.h
+++ b/deps/v8/src/objects/heap-object.h
@@ -61,6 +61,8 @@ using InSharedSpace = base::StrongAlias<struct InSharedSpaceTag, bool>;
// HeapObject is the superclass for all classes describing heap allocated
// objects.
V8_OBJECT class HeapObject {
+ V8_IT_ABSTRACT;
+
public:
// [map]: Contains a map which contains the object's reflective
// information.
diff --git a/deps/v8/src/objects/hole.h b/deps/v8/src/objects/hole.h
index 255e86fd981..ab21eea43f4 100644
--- a/deps/v8/src/objects/hole.h
+++ b/deps/v8/src/objects/hole.h
@@ -14,6 +14,9 @@ namespace v8 {
namespace internal {
V8_OBJECT class Hole : public HeapObject {
+ V8_IT_OWN_TYPE;
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
DECL_VERIFIER(Hole)
DECL_PRINTER(Hole)
@@ -34,6 +37,7 @@ V8_OBJECT class Hole : public HeapObject {
#define DEFINE_HOLE_TYPE(Name, name, Root) \
V8_OBJECT class Name : public Hole { \
+ V8_IT_REUSE_PARENT; \
} V8_OBJECT_END;
HOLE_LIST(DEFINE_HOLE_TYPE)
diff --git a/deps/v8/src/objects/instance-type-checker.h b/deps/v8/src/objects/instance-type-checker.h
index 33c9a76256e..c562d961dcf 100644
--- a/deps/v8/src/objects/instance-type-checker.h
+++ b/deps/v8/src/objects/instance-type-checker.h
@@ -18,15 +18,13 @@ namespace internal {
class Map;
// List of object types that have a single unique instance type.
-#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \
- TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(V) \
- TORQUE_INSTANCE_CHECKERS_SINGLE_ONLY_DECLARED(V) \
- V(BigInt, BIGINT_TYPE) \
+#define INSTANCE_TYPE_CHECKERS_SINGLE(V) \
+ INSTANCE_TYPE_LIST_SINGLE(V) \
+ V(BigInt, BIGINT_TYPE) \
V(FixedArrayExact, FIXED_ARRAY_TYPE)
#define INSTANCE_TYPE_CHECKERS_RANGE(V) \
- TORQUE_INSTANCE_CHECKERS_RANGE_FULLY_DEFINED(V) \
- TORQUE_INSTANCE_CHECKERS_RANGE_ONLY_DECLARED(V) \
+ INSTANCE_TYPE_LIST_RANGE(V) \
V(CallableJSFunction, FIRST_CALLABLE_JS_FUNCTION_TYPE, \
LAST_CALLABLE_JS_FUNCTION_TYPE)
diff --git a/deps/v8/src/objects/instance-type-inl.h b/deps/v8/src/objects/instance-type-inl.h
index 5a8b7ccee7c..d814b90edca 100644
--- a/deps/v8/src/objects/instance-type-inl.h
+++ b/deps/v8/src/objects/instance-type-inl.h
@@ -20,6 +20,53 @@
namespace v8::internal {
+constexpr std::optional<RootIndex> Map::TryGetMapRootIdxFor(InstanceType type) {
+ switch (type) {
+#define MAKE_CASE(TYPE, Name, name) \
+ case TYPE: \
+ return RootIndex::k##Name##Map;
+ STRUCT_LIST(MAKE_CASE)
+#undef MAKE_CASE
+ case DESCRIPTOR_ARRAY_TYPE:
+ return RootIndex::kDescriptorArrayMap;
+ case ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE:
+ return RootIndex::kOnHeapBasicBlockProfilerDataMap;
+ case TURBOFAN_BITSET_TYPE_TYPE:
+ return RootIndex::kTurbofanBitsetTypeMap;
+ case TURBOFAN_UNION_TYPE_TYPE:
+ return RootIndex::kTurbofanUnionTypeMap;
+ case TURBOFAN_RANGE_TYPE_TYPE:
+ return RootIndex::kTurbofanRangeTypeMap;
+ case TURBOFAN_HEAP_CONSTANT_TYPE_TYPE:
+ return RootIndex::kTurbofanHeapConstantTypeMap;
+ case TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE:
+ return RootIndex::kTurbofanOtherNumberConstantTypeMap;
+ case TURBOSHAFT_WORD32_RANGE_TYPE_TYPE:
+ return RootIndex::kTurboshaftWord32RangeTypeMap;
+ case TURBOSHAFT_WORD32_SET_TYPE_TYPE:
+ return RootIndex::kTurboshaftWord32SetTypeMap;
+ case TURBOSHAFT_WORD64_RANGE_TYPE_TYPE:
+ return RootIndex::kTurboshaftWord64RangeTypeMap;
+ case TURBOSHAFT_WORD64_SET_TYPE_TYPE:
+ return RootIndex::kTurboshaftWord64SetTypeMap;
+ case TURBOSHAFT_FLOAT64_RANGE_TYPE_TYPE:
+ return RootIndex::kTurboshaftFloat64RangeTypeMap;
+ case TURBOSHAFT_FLOAT64_SET_TYPE_TYPE:
+ return RootIndex::kTurboshaftFloat64SetTypeMap;
+ case SORT_STATE_TYPE:
+ return RootIndex::kSortStateMap;
+#if V8_ENABLE_WEBASSEMBLY
+ case WASM_FAST_API_CALL_DATA_TYPE:
+ return RootIndex::kWasmFastApiCallDataMap;
+ case WASM_STRING_VIEW_ITER_TYPE:
+ return RootIndex::kWasmStringViewIterMap;
+#endif // V8_ENABLE_WEBASSEMBLY
+ default:
+ break;
+ }
+ return {};
+}
+
namespace InstanceTypeChecker {
// INSTANCE_TYPE_CHECKERS macro defines some "types" that do not have
@@ -32,8 +79,7 @@ namespace InstanceTypeTraits {
#define DECL_TYPE(type, ...) class type;
INSTANCE_TYPE_CHECKERS(DECL_TYPE)
-TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(DECL_TYPE)
-TORQUE_INSTANCE_CHECKERS_MULTIPLE_ONLY_DECLARED(DECL_TYPE)
+INSTANCE_TYPE_LIST_MULTIPLE(DECL_TYPE)
HEAP_OBJECT_TYPE_LIST(DECL_TYPE)
#undef DECL_TYPE
@@ -655,7 +701,9 @@ V8_INLINE bool IsJSApiWrapperObject(Tagged<Map> map_object) {
V8_INLINE constexpr bool IsCppHeapPointerWrapperObject(
InstanceType instance_type) {
return IsJSApiWrapperObject(instance_type) ||
- IsCppHeapExternalObject(instance_type);
+ IsCppHeapExternalObject(instance_type) ||
+ IsCppGCManagedBase(instance_type) ||
+ IsEmbedderDataArray(instance_type);
}
V8_INLINE bool IsCppHeapPointerWrapperObject(Tagged<Map> map_object) {
@@ -665,7 +713,7 @@ V8_INLINE bool IsCppHeapPointerWrapperObject(Tagged<Map> map_object) {
} // namespace InstanceTypeChecker
#define TYPE_CHECKER(type, ...) \
- bool Is##type##Map(Tagged<Map> map) { \
+ inline bool Is##type##Map(Tagged<Map> map) { \
return InstanceTypeChecker::Is##type(map); \
}
diff --git a/deps/v8/src/objects/instance-type.h b/deps/v8/src/objects/instance-type.h
index cac5528e347..f1cdcf99f7b 100644
--- a/deps/v8/src/objects/instance-type.h
+++ b/deps/v8/src/objects/instance-type.h
@@ -6,8 +6,8 @@
#define V8_OBJECTS_INSTANCE_TYPE_H_
#include "include/v8-internal.h"
+#include "src/objects/instance-types-gen.h"
#include "src/objects/objects-definitions.h"
-#include "torque-generated/instance-types.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -178,6 +178,14 @@ enum InstanceType : uint16_t {
TORQUE_ASSIGNED_INSTANCE_TYPES(MAKE_TORQUE_INSTANCE_TYPE)
#undef MAKE_TORQUE_INSTANCE_TYPE
+// During the metagen libclang harvest's bootstrap parse, the generated
+// IT symbols (SYMBOL_TYPE, FIRST_JS_FUNCTION_TYPE, ...) do not yet
+// exist -- metagen is parsing this file to produce them. Skip
+// file-scope references to those symbols so the parse succeeds; the
+// harvest only needs class declarations, not IT-value relationships.
+// Function-body uses of the same symbols are unaffected because the
+// harvest uses PARSE_SKIP_FUNCTION_BODIES.
+#ifndef V8_METAGEN_GENERATION_PASS
// Pseudo-types
FIRST_UNIQUE_NAME_TYPE = INTERNALIZED_TWO_BYTE_STRING_TYPE,
LAST_UNIQUE_NAME_TYPE = SYMBOL_TYPE,
@@ -204,8 +212,13 @@ enum InstanceType : uint16_t {
// TODO(ishell): define a dedicated instance type for DependentCode to
// simplify CodeSerializer.
DEPENDENT_CODE_TYPE = WEAK_ARRAY_LIST_TYPE,
+#endif // V8_METAGEN_GENERATION_PASS
};
+// See the comment on the matching guard inside the enum above. Same
+// rationale: file-scope references to symbols the harvest hasn't
+// emitted yet are skipped during metagen's bootstrap parse.
+#ifndef V8_METAGEN_GENERATION_PASS
// This constant is defined outside of the InstanceType enum because the
// string instance types are sparse and there's no such string instance type.
// But it's still useful for range checks to have such a value.
@@ -273,6 +286,7 @@ TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(CHECK_INSTANCE_TYPE)
// Make sure it doesn't matter whether we sign-extend or zero-extend these
// values, because Torque treats InstanceType as signed.
static_assert(LAST_TYPE < 1 << 15);
+#endif // V8_METAGEN_GENERATION_PASS
V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
InstanceType instance_type);
@@ -369,12 +383,14 @@ V8_EXPORT_PRIVATE std::string ToString(InstanceType instance_type);
IF_WASM(V, _, WasmStringViewIterMap, wasm_string_view_iter_map, \
WasmStringViewIter)
+#ifndef V8_METAGEN_GENERATION_PASS
#ifdef V8_ENABLE_SWISS_NAME_DICTIONARY
static constexpr InstanceType PROPERTY_DICTIONARY_TYPE =
SWISS_NAME_DICTIONARY_TYPE;
#else
static constexpr InstanceType PROPERTY_DICTIONARY_TYPE = NAME_DICTIONARY_TYPE;
#endif
+#endif // V8_METAGEN_GENERATION_PASS
namespace InstanceTypeChecker {
V8_INLINE bool IsSeqString(Tagged<Map>);
diff --git a/deps/v8/src/objects/instance-types-gen.h b/deps/v8/src/objects/instance-types-gen.h
new file mode 100644
index 00000000000..e708f32ecb9
--- /dev/null
+++ b/deps/v8/src/objects/instance-types-gen.h
@@ -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.
+
+#ifndef V8_OBJECTS_INSTANCE_TYPES_GEN_H_
+#define V8_OBJECTS_INSTANCE_TYPES_GEN_H_
+
+// Selects which instance-type generator's output is compiled into V8:
+// metagen (tools/metagen/) or Torque's emission. Controlled by the build arg
+// v8_use_metagen_instance_types (GN and Bazel): when off, the build sets
+// V8_USE_METAGEN_INSTANCE_TYPES=0 (the "features" config in BUILD.gn,
+// ":define_flags" in BUILD.bazel); when on it is left undefined and the
+// fallback below selects metagen, so every translation unit agrees regardless
+// of which configs it picks up. Torque runs either way; the metagen harvest is
+// only in the build graph when the arg is on.
+#if !defined(V8_USE_METAGEN_INSTANCE_TYPES)
+#define V8_USE_METAGEN_INSTANCE_TYPES 1
+#endif
+
+// The harvest pass is checked before the switch, not inside it: the
+// harvest action depends on neither generator, so on either setting its
+// parse would reach for a header that does not exist yet.
+#ifdef V8_METAGEN_GENERATION_PASS
+// This is metagen's own libclang harvest, parsing the headers that
+// produce metagen/instance-types.h -- so that file does not exist yet,
+// and Torque has not necessarily run either. Define the macros both
+// paths supply as no-ops: the harvest reads class declarations, not
+// instance-type values, and instance-type.h skips its file-scope uses
+// of the generated symbols under the same guard.
+#define TORQUE_ASSIGNED_INSTANCE_TYPES(V)
+#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V)
+#define INSTANCE_TYPE_LIST_SINGLE(V)
+#define INSTANCE_TYPE_LIST_MULTIPLE(V)
+#define INSTANCE_TYPE_LIST_RANGE(V)
+#elif V8_USE_METAGEN_INSTANCE_TYPES
+#include "metagen/instance-types.h"
+#else
+#include "torque-generated/instance-types.h"
+// metagen emits the INSTANCE_TYPE_LIST_{SINGLE,MULTIPLE,RANGE} buckets
+// inside metagen/instance-types.h; on the Torque path they come from this
+// separate generated header. Remove with the
+// V8_USE_METAGEN_INSTANCE_TYPES switch.
+#include "torque-generated/instance-type-checker-lists.h"
+// metagen derives HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST from Name##Print /
+// Name##Verify declarations, which Torque knows nothing about. The debug-
+// reader lists (classes with a Torque body) are the exact set that carried
+// the Print/Verify dispatch before the metagen cutover, so alias them here.
+// Remove with the V8_USE_METAGEN_INSTANCE_TYPES switch.
+#include "torque-generated/debug-reader-classes-list.h"
+#define HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST(V) \
+ TORQUE_DEBUG_READER_CLASSES_SINGLE(V) \
+ TORQUE_DEBUG_READER_CLASSES_MULTIPLE(V)
+#endif
+
+#endif // V8_OBJECTS_INSTANCE_TYPES_GEN_H_
diff --git a/deps/v8/src/objects/instruction-stream.cc b/deps/v8/src/objects/instruction-stream.cc
index 77e283c1b3a..5e02a282350 100644
--- a/deps/v8/src/objects/instruction-stream.cc
+++ b/deps/v8/src/objects/instruction-stream.cc
@@ -82,6 +82,8 @@ InstructionStream::WriteBarrierPromise InstructionStream::RelocateFromDesc(
#else
UNREACHABLE();
#endif
+ } else if (RelocInfo::IsJSDispatchHandle(mode)) {
+ write_barrier_promise.RegisterAddress(it.rinfo()->pc());
} else {
intptr_t delta =
instruction_start() - reinterpret_cast<Address>(desc.buffer);
@@ -111,6 +113,10 @@ void InstructionStream::RelocateFromDescWriteBarriers(
WriteBarrier::ForRelocInfo(this, it.rinfo(), target_istream,
UPDATE_WRITE_BARRIER);
write_barrier_promise.ResolveAddress(it.rinfo()->pc());
+ } else if (RelocInfo::IsJSDispatchHandle(mode)) {
+ JSDispatchHandle handle = it.rinfo()->js_dispatch_handle();
+ WriteBarrier::ForJSDispatchHandle(this, handle, UPDATE_WRITE_BARRIER);
+ write_barrier_promise.ResolveAddress(it.rinfo()->pc());
}
}
}
diff --git a/deps/v8/src/objects/instruction-stream.h b/deps/v8/src/objects/instruction-stream.h
index e969cd0da6b..1a2bb018ebe 100644
--- a/deps/v8/src/objects/instruction-stream.h
+++ b/deps/v8/src/objects/instruction-stream.h
@@ -34,6 +34,8 @@ class WritableJitAllocation;
// and contains trusted content (machine code). However, it is special in that
// it doesn't live in the trusted space but instead in the code space.
V8_OBJECT class InstructionStream : public TrustedObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
// All InstructionStream objects have the following layout:
//
diff --git a/deps/v8/src/objects/intl-objects.cc b/deps/v8/src/objects/intl-objects.cc
index af6c577f98a..7a36b11b33d 100644
--- a/deps/v8/src/objects/intl-objects.cc
+++ b/deps/v8/src/objects/intl-objects.cc
@@ -32,6 +32,7 @@
#include "src/objects/js-temporal-objects.h"
#endif // V8_TEMPORAL_SUPPORT
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "src/objects/property-descriptor.h"
@@ -1013,7 +1014,7 @@ Intl::CompareStringsOptions Intl::CompareStringsOptionsFor(
//
// The actual conditions are verified in debug builds in
// CollatorAllowsFastComparison.
- static const char* const kFastLocales[] = {
+ static constexpr std::string_view kFastLocales[] = {
"en-US", "en", "fr", "es", "de", "pt", "it", "ca",
"de-AT", "fi", "id", "id-ID", "ms", "nl", "pl", "ro",
"sl", "sv", "sw", "vi", "en-DE", "en-GB",
@@ -1021,8 +1022,10 @@ Intl::CompareStringsOptions Intl::CompareStringsOptionsFor(
if (IsUndefined(*locales)) {
const std::string& default_locale = isolate->DefaultLocale();
- for (const char* fast_locale : kFastLocales) {
- if (strcmp(fast_locale, default_locale.c_str()) == 0) {
+ std::string_view default_view(default_locale);
+
+ for (const std::string_view& fast_locale : kFastLocales) {
+ if (fast_locale == default_view) {
return CompareStringsOptions::kTryFastPath;
}
}
@@ -1033,8 +1036,8 @@ Intl::CompareStringsOptions Intl::CompareStringsOptionsFor(
if (!IsString(*locales)) return CompareStringsOptions::kNone;
auto locales_string = Cast<String>(locales);
- for (const char* fast_locale : kFastLocales) {
- if (locales_string->IsEqualTo(base::CStrVector(fast_locale), isolate)) {
+ for (const std::string_view& fast_locale : kFastLocales) {
+ if (locales_string->IsEqualTo(base::VectorOf(fast_locale), isolate)) {
return CompareStringsOptions::kTryFastPath;
}
}
@@ -1084,7 +1087,8 @@ 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 {};
- Managed<icu::Collator>::Ptr icu_collator = collator->icu_collator()->ptr();
+ CppGCManaged<icu::Collator>::Ptr icu_collator =
+ collator->icu_collator()->ptr();
if (can_cache) {
isolate->set_icu_object_in_cache(
Isolate::ICUObjectCacheType::kDefaultCollator, locales,
@@ -1603,7 +1607,7 @@ MaybeDirectHandle<String> Intl::NumberToLocaleString(
isolate, number_format,
New<JSNumberFormat>(isolate, constructor, locales, options, method_name));
- Managed<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
+ CppGCManaged<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 b93c53dd9a0..9487fa94646 100644
--- a/deps/v8/src/objects/intl-objects.h
+++ b/deps/v8/src/objects/intl-objects.h
@@ -47,18 +47,20 @@ class Notation;
namespace v8::internal {
-#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
+#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
struct NumberFormatSpan {
int32_t field_id;
@@ -78,8 +80,8 @@ class JSCollator;
// Owns the ICU break iterator together with the string buffer it refers to.
class IcuBreakIteratorWithText final {
public:
- static constexpr ExternalPointerTag kManagedTag =
- kIcuBreakIteratorWithTextTag;
+ static constexpr ManagedTypeId kTypeID =
+ ManagedTypeId::kIcuBreakIteratorWithText;
// Adopts the given iterator with an empty string.
explicit IcuBreakIteratorWithText(
diff --git a/deps/v8/src/objects/js-array-buffer-inl.h b/deps/v8/src/objects/js-array-buffer-inl.h
index 5e90240d0a9..79c39f07268 100644
--- a/deps/v8/src/objects/js-array-buffer-inl.h
+++ b/deps/v8/src/objects/js-array-buffer-inl.h
@@ -169,6 +169,23 @@ void JSArrayBuffer::set_extension(ArrayBufferExtension* extension) {
WriteBarrier::ForArrayBufferExtension(this, extension);
}
+ArrayBufferExtension* JSArrayBuffer::extract_extension(
+ Isolate* isolate,
+ const DisallowGarbageCollection& disallow_gc V8_LIFETIME_BOUND) {
+#if V8_COMPRESS_POINTERS
+ ExternalPointerHandle handle =
+ base::AsAtomic32::Relaxed_Load(extension_handle_location());
+ if (handle == kNullExternalPointerHandle) {
+ return nullptr;
+ }
+ return reinterpret_cast<ArrayBufferExtension*>(
+ isolate->external_pointer_table().Exchange(handle, kNullAddress,
+ kArrayBufferExtensionTag));
+#else
+ return base::AsAtomicPointer::Relaxed_Swap(extension_location(), nullptr);
+#endif // V8_COMPRESS_POINTERS
+}
+
#if V8_COMPRESS_POINTERS
ExternalPointerHandle* JSArrayBuffer::extension_handle_location() const {
return reinterpret_cast<ExternalPointerHandle*>(extension_.storage_address());
diff --git a/deps/v8/src/objects/js-array-buffer.cc b/deps/v8/src/objects/js-array-buffer.cc
index 9c10ef1b409..5c44f10c5d2 100644
--- a/deps/v8/src/objects/js-array-buffer.cc
+++ b/deps/v8/src/objects/js-array-buffer.cc
@@ -217,14 +217,19 @@ bool JSArrayBuffer::TryDetachViews(DirectHandle<JSArrayBuffer> array_buffer,
void JSArrayBuffer::DetachInternal(DirectHandle<JSArrayBuffer> array_buffer,
bool force_for_wasm_memory,
Isolate* isolate) {
- ArrayBufferExtension* extension = array_buffer->extension();
-
- if (extension) {
+ {
DisallowGarbageCollection disallow_gc;
- isolate->heap()->DetachArrayBufferExtension(extension);
- std::shared_ptr<BackingStore> backing_store =
- array_buffer->RemoveExtension();
- CHECK_IMPLIES(force_for_wasm_memory, backing_store->is_wasm_memory());
+ ArrayBufferExtension* extension =
+ array_buffer->extract_extension(isolate, disallow_gc);
+ if (extension) {
+ isolate->heap()->DetachArrayBufferExtension(extension);
+ // Prevent concurrent detachment vs background copying if an attacker
+ // swapped the extension pointer to a shared buffer's extension.
+ SBXCHECK(!extension->is_shared());
+ std::shared_ptr<BackingStore> backing_store =
+ extension->RemoveBackingStore();
+ CHECK_IMPLIES(force_for_wasm_memory, backing_store->is_wasm_memory());
+ }
}
array_buffer->set_was_detached(true, kReleaseStore);
@@ -331,19 +336,6 @@ ArrayBufferExtension* JSArrayBuffer::CreateExtension(
return extension;
}
-std::shared_ptr<BackingStore> JSArrayBuffer::RemoveExtension() {
- ArrayBufferExtension* extension = this->extension();
- DCHECK_NOT_NULL(extension);
- // Prevent concurrent detachment vs background copying if an attacker
- // swapped the extension pointer to a shared buffer's extension.
- SBXCHECK(!extension->is_shared());
- auto result = extension->RemoveBackingStore();
- // Remove pointer to extension such that the next GC will free it
- // automatically.
- set_extension(nullptr);
- return result;
-}
-
Handle<JSArrayBuffer> JSTypedArray::GetBuffer(Isolate* isolate) {
DirectHandle<JSTypedArray> self(this, isolate);
DCHECK(IsTypedArrayOrRabGsabTypedArrayElementsKind(self->GetElementsKind()));
diff --git a/deps/v8/src/objects/js-array-buffer.h b/deps/v8/src/objects/js-array-buffer.h
index e0794c63e1b..0376f9fa508 100644
--- a/deps/v8/src/objects/js-array-buffer.h
+++ b/deps/v8/src/objects/js-array-buffer.h
@@ -12,6 +12,7 @@
#include "src/objects/backing-store.h"
#include "src/objects/js-function.h"
#include "src/objects/js-objects.h"
+#include "src/sandbox/check.h"
#include "src/sandbox/external-pointer.h"
// Has to be the last include (doesn't have include guards):
@@ -55,6 +56,12 @@ V8_OBJECT class JSArrayBuffer : public JSAPIObjectWithEmbedderSlots {
inline ArrayBufferExtension* extension() const;
inline void set_extension(ArrayBufferExtension* value);
inline void init_extension();
+ // Returns the current extension and resets it to nullptr. Expects a witness
+ // DisallowGarbageCollection to make sure the returned extension isn't freed
+ // while a pointer to it is held on stack.
+ inline ArrayBufferExtension* extract_extension(
+ Isolate* isolate,
+ const DisallowGarbageCollection& disallow_gc V8_LIFETIME_BOUND);
// [bit_field]: boolean flags
inline uint32_t bit_field() const;
@@ -182,9 +189,6 @@ V8_OBJECT class JSArrayBuffer : public JSAPIObjectWithEmbedderSlots {
V8_EXPORT_PRIVATE ArrayBufferExtension* CreateExtension(
Isolate* isolate, std::shared_ptr<BackingStore> backing_store);
- // Frees the associated ArrayBufferExtension and returns its backing store.
- std::shared_ptr<BackingStore> RemoveExtension();
-
//
// Serializer/deserializer support.
//
@@ -319,7 +323,7 @@ class ArrayBufferExtension final
bool IsMarked() const { return marked_.load(std::memory_order_relaxed); }
void YoungMark() {
- DCHECK_EQ(ArrayBufferExtension::Age::kYoung, age());
+ SBXCHECK_EQ(ArrayBufferExtension::Age::kYoung, age());
set_young_gc_state(GcState::Copied);
}
void YoungMarkPromoted() {
@@ -424,6 +428,8 @@ class ArrayBufferExtension final
};
V8_OBJECT class JSArrayBufferView : public JSAPIObjectWithEmbedderSlots {
+ V8_IT_ABSTRACT;
+
public:
// [buffer]: the underlying ArrayBuffer.
inline Tagged<JSArrayBuffer> buffer() const;
@@ -486,6 +492,8 @@ static_assert(IsAligned(offsetof(JSArrayBufferView, raw_byte_length_),
kUIntptrSize));
V8_OBJECT class JSTypedArray : public JSArrayBufferView {
+ V8_IT_OWN_TYPE;
+
public:
static constexpr size_t kMaxByteLength = JSArrayBuffer::kMaxByteLength;
static_assert(kMaxByteLength == v8::TypedArray::kMaxByteLength);
@@ -633,6 +641,8 @@ V8_OBJECT class JSDetachedTypedArray : public JSTypedArray {
} V8_OBJECT_END;
V8_OBJECT class JSDataViewOrRabGsabDataView : public JSArrayBufferView {
+ V8_IT_ABSTRACT;
+
public:
// [data_pointer]: pointer to the actual data.
inline void* data_pointer() const;
@@ -676,6 +686,7 @@ V8_OBJECT class JSRabGsabDataView : public JSDataViewOrRabGsabDataView {
} V8_OBJECT_END;
V8_OBJECT class TypedArrayConstructor : public JSFunctionWithPrototype {
+ V8_IT_ABSTRACT;
} V8_OBJECT_END;
V8_OBJECT class Uint8TypedArrayConstructor : public TypedArrayConstructor {
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-array.h b/deps/v8/src/objects/js-array.h
index 326cdcf5097..5a9ed5b625f 100644
--- a/deps/v8/src/objects/js-array.h
+++ b/deps/v8/src/objects/js-array.h
@@ -22,6 +22,8 @@ namespace internal {
// Please note: push and pop can be used to grow and shrink the array.
// - slow, backing storage is a HashTable with numbers as keys.
V8_OBJECT class JSArray : public JSObject {
+ V8_IT_OWN_TYPE;
+
public:
// [length]: The length property.
inline Tagged<Number> length() const;
@@ -197,6 +199,9 @@ V8_OBJECT class JSArrayIterator : public JSObject {
// Helper class for JSArrays that are template literal objects
V8_OBJECT class TemplateLiteralObject : public JSArray {
+ V8_IT_REUSE_PARENT;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
inline Tagged<JSArray> raw() const;
inline void set_raw(Tagged<JSArray> value,
diff --git a/deps/v8/src/objects/js-atomics-synchronization.h b/deps/v8/src/objects/js-atomics-synchronization.h
index ba61b37fac3..906102e7df6 100644
--- a/deps/v8/src/objects/js-atomics-synchronization.h
+++ b/deps/v8/src/objects/js-atomics-synchronization.h
@@ -35,6 +35,8 @@ using detail::WaiterQueueNode;
// mutex and the condition variable.
V8_OBJECT class JSSynchronizationPrimitive : public AlwaysSharedSpaceJSObject {
+ V8_IT_ABSTRACT;
+
public:
class BodyDescriptor;
diff --git a/deps/v8/src/objects/js-break-iterator-inl.h b/deps/v8/src/objects/js-break-iterator-inl.h
index c6f5950dc8c..99dc073e0fb 100644
--- a/deps/v8/src/objects/js-break-iterator-inl.h
+++ b/deps/v8/src/objects/js-break-iterator-inl.h
@@ -13,7 +13,8 @@
// Include the non-inl header before the rest of the headers.
#include "src/objects/js-function.h"
-#include "src/objects/objects-inl.h" // For CastTraits<Managed<T>>.
+#include "src/objects/managed-inl.h"
+#include "src/objects/objects-inl.h"
#include "src/objects/tagged-field-inl.h"
// Has to be the last include (doesn't have include guards):
@@ -29,14 +30,15 @@ void JSV8BreakIterator::set_locale(Tagged<String> value,
locale_.store(this, value, mode);
}
-Tagged<Managed<IcuBreakIteratorWithText>>
+Tagged<CppGCManaged<IcuBreakIteratorWithText>>
JSV8BreakIterator::icu_iterator_with_text() const {
- return Cast<Managed<IcuBreakIteratorWithText>>(
+ return Cast<CppGCManaged<IcuBreakIteratorWithText>>(
icu_iterator_with_text_.load());
}
void JSV8BreakIterator::set_icu_iterator_with_text(
- Tagged<Managed<IcuBreakIteratorWithText>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<IcuBreakIteratorWithText>> value,
+ WriteBarrierMode mode) {
icu_iterator_with_text_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-break-iterator.cc b/deps/v8/src/objects/js-break-iterator.cc
index 30e22de23d2..502071cbe94 100644
--- a/deps/v8/src/objects/js-break-iterator.cc
+++ b/deps/v8/src/objects/js-break-iterator.cc
@@ -105,9 +105,9 @@ MaybeDirectHandle<JSV8BreakIterator> JSV8BreakIterator::New(
// Construct the managed holder; initially the string is null
auto iterator_with_text =
std::make_shared<IcuBreakIteratorWithText>(std::move(break_iterator));
- DirectHandle<Managed<IcuBreakIteratorWithText>> managed =
- Managed<IcuBreakIteratorWithText>::From(isolate, 0,
- std::move(iterator_with_text));
+ DirectHandle<CppGCManaged<IcuBreakIteratorWithText>> managed =
+ CppGCManaged<IcuBreakIteratorWithText>::Create(
+ isolate, 0, std::move(iterator_with_text));
DirectHandle<String> locale_str =
isolate->factory()->NewStringFromAsciiChecked(r.locale.c_str());
diff --git a/deps/v8/src/objects/js-break-iterator.h b/deps/v8/src/objects/js-break-iterator.h
index 2ea1b70bcd2..f82b6a6ee59 100644
--- a/deps/v8/src/objects/js-break-iterator.h
+++ b/deps/v8/src/objects/js-break-iterator.h
@@ -55,10 +55,10 @@ V8_OBJECT class JSV8BreakIterator : public JSObject {
inline void set_locale(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<IcuBreakIteratorWithText>> icu_iterator_with_text()
+ inline Tagged<CppGCManaged<IcuBreakIteratorWithText>> icu_iterator_with_text()
const;
inline void set_icu_iterator_with_text(
- Tagged<Managed<IcuBreakIteratorWithText>> value,
+ Tagged<CppGCManaged<IcuBreakIteratorWithText>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<UnionOf<Undefined, JSFunction>> bound_adopt_text() const;
@@ -90,7 +90,7 @@ V8_OBJECT class JSV8BreakIterator : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<Foreign> icu_iterator_with_text_;
+ TaggedMember<CppGCManaged<IcuBreakIteratorWithText>> icu_iterator_with_text_;
TaggedMember<UnionOf<Undefined, JSFunction>> bound_adopt_text_;
TaggedMember<UnionOf<Undefined, JSFunction>> bound_first_;
TaggedMember<UnionOf<Undefined, JSFunction>> bound_next_;
diff --git a/deps/v8/src/objects/js-break-iterator.tq b/deps/v8/src/objects/js-break-iterator.tq
index 3ae2cffade6..c9966266bfb 100644
--- a/deps/v8/src/objects/js-break-iterator.tq
+++ b/deps/v8/src/objects/js-break-iterator.tq
@@ -7,7 +7,8 @@
@cppObjectLayoutDefinition
extern class JSV8BreakIterator extends JSObject {
locale: String;
- icu_iterator_with_text: Foreign; // Managed<IcuBreakIteratorWithText>
+ icu_iterator_with_text:
+ CppGCManagedBase; // CppGCManaged<IcuBreakIteratorWithText>
bound_adopt_text: Undefined|JSFunction;
bound_first: Undefined|JSFunction;
bound_next: Undefined|JSFunction;
diff --git a/deps/v8/src/objects/js-collator-inl.h b/deps/v8/src/objects/js-collator-inl.h
index 4e99e8b5452..cf4dde66747 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<Managed<icu::Collator>> JSCollator::icu_collator() const {
- return Cast<Managed<icu::Collator>>(icu_collator_.load());
+Tagged<CppGCManaged<icu::Collator>> JSCollator::icu_collator() const {
+ return Cast<CppGCManaged<icu::Collator>>(icu_collator_.load());
}
-void JSCollator::set_icu_collator(Tagged<Managed<icu::Collator>> value,
+void JSCollator::set_icu_collator(Tagged<CppGCManaged<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 f70ba1eb5da..608ee630dff 100644
--- a/deps/v8/src/objects/js-collator.cc
+++ b/deps/v8/src/objects/js-collator.cc
@@ -91,7 +91,8 @@ DirectHandle<JSObject> JSCollator::ResolvedOptions(
DirectHandle<JSObject> options =
isolate->factory()->NewJSObject(isolate->object_function());
- Managed<icu::Collator>::Ptr icu_collator = collator->icu_collator()->ptr();
+ CppGCManaged<icu::Collator>::Ptr icu_collator =
+ collator->icu_collator()->ptr();
DCHECK_NOT_NULL(icu_collator);
UErrorCode status = U_ZERO_ERROR;
@@ -573,8 +574,8 @@ MaybeHandle<JSCollator> JSCollator::New(Isolate* isolate, DirectHandle<Map> map,
DCHECK(U_SUCCESS(status));
}
- DirectHandle<Managed<icu::Collator>> managed_collator =
- Managed<icu::Collator>::From(isolate, 0, std::move(icu_collator));
+ DirectHandle<CppGCManaged<icu::Collator>> managed_collator =
+ CppGCManaged<icu::Collator>::Create(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 f8ae3c967ab..0d914ed11d6 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<Managed<icu::Collator>> icu_collator() const;
- inline void set_icu_collator(Tagged<Managed<icu::Collator>> value,
+ inline Tagged<CppGCManaged<icu::Collator>> icu_collator() const;
+ inline void set_icu_collator(Tagged<CppGCManaged<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<Foreign> icu_collator_;
+ TaggedMember<CppGCManaged<icu::Collator>> 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 4abc1b6c5f4..558f07a193c 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: Foreign; // Managed<icu::Collator>
+ icu_collator: CppGCManagedBase; // CppGCManaged<icu::Collator>
bound_compare: Undefined|JSFunction;
locale: String;
}
diff --git a/deps/v8/src/objects/js-collection-iterator.h b/deps/v8/src/objects/js-collection-iterator.h
index 3f76cf67b2b..d74043617cd 100644
--- a/deps/v8/src/objects/js-collection-iterator.h
+++ b/deps/v8/src/objects/js-collection-iterator.h
@@ -17,6 +17,8 @@ namespace v8 {
namespace internal {
V8_OBJECT class JSCollectionIterator : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
inline Tagged<Object> table() const;
inline void set_table(Tagged<Object> value,
diff --git a/deps/v8/src/objects/js-collection.h b/deps/v8/src/objects/js-collection.h
index 6cd14e791ba..6fdba04ad21 100644
--- a/deps/v8/src/objects/js-collection.h
+++ b/deps/v8/src/objects/js-collection.h
@@ -18,6 +18,8 @@ class OrderedHashSet;
class OrderedHashMap;
V8_OBJECT class JSCollection : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
// The backing hash table.
inline Tagged<Object> table() const;
@@ -47,6 +49,8 @@ V8_OBJECT class JSSet final : public JSCollection {
V8_OBJECT class JSSetIterator
: public OrderedHashTableIterator<JSSetIterator, OrderedHashSet> {
+ V8_IT_ABSTRACT;
+
public:
// Dispatched behavior.
DECL_PRINTER(JSSetIterator)
@@ -67,6 +71,8 @@ V8_OBJECT class JSMap final : public JSCollection {
V8_OBJECT class JSMapIterator
: public OrderedHashTableIterator<JSMapIterator, OrderedHashMap> {
+ V8_IT_ABSTRACT;
+
public:
// Dispatched behavior.
DECL_PRINTER(JSMapIterator)
@@ -79,6 +85,8 @@ V8_OBJECT class JSMapIterator
// Base class for both JSWeakMap and JSWeakSet
V8_OBJECT class JSWeakCollection : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
// The backing hash table mapping keys to values.
inline Tagged<Object> table() const;
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 7a1f527cd2f..5b4a10acca8 100644
--- a/deps/v8/src/objects/js-data-object-builder-inl.h
+++ b/deps/v8/src/objects/js-data-object-builder-inl.h
@@ -17,6 +17,7 @@
#include "src/objects/heap-object-set-map-inl.h"
#include "src/objects/js-objects-inl.h"
#include "src/objects/map-updater.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/transitions-inl.h"
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 e74a08904eb..9789cb63899 100644
--- a/deps/v8/src/objects/js-date-time-format-inl.h
+++ b/deps/v8/src/objects/js-date-time-format-inl.h
@@ -25,30 +25,32 @@ void JSDateTimeFormat::set_locale(Tagged<String> value, WriteBarrierMode mode) {
locale_.store(this, value, mode);
}
-Tagged<Managed<icu::Locale>> JSDateTimeFormat::icu_locale() const {
- return Cast<Managed<icu::Locale>>(icu_locale_.load());
+Tagged<CppGCManaged<icu::Locale>> JSDateTimeFormat::icu_locale() const {
+ return Cast<CppGCManaged<icu::Locale>>(icu_locale_.load());
}
-void JSDateTimeFormat::set_icu_locale(Tagged<Managed<icu::Locale>> value,
- WriteBarrierMode mode) {
+void JSDateTimeFormat::set_icu_locale(
+ Tagged<CppGCManaged<icu::Locale>> value, WriteBarrierMode mode) {
icu_locale_.store(this, value, mode);
}
-Tagged<Managed<icu::SimpleDateFormat>>
+Tagged<CppGCManaged<icu::SimpleDateFormat>>
JSDateTimeFormat::icu_simple_date_format() const {
- return Cast<Managed<icu::SimpleDateFormat>>(icu_simple_date_format_.load());
+ return Cast<CppGCManaged<icu::SimpleDateFormat>>(
+ icu_simple_date_format_.load());
}
void JSDateTimeFormat::set_icu_simple_date_format(
- Tagged<Managed<icu::SimpleDateFormat>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<icu::SimpleDateFormat>> value, WriteBarrierMode mode) {
icu_simple_date_format_.store(this, value, mode);
}
-Tagged<Managed<icu::DateIntervalFormat>>
+Tagged<CppGCManaged<icu::DateIntervalFormat>>
JSDateTimeFormat::icu_date_interval_format() const {
- return Cast<Managed<icu::DateIntervalFormat>>(
+ return Cast<CppGCManaged<icu::DateIntervalFormat>>(
icu_date_interval_format_.load());
}
void JSDateTimeFormat::set_icu_date_interval_format(
- Tagged<Managed<icu::DateIntervalFormat>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<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 aef4a74bc8c..e144c1bd33d 100644
--- a/deps/v8/src/objects/js-date-time-format.cc
+++ b/deps/v8/src/objects/js-date-time-format.cc
@@ -14,6 +14,7 @@
#include "src/base/bit-field.h"
#include "src/base/logging.h"
+#include "src/base/small-map.h"
#include "src/date/date.h"
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
@@ -25,6 +26,7 @@
#include "temporal_rs/Instant.hpp"
#endif // V8_TEMPORAL_SUPPORT
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/calendar.h"
#include "unicode/dtitvfmt.h"
@@ -200,7 +202,11 @@ static std::vector<PatternItem> BuildPatternItems() {
{{"GGGGG", "narrow"}, {"GGGG", "long"}, {"GGG", "short"}},
kNarrowLongShort),
PatternItem(Year::kShift, DateTimeProperty::kYear,
- {{"yy", "2-digit"}, {"y", "numeric"}}, k2DigitNumeric)};
+ {{"yy", "2-digit"},
+ {"y", "numeric"},
+ {"YY", "2-digit"},
+ {"Y", "numeric"}},
+ k2DigitNumeric)};
// Sometimes we get L instead of M for month - standalone name.
items.push_back(PatternItem(Month::kShift, DateTimeProperty::kMonth,
{{"MMMMM", "narrow"},
@@ -678,10 +684,11 @@ MaybeDirectHandle<JSObject> JSDateTimeFormat::ResolvedOptions(
DirectHandle<String> locale(date_time_format->locale(), isolate);
DCHECK(!date_time_format->icu_locale().is_null());
- Managed<icu::Locale>::Ptr icu_locale = date_time_format->icu_locale()->ptr();
+ CppGCManaged<icu::Locale>::Ptr icu_locale =
+ date_time_format->icu_locale()->ptr();
DCHECK_NOT_NULL(icu_locale);
- Managed<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
+ CppGCManaged<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
date_time_format->icu_simple_date_format()->ptr();
DirectHandle<Object> timezone =
JSDateTimeFormat::TimeZone(isolate, date_time_format);
@@ -995,7 +1002,7 @@ template <typename T>
Maybe<DateTimeValueRecord> HandleDateTimeTemporalGeneric(
Isolate* isolate, DirectHandle<JSDateTimeFormat> date_time_format,
PatternKind kind, DirectHandle<T> temporal) {
- Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
+ CppGCManaged<icu::SimpleDateFormat>::Ptr icu_date_format =
date_time_format->icu_simple_date_format()->ptr();
// Onlt perform this check for calendared types (not Time)
@@ -1682,12 +1689,17 @@ std::unique_ptr<icu::SimpleDateFormat> GetSimpleDateTimeForTemporal(
JSDateTimeFormat::DateTimeStyle time_style,
bool has_to_locale_string_time_zone) {
DCHECK_NE(kind, PatternKind::kDate);
+ icu::UnicodeString original_skeleton = SkeletonFromDateFormat(date_format);
icu::UnicodeString skeleton = GetSkeletonForPatternKind(
- SkeletonFromDateFormat(date_format), explicit_components_in_options, kind,
- date_style, time_style, has_to_locale_string_time_zone);
+ original_skeleton, explicit_components_in_options, kind, date_style,
+ time_style, has_to_locale_string_time_zone);
if (skeleton.length() == 0) {
return nullptr;
}
+ if (skeleton == original_skeleton) {
+ return std::unique_ptr<icu::SimpleDateFormat>(
+ static_cast<icu::SimpleDateFormat*>(date_format.clone()));
+ }
UErrorCode status = U_ZERO_ERROR;
std::unique_ptr<icu::SimpleDateFormat> result(
static_cast<icu::SimpleDateFormat*>(
@@ -1781,7 +1793,7 @@ MaybeDirectHandle<String> FormatDateTime(
MaybeDirectHandle<String> FormatMillisecondsByKindToString(
Isolate* isolate, DirectHandle<JSDateTimeFormat> date_time_format,
DirectHandle<Object> value, PatternKind kind, bool is_plain, double x) {
- Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
+ CppGCManaged<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(
@@ -1837,7 +1849,7 @@ MaybeDirectHandle<String> JSDateTimeFormat::DateTimeFormat(
x = Object::NumberValue(*date);
}
// 5. Return FormatDateTime(dtf, x).
- Managed<icu::SimpleDateFormat>::Ptr format =
+ CppGCManaged<icu::SimpleDateFormat>::Ptr format =
date_time_format->icu_simple_date_format()->ptr();
return FormatDateTime(isolate, *format, x);
}
@@ -1907,7 +1919,7 @@ MaybeDirectHandle<String> JSDateTimeFormat::ToLocaleDateTime(
JSDateTimeFormat::CreateDateTimeFormat(
isolate, map, locales, options, required, defaults, {}, method_name));
- Managed<icu::SimpleDateFormat>::Ptr format =
+ CppGCManaged<icu::SimpleDateFormat>::Ptr format =
date_time_format->icu_simple_date_format()->ptr();
if (can_cache) {
isolate->set_icu_object_in_cache(cache_type, locales,
@@ -2118,6 +2130,19 @@ std::unique_ptr<icu::TimeZone> JSDateTimeFormat::CreateTimeZone(
namespace {
+constexpr size_t kMaxCacheSize = 9;
+
+template <typename T>
+using IntlCacheMap = base::SmallMap<std::map<std::string, std::unique_ptr<T>>,
+ kMaxCacheSize, std::equal_to<std::string>>;
+
+template <typename T>
+void ClearCacheIfFull(IntlCacheMap<T>& map) {
+ if (map.size() >= kMaxCacheSize) {
+ map.clear();
+ }
+}
+
class CalendarCache {
public:
icu::Calendar* CreateCalendar(const icu::Locale& locale, icu::TimeZone* tz) {
@@ -2153,15 +2178,13 @@ class CalendarCache {
DCHECK(U_SUCCESS(status));
}
- if (map_.size() > 8) { // Cache at most 8 calendars.
- map_.clear();
- }
+ ClearCacheIfFull(map_);
map_[key] = std::move(calendar);
return map_[key]->clone();
}
private:
- std::map<std::string, std::unique_ptr<icu::Calendar>> map_;
+ IntlCacheMap<icu::Calendar> map_;
base::Mutex mutex_;
};
@@ -2271,9 +2294,7 @@ class DateFormatCache {
return static_cast<icu::SimpleDateFormat*>(it->second->clone());
}
- if (map_.size() > 8) { // Cache at most 8 DateFormats.
- map_.clear();
- }
+ ClearCacheIfFull(map_);
std::unique_ptr<icu::SimpleDateFormat> instance(
CreateICUDateFormat(icu_locale, skeleton, generator, hc));
if (instance == nullptr) return nullptr;
@@ -2282,7 +2303,7 @@ class DateFormatCache {
}
private:
- std::map<std::string, std::unique_ptr<icu::SimpleDateFormat>> map_;
+ IntlCacheMap<icu::SimpleDateFormat> map_;
base::Mutex mutex_;
};
@@ -2325,7 +2346,7 @@ std::unique_ptr<icu::DateIntervalFormat> LazyCreateDateIntervalFormat(
loc.setUnicodeKeywordValue("hc", hcString, status);
}
- Managed<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
+ CppGCManaged<icu::SimpleDateFormat>::Ptr icu_simple_date_format =
date_time_format->icu_simple_date_format()->ptr();
icu::UnicodeString skeleton = GetSkeletonForPatternKind(
@@ -2340,9 +2361,9 @@ std::unique_ptr<icu::DateIntervalFormat> LazyCreateDateIntervalFormat(
if (kind != PatternKind::kDate) {
return date_interval_format;
}
- DirectHandle<Managed<icu::DateIntervalFormat>> managed_interval_format =
- Managed<icu::DateIntervalFormat>::From(isolate, 0,
- std::move(date_interval_format));
+ DirectHandle<CppGCManaged<icu::DateIntervalFormat>> managed_interval_format =
+ CppGCManaged<icu::DateIntervalFormat>::Create(
+ isolate, 0, std::move(date_interval_format));
date_time_format->set_icu_date_interval_format(*managed_interval_format);
DisallowGarbageCollection no_gc;
@@ -2539,6 +2560,9 @@ class DateTimePatternGeneratorCache {
orig = icu::DateTimePatternGenerator::createInstance("root", status);
}
if (U_SUCCESS(status) && orig != nullptr) {
+ if (v8_flags.intl_date_time_pattern_generator_cache_eviction) {
+ ClearCacheIfFull(map_);
+ }
map_[key].reset(orig);
} else {
DCHECK(status == U_MEMORY_ALLOCATION_ERROR);
@@ -2555,7 +2579,7 @@ class DateTimePatternGeneratorCache {
}
private:
- std::map<std::string, std::unique_ptr<icu::DateTimePatternGenerator>> map_;
+ IntlCacheMap<icu::DateTimePatternGenerator> map_;
base::Mutex mutex_;
};
@@ -3057,16 +3081,16 @@ MaybeDirectHandle<JSDateTimeFormat> JSDateTimeFormat::CreateDateTimeFormat(
isolate->factory()->NewStringFromAsciiChecked(
maybe_locale_str.FromJust().c_str());
- DirectHandle<Managed<icu::Locale>> managed_locale =
- Managed<icu::Locale>::From(
+ DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
+ CppGCManaged<icu::Locale>::Create(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
- DirectHandle<Managed<icu::SimpleDateFormat>> managed_format =
- Managed<icu::SimpleDateFormat>::From(isolate, 0,
- std::move(icu_date_format));
+ DirectHandle<CppGCManaged<icu::SimpleDateFormat>> managed_format =
+ CppGCManaged<icu::SimpleDateFormat>::Create(isolate, 0,
+ std::move(icu_date_format));
- DirectHandle<Managed<icu::DateIntervalFormat>> managed_interval_format =
- Managed<icu::DateIntervalFormat>::From(isolate, 0, nullptr);
+ DirectHandle<CppGCManaged<icu::DateIntervalFormat>> managed_interval_format =
+ CppGCManaged<icu::DateIntervalFormat>::Create(isolate, 0, nullptr);
// Now all properties are ready, so we can allocate the result object.
DirectHandle<JSDateTimeFormat> date_time_format = Cast<JSDateTimeFormat>(
@@ -3104,6 +3128,7 @@ DirectHandle<String> IcuDateFieldIdToDateType(int32_t field_id,
return isolate->factory()->literal_string();
case UDAT_YEAR_FIELD:
case UDAT_EXTENDED_YEAR_FIELD:
+ case UDAT_YEAR_WOY_FIELD:
return isolate->factory()->year_string();
case UDAT_YEAR_NAME_FIELD:
return isolate->factory()->yearName_string();
@@ -3163,7 +3188,7 @@ MaybeDirectHandle<JSArray> FormatMillisecondsByKindToArray(
bool output_source) {
icu::FieldPositionIterator fp_iter;
UErrorCode status = U_ZERO_ERROR;
- Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
+ CppGCManaged<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(),
@@ -3468,7 +3493,7 @@ std::optional<MaybeDirectHandle<T>> PartitionDateTimeRangePattern(
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError));
}
- Managed<icu::SimpleDateFormat>::Ptr date_format =
+ CppGCManaged<icu::SimpleDateFormat>::Ptr date_format =
date_time_format->icu_simple_date_format()->ptr();
const icu::Calendar* calendar = date_format->getCalendar();
@@ -3562,7 +3587,7 @@ MaybeDirectHandle<T> FormatRangeCommonWithTemporalSupport(
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError));
}
- Managed<icu::SimpleDateFormat>::Ptr icu_date_format =
+ CppGCManaged<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 700c2e97366..4af5c0691dd 100644
--- a/deps/v8/src/objects/js-date-time-format.h
+++ b/deps/v8/src/objects/js-date-time-format.h
@@ -168,19 +168,20 @@ V8_OBJECT class JSDateTimeFormat : public JSObject {
inline void set_locale(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<icu::Locale>> icu_locale() const;
- inline void set_icu_locale(Tagged<Managed<icu::Locale>> value,
+ inline Tagged<CppGCManaged<icu::Locale>> icu_locale() const;
+ inline void set_icu_locale(Tagged<CppGCManaged<icu::Locale>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<icu::SimpleDateFormat>> icu_simple_date_format() const;
+ inline Tagged<CppGCManaged<icu::SimpleDateFormat>> icu_simple_date_format()
+ const;
inline void set_icu_simple_date_format(
- Tagged<Managed<icu::SimpleDateFormat>> value,
+ Tagged<CppGCManaged<icu::SimpleDateFormat>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<icu::DateIntervalFormat>> icu_date_interval_format()
- const;
+ inline Tagged<CppGCManaged<icu::DateIntervalFormat>>
+ icu_date_interval_format() const;
inline void set_icu_date_interval_format(
- Tagged<Managed<icu::DateIntervalFormat>> value,
+ Tagged<CppGCManaged<icu::DateIntervalFormat>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<UnionOf<JSFunction, Undefined>> bound_format() const;
@@ -201,9 +202,9 @@ V8_OBJECT class JSDateTimeFormat : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<Foreign> icu_locale_;
- TaggedMember<Foreign> icu_simple_date_format_;
- TaggedMember<Foreign> icu_date_interval_format_;
+ TaggedMember<CppGCManaged<icu::Locale>> icu_locale_;
+ TaggedMember<CppGCManaged<icu::SimpleDateFormat>> icu_simple_date_format_;
+ TaggedMember<CppGCManaged<icu::DateIntervalFormat>> 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 5ca6d8c2f40..3bf82fdc066 100644
--- a/deps/v8/src/objects/js-date-time-format.tq
+++ b/deps/v8/src/objects/js-date-time-format.tq
@@ -20,9 +20,11 @@ bitfield struct JSDateTimeFormatFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSDateTimeFormat extends JSObject {
locale: String;
- icu_locale: Foreign; // Managed<icu::Locale>
- icu_simple_date_format: Foreign; // Managed<icu::SimpleDateFormat>
- icu_date_interval_format: Foreign; // Managed<icu::DateIntervalFormat>
+ icu_locale: CppGCManagedBase; // CppGCManaged<icu::Locale>
+ icu_simple_date_format:
+ CppGCManagedBase; // CppGCManaged<icu::SimpleDateFormat>
+ icu_date_interval_format:
+ CppGCManagedBase; // CppGCManaged<icu::DateIntervalFormat>
bound_format: JSFunction|Undefined;
flags: SmiTagged<JSDateTimeFormatFlags>;
}
diff --git a/deps/v8/src/objects/js-display-names-inl.h b/deps/v8/src/objects/js-display-names-inl.h
index 692ff9105ff..9084bfd31b4 100644
--- a/deps/v8/src/objects/js-display-names-inl.h
+++ b/deps/v8/src/objects/js-display-names-inl.h
@@ -12,6 +12,7 @@
#include "src/objects/js-display-names.h"
// Include the non-inl header before the rest of the headers.
+#include "src/objects/managed-inl.h"
#include "src/objects/objects-inl.h"
// Has to be the last include (doesn't have include guards):
@@ -20,12 +21,12 @@
namespace v8 {
namespace internal {
-Tagged<Managed<DisplayNamesInternal>> JSDisplayNames::internal() const {
- return Cast<Managed<DisplayNamesInternal>>(internal_.load());
+Tagged<CppGCManaged<DisplayNamesInternal>> JSDisplayNames::internal() const {
+ return Cast<CppGCManaged<DisplayNamesInternal>>(internal_.load());
}
-void JSDisplayNames::set_internal(Tagged<Managed<DisplayNamesInternal>> value,
- WriteBarrierMode mode) {
+void JSDisplayNames::set_internal(
+ Tagged<CppGCManaged<DisplayNamesInternal>> value, WriteBarrierMode mode) {
internal_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-display-names.cc b/deps/v8/src/objects/js-display-names.cc
index cfdd4f4836c..2a2c3231755 100644
--- a/deps/v8/src/objects/js-display-names.cc
+++ b/deps/v8/src/objects/js-display-names.cc
@@ -79,7 +79,8 @@ UDisplayContext ToUDisplayContext(JSDisplayNames::Style style) {
// Abstract class for all different types.
class DisplayNamesInternal {
public:
- static constexpr ExternalPointerTag kManagedTag = kDisplayNamesInternalTag;
+ static constexpr ManagedTypeId kTypeID =
+ ManagedTypeId::kDisplayNamesInternal;
DisplayNamesInternal() = default;
virtual ~DisplayNamesInternal() = default;
@@ -531,8 +532,9 @@ MaybeDirectHandle<JSDisplayNames> JSDisplayNames::New(
THROW_NEW_ERROR(isolate, NewTypeError(MessageTemplate::kIcuError));
}
- DirectHandle<Managed<DisplayNamesInternal>> managed_internal =
- Managed<DisplayNamesInternal>::From(isolate, 0, std::move(internal));
+ DirectHandle<CppGCManaged<DisplayNamesInternal>> managed_internal =
+ CppGCManaged<DisplayNamesInternal>::Create(isolate, 0,
+ std::move(internal));
DirectHandle<JSDisplayNames> display_names =
Cast<JSDisplayNames>(factory->NewFastOrSlowJSObjectFromMap(map));
@@ -556,7 +558,7 @@ DirectHandle<JSObject> JSDisplayNames::ResolvedOptions(
DirectHandle<JSObject> options =
factory->NewJSObject(isolate->object_function());
- Managed<DisplayNamesInternal>::Ptr internal =
+ CppGCManaged<DisplayNamesInternal>::Ptr internal =
display_names->internal()->ptr();
Maybe<std::string> maybe_locale = Intl::ToLanguageTag(internal->locale());
@@ -609,7 +611,7 @@ MaybeDirectHandle<Object> JSDisplayNames::Of(
DirectHandle<String> code;
ASSIGN_RETURN_ON_EXCEPTION(isolate, code,
Object::ToString(isolate, code_obj));
- Managed<DisplayNamesInternal>::Ptr internal =
+ CppGCManaged<DisplayNamesInternal>::Ptr internal =
display_names->internal()->ptr();
Maybe<icu::UnicodeString> maybe_result =
internal->of(isolate, code->ToCString().get());
diff --git a/deps/v8/src/objects/js-display-names.h b/deps/v8/src/objects/js-display-names.h
index 549b8929130..d3f308aa864 100644
--- a/deps/v8/src/objects/js-display-names.h
+++ b/deps/v8/src/objects/js-display-names.h
@@ -91,8 +91,8 @@ V8_OBJECT class JSDisplayNames : public JSObject {
static_assert(LanguageDisplayBit::is_valid(LanguageDisplay::kDialect));
static_assert(LanguageDisplayBit::is_valid(LanguageDisplay::kStandard));
- inline Tagged<Managed<DisplayNamesInternal>> internal() const;
- inline void set_internal(Tagged<Managed<DisplayNamesInternal>> value,
+ inline Tagged<CppGCManaged<DisplayNamesInternal>> internal() const;
+ inline void set_internal(Tagged<CppGCManaged<DisplayNamesInternal>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int flags() const;
@@ -104,7 +104,7 @@ V8_OBJECT class JSDisplayNames : public JSObject {
static const int kHeaderSize;
public:
- TaggedMember<Foreign> internal_;
+ TaggedMember<CppGCManaged<DisplayNamesInternal>> internal_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-display-names.tq b/deps/v8/src/objects/js-display-names.tq
index 7934c6fd17c..a26080530ff 100644
--- a/deps/v8/src/objects/js-display-names.tq
+++ b/deps/v8/src/objects/js-display-names.tq
@@ -18,6 +18,6 @@ bitfield struct JSDisplayNamesFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSDisplayNames extends JSObject {
- internal: Foreign; // Managed<DisplayNamesInternal>
+ internal: CppGCManagedBase; // CppGCManaged<DisplayNamesInternal>
flags: SmiTagged<JSDisplayNamesFlags>;
}
diff --git a/deps/v8/src/objects/js-disposable-stack.h b/deps/v8/src/objects/js-disposable-stack.h
index 804242a186d..a55c5f00950 100644
--- a/deps/v8/src/objects/js-disposable-stack.h
+++ b/deps/v8/src/objects/js-disposable-stack.h
@@ -41,6 +41,8 @@ using DisposeCallTypeBit =
using DisposeHintBit = DisposeCallTypeBit::Next<DisposeMethodHint, 1>;
V8_OBJECT class JSDisposableStackBase : public JSObject {
+ V8_IT_OWN_TYPE;
+
public:
inline Tagged<FixedArray> stack() const;
inline void set_stack(Tagged<FixedArray> value,
diff --git a/deps/v8/src/objects/js-duration-format-inl.h b/deps/v8/src/objects/js-duration-format-inl.h
index d8f785d1575..b016df321dd 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<Managed<icu::Locale>> JSDurationFormat::icu_locale() const {
- return Cast<Managed<icu::Locale>>(icu_locale_.load());
+Tagged<CppGCManaged<icu::Locale>> JSDurationFormat::icu_locale() const {
+ return Cast<CppGCManaged<icu::Locale>>(icu_locale_.load());
}
-void JSDurationFormat::set_icu_locale(Tagged<Managed<icu::Locale>> value,
- WriteBarrierMode mode) {
+void JSDurationFormat::set_icu_locale(
+ Tagged<CppGCManaged<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<Managed<icu::number::LocalizedNumberFormatter>>
+Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
JSDurationFormat::icu_number_formatter() const {
- return Cast<Managed<icu::number::LocalizedNumberFormatter>>(
+ return Cast<CppGCManaged<icu::number::LocalizedNumberFormatter>>(
icu_number_formatter_.load());
}
void JSDurationFormat::set_icu_number_formatter(
- Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<CppGCManaged<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 36458e43cb0..4b42cc49c3a 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<Managed<icu::Locale>> managed_locale =
- Managed<icu::Locale>::From(
+ DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
+ CppGCManaged<icu::Locale>::Create(
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<Managed<icu::number::LocalizedNumberFormatter>>
+ DirectHandle<CppGCManaged<icu::number::LocalizedNumberFormatter>>
managed_number_formatter =
- Managed<icu::number::LocalizedNumberFormatter>::From(
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Create(
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 ca42ec1c886..fad50ad3499 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<Managed<icu::Locale>> icu_locale() const;
- inline void set_icu_locale(Tagged<Managed<icu::Locale>> value,
+ inline Tagged<CppGCManaged<icu::Locale>> icu_locale() const;
+ inline void set_icu_locale(Tagged<CppGCManaged<icu::Locale>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<icu::number::LocalizedNumberFormatter>>
+ inline Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
icu_number_formatter() const;
inline void set_icu_number_formatter(
- Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(JSDurationFormat)
@@ -227,8 +227,9 @@ V8_OBJECT class JSDurationFormat : public JSObject {
public:
TaggedMember<Smi> style_flags_;
TaggedMember<Smi> display_flags_;
- TaggedMember<Foreign> icu_locale_;
- TaggedMember<Foreign> icu_number_formatter_;
+ TaggedMember<CppGCManaged<icu::Locale>> icu_locale_;
+ TaggedMember<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ 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 d43c4b0e3a4..5e47435afb9 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: Foreign; // Managed<icu::Locale>
+ icu_locale: CppGCManagedBase; // CppGCManaged<icu::Locale>
icu_number_formatter:
- Foreign; // Managed<icu::number::LocalizedNumberFormatter>
+ CppGCManagedBase; // CppGCManaged<icu::number::LocalizedNumberFormatter>
}
diff --git a/deps/v8/src/objects/js-function-inl.h b/deps/v8/src/objects/js-function-inl.h
index d5fd5df0f82..6adb7967242 100644
--- a/deps/v8/src/objects/js-function-inl.h
+++ b/deps/v8/src/objects/js-function-inl.h
@@ -350,6 +350,7 @@ std::optional<CodeKind> JSFunction::GetRequestedOptimizationIfAny(
break;
case TieringBuiltin::kMarkLazyDeoptimized:
case TieringBuiltin::kMarkReoptimizeLazyDeoptimized:
+ case TieringBuiltin::kMarkFlushed:
case TieringBuiltin::kFunctionLogNextExecution:
break;
}
@@ -357,6 +358,7 @@ std::optional<CodeKind> JSFunction::GetRequestedOptimizationIfAny(
}
void JSFunction::ResetTieringRequests(Isolate* isolate) {
+ if (has_feedback_vector()) feedback_vector()->reset_osr_urgency();
isolate->js_dispatch_table().ResetTieringRequest(dispatch_handle());
}
diff --git a/deps/v8/src/objects/js-function.cc b/deps/v8/src/objects/js-function.cc
index 3f80dc30378..63423bfe127 100644
--- a/deps/v8/src/objects/js-function.cc
+++ b/deps/v8/src/objects/js-function.cc
@@ -10,7 +10,6 @@
#include "src/codegen/compiler.h"
#include "src/common/globals.h"
#include "src/diagnostics/code-tracer.h"
-#include "src/debug/debug.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate.h"
#include "src/execution/tiering-manager.h"
@@ -22,8 +21,10 @@
#include "src/objects/feedback-cell-inl.h"
#include "src/objects/feedback-vector.h"
#include "src/objects/instance-type-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/object-predicates-inl.h"
#include "src/objects/objects.h"
+#include "src/objects/shared-function-info-inl.h"
#include "src/roots/roots.h"
#include "src/strings/string-builder-inl.h"
@@ -923,7 +924,7 @@ void JSFunction::SetInitialMap(Isolate* isolate,
if (function->TryGetPrototypeOrInitialMap(&pomd) &&
pomd.has_non_instance_prototype) {
pomd.non_instance_prototype_tuple->set_value1(*initial_map,
- kRelaxedStore);
+ kReleaseStore);
} else {
function->set_prototype_or_initial_map(*initial_map, kReleaseStore);
}
@@ -1591,12 +1592,22 @@ void JSFunction::ClearAllTypeFeedbackInfoForTesting(Isolate* isolate) {
it.current_bytecode())) {
continue;
}
- bytecode_array->set(
- it.GetEmbeddedFeedbackOffset(kEmbeddedFeedbackOperandIndex) +
- kHeapObjectTag - BytecodeArray::kHeaderSize,
- kUninitializedEmbeddedFeedback);
+ int operand_index = interpreter::Bytecodes::IsUnaryOpWithEmbeddedFeedback(
+ it.current_bytecode())
+ ? kUnaryEmbeddedFeedbackOperandIndex
+ : kEmbeddedFeedbackOperandIndex;
+ bytecode_array->set(it.GetEmbeddedFeedbackOffset(operand_index) +
+ kHeapObjectTag - BytecodeArray::kHeaderSize,
+ kUninitializedEmbeddedFeedback);
}
}
+ if (shared()->HasBaselineCode()) {
+ shared()->FlushBaselineCode();
+ }
+ if (ActiveTierIsBaseline(isolate)) {
+ ResetTieringRequests(isolate);
+ UpdateCode(isolate, *BUILTIN_CODE(isolate, InterpreterEntryTrampoline));
+ }
}
} // namespace v8::internal
diff --git a/deps/v8/src/objects/js-function.h b/deps/v8/src/objects/js-function.h
index 5c798410c86..f07734c116c 100644
--- a/deps/v8/src/objects/js-function.h
+++ b/deps/v8/src/objects/js-function.h
@@ -24,6 +24,8 @@ class Tuple2;
// It doesn't carry any functionality but allows function classes to be
// identified in the type system.
V8_OBJECT class JSFunctionOrBoundFunctionOrWrappedFunction : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
static const int kLengthDescriptorIndex = 0;
static const int kNameDescriptorIndex = 1;
@@ -127,6 +129,8 @@ enum class BudgetModification { kReduce, kRaise, kReset };
// prototype. Respective subclass defines the layout of the object in memory
// but all the JSFunction related logic lives in this class.
V8_OBJECT class JSFunction : public JSFunctionOrBoundFunctionOrWrappedFunction {
+ V8_IT_ABSTRACT;
+
public:
DECL_RELEASE_ACQUIRE_ACCESSORS(
prototype_or_initial_map,
@@ -254,7 +258,6 @@ V8_OBJECT class JSFunction : public JSFunctionOrBoundFunctionOrWrappedFunction {
// kinds, e.g. TURBOFAN, ignore the tiering state).
inline bool ChecksTieringState(IsolateForSandbox isolate);
-
// Tiering up a function happens as follows:
// 1. RequestOptimization is called
// -> From now on `IsOptimizationRequested` and also
@@ -564,6 +567,8 @@ inline constexpr int JSFunctionWithoutPrototype::kMinSize =
// Defines layout of JavaScript functions with prototype.
V8_OBJECT class JSFunctionWithPrototype : public JSFunction {
+ V8_IT_ORDER(LAST);
+
public:
static const int kHeaderSize;
static const int kMinSize;
@@ -595,6 +600,7 @@ inline constexpr int JSFunctionWithPrototype::kMinSize =
sizeof(JSFunctionWithPrototype);
V8_OBJECT class JSClassConstructor : public JSFunctionWithPrototype {
+ V8_IT_ORDER(LAST);
} V8_OBJECT_END;
} // namespace v8::internal
diff --git a/deps/v8/src/objects/js-generator.h b/deps/v8/src/objects/js-generator.h
index 987081fc0d8..874ab784e84 100644
--- a/deps/v8/src/objects/js-generator.h
+++ b/deps/v8/src/objects/js-generator.h
@@ -20,6 +20,8 @@ class JSPromise;
class StructBodyDescriptor;
V8_OBJECT class JSGeneratorObject : public JSObject {
+ V8_IT_OWN_TYPE;
+
public:
enum ResumeMode { kNext, kReturn, kThrow, kRethrow };
diff --git a/deps/v8/src/objects/js-interceptor-map.h b/deps/v8/src/objects/js-interceptor-map.h
index 1bf77351fa0..5c9b246a934 100644
--- a/deps/v8/src/objects/js-interceptor-map.h
+++ b/deps/v8/src/objects/js-interceptor-map.h
@@ -17,6 +17,8 @@ class InterceptorInfo;
// Extended map for interceptor objects, it caches named and indexed
// InterceptorInfo objects in the Map for faster access.
V8_OBJECT class JSInterceptorMap : public ExtendedMap {
+ V8_IT_REUSE_PARENT;
+
public:
using SupportsFastIterableToListBit = base::BitField<bool, 0, 1, uint8_t>;
diff --git a/deps/v8/src/objects/js-iterator-helpers.h b/deps/v8/src/objects/js-iterator-helpers.h
index 8090847f0f4..048a509ab48 100644
--- a/deps/v8/src/objects/js-iterator-helpers.h
+++ b/deps/v8/src/objects/js-iterator-helpers.h
@@ -70,6 +70,8 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
// The superclass of all iterator helpers.
V8_OBJECT class JSIteratorHelper : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
inline JSIteratorHelperState state() const;
inline void set_state(JSIteratorHelperState value);
@@ -85,6 +87,8 @@ V8_OBJECT class JSIteratorHelper : public JSObject {
// The superclass of iterator helpers that have a single underlying iterator.
V8_OBJECT class JSIteratorHelperSimple : public JSIteratorHelper {
+ V8_IT_ABSTRACT;
+
public:
inline Tagged<JSReceiver> underlying_iterator_object() const;
inline void set_underlying_iterator_object(
@@ -219,6 +223,8 @@ V8_OBJECT class JSIteratorConcatHelper final : public JSIteratorHelperSimple {
// The iterator helper returned by Iterator.zip and Iterator.zipKeyed.
V8_OBJECT class JSIteratorZipHelper : public JSIteratorHelper {
+ V8_IT_OWN_TYPE;
+
public:
inline Tagged<FixedArray> underlying_iterators() const;
inline void set_underlying_iterators(
diff --git a/deps/v8/src/objects/js-list-format-inl.h b/deps/v8/src/objects/js-list-format-inl.h
index fef695de69d..925d421a784 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<Managed<icu::ListFormatter>> JSListFormat::icu_formatter() const {
- return Cast<Managed<icu::ListFormatter>>(icu_formatter_.load());
+Tagged<CppGCManaged<icu::ListFormatter>> JSListFormat::icu_formatter() const {
+ return Cast<CppGCManaged<icu::ListFormatter>>(icu_formatter_.load());
}
-void JSListFormat::set_icu_formatter(Tagged<Managed<icu::ListFormatter>> value,
- WriteBarrierMode mode) {
+void JSListFormat::set_icu_formatter(
+ Tagged<CppGCManaged<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 da6e33abcd7..6257491fc07 100644
--- a/deps/v8/src/objects/js-list-format.cc
+++ b/deps/v8/src/objects/js-list-format.cc
@@ -125,8 +125,9 @@ MaybeDirectHandle<JSListFormat> JSListFormat::New(
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError));
}
- DirectHandle<Managed<icu::ListFormatter>> managed_formatter =
- Managed<icu::ListFormatter>::From(isolate, 0, std::move(formatter));
+ DirectHandle<CppGCManaged<icu::ListFormatter>> managed_formatter =
+ CppGCManaged<icu::ListFormatter>::Create(isolate, 0,
+ std::move(formatter));
// Now all properties are ready, so we can allocate the result object.
DirectHandle<JSListFormat> list_format =
@@ -225,7 +226,8 @@ MaybeDirectHandle<T> FormatListCommon(
MAYBE_RETURN(maybe_array, DirectHandle<T>());
std::vector<icu::UnicodeString> array = maybe_array.FromJust();
- Managed<icu::ListFormatter>::Ptr formatter = format->icu_formatter()->ptr();
+ CppGCManaged<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 c4ea672eeb7..5d7cd57350c 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<Managed<icu::ListFormatter>> icu_formatter() const;
- inline void set_icu_formatter(Tagged<Managed<icu::ListFormatter>> value,
+ inline Tagged<CppGCManaged<icu::ListFormatter>> icu_formatter() const;
+ inline void set_icu_formatter(Tagged<CppGCManaged<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<Foreign> icu_formatter_;
+ TaggedMember<CppGCManaged<icu::ListFormatter>> 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 ba8256c07d4..80ac3757af6 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: Foreign; // Managed<icu::ListFormatter>
+ icu_formatter: CppGCManagedBase; // CppGCManaged<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 87953ea807e..555f18821a8 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<Managed<icu::Locale>> JSLocale::icu_locale() const {
- return Cast<Managed<icu::Locale>>(icu_locale_.load());
+Tagged<CppGCManaged<icu::Locale>> JSLocale::icu_locale() const {
+ return Cast<CppGCManaged<icu::Locale>>(icu_locale_.load());
}
-void JSLocale::set_icu_locale(Tagged<Managed<icu::Locale>> value,
+void JSLocale::set_icu_locale(Tagged<CppGCManaged<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 b70986af085..a1d67754f48 100644
--- a/deps/v8/src/objects/js-locale.cc
+++ b/deps/v8/src/objects/js-locale.cc
@@ -8,6 +8,8 @@
#include "src/objects/js-locale.h"
+#include <algorithm>
+#include <cctype>
#include <map>
#include <memory>
#include <string>
@@ -145,7 +147,7 @@ Maybe<bool> InsertOptionsIntoLocale(Isolate* isolate,
DirectHandle<Object> UnicodeKeywordValue(Isolate* isolate,
DirectHandle<JSLocale> locale,
const char* key) {
- Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
UErrorCode status = U_ZERO_ERROR;
std::string value =
icu_locale->getUnicodeKeywordValue<std::string>(key, status);
@@ -285,28 +287,30 @@ bool JSLocale::StartsWithUnicodeLanguageId(std::string_view value) {
}
namespace {
-// Return true if variants contain duplicate elements.
-bool DuplicateVariants(std::string variants) {
+// Return false if variants contain duplicate elements or invalid delimiters.
+bool IsValidVariants(std::string_view variants) {
// The length of one unicode_variant_subtag is between 4-8. To have
- // duplicate, the length of the variants need to be >= 4+1+4 = 9.
+ // duplicate or multiple subtags, the length of the variants need to be >=
+ // 4+1+4 = 9.
if (variants.length() >= 9) {
- std::transform(
- variants.begin(), variants.end(), variants.begin(),
- [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
- size_t pos = 0;
- size_t count = 1;
std::set<std::string> set;
- while ((pos = variants.find('-')) != std::string::npos) {
- set.insert(variants.substr(0, pos));
- variants.erase(0, pos + 1);
- count++;
- }
- set.insert(variants);
- if (count != set.size()) {
- return true;
+ size_t start = 0;
+ for (size_t i = 0; i <= variants.length(); ++i) {
+ if (i == variants.length() || variants[i] == '-') {
+ std::string subtag(variants.substr(start, i - start));
+ std::transform(
+ subtag.begin(), subtag.end(), subtag.begin(),
+ [](unsigned char c) { return static_cast<char>(std::tolower(c)); });
+ if (!set.insert(subtag).second) {
+ return false;
+ }
+ start = i + 1;
+ } else if (variants[i] == '_') {
+ return false;
+ }
}
}
- return false;
+ return true;
}
Maybe<bool> ApplyOptionsToTag(Isolate* isolate, DirectHandle<String> tag,
DirectHandle<JSReceiver> options,
@@ -391,33 +395,31 @@ Maybe<bool> ApplyOptionsToTag(Isolate* isolate, DirectHandle<String> tag,
}
}
- if (v8_flags.js_intl_locale_variants) {
- // 8. Let variants be ? GetOption(options, "variants", string, empty,
- // GetLocaleVariants(baseName)).
- DirectHandle<String> variants_str;
- Maybe<bool> maybe_variants =
- GetStringOption(isolate, options, isolate->factory()->variants_string(),
- "ApplyOptionsToTag", &variants_str);
- MAYBE_RETURN(maybe_variants, Nothing<bool>());
- // 9. If variants is not undefined, then
- if (maybe_variants.FromJust()) {
- // a. If variants is the empty String, throw a RangeError exception.
- // b. Let lowerVariants be the ASCII-lowercase of variants.
- std::string variants_stdstr = variants_str->ToStdString();
- // c. Let variantSubtags be StringSplitToList(lowerVariants, "-").
- // d. For each element variant of variantSubtags, do
- // i. If variant cannot be matched by the unicode_variant_subtag Unicode
- // locale nonterminal, throw a RangeError exception.
- builder->setVariant(variants_stdstr);
- builder->build(status);
- if (U_FAILURE(status) || variants_stdstr.empty()) {
- return Just(false);
- }
- // e. If variantSubtags contains any duplicate elements, throw a
- // RangeError exception.
- if (DuplicateVariants(variants_stdstr)) {
- return Just(false);
- }
+ // 8. Let variants be ? GetOption(options, "variants", string, empty,
+ // GetLocaleVariants(baseName)).
+ DirectHandle<String> variants_str;
+ Maybe<bool> maybe_variants =
+ GetStringOption(isolate, options, isolate->factory()->variants_string(),
+ "ApplyOptionsToTag", &variants_str);
+ MAYBE_RETURN(maybe_variants, Nothing<bool>());
+ // 9. If variants is not undefined, then
+ if (maybe_variants.FromJust()) {
+ // a. If variants is the empty String, throw a RangeError exception.
+ // b. Let lowerVariants be the ASCII-lowercase of variants.
+ std::string variants_stdstr = variants_str->ToStdString();
+ // c. Let variantSubtags be StringSplitToList(lowerVariants, "-").
+ // d. For each element variant of variantSubtags, do
+ // i. If variant cannot be matched by the unicode_variant_subtag Unicode
+ // locale nonterminal, throw a RangeError exception.
+ builder->setVariant(variants_stdstr);
+ builder->build(status);
+ if (U_FAILURE(status) || variants_stdstr.empty()) {
+ return Just(false);
+ }
+ // e. If variantSubtags contains any duplicate elements, throw a
+ // RangeError exception.
+ if (!IsValidVariants(variants_stdstr)) {
+ return Just(false);
}
}
@@ -475,8 +477,8 @@ MaybeDirectHandle<JSLocale> JSLocale::New(Isolate* isolate,
}
// 31. Set locale.[[Locale]] to r.[[locale]].
- DirectHandle<Managed<icu::Locale>> managed_locale =
- Managed<icu::Locale>::From(
+ DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
+ CppGCManaged<icu::Locale>::Create(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
// Now all properties are ready, so we can allocate the result object.
@@ -491,8 +493,8 @@ namespace {
MaybeDirectHandle<JSLocale> Construct(Isolate* isolate,
const icu::Locale& icu_locale) {
- DirectHandle<Managed<icu::Locale>> managed_locale =
- Managed<icu::Locale>::From(
+ DirectHandle<CppGCManaged<icu::Locale>> managed_locale =
+ CppGCManaged<icu::Locale>::Create(
isolate, 0, std::shared_ptr<icu::Locale>{icu_locale.clone()});
DirectHandle<JSFunction> constructor(
@@ -611,6 +613,118 @@ MaybeDirectHandle<JSArray> GetKeywordValuesFromLocale(
namespace {
+// https://tc39.es/ecma402/#sec-canonicalunicodesubdivision
+std::string CanonicalUnicodeSubdivision(const icu::Locale& icu_locale,
+ const char* key) {
+ UErrorCode status = U_ZERO_ERROR;
+ // 1. Let subdivision be UnicodeExtensionValue(locale, key).
+ std::string subdivision =
+ icu_locale.getUnicodeKeywordValue<std::string>(key, status);
+
+ // 2. If subdivision is ~empty~, return undefined.
+ if (U_FAILURE(status) || subdivision.empty()) return "";
+
+ // 3. If subdivision cannot be matched by the unicode_subdivision_id Unicode
+ // locale nonterminal, return undefined.
+ // unicode_subdivision_id = unicode_region_subtag unicode_subdivision_suffix
+ // unicode_region_subtag = (alpha{2} | digit{3})
+ // unicode_subdivision_suffix = alphanum{1,4}
+ //
+ // 4. Let region be the longest prefix of subdivision matched by the
+ // unicode_region_subtag Unicode locale nonterminal.
+ // Real examples: "gbeng" -> region "GB", "usca" -> region "US", "001abc" ->
+ // region "001".
+ std::string_view sub_view(subdivision);
+ std::string_view region;
+ if (sub_view.length() >= 4 && IsDigit(sub_view.substr(0, 3), 3, 3)) {
+ if (!IsAlphanum(sub_view.substr(3), 1, 4)) return "";
+ region = sub_view.substr(0, 3);
+ } else {
+ if (sub_view.length() < 3 || !IsAlpha(sub_view.substr(0, 2), 2, 2) ||
+ !IsAlphanum(sub_view.substr(2), 1, 4)) {
+ return "";
+ }
+ region = sub_view.substr(0, 2);
+ }
+
+ // 5. Let regionLocale be the string-concatenation of "und-" and region.
+ // 6. Set regionLocale to CanonicalizeUnicodeLocaleId(regionLocale).
+ // 7. Return GetLocaleRegion(regionLocale).
+ std::string result(region);
+ std::transform(result.begin(), result.end(), result.begin(),
+ [](unsigned char c) { return std::toupper(c); });
+ return result;
+}
+
+struct RegionPreferenceRecord {
+ std::string region;
+ std::string region_override;
+};
+
+// https://tc39.es/ecma402/#sec-regionpreference
+RegionPreferenceRecord RegionPreference(const icu::Locale& icu_locale) {
+ // 1. Let region be GetLocaleRegion(locale).
+ const char* country = icu_locale.getCountry();
+ std::string region = (country != nullptr) ? country : "";
+
+ // 2. If region is undefined, then
+ if (region.empty()) {
+ // a. Set region to CanonicalUnicodeSubdivision(locale, "sd").
+ region = CanonicalUnicodeSubdivision(icu_locale, "sd");
+
+ // b. If region is undefined, then
+ if (region.empty()) {
+ // i. Let maximal be the result of the Add Likely Subtags algorithm
+ // applied to locale. If an error is signaled, set maximal to locale.
+ // ii. Set maximal to CanonicalizeUnicodeLocaleId(maximal).
+ UErrorCode status = U_ZERO_ERROR;
+ icu::Locale maximal = icu_locale;
+ maximal.addLikelySubtags(status);
+ if (U_FAILURE(status)) maximal = icu_locale;
+
+ // iii. Set region to GetLocaleRegion(maximal).
+ const char* max_country = maximal.getCountry();
+ region = (max_country != nullptr) ? max_country : "";
+
+ // iv. If region is undefined, then
+ if (region.empty()) {
+ // 1. Set region to "001".
+ region = "001";
+ }
+ }
+ }
+
+ // 3. Let regionOverride be CanonicalUnicodeSubdivision(locale, "rg").
+ std::string region_override = CanonicalUnicodeSubdivision(icu_locale, "rg");
+
+ // 4. Return { [[Region]]: region, [[RegionOverride]]: regionOverride }.
+ return {region, region_override};
+}
+
+// Applies RegionPreference(icu_locale) to construct an icu::Locale with the
+// preferred lookup region. Implements region resolution for:
+// - (CalendarsOfLocale) 2-3. Let preference be
+// RegionPreference(loc.[[Locale]]).
+// If preference.[[RegionOverride]] is not undefined, let preferredRegions be
+// « preference.[[RegionOverride]], preference.[[Region]] »; else ...
+// - (HourCyclesOfLocale) 2-3. Let preference be
+// RegionPreference(loc.[[Locale]]).
+// If preference.[[RegionOverride]] is not undefined, let preferredRegions be
+// « preference.[[RegionOverride]], preference.[[Region]] »; else ...
+// - (WeekInfoOfLocale) 1-5. Let preference be RegionPreference(loc.[[Locale]]).
+// Select lookupRegion based on regionOverride or region.
+icu::Locale ApplyRegionPreference(const icu::Locale& icu_locale) {
+ RegionPreferenceRecord pref = RegionPreference(icu_locale);
+ std::string lookup_region =
+ !pref.region_override.empty() ? pref.region_override : pref.region;
+ UErrorCode status = U_ZERO_ERROR;
+ icu::Locale res = icu::LocaleBuilder()
+ .setLocale(icu_locale)
+ .setRegion(lookup_region)
+ .build(status);
+ return U_SUCCESS(status) ? res : icu_locale;
+}
+
MaybeDirectHandle<JSArray> CalendarsForLocale(Isolate* isolate,
const icu::Locale& icu_locale,
bool commonly_used, bool sort) {
@@ -623,7 +737,8 @@ MaybeDirectHandle<JSArray> CalendarsForLocale(Isolate* isolate,
MaybeDirectHandle<JSArray> JSLocale::GetCalendars(
Isolate* isolate, DirectHandle<JSLocale> locale) {
icu::Locale icu_locale(*(locale->icu_locale()->ptr()));
- return CalendarsForLocale(isolate, icu_locale, true, false);
+ return CalendarsForLocale(isolate, ApplyRegionPreference(icu_locale), true,
+ false);
}
MaybeDirectHandle<JSArray> Intl::AvailableCalendars(Isolate* isolate) {
@@ -665,7 +780,8 @@ MaybeDirectHandle<JSArray> JSLocale::GetHourCycles(
}
status = U_ZERO_ERROR;
std::unique_ptr<icu::DateTimePatternGenerator> generator(
- icu::DateTimePatternGenerator::createInstance(icu_locale, status));
+ icu::DateTimePatternGenerator::createInstance(
+ ApplyRegionPreference(icu_locale), status));
if (U_FAILURE(status)) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError));
}
@@ -809,8 +925,8 @@ MaybeDirectHandle<JSObject> JSLocale::GetWeekInfo(
DirectHandle<JSObject> info =
factory->NewJSObject(isolate->object_function());
UErrorCode status = U_ZERO_ERROR;
- std::unique_ptr<icu::Calendar> calendar(
- icu::Calendar::createInstance(*(locale->icu_locale()->ptr()), status));
+ std::unique_ptr<icu::Calendar> calendar(icu::Calendar::createInstance(
+ ApplyRegionPreference(*(locale->icu_locale()->ptr())), status));
if (U_FAILURE(status)) {
THROW_NEW_ERROR(isolate, NewRangeError(MessageTemplate::kIcuError));
}
@@ -858,7 +974,7 @@ MaybeDirectHandle<JSObject> JSLocale::GetWeekInfo(
DirectHandle<Object> JSLocale::Language(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
const char* language = icu_locale->getLanguage();
constexpr const char kUnd[] = "und";
if (strlen(language) == 0) {
@@ -870,7 +986,7 @@ DirectHandle<Object> JSLocale::Language(Isolate* isolate,
DirectHandle<Object> JSLocale::Script(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ CppGCManaged<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);
@@ -895,7 +1011,7 @@ DirectHandle<Object> JSLocale::Variants(Isolate* isolate,
DirectHandle<Object> JSLocale::Region(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ CppGCManaged<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);
@@ -936,7 +1052,7 @@ DirectHandle<Object> JSLocale::HourCycle(Isolate* isolate,
DirectHandle<Object> JSLocale::Numeric(Isolate* isolate,
DirectHandle<JSLocale> locale) {
Factory* factory = isolate->factory();
- Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ CppGCManaged<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
UErrorCode status = U_ZERO_ERROR;
std::string numeric =
icu_locale->getUnicodeKeywordValue<std::string>("kn", status);
@@ -949,7 +1065,7 @@ DirectHandle<Object> JSLocale::NumberingSystem(Isolate* isolate,
}
std::string JSLocale::ToString(DirectHandle<JSLocale> locale) {
- Managed<icu::Locale>::Ptr icu_locale = locale->icu_locale()->ptr();
+ CppGCManaged<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 bfb79ba1bf4..28649bd4fcd 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<Managed<icu::Locale>> icu_locale() const;
- inline void set_icu_locale(Tagged<Managed<icu::Locale>> value,
+ inline Tagged<CppGCManaged<icu::Locale>> icu_locale() const;
+ inline void set_icu_locale(Tagged<CppGCManaged<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<Foreign> icu_locale_;
+ TaggedMember<CppGCManaged<icu::Locale>> 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 60c97710856..f46665fcb58 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: Foreign; // Managed<icu::Locale>
+ icu_locale: CppGCManagedBase; // CppGCManaged<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 2a14788a33d..31e99afaf0b 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<Managed<icu::number::LocalizedNumberFormatter>>
+Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
JSNumberFormat::icu_number_formatter() const {
- return Cast<Managed<icu::number::LocalizedNumberFormatter>>(
+ return Cast<CppGCManaged<icu::number::LocalizedNumberFormatter>>(
icu_number_formatter_.load());
}
void JSNumberFormat::set_icu_number_formatter(
- Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<CppGCManaged<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 16b9ddcd65c..63b56481563 100644
--- a/deps/v8/src/objects/js-number-format.cc
+++ b/deps/v8/src/objects/js-number-format.cc
@@ -17,6 +17,7 @@
#include "src/objects/intl-objects.h"
#include "src/objects/js-number-format-inl.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "src/strings/char-predicates-inl.h"
@@ -876,7 +877,7 @@ DirectHandle<JSObject> JSNumberFormat::ResolvedOptions(
Factory* factory = isolate->factory();
UErrorCode status = U_ZERO_ERROR;
- Managed<icu::number::LocalizedNumberFormatter>::Ptr fmt =
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr fmt =
number_format->icu_number_formatter()->ptr();
icu::UnicodeString skeleton = fmt->toSkeleton(status);
DCHECK(U_SUCCESS(status));
@@ -1462,9 +1463,9 @@ MaybeDirectHandle<JSNumberFormat> JSNumberFormat::New(
//
icu::number::LocalizedNumberFormatter fmt = settings.locale(icu_locale);
- DirectHandle<Managed<icu::number::LocalizedNumberFormatter>>
+ DirectHandle<CppGCManaged<icu::number::LocalizedNumberFormatter>>
managed_number_formatter =
- Managed<icu::number::LocalizedNumberFormatter>::From(
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Create(
isolate, 0,
std::make_shared<icu::number::LocalizedNumberFormatter>(fmt));
@@ -2019,7 +2020,7 @@ MaybeDirectHandle<T> PartitionNumberRangePattern(
factory->NewStringFromStaticChars("end"), end));
}
- Managed<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
number_format->icu_number_formatter()->ptr();
Maybe<icu::number::LocalizedNumberRangeFormatter> maybe_range_formatter =
@@ -2121,7 +2122,7 @@ MaybeDirectHandle<String> JSNumberFormat::NumberFormatFunction(
IntlMathematicalValue::From(isolate, value));
// 5. Return FormatNumeric(nf, x).
- Managed<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
number_format->icu_number_formatter()->ptr();
Maybe<icu::number::FormattedNumber> maybe_formatted =
IntlMathematicalValue::FormatNumeric(isolate, lfmt.raw(), x);
@@ -2139,7 +2140,7 @@ MaybeDirectHandle<JSArray> JSNumberFormat::FormatToParts(
ASSIGN_RETURN_ON_EXCEPTION(isolate, value,
IntlMathematicalValue::From(isolate, numeric_obj));
- Managed<icu::number::LocalizedNumberFormatter>::Ptr lfmt =
+ CppGCManaged<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 6cd8138359a..64dea2e4b76 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<Managed<icu::number::LocalizedNumberFormatter>>
+ inline Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
icu_number_formatter() const;
inline void set_icu_number_formatter(
- Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<UnionOf<JSFunction, Undefined>> bound_format() const;
@@ -130,7 +130,8 @@ V8_OBJECT class JSNumberFormat : public JSObject {
public:
TaggedMember<String> locale_;
- TaggedMember<Foreign> icu_number_formatter_;
+ TaggedMember<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ 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 59f29cdd34b..a17c1d63de2 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:
- Foreign; // Managed<icu::number::LocalizedNumberFormatter>
+ CppGCManagedBase; // CppGCManaged<icu::number::LocalizedNumberFormatter>
bound_format: JSFunction|Undefined;
}
diff --git a/deps/v8/src/objects/js-objects.cc b/deps/v8/src/objects/js-objects.cc
index fd50cca1988..47da2576efe 100644
--- a/deps/v8/src/objects/js-objects.cc
+++ b/deps/v8/src/objects/js-objects.cc
@@ -55,6 +55,8 @@
#include "src/objects/js-shadow-realm.h"
#include "src/objects/js-shared-array.h"
#include "src/objects/js-struct.h"
+#include "src/objects/map-word.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-details.h"
#ifdef V8_TEMPORAL_SUPPORT
#include "src/objects/js-temporal-objects-inl.h"
@@ -139,6 +141,7 @@ Maybe<bool> JSReceiver::HasProperty(LookupIterator* it) {
JSDeferredModuleNamespace::EvaluateModuleSync(it->isolate(), holder);
RETURN_EXCEPTION_IF_EXCEPTION(it->isolate());
}
+ JSModuleNamespace::MaybeCountMissingDefaultWithStarExport(it);
continue;
}
case LookupIterator::ACCESSOR:
@@ -865,23 +868,31 @@ int GetIdentityHashHelper(Tagged<JSReceiver> object) {
return Smi::ToInt(properties);
}
- if (IsPropertyArray(properties)) {
- return Cast<PropertyArray>(properties)->Hash();
+ Tagged<HeapObject> properties_object = Cast<HeapObject>(properties);
+ if (MapWord properties_object_map = properties_object->map_word(kRelaxedLoad);
+ properties_object_map.IsForwardingAddress()) {
+ properties_object =
+ properties_object_map.ToForwardingAddress(properties_object);
+ DCHECK(!properties_object->map_word(kRelaxedLoad).IsForwardingAddress());
}
- if (IsPropertyDictionary(properties)) {
- return Cast<PropertyDictionary>(properties)->Hash();
+ if (IsPropertyArray(properties_object)) {
+ return Cast<PropertyArray>(properties_object)->Hash();
}
- if (IsGlobalDictionary(properties)) {
- return Cast<GlobalDictionary>(properties)->Hash();
+ if (IsPropertyDictionary(properties_object)) {
+ return Cast<PropertyDictionary>(properties_object)->Hash();
+ }
+
+ if (IsGlobalDictionary(properties_object)) {
+ return Cast<GlobalDictionary>(properties_object)->Hash();
}
#ifdef DEBUG
ReadOnlyRoots roots = GetReadOnlyRoots();
- DCHECK(properties == roots.empty_fixed_array() ||
- properties == roots.empty_property_dictionary() ||
- properties == roots.empty_swiss_property_dictionary());
+ DCHECK(properties_object == roots.empty_fixed_array() ||
+ properties_object == roots.empty_property_dictionary() ||
+ properties_object == roots.empty_swiss_property_dictionary());
#endif
return PropertyArray::kNoHashSentinel;
@@ -1868,45 +1879,46 @@ Maybe<bool> JSReceiver::AddPrivateField(LookupIterator* it,
DCHECK(it->GetName()->IsAnyPrivateName());
DirectHandle<Symbol> symbol = Cast<Symbol>(it->GetName());
- switch (it->state()) {
- case LookupIterator::JSPROXY: {
- PropertyDescriptor new_desc;
- new_desc.set_value(Cast<JSAny>(value));
- new_desc.set_writable(true);
- new_desc.set_enumerable(true);
- new_desc.set_configurable(true);
- return JSProxy::SetPrivateSymbol(isolate, Cast<JSProxy>(receiver), symbol,
- &new_desc, should_throw);
- }
- case LookupIterator::WASM_OBJECT:
- RETURN_FAILURE(isolate, kThrowOnError,
- NewTypeError(MessageTemplate::kWasmObjectsAreOpaque));
- case LookupIterator::MODULE_NAMESPACE:
- case LookupIterator::DATA:
- case LookupIterator::INTERCEPTOR:
- case LookupIterator::ACCESSOR:
- case LookupIterator::TYPED_ARRAY_INDEX_NOT_FOUND:
- case LookupIterator::STRING_LOOKUP_START_OBJECT:
- UNREACHABLE();
-
- case LookupIterator::ACCESS_CHECK: {
- if (!it->HasAccess()) {
- RETURN_ON_EXCEPTION_VALUE(
- isolate,
- it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>()),
- Nothing<bool>());
+ for (;; it->Next()) {
+ switch (it->state()) {
+ case LookupIterator::JSPROXY: {
+ PropertyDescriptor new_desc;
+ new_desc.set_value(Cast<JSAny>(value));
+ new_desc.set_writable(true);
+ new_desc.set_enumerable(true);
+ new_desc.set_configurable(true);
+ return JSProxy::SetPrivateSymbol(isolate, Cast<JSProxy>(receiver),
+ symbol, &new_desc, should_throw);
+ }
+ case LookupIterator::WASM_OBJECT:
+ RETURN_FAILURE(isolate, kThrowOnError,
+ NewTypeError(MessageTemplate::kWasmObjectsAreOpaque));
+ case LookupIterator::MODULE_NAMESPACE:
+ case LookupIterator::DATA:
+ case LookupIterator::INTERCEPTOR:
+ case LookupIterator::ACCESSOR:
+ case LookupIterator::TYPED_ARRAY_INDEX_NOT_FOUND:
+ case LookupIterator::STRING_LOOKUP_START_OBJECT:
UNREACHABLE();
+
+ case LookupIterator::ACCESS_CHECK: {
+ if (!it->HasAccess()) {
+ RETURN_ON_EXCEPTION_VALUE(
+ isolate,
+ it->isolate()->ReportFailedAccessCheck(it->GetHolder<JSObject>()),
+ Nothing<bool>());
+ UNREACHABLE();
+ }
+ continue;
}
- break;
- }
- case LookupIterator::TRANSITION:
- case LookupIterator::NOT_FOUND:
- break;
+ case LookupIterator::TRANSITION:
+ case LookupIterator::NOT_FOUND:
+ return Object::TransitionAndWriteDataProperty(
+ it, value, NONE, should_throw, StoreOrigin::kMaybeKeyed);
+ }
+ UNREACHABLE();
}
-
- return Object::TransitionAndWriteDataProperty(it, value, NONE, should_throw,
- StoreOrigin::kMaybeKeyed);
}
// static
@@ -2734,6 +2746,8 @@ int JSObject::GetHeaderSize(InstanceType type) {
return JSSegments::kHeaderSize;
#endif // V8_INTL_SUPPORT
#if V8_ENABLE_WEBASSEMBLY
+ case WASM_CUSTOM_MAP_WRAPPER_TYPE:
+ return WasmCustomMapWrapper::kHeaderSize;
case WASM_GLOBAL_OBJECT_TYPE:
return WasmGlobalObject::kHeaderSize;
case WASM_INSTANCE_OBJECT_TYPE:
@@ -3035,6 +3049,9 @@ void JSObject::JSObjectShortPrint(StringStream* accumulator) {
case CPP_HEAP_EXTERNAL_OBJECT_TYPE:
accumulator->Add("<CppHeapExternalObject>");
break;
+ case CPP_GCMANAGED_BASE_TYPE:
+ accumulator->Add("<CppGCManagedBase>");
+ break;
default: {
Tagged<Map> map_of_this = map();
@@ -3817,9 +3834,9 @@ Maybe<bool> JSObject::DefineOwnPropertyIgnoreAttributes(
InterceptorResult result;
if (semantics == EnforceDefineSemantics::kDefine) {
PropertyDescriptor descriptor;
- descriptor.set_configurable((attributes & DONT_DELETE) != 0);
- descriptor.set_enumerable((attributes & DONT_ENUM) != 0);
- descriptor.set_writable((attributes & READ_ONLY) != 0);
+ descriptor.set_configurable((attributes & DONT_DELETE) == 0);
+ descriptor.set_enumerable((attributes & DONT_ENUM) == 0);
+ descriptor.set_writable((attributes & READ_ONLY) == 0);
descriptor.set_value(Cast<JSAny>(value));
if (!DefinePropertyWithInterceptorInternal(it, it->GetInterceptor(),
should_throw, &descriptor)
@@ -4315,7 +4332,9 @@ bool TestDictionaryPropertiesIntegrityLevel(Tagged<Dictionary> dict,
if (Object::FilterKey(key, ALL_PROPERTIES)) continue;
PropertyDetails details = dict->DetailsAt(i);
if (details.IsConfigurable()) return false;
- if (level == FROZEN && details.kind() == PropertyKind::kData &&
+ if (level == FROZEN &&
+ (details.kind() == PropertyKind::kData ||
+ IsAccessorInfo(dict->ValueAt(i))) &&
!details.IsReadOnly()) {
return false;
}
@@ -4334,7 +4353,9 @@ bool TestFastPropertiesIntegrityLevel(Tagged<Map> map,
if (descriptors->GetKey(i)->IsAnyPrivate()) continue;
PropertyDetails details = descriptors->GetDetails(i);
if (details.IsConfigurable()) return false;
- if (level == FROZEN && details.kind() == PropertyKind::kData &&
+ if (level == FROZEN &&
+ (details.kind() == PropertyKind::kData ||
+ IsAccessorInfo(descriptors->GetStrongValue(i))) &&
!details.IsReadOnly()) {
return false;
}
diff --git a/deps/v8/src/objects/js-objects.h b/deps/v8/src/objects/js-objects.h
index 7fb30bcc400..bc9e3d6b80f 100644
--- a/deps/v8/src/objects/js-objects.h
+++ b/deps/v8/src/objects/js-objects.h
@@ -42,6 +42,9 @@ class Null;
// JSReceiver includes types on which properties can be defined, i.e.,
// JSObject and JSProxy.
V8_OBJECT class JSReceiver : public HeapObject {
+ V8_IT_ABSTRACT;
+ V8_IT_ORDER(LAST);
+
public:
using Properties =
UnionOf<SwissNameDictionary, FixedArrayBase, PropertyArray>;
@@ -377,6 +380,9 @@ V8_OBJECT class JSReceiver : public HeapObject {
// Note that the map of JSObject changes during execution to enable inline
// caching.
V8_OBJECT class JSObject : public JSReceiver {
+ V8_IT_FIXED_VALUE(0x421);
+ V8_IT_ORDER(LAST);
+
public:
static const int kEndOfStrongFieldsOffset;
static const int kHeaderSize;
@@ -1057,6 +1063,8 @@ static_assert(JSObject::kHeaderSize + JSObject::kMaxEmbedderFields *
// by [in-object properties]) is managed by the Map + BodyDescriptor and never
// shows up as a C++ member.
V8_OBJECT class JSObjectWithEmbedderSlots : public JSObject {
+ V8_IT_OWN_TYPE;
+
public:
DECL_PRINTER(JSObjectWithEmbedderSlots)
DECL_VERIFIER(JSObjectWithEmbedderSlots)
@@ -1074,6 +1082,8 @@ static_assert(JSObjectWithEmbedderSlots::kHeaderSize == JSObject::kHeaderSize);
// [embedder fields] + [in-object properties] tail is managed by the Map +
// BodyDescriptor.
V8_OBJECT class JSAPIObjectWithEmbedderSlots : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
class BodyDescriptor;
@@ -1091,6 +1101,9 @@ inline constexpr int JSAPIObjectWithEmbedderSlots::kHeaderSize =
// functionality but allows function classes to be identified in the type
// system.
V8_OBJECT class JSCustomElementsObject : public JSObject {
+ V8_IT_ABSTRACT;
+ V8_IT_ORDER(FIRST);
+
public:
static const int kHeaderSize;
} V8_OBJECT_END;
@@ -1107,6 +1120,9 @@ static_assert(JSCustomElementsObject::kHeaderSize == JSObject::kHeaderSize);
// can access both sibling hierarchies at the same offset (see the
// static_assert in cpp-heap-object-wrapper.h).
V8_OBJECT class JSSpecialObject : public JSCustomElementsObject {
+ V8_IT_ABSTRACT;
+ V8_IT_ORDER(FIRST);
+
public:
static const int kHeaderSize;
@@ -1150,6 +1166,8 @@ V8_OBJECT class JSExternalObject : public JSObject {
// "enumerable" and "configurable" properties, as assigned by the
// FromPropertyDescriptor function for regular accessor properties.
class JSAccessorPropertyDescriptor : public JSObject {
+ V8_IT_REUSE_PARENT;
+
public:
// Layout description.
#define JS_ACCESSOR_PROPERTY_DESCRIPTOR_FIELDS(V) \
@@ -1173,6 +1191,8 @@ class JSAccessorPropertyDescriptor : public JSObject {
// "enumerable" and "configurable" properties, as assigned by the
// FromPropertyDescriptor function for regular data properties.
class JSDataPropertyDescriptor : public JSObject {
+ V8_IT_REUSE_PARENT;
+
public:
// Layout description.
#define JS_DATA_PROPERTY_DESCRIPTOR_FIELDS(V) \
@@ -1195,6 +1215,8 @@ class JSDataPropertyDescriptor : public JSObject {
// This initial map adds in-object properties for "done" and "value",
// as specified by ES6 section 25.1.1.3 The IteratorResult Interface.
class JSIteratorResult : public JSObject {
+ V8_IT_REUSE_PARENT;
+
public:
DECL_ACCESSORS(value, Tagged<Object>)
@@ -1596,6 +1618,8 @@ V8_OBJECT class JSValidIteratorWrapper : public JSObject {
// This initial map adds in-object properties for "promise", "resolve", and
// "reject", in that order.
class JSPromiseWithResolversResult : public JSObject {
+ V8_IT_REUSE_PARENT;
+
public:
DECL_ACCESSORS(promise, Tagged<Object>)
@@ -1627,6 +1651,8 @@ class JSPromiseWithResolversResult : public JSObject {
// JSUint8ArraySetFromResult is just a JSObject with a specific initial map.
// This initial map adds in-object properties for "read" and "written",
class JSUint8ArraySetFromResult : public JSObject {
+ V8_IT_REUSE_PARENT;
+
public:
DECL_ACCESSORS(read, Tagged<Object>)
@@ -1652,6 +1678,7 @@ class JSUint8ArraySetFromResult : public JSObject {
};
V8_OBJECT class JSInternalPrototypeBase : public JSObject {
+ V8_IT_ABSTRACT;
} V8_OBJECT_END;
V8_OBJECT class JSObjectPrototype : public JSInternalPrototypeBase {
} V8_OBJECT_END;
@@ -1675,15 +1702,14 @@ V8_OBJECT class JSStringIteratorPrototype : public JSInternalPrototypeBase {
} V8_OBJECT_END;
V8_OBJECT class JSApiObject : public JSAPIObjectWithEmbedderSlots {
+ V8_IT_FIXED_VALUE(0x422);
} V8_OBJECT_END;
-// TODO(jgruber): This only exists to widen the JSApiObject instance type into
-// the embedder-reservable range [kFirstJSApiObjectType, kLastJSApiObjectType],
-// by pinning the upper bound at kLastJSApiObjectType. Removing it requires a
-// way to reserve an arbitrary-width instance type range for a childless class
-// in the instance type generator.
V8_OBJECT class JSLastDummyApiObject : public JSApiObject {
+ V8_IT_ORDER(LAST);
+ V8_IT_FIXED_VALUE(0x80a);
} V8_OBJECT_END;
V8_OBJECT class JSSpecialApiObject : public JSSpecialObject {
+ V8_IT_FIXED_VALUE(0x410);
} V8_OBJECT_END;
V8_OBJECT class JSContextExtensionObject : public JSObject {
diff --git a/deps/v8/src/objects/js-plural-rules-inl.h b/deps/v8/src/objects/js-plural-rules-inl.h
index 6d395097d9b..f522ae92d30 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<Managed<icu::PluralRules>> JSPluralRules::icu_plural_rules() const {
- return Cast<Managed<icu::PluralRules>>(icu_plural_rules_.load());
+Tagged<CppGCManaged<icu::PluralRules>> JSPluralRules::icu_plural_rules() const {
+ return Cast<CppGCManaged<icu::PluralRules>>(icu_plural_rules_.load());
}
void JSPluralRules::set_icu_plural_rules(
- Tagged<Managed<icu::PluralRules>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<icu::PluralRules>> value, WriteBarrierMode mode) {
icu_plural_rules_.store(this, value, mode);
}
-Tagged<Managed<icu::number::LocalizedNumberFormatter>>
+Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
JSPluralRules::icu_number_formatter() const {
- return Cast<Managed<icu::number::LocalizedNumberFormatter>>(
+ return Cast<CppGCManaged<icu::number::LocalizedNumberFormatter>>(
icu_number_formatter_.load());
}
void JSPluralRules::set_icu_number_formatter(
- Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<CppGCManaged<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 6e7cccf3f20..ff863ddb421 100644
--- a/deps/v8/src/objects/js-plural-rules.cc
+++ b/deps/v8/src/objects/js-plural-rules.cc
@@ -179,12 +179,13 @@ MaybeDirectHandle<JSPluralRules> JSPluralRules::New(
icu::number::LocalizedNumberFormatter icu_number_formatter =
settings.locale(icu_locale);
- DirectHandle<Managed<icu::PluralRules>> managed_plural_rules =
- Managed<icu::PluralRules>::From(isolate, 0, std::move(icu_plural_rules));
+ DirectHandle<CppGCManaged<icu::PluralRules>> managed_plural_rules =
+ CppGCManaged<icu::PluralRules>::Create(isolate, 0,
+ std::move(icu_plural_rules));
- DirectHandle<Managed<icu::number::LocalizedNumberFormatter>>
+ DirectHandle<CppGCManaged<icu::number::LocalizedNumberFormatter>>
managed_number_formatter =
- Managed<icu::number::LocalizedNumberFormatter>::From(
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Create(
isolate, 0,
std::make_shared<icu::number::LocalizedNumberFormatter>(
icu_number_formatter));
@@ -210,11 +211,11 @@ MaybeDirectHandle<JSPluralRules> JSPluralRules::New(
MaybeDirectHandle<String> JSPluralRules::ResolvePlural(
Isolate* isolate, DirectHandle<JSPluralRules> plural_rules, double number) {
- Managed<icu::PluralRules>::Ptr icu_plural_rules =
+ CppGCManaged<icu::PluralRules>::Ptr icu_plural_rules =
plural_rules->icu_plural_rules()->ptr();
DCHECK_NOT_NULL(icu_plural_rules);
- Managed<icu::number::LocalizedNumberFormatter>::Ptr fmt =
+ CppGCManaged<icu::number::LocalizedNumberFormatter>::Ptr fmt =
plural_rules->icu_number_formatter()->ptr();
DCHECK_NOT_NULL(fmt);
@@ -233,7 +234,7 @@ MaybeDirectHandle<String> JSPluralRules::ResolvePlural(
MaybeDirectHandle<String> JSPluralRules::ResolvePluralRange(
Isolate* isolate, DirectHandle<JSPluralRules> plural_rules, double x,
double y) {
- Managed<icu::PluralRules>::Ptr icu_plural_rules =
+ CppGCManaged<icu::PluralRules>::Ptr icu_plural_rules =
plural_rules->icu_plural_rules()->ptr();
DCHECK_NOT_NULL(icu_plural_rules);
@@ -294,7 +295,7 @@ DirectHandle<JSObject> JSPluralRules::ResolvedOptions(
plural_rules->TypeAsString(isolate), "type");
UErrorCode status = U_ZERO_ERROR;
- Managed<icu::number::LocalizedNumberFormatter>::Ptr icu_number_formatter =
+ CppGCManaged<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));
@@ -336,7 +337,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".
- Managed<icu::PluralRules>::Ptr icu_plural_rules =
+ CppGCManaged<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 e66c3014b20..7be9e6517a8 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<Managed<icu::PluralRules>> icu_plural_rules() const;
+ inline Tagged<CppGCManaged<icu::PluralRules>> icu_plural_rules() const;
inline void set_icu_plural_rules(
- Tagged<Managed<icu::PluralRules>> value,
+ Tagged<CppGCManaged<icu::PluralRules>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<icu::number::LocalizedNumberFormatter>>
+ inline Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>>
icu_number_formatter() const;
inline void set_icu_number_formatter(
- Tagged<Managed<icu::number::LocalizedNumberFormatter>> value,
+ Tagged<CppGCManaged<icu::number::LocalizedNumberFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_VERIFIER(JSPluralRules)
@@ -92,8 +92,9 @@ V8_OBJECT class JSPluralRules : public JSObject {
public:
TaggedMember<String> locale_;
TaggedMember<Smi> flags_;
- TaggedMember<Foreign> icu_plural_rules_;
- TaggedMember<Foreign> icu_number_formatter_;
+ TaggedMember<CppGCManaged<icu::PluralRules>> icu_plural_rules_;
+ TaggedMember<CppGCManaged<icu::number::LocalizedNumberFormatter>>
+ 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 ed81e501622..0694715eefb 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: Foreign; // Managed<icu::PluralRules>
+ icu_plural_rules: CppGCManagedBase; // CppGCManaged<icu::PluralRules>
icu_number_formatter:
- Foreign; // Managed<icu::number::LocalizedNumberFormatter>
+ CppGCManagedBase; // CppGCManaged<icu::number::LocalizedNumberFormatter>
}
diff --git a/deps/v8/src/objects/js-proxy.h b/deps/v8/src/objects/js-proxy.h
index 159871e7759..a950e2da43b 100644
--- a/deps/v8/src/objects/js-proxy.h
+++ b/deps/v8/src/objects/js-proxy.h
@@ -7,7 +7,6 @@
#include "src/objects/js-objects.h"
#include "src/objects/oddball.h"
-#include "torque-generated/builtin-definitions.h"
// Has to be the last include (doesn't have include guards):
#include "src/objects/object-macros.h"
@@ -161,6 +160,8 @@ static_assert(static_cast<int>(offsetof(JSObject, elements_)) ==
// Shape-style: no own C++ storage; fields live in the parent JSObject's
// in-object property slots at fixed offsets past JSObject::kHeaderSize.
class JSProxyRevocableResult : public JSObject {
+ V8_IT_REUSE_PARENT;
+
public:
static constexpr int kProxySlotIndex = 0;
static constexpr int kRevokeSlotIndex = 1;
diff --git a/deps/v8/src/objects/js-regexp-inl.h b/deps/v8/src/objects/js-regexp-inl.h
index ac199d5ca29..b5e85bab236 100644
--- a/deps/v8/src/objects/js-regexp-inl.h
+++ b/deps/v8/src/objects/js-regexp-inl.h
@@ -129,6 +129,29 @@ void RegExpData::set_quick_check_value(uint32_t value) {
quick_check_value_ = value;
}
+void RegExpData::set_quick_check_reject_bitset_word(int index, uint32_t value) {
+ DCHECK_LT(static_cast<unsigned>(index), kQuickCheckBitsetWords);
+ quick_check_reject_bitset_[index] = value;
+}
+
+uint32_t RegExpData::internal_flags() const { return internal_flags_; }
+void RegExpData::set_internal_flags(uint32_t value) { internal_flags_ = value; }
+
+void RegExpData::clear_quick_check() {
+ quick_check_mask_ = 0;
+ quick_check_value_ = 0;
+ for (int i = 0; i < kQuickCheckBitsetWords; i++) {
+ quick_check_reject_bitset_[i] = 0;
+ }
+ // kHasQuickCheck is the only internal flag, so this clears the quick check
+ // too. The padding just tags along, since it sits in the same tail and is
+ // otherwise never written.
+ internal_flags_ = 0;
+#if TAGGED_SIZE_8_BYTES
+ optional_padding_ = 0;
+#endif
+}
+
int RegExpData::capture_count() const {
switch (type_tag()) {
case Type::ATOM:
diff --git a/deps/v8/src/objects/js-regexp.cc b/deps/v8/src/objects/js-regexp.cc
index e740e526134..dd5104463e6 100644
--- a/deps/v8/src/objects/js-regexp.cc
+++ b/deps/v8/src/objects/js-regexp.cc
@@ -6,6 +6,7 @@
#include <optional>
+#include "src/base/memory.h"
#include "src/base/strings.h"
#include "src/common/globals.h"
#include "src/objects/code.h"
@@ -98,7 +99,6 @@ DirectHandle<JSRegExpResultIndices> JSRegExpResultIndices::BuildIndices(
// are undefined. In the latter case we don't do anything, in the former
// case we update the entry.
if (group_entry.is_found()) {
- DCHECK(v8_flags.js_regexp_duplicate_named_groups);
if (!IsUndefined(*capture_indices)) {
DCHECK(IsUndefined(group_names_dict->ValueAt(group_entry)));
group_names_dict->ValueAtPut(group_entry, *capture_indices);
@@ -229,6 +229,32 @@ bool RegExpData::HasCompiledCode() const {
return re_data->has_latin1_code() || re_data->has_uc16_code();
}
+bool RegExpData::QuickCheckRejects(base::Vector<const uint8_t> subject,
+ int index) const {
+ DCHECK_LE(0, index);
+ DCHECK_LE(index, subject.length());
+ if ((internal_flags() & kHasQuickCheck) == 0) return false;
+
+ const int remaining = subject.length() - index;
+
+ // The mask compares four characters at once, so it needs four to be left.
+ // Near the end of the subject we skip it and fall through to the bitset,
+ // which only ever looks at one.
+ if (quick_check_mask() != 0 &&
+ remaining >= static_cast<int>(sizeof(uint32_t))) {
+ uint32_t chars = base::ReadUnalignedValue<uint32_t>(
+ reinterpret_cast<Address>(subject.begin() + index));
+ if ((chars & quick_check_mask()) != quick_check_value()) return true;
+ }
+
+ // A set bit means "no match can start with this character", so an all-zero
+ // bitset rejects nothing and costs us only the test. There is nothing to
+ // look at only once the position is past the last character.
+ if (remaining == 0) return false;
+ const auto [word, bit] = QuickCheckBitsetBit(subject[index]);
+ return (quick_check_reject_bitset_[word] & bit) != 0;
+}
+
// Only irregexps are subject to tier-up.
bool IrRegExpData::CanTierUp() {
return v8_flags.regexp_tier_up && type_tag() == Type::IRREGEXP;
diff --git a/deps/v8/src/objects/js-regexp.h b/deps/v8/src/objects/js-regexp.h
index e428ced03dc..faf30181789 100644
--- a/deps/v8/src/objects/js-regexp.h
+++ b/deps/v8/src/objects/js-regexp.h
@@ -6,9 +6,11 @@
#define V8_OBJECTS_JS_REGEXP_H_
#include <optional>
+#include <utility>
#include "include/v8-regexp.h"
#include "src/base/bit-field.h"
+#include "src/base/vector.h"
#include "src/objects/contexts.h"
#include "src/objects/js-array.h"
#include "src/objects/trusted-object.h"
@@ -186,6 +188,8 @@ DEFINE_OPERATORS_FOR_FLAGS(JSRegExp::Flags)
class RegExpDataWrapper;
V8_OBJECT class RegExpData : public ExposedTrustedObject {
+ V8_IT_OWN_TYPE;
+
public:
enum class Type : uint8_t {
ATOM, // A simple string match.
@@ -193,6 +197,28 @@ V8_OBJECT class RegExpData : public ExposedTrustedObject {
EXPERIMENTAL, // Compiled to use the experimental linear time engine.
};
+ // The first-character bitset covers the latin-1 range, one bit per character.
+ static constexpr int kQuickCheckBitsetChars = 256;
+ static constexpr int kQuickCheckBitsetBitsPerWord = 32;
+ static constexpr int kQuickCheckBitsetWords =
+ kQuickCheckBitsetChars / kQuickCheckBitsetBitsPerWord;
+
+ // Where |c| lives in the bitset: which word to load, and which bit to test
+ // in it. For 'a' (97) that is word 3, bit 1.
+ static constexpr std::pair<int, uint32_t> QuickCheckBitsetBit(uint8_t c) {
+ return {c / kQuickCheckBitsetBitsPerWord,
+ uint32_t{1} << (c % kQuickCheckBitsetBitsPerWord)};
+ }
+
+ // Flags not exposed to JS, stored separately from flags_ above.
+ // TODO(jgruber): Merge these into flags_, which has spare bits.
+ enum InternalFlag : uint32_t {
+ // Set if either quick-check filter was built. Most regexps get neither,
+ // so this lets the exec path skip straight past both with one test
+ // instead of loading the subject and running the bitset check to find out.
+ kHasQuickCheck = 1 << 0,
+ };
+
inline Type type_tag() const;
inline void set_type_tag(Type);
@@ -217,6 +243,18 @@ V8_OBJECT class RegExpData : public ExposedTrustedObject {
inline uint32_t quick_check_value() const;
inline void set_quick_check_value(uint32_t value);
+ inline void set_quick_check_reject_bitset_word(int index, uint32_t value);
+
+ inline uint32_t internal_flags() const;
+ inline void set_internal_flags(uint32_t value);
+
+ inline void clear_quick_check();
+
+ // True iff the quick-check filters prove that no match can begin at
+ // |subject[index]|. |subject| must be one-byte and flat. Mirrored by
+ // RegExpExecInternal in builtins-regexp-gen.cc; keep the two in sync.
+ bool QuickCheckRejects(base::Vector<const uint8_t> subject, int index) const;
+
inline int capture_count() const;
static constexpr bool TypeSupportsCaptures(Type t) {
@@ -237,6 +275,19 @@ V8_OBJECT class RegExpData : public ExposedTrustedObject {
TaggedMember<RegExpDataWrapper> wrapper_;
uint32_t quick_check_mask_;
uint32_t quick_check_value_;
+ // One bit per latin-1 character. Set means no match can begin with that
+ // character; clear means "maybe".
+ //
+ // TODO(jgruber): Move the quick-check fields down to IrRegExpData. Only
+ // Irregexp ever fills them in, so ATOM data pays 40 bytes for nothing.
+ // EXPERIMENTAL data is already an IrRegExpData, but shares the exec path's
+ // check with IRREGEXP and does not fill the fields in either, so the fields
+ // stay dead there whichever class they live on.
+ uint32_t quick_check_reject_bitset_[kQuickCheckBitsetWords];
+ uint32_t internal_flags_;
+#if TAGGED_SIZE_8_BYTES
+ uint32_t optional_padding_;
+#endif
} V8_OBJECT_END;
V8_OBJECT class RegExpDataWrapper : public Struct {
@@ -345,6 +396,8 @@ V8_OBJECT class IrRegExpData : public RegExpData {
// and `kInObjectPropertyCount` is the total count of in-object properties
// relative to JSArray::kHeaderSize.
V8_OBJECT class JSRegExpResult : public JSArray {
+ V8_IT_REUSE_PARENT;
+
public:
// TODO(joshualitt): We would like to add printers and verifiers to
// JSRegExpResult, and maybe JSRegExpResultIndices, but both have the same
@@ -375,6 +428,8 @@ V8_OBJECT class JSRegExpResult : public JSArray {
} V8_OBJECT_END;
V8_OBJECT class JSRegExpResultWithIndices : public JSRegExpResult {
+ V8_IT_REUSE_PARENT;
+
public:
// Additional in-object property past JSRegExpResult's fields.
static constexpr int kAdditionalInObjectPropertyCount = 1;
@@ -393,6 +448,8 @@ V8_OBJECT class JSRegExpResultWithIndices : public JSRegExpResult {
// This class just holds constants used when creating the result.
// After creation the result must be treated as a JSArray in all regards.
V8_OBJECT class JSRegExpResultIndices : public JSArray {
+ V8_IT_REUSE_PARENT;
+
public:
static DirectHandle<JSRegExpResultIndices> BuildIndices(
Isolate* isolate, DirectHandle<RegExpMatchInfo> match_info,
diff --git a/deps/v8/src/objects/js-regexp.tq b/deps/v8/src/objects/js-regexp.tq
index 3dbacfcea70..0ba458fcc4e 100644
--- a/deps/v8/src/objects/js-regexp.tq
+++ b/deps/v8/src/objects/js-regexp.tq
@@ -24,6 +24,10 @@ extern class RegExpData extends ExposedTrustedObject {
wrapper: RegExpDataWrapper;
quick_check_mask: uint32;
quick_check_value: uint32;
+ // One bit per latin-1 character; see RegExpData::kQuickCheckBitsetWords.
+ quick_check_reject_bitset[8]: uint32;
+ internal_flags: uint32;
+ @if(TAGGED_SIZE_8_BYTES) optional_padding: uint32;
}
@cppObjectLayoutDefinition
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 632add2449f..bd55eef3283 100644
--- a/deps/v8/src/objects/js-relative-time-format-inl.h
+++ b/deps/v8/src/objects/js-relative-time-format-inl.h
@@ -34,12 +34,13 @@ void JSRelativeTimeFormat::set_numberingSystem(Tagged<String> value,
numberingSystem_.store(this, value, mode);
}
-Tagged<Managed<icu::RelativeDateTimeFormatter>>
+Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>>
JSRelativeTimeFormat::icu_formatter() const {
- return Cast<Managed<icu::RelativeDateTimeFormatter>>(icu_formatter_.load());
+ return Cast<CppGCManaged<icu::RelativeDateTimeFormatter>>(
+ icu_formatter_.load());
}
void JSRelativeTimeFormat::set_icu_formatter(
- Tagged<Managed<icu::RelativeDateTimeFormatter>> value,
+ Tagged<CppGCManaged<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 7f4bf8583c1..d964d9c8de6 100644
--- a/deps/v8/src/objects/js-relative-time-format.cc
+++ b/deps/v8/src/objects/js-relative-time-format.cc
@@ -18,6 +18,7 @@
#include "src/objects/js-number-format.h"
#include "src/objects/js-relative-time-format-inl.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "unicode/decimfmt.h"
@@ -212,9 +213,9 @@ MaybeDirectHandle<JSRelativeTimeFormat> JSRelativeTimeFormat::New(
isolate->factory()->NewStringFromAsciiChecked(
Intl::GetNumberingSystem(icu_locale).c_str());
- DirectHandle<Managed<icu::RelativeDateTimeFormatter>> managed_formatter =
- Managed<icu::RelativeDateTimeFormatter>::From(isolate, 0,
- std::move(icu_formatter));
+ DirectHandle<CppGCManaged<icu::RelativeDateTimeFormatter>>
+ managed_formatter = CppGCManaged<icu::RelativeDateTimeFormatter>::Create(
+ isolate, 0, std::move(icu_formatter));
DirectHandle<JSRelativeTimeFormat> relative_time_format_holder =
Cast<JSRelativeTimeFormat>(
@@ -250,7 +251,7 @@ DirectHandle<String> StyleAsString(Isolate* isolate, Style style) {
DirectHandle<JSObject> JSRelativeTimeFormat::ResolvedOptions(
Isolate* isolate, DirectHandle<JSRelativeTimeFormat> format_holder) {
Factory* factory = isolate->factory();
- Managed<icu::RelativeDateTimeFormatter>::Ptr formatter =
+ CppGCManaged<icu::RelativeDateTimeFormatter>::Ptr formatter =
format_holder->icu_formatter()->ptr();
DCHECK_NOT_NULL(formatter);
DirectHandle<JSObject> result =
@@ -355,7 +356,7 @@ MaybeDirectHandle<T> FormatCommon(
MessageTemplate::kNotFiniteNumber,
isolate->factory()->NewStringFromAsciiChecked(func_name)));
}
- Managed<icu::RelativeDateTimeFormatter>::Ptr formatter =
+ CppGCManaged<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 f7d67d95a44..ee2de453139 100644
--- a/deps/v8/src/objects/js-relative-time-format.h
+++ b/deps/v8/src/objects/js-relative-time-format.h
@@ -64,9 +64,10 @@ V8_OBJECT class JSRelativeTimeFormat : public JSObject {
inline void set_numberingSystem(Tagged<String> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<icu::RelativeDateTimeFormatter>> icu_formatter() const;
+ inline Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>>
+ icu_formatter() const;
inline void set_icu_formatter(
- Tagged<Managed<icu::RelativeDateTimeFormatter>> value,
+ Tagged<CppGCManaged<icu::RelativeDateTimeFormatter>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int flags() const;
@@ -100,7 +101,7 @@ V8_OBJECT class JSRelativeTimeFormat : public JSObject {
public:
TaggedMember<String> locale_;
TaggedMember<String> numberingSystem_;
- TaggedMember<Foreign> icu_formatter_;
+ TaggedMember<CppGCManaged<icu::RelativeDateTimeFormatter>> 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 f5f2c990973..e14ae99e2c6 100644
--- a/deps/v8/src/objects/js-relative-time-format.tq
+++ b/deps/v8/src/objects/js-relative-time-format.tq
@@ -15,6 +15,7 @@ bitfield struct JSRelativeTimeFormatFlags extends uint31 {
extern class JSRelativeTimeFormat extends JSObject {
locale: String;
numberingSystem: String;
- icu_formatter: Foreign; // Managed<icu::RelativeDateTimeFormatter>
+ icu_formatter:
+ CppGCManagedBase; // CppGCManaged<icu::RelativeDateTimeFormatter>
flags: SmiTagged<JSRelativeTimeFormatFlags>;
}
diff --git a/deps/v8/src/objects/js-segment-iterator-inl.h b/deps/v8/src/objects/js-segment-iterator-inl.h
index 54863a92ba0..67771142408 100644
--- a/deps/v8/src/objects/js-segment-iterator-inl.h
+++ b/deps/v8/src/objects/js-segment-iterator-inl.h
@@ -12,6 +12,7 @@
#include "src/objects/js-segment-iterator.h"
// Include the non-inl header before the rest of the headers.
+#include "src/objects/managed-inl.h"
#include "src/objects/objects-inl.h"
// Has to be the last include (doesn't have include guards):
@@ -20,13 +21,14 @@
namespace v8 {
namespace internal {
-Tagged<Managed<IcuBreakIteratorWithText>>
+Tagged<CppGCManaged<IcuBreakIteratorWithText>>
JSSegmentIterator::icu_iterator_with_text() const {
- return Cast<Managed<IcuBreakIteratorWithText>>(
+ return Cast<CppGCManaged<IcuBreakIteratorWithText>>(
icu_iterator_with_text_.load());
}
void JSSegmentIterator::set_icu_iterator_with_text(
- Tagged<Managed<IcuBreakIteratorWithText>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<IcuBreakIteratorWithText>> value,
+ WriteBarrierMode mode) {
icu_iterator_with_text_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-segment-iterator.cc b/deps/v8/src/objects/js-segment-iterator.cc
index ee9c2aee121..3dfd71c69e4 100644
--- a/deps/v8/src/objects/js-segment-iterator.cc
+++ b/deps/v8/src/objects/js-segment-iterator.cc
@@ -42,8 +42,9 @@ MaybeDirectHandle<JSSegmentIterator> JSSegmentIterator::Create(
incoming_break_iterator.clone()};
auto iterator_with_text = std::make_shared<IcuBreakIteratorWithText>(
isolate, std::move(cloned_iterator), input_string);
- DirectHandle<Managed<IcuBreakIteratorWithText>> managed =
- Managed<IcuBreakIteratorWithText>::From(isolate, 0, iterator_with_text);
+ DirectHandle<CppGCManaged<IcuBreakIteratorWithText>> managed =
+ CppGCManaged<IcuBreakIteratorWithText>::Create(isolate, 0,
+ iterator_with_text);
// 5. Set iterator.[[IteratedStringNextSegmentCodeUnitIndex]] to 0.
iterator_with_text->iterator()->first();
@@ -92,7 +93,7 @@ MaybeDirectHandle<JSReceiver> JSSegmentIterator::Next(
STACK_CHECK(isolate, MaybeDirectHandle<JSReceiver>());
Factory* factory = isolate->factory();
- Managed<IcuBreakIteratorWithText>::Ptr iterator_with_text =
+ CppGCManaged<IcuBreakIteratorWithText>::Ptr iterator_with_text =
segment_iterator->icu_iterator_with_text()->ptr();
icu::BreakIterator* const icu_break_iterator = iterator_with_text->iterator();
diff --git a/deps/v8/src/objects/js-segment-iterator.h b/deps/v8/src/objects/js-segment-iterator.h
index cf5f293e565..9ea69716d4b 100644
--- a/deps/v8/src/objects/js-segment-iterator.h
+++ b/deps/v8/src/objects/js-segment-iterator.h
@@ -40,10 +40,10 @@ V8_OBJECT class JSSegmentIterator : public JSObject {
Handle<String> GranularityAsString(Isolate* isolate) const;
// SegmentIterator accessors.
- inline Tagged<Managed<IcuBreakIteratorWithText>> icu_iterator_with_text()
+ inline Tagged<CppGCManaged<IcuBreakIteratorWithText>> icu_iterator_with_text()
const;
inline void set_icu_iterator_with_text(
- Tagged<Managed<IcuBreakIteratorWithText>> value,
+ Tagged<CppGCManaged<IcuBreakIteratorWithText>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<String> raw_string() const;
@@ -70,7 +70,7 @@ V8_OBJECT class JSSegmentIterator : public JSObject {
static const int kHeaderSize;
public:
- TaggedMember<Foreign> icu_iterator_with_text_;
+ TaggedMember<CppGCManaged<IcuBreakIteratorWithText>> icu_iterator_with_text_;
TaggedMember<String> raw_string_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
@@ -78,6 +78,9 @@ V8_OBJECT class JSSegmentIterator : public JSObject {
inline constexpr int JSSegmentIterator::kHeaderSize = sizeof(JSSegmentIterator);
V8_OBJECT class JSSegmentDataObject : public JSObject {
+ V8_IT_REUSE_PARENT;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
inline Tagged<String> segment() const;
inline void set_segment(Tagged<String> value,
@@ -105,6 +108,9 @@ inline constexpr int JSSegmentDataObject::kHeaderSize =
sizeof(JSSegmentDataObject);
V8_OBJECT class JSSegmentDataObjectWithIsWordLike : public JSSegmentDataObject {
+ V8_IT_NO_AUTO_CHECKER;
+ V8_IT_REUSE_PARENT;
+
public:
inline Tagged<Boolean> is_word_like() const;
inline void set_is_word_like(Tagged<Boolean> value,
diff --git a/deps/v8/src/objects/js-segment-iterator.tq b/deps/v8/src/objects/js-segment-iterator.tq
index b74f8bdbb94..57297537031 100644
--- a/deps/v8/src/objects/js-segment-iterator.tq
+++ b/deps/v8/src/objects/js-segment-iterator.tq
@@ -11,7 +11,8 @@ bitfield struct JSSegmentIteratorFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSSegmentIterator extends JSObject {
- icu_iterator_with_text: Foreign; // Managed<IcuBreakIteratorWithText>
+ icu_iterator_with_text:
+ CppGCManagedBase; // CppGCManaged<IcuBreakIteratorWithText>
raw_string: String;
flags: SmiTagged<JSSegmentIteratorFlags>;
}
diff --git a/deps/v8/src/objects/js-segmenter-inl.h b/deps/v8/src/objects/js-segmenter-inl.h
index fc2724b0fc3..ff27f0874ed 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<Managed<icu::BreakIterator>> JSSegmenter::icu_break_iterator() const {
- return Cast<Managed<icu::BreakIterator>>(icu_break_iterator_.load());
+Tagged<CppGCManaged<icu::BreakIterator>> JSSegmenter::icu_break_iterator() const {
+ return Cast<CppGCManaged<icu::BreakIterator>>(icu_break_iterator_.load());
}
void JSSegmenter::set_icu_break_iterator(
- Tagged<Managed<icu::BreakIterator>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<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 5186cce701a..3fc43dca822 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<Managed<icu::BreakIterator>> managed_break_iterator =
- Managed<icu::BreakIterator>::From(isolate, 0,
- std::move(icu_break_iterator));
+ DirectHandle<CppGCManaged<icu::BreakIterator>> managed_break_iterator =
+ CppGCManaged<icu::BreakIterator>::Create(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 0689d93bf0e..0b9b7281d61 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<Managed<icu::BreakIterator>> icu_break_iterator() const;
+ inline Tagged<CppGCManaged<icu::BreakIterator>> icu_break_iterator() const;
inline void set_icu_break_iterator(
- Tagged<Managed<icu::BreakIterator>> value,
+ Tagged<CppGCManaged<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<Foreign> icu_break_iterator_;
+ TaggedMember<CppGCManaged<icu::BreakIterator>> 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 5933038f289..2dabdf17261 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: Foreign; // Managed<icu::BreakIterator>
+ icu_break_iterator: CppGCManagedBase; // CppGCManaged<icu::BreakIterator>
flags: SmiTagged<JSSegmenterFlags>;
}
diff --git a/deps/v8/src/objects/js-segments-inl.h b/deps/v8/src/objects/js-segments-inl.h
index ede3a35f573..3d8c9e5d474 100644
--- a/deps/v8/src/objects/js-segments-inl.h
+++ b/deps/v8/src/objects/js-segments-inl.h
@@ -12,6 +12,7 @@
#include "src/objects/js-segments.h"
// Include the non-inl header before the rest of the headers.
+#include "src/objects/managed-inl.h"
#include "src/objects/objects-inl.h"
// Has to be the last include (doesn't have include guards):
@@ -20,13 +21,14 @@
namespace v8 {
namespace internal {
-Tagged<Managed<IcuBreakIteratorWithText>> JSSegments::icu_iterator_with_text()
- const {
- return Cast<Managed<IcuBreakIteratorWithText>>(
+Tagged<CppGCManaged<IcuBreakIteratorWithText>>
+JSSegments::icu_iterator_with_text() const {
+ return Cast<CppGCManaged<IcuBreakIteratorWithText>>(
icu_iterator_with_text_.load());
}
void JSSegments::set_icu_iterator_with_text(
- Tagged<Managed<IcuBreakIteratorWithText>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<IcuBreakIteratorWithText>> value,
+ WriteBarrierMode mode) {
icu_iterator_with_text_.store(this, value, mode);
}
diff --git a/deps/v8/src/objects/js-segments.cc b/deps/v8/src/objects/js-segments.cc
index 4dd4ea57867..85805252362 100644
--- a/deps/v8/src/objects/js-segments.cc
+++ b/deps/v8/src/objects/js-segments.cc
@@ -34,8 +34,9 @@ MaybeDirectHandle<JSSegments> JSSegments::Create(
segmenter->icu_break_iterator()->ptr()->clone()};
auto iterator_with_text = std::make_shared<IcuBreakIteratorWithText>(
isolate, std::move(cloned_iterator), string);
- DirectHandle<Managed<IcuBreakIteratorWithText>> managed =
- Managed<IcuBreakIteratorWithText>::From(isolate, 0, iterator_with_text);
+ DirectHandle<CppGCManaged<IcuBreakIteratorWithText>> managed =
+ CppGCManaged<IcuBreakIteratorWithText>::Create(isolate, 0,
+ iterator_with_text);
// 1. Let internalSlotsList be « [[SegmentsSegmenter]], [[SegmentsString]] ».
// 2. Let segments be ! ObjectCreate(%Segments.prototype%, internalSlotsList).
@@ -60,7 +61,7 @@ MaybeDirectHandle<JSSegments> JSSegments::Create(
// https://tc39.es/ecma402/#sec-%segmentsprototype%.containing
MaybeDirectHandle<Object> JSSegments::Containing(
Isolate* isolate, DirectHandle<JSSegments> segments, double n_double) {
- Managed<IcuBreakIteratorWithText>::Ptr iterator_with_text =
+ CppGCManaged<IcuBreakIteratorWithText>::Ptr iterator_with_text =
segments->icu_iterator_with_text()->ptr();
// 5. Let len be the length of string.
const icu::UnicodeString& unicode_string = *iterator_with_text->text();
diff --git a/deps/v8/src/objects/js-segments.h b/deps/v8/src/objects/js-segments.h
index 4c85c0403e6..4a34b053f1d 100644
--- a/deps/v8/src/objects/js-segments.h
+++ b/deps/v8/src/objects/js-segments.h
@@ -51,10 +51,10 @@ V8_OBJECT class JSSegments : public JSObject {
Handle<String> GranularityAsString(Isolate* isolate) const;
// SegmentIterator accessors.
- inline Tagged<Managed<IcuBreakIteratorWithText>> icu_iterator_with_text()
+ inline Tagged<CppGCManaged<IcuBreakIteratorWithText>> icu_iterator_with_text()
const;
inline void set_icu_iterator_with_text(
- Tagged<Managed<IcuBreakIteratorWithText>> value,
+ Tagged<CppGCManaged<IcuBreakIteratorWithText>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<String> raw_string() const;
@@ -81,7 +81,7 @@ V8_OBJECT class JSSegments : public JSObject {
static const int kHeaderSize;
public:
- TaggedMember<Foreign> icu_iterator_with_text_;
+ TaggedMember<CppGCManaged<IcuBreakIteratorWithText>> icu_iterator_with_text_;
TaggedMember<String> raw_string_;
TaggedMember<Smi> flags_;
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/js-segments.tq b/deps/v8/src/objects/js-segments.tq
index 1390d823194..94fc14d271c 100644
--- a/deps/v8/src/objects/js-segments.tq
+++ b/deps/v8/src/objects/js-segments.tq
@@ -11,7 +11,8 @@ bitfield struct JSSegmentsFlags extends uint31 {
@cppObjectLayoutDefinition
extern class JSSegments extends JSObject {
- icu_iterator_with_text: Foreign; // Managed<IcuBreakIteratorWithText>
+ icu_iterator_with_text:
+ CppGCManagedBase; // CppGCManaged<IcuBreakIteratorWithText>
raw_string: String;
flags: SmiTagged<JSSegmentsFlags>;
}
diff --git a/deps/v8/src/objects/js-struct.h b/deps/v8/src/objects/js-struct.h
index 2ba61226334..3f8c881163f 100644
--- a/deps/v8/src/objects/js-struct.h
+++ b/deps/v8/src/objects/js-struct.h
@@ -15,6 +15,8 @@ namespace v8 {
namespace internal {
V8_OBJECT class AlwaysSharedSpaceJSObject : public JSObject {
+ V8_IT_ABSTRACT;
+
public:
// Prepare a Map to be used as the instance map for shared JS objects.
static void PrepareMapNoEnumerableProperties(Tagged<Map> map);
diff --git a/deps/v8/src/objects/js-temporal-helpers.cc b/deps/v8/src/objects/js-temporal-helpers.cc
index ef88ff4de54..2fa72a96a91 100644
--- a/deps/v8/src/objects/js-temporal-helpers.cc
+++ b/deps/v8/src/objects/js-temporal-helpers.cc
@@ -5,6 +5,7 @@
#include "src/objects/js-temporal-helpers.h"
#include "src/objects/js-objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
namespace v8::internal::temporal {
diff --git a/deps/v8/src/objects/js-temporal-objects-inl.h b/deps/v8/src/objects/js-temporal-objects-inl.h
index b59251c656b..1cf3e058556 100644
--- a/deps/v8/src/objects/js-temporal-objects-inl.h
+++ b/deps/v8/src/objects/js-temporal-objects-inl.h
@@ -10,6 +10,7 @@
#include "src/api/api-inl.h"
#include "src/objects/contexts-inl.h"
+#include "src/objects/managed-inl.h"
#include "src/objects/objects-inl.h"
// Rust includes to transitively include
@@ -29,13 +30,13 @@ namespace v8 {
namespace internal {
// temporal_rs object getters
-#define DEFINE_TEMPORAL_ACCESSORS(JSType, field, RustType_) \
- inline Tagged<Managed<RustType_>> JSType::field() const { \
- return field##_.load(); \
- } \
- inline void JSType::set_##field(Tagged<Managed<RustType_>> value, \
- WriteBarrierMode mode) { \
- field##_.store(this, value, mode); \
+#define DEFINE_TEMPORAL_ACCESSORS(JSType, field, RustType_) \
+ inline Tagged<CppGCManaged<RustType_>> JSType::field() const { \
+ return field##_.load(); \
+ } \
+ inline void JSType::set_##field(Tagged<CppGCManaged<RustType_>> value, \
+ WriteBarrierMode mode) { \
+ field##_.store(this, value, mode); \
}
DEFINE_TEMPORAL_ACCESSORS(JSTemporalInstant, instant, temporal_rs::Instant)
@@ -72,13 +73,13 @@ DEFINE_CTOR_HELPER(JSTemporalZonedDateTime, zoned_date_time)
// Paired with DECL_ACCESSORS_FOR_RUST_WRAPPER
// Can be omitted and overridden if needed.
-#define DEFINE_ACCESSORS_FOR_RUST_WRAPPER(field, JSType) \
- inline void JSType::initialize_with_wrapped_rust_value( \
- Tagged<Managed<JSType::RustType>> handle) { \
- this->set_##field(handle); \
- } \
- inline Managed<JSType::RustType>::Ptr JSType::wrapped_rust() const { \
- return this->field()->ptr(); \
+#define DEFINE_ACCESSORS_FOR_RUST_WRAPPER(field, JSType) \
+ inline void JSType::initialize_with_wrapped_rust_value( \
+ Tagged<CppGCManaged<JSType::RustType>> handle) { \
+ this->set_##field(handle); \
+ } \
+ inline CppGCManaged<JSType::RustType>::Ptr JSType::wrapped_rust() const { \
+ return this->field()->ptr(); \
}
DEFINE_ACCESSORS_FOR_RUST_WRAPPER(instant, JSTemporalInstant)
diff --git a/deps/v8/src/objects/js-temporal-objects.cc b/deps/v8/src/objects/js-temporal-objects.cc
index 227c4f2e807..8b2b0a7a39d 100644
--- a/deps/v8/src/objects/js-temporal-objects.cc
+++ b/deps/v8/src/objects/js-temporal-objects.cc
@@ -22,6 +22,7 @@
#include "src/objects/js-temporal-objects-inl.h"
#include "src/objects/js-temporal-zoneinfo64.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/option-utils.h"
#include "src/objects/property-descriptor.h"
@@ -203,12 +204,12 @@ MaybeDirectHandle<JSType> ConstructRustWrappingType(
Isolate* isolate, DirectHandle<JSFunction> target,
DirectHandle<HeapObject> new_target,
std::unique_ptr<typename JSType::RustType>&& rust_value) {
- // Managed requires shared ownership
+ // CppGCManaged requires shared ownership
std::shared_ptr<typename JSType::RustType> rust_shared =
std::move(rust_value);
- DirectHandle<Managed<typename JSType::RustType>> managed =
- Managed<typename JSType::RustType>::From(isolate, 0, rust_shared);
+ DirectHandle<CppGCManaged<typename JSType::RustType>> managed =
+ CppGCManaged<typename JSType::RustType>::Create(isolate, 0, rust_shared);
ORDINARY_CREATE_FROM_CONSTRUCTOR(object, target, new_target, JSType)
object->initialize_with_wrapped_rust_value(*managed);
@@ -2521,12 +2522,12 @@ MaybeDirectHandle<JSTemporalPlainTime> ToTemporalTime(
// handles the midnight-setting
//
// https://tc39.es/proposal-temporal/#sec-temporal-totimerecordormidnight
-Maybe<Managed<temporal_rs::PlainTime>::Ptr> ToTimeRecordOrMidnight(
+Maybe<CppGCManaged<temporal_rs::PlainTime>::Ptr> ToTimeRecordOrMidnight(
Isolate* isolate, DirectHandle<Object> item,
DirectHandle<JSTemporalPlainTime>& output_time, const char* method_name) {
// 1. If item is undefined, return MidnightTimeRecord().
if (IsUndefined(*item)) {
- return Just(Managed<temporal_rs::PlainTime>::Ptr());
+ return Just(CppGCManaged<temporal_rs::PlainTime>::Ptr());
}
// 2. Let plainTime be ? ToTemporalTime(item).
@@ -2534,7 +2535,7 @@ Maybe<Managed<temporal_rs::PlainTime>::Ptr> ToTimeRecordOrMidnight(
ToTemporalTime(isolate, item, {}, method_name));
// 3. Return plainTime.[[Time]].
- Managed<temporal_rs::PlainTime>::Ptr empty = output_time->wrapped_rust();
+ CppGCManaged<temporal_rs::PlainTime>::Ptr empty = output_time->wrapped_rust();
return Just(std::move(empty));
}
@@ -3540,7 +3541,7 @@ MaybeDirectHandle<JSType> AddDurationToGeneric(
template <typename JSType, typename PartialType>
MaybeDirectHandle<JSType> GenericWithHelper(
Isolate* isolate,
- const typename Managed<typename JSType::RustType>::Ptr& rust_object,
+ const typename CppGCManaged<typename JSType::RustType>::Ptr& rust_object,
CombinedRecord& fields, DirectHandle<Object> options_obj,
const char* method_name) {
// 8. Let resolvedOptions be ? GetOptionsObject(options).
@@ -3566,7 +3567,7 @@ template <>
MaybeDirectHandle<JSTemporalZonedDateTime>
GenericWithHelper<JSTemporalZonedDateTime, temporal_rs::PartialZonedDateTime>(
Isolate* isolate,
- const Managed<JSTemporalZonedDateTime::RustType>::Ptr& rust_object,
+ const CppGCManaged<JSTemporalZonedDateTime::RustType>::Ptr& rust_object,
CombinedRecord& fields, DirectHandle<Object> options_obj,
const char* method_name) {
// 19. Let resolvedOptions be ? GetOptionsObject(options).
@@ -4309,7 +4310,7 @@ MaybeDirectHandle<JSTemporalPlainDateTime> JSTemporalPlainDate::ToPlainDateTime(
static const char method_name[] = "Temporal.PlainDate.toPlainDateTime";
// 3. Let time be ? ToTimeRecordOrMidnight(temporalTime).
- Managed<temporal_rs::PlainTime>::Ptr maybe_time;
+ CppGCManaged<temporal_rs::PlainTime>::Ptr maybe_time;
DirectHandle<JSTemporalPlainTime> time_output;
MOVE_RETURN_ON_EXCEPTION(
isolate, maybe_time,
@@ -4399,7 +4400,7 @@ MaybeDirectHandle<JSTemporalZonedDateTime> JSTemporalPlainDate::ToZonedDateTime(
}
DirectHandle<JSTemporalPlainTime> temporal_time;
- Managed<temporal_rs::PlainTime>::Ptr temporal_time_rust;
+ CppGCManaged<temporal_rs::PlainTime>::Ptr temporal_time_rust;
// 5. If temporalTime is undefined, then
if (temporal_time_obj.is_null() || IsUndefined(*temporal_time_obj)) {
@@ -4750,7 +4751,7 @@ JSTemporalPlainDateTime::WithPlainTime(
"Temporal.PlainDateTime.prototype.withPlainTime";
// 3. Let time be ? ToTimeRecordOrMidnight(plainTimeLike).
- Managed<temporal_rs::PlainTime>::Ptr maybe_time;
+ CppGCManaged<temporal_rs::PlainTime>::Ptr maybe_time;
DirectHandle<JSTemporalPlainTime> time_output;
MOVE_RETURN_ON_EXCEPTION(
isolate, maybe_time,
@@ -6142,7 +6143,7 @@ JSTemporalZonedDateTime::WithPlainTime(
// (handled later in Rust, idempotent)
DirectHandle<JSTemporalPlainTime> plain_time_obj;
- Managed<temporal_rs::PlainTime>::Ptr plain_time;
+ CppGCManaged<temporal_rs::PlainTime>::Ptr plain_time;
// 6. If plainTimeLike is undefined, then
if (IsUndefined(*plain_time_like)) {
diff --git a/deps/v8/src/objects/js-temporal-objects.h b/deps/v8/src/objects/js-temporal-objects.h
index 331df92a801..cb056823e56 100644
--- a/deps/v8/src/objects/js-temporal-objects.h
+++ b/deps/v8/src/objects/js-temporal-objects.h
@@ -31,15 +31,15 @@ namespace internal {
// body.
#define DECL_ACCESSORS_FOR_RUST_WRAPPER(field, RustType_) \
typedef RustType_ RustType; \
- inline Tagged<Managed<RustType_>> field() const; \
- inline void set_##field(Tagged<Managed<RustType_>> value, \
+ inline Tagged<CppGCManaged<RustType_>> field() const; \
+ inline void set_##field(Tagged<CppGCManaged<RustType_>> value, \
WriteBarrierMode mode = UPDATE_WRITE_BARRIER); \
inline void initialize_with_wrapped_rust_value( \
- Tagged<Managed<RustType_>> handle); \
- inline Managed<RustType_>::Ptr wrapped_rust() const; \
+ Tagged<CppGCManaged<RustType_>> handle); \
+ inline CppGCManaged<RustType_>::Ptr wrapped_rust() const; \
\
public: \
- TaggedMember<Managed<RustType_>> field##_;
+ TaggedMember<CppGCManaged<RustType_>> field##_;
// Adds JSTemporalFoo::GetConstructorTarget()
// that can be used to obtain a constructor target/new_target for constructing
@@ -51,22 +51,22 @@ namespace internal {
// js-temporal-objects.tq, adding DEFINE_ACCESSORS_FOR_RUST_WRAPPER
// to js-temporal-objects.cc, and adding an ACCESSORS entry to
// js-temporal-objects-inl.h
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::Instant,
- kTemporalInstantTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::Duration,
- kTemporalDurationTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::PlainDate,
- kTemporalPlainDateTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::PlainDateTime,
- kTemporalPlainDateTimeTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::PlainMonthDay,
- kTemporalPlainMonthDayTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::PlainTime,
- kTemporalPlainTimeTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::PlainYearMonth,
- kTemporalPlainYearMonthTag)
-ASSIGN_EXTERNAL_POINTER_TAG_FOR_MANAGED(temporal_rs::ZonedDateTime,
- kTemporalZonedDateTimeTag)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::Instant,
+ ManagedTypeId::kTemporalInstant)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::Duration,
+ ManagedTypeId::kTemporalDuration)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::PlainDate,
+ ManagedTypeId::kTemporalPlainDate)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::PlainDateTime,
+ ManagedTypeId::kTemporalPlainDateTime)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::PlainMonthDay,
+ ManagedTypeId::kTemporalPlainMonthDay)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::PlainTime,
+ ManagedTypeId::kTemporalPlainTime)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::PlainYearMonth,
+ ManagedTypeId::kTemporalPlainYearMonth)
+ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(temporal_rs::ZonedDateTime,
+ ManagedTypeId::kTemporalZonedDateTime)
class JSTemporalPlainDate;
class JSTemporalPlainMonthDay;
class JSTemporalPlainYearMonth;
diff --git a/deps/v8/src/objects/js-temporal-objects.tq b/deps/v8/src/objects/js-temporal-objects.tq
index e9fa0c9a537..ddcc9606c71 100644
--- a/deps/v8/src/objects/js-temporal-objects.tq
+++ b/deps/v8/src/objects/js-temporal-objects.tq
@@ -6,40 +6,41 @@
@cppObjectLayoutDefinition
extern class JSTemporalDuration extends JSObject {
- duration: Foreign; // Managed<temporal_rs::Duration>
+ duration: CppGCManagedBase; // CppGCManaged<temporal_rs::Duration>
}
@cppObjectLayoutDefinition
extern class JSTemporalInstant extends JSObject {
- instant: Foreign; // Managed<temporal_rs::Instant>
+ instant: CppGCManagedBase; // CppGCManaged<temporal_rs::Instant>
}
@cppObjectLayoutDefinition
extern class JSTemporalPlainDateTime extends JSObject {
- date_time: Foreign; // Managed<temporal_rs::PlainDateTime>
+ date_time: CppGCManagedBase; // CppGCManaged<temporal_rs::PlainDateTime>
}
@cppObjectLayoutDefinition
extern class JSTemporalPlainDate extends JSObject {
- date: Foreign; // Managed<temporal_rs::PlainDate>
+ date: CppGCManagedBase; // CppGCManaged<temporal_rs::PlainDate>
}
@cppObjectLayoutDefinition
extern class JSTemporalPlainMonthDay extends JSObject {
- month_day: Foreign; // Managed<temporal_rs::PlainMonthDay>
+ month_day: CppGCManagedBase; // CppGCManaged<temporal_rs::PlainMonthDay>
}
@cppObjectLayoutDefinition
extern class JSTemporalPlainTime extends JSObject {
- time: Foreign; // Managed<temporal_rs::PlainTime>
+ time: CppGCManagedBase; // CppGCManaged<temporal_rs::PlainTime>
}
@cppObjectLayoutDefinition
extern class JSTemporalPlainYearMonth extends JSObject {
- year_month: Foreign; // Managed<temporal_rs::PlainDate>
+ year_month: CppGCManagedBase; // CppGCManaged<temporal_rs::PlainDate>
}
@cppObjectLayoutDefinition
extern class JSTemporalZonedDateTime extends JSObject {
- zoned_date_time: Foreign; // Managed<temporal_rs::ZonedDateTime>
+ zoned_date_time:
+ CppGCManagedBase; // CppGCManaged<temporal_rs::ZonedDateTime>
}
diff --git a/deps/v8/src/objects/js-temporal-zoneinfo64.cc b/deps/v8/src/objects/js-temporal-zoneinfo64.cc
index 007d63589c5..99dd3a84c1e 100644
--- a/deps/v8/src/objects/js-temporal-zoneinfo64.cc
+++ b/deps/v8/src/objects/js-temporal-zoneinfo64.cc
@@ -11,36 +11,8 @@
#include "temporal_rs/TimeZone.hpp"
#ifdef V8_INTL_SUPPORT
-#ifndef V8_ENABLE_TEMPORAL_SYSTEMICU
-// ICU internal header file
#include "udatamem.h"
#else
-/**
- * Shadow definition of UDataMemory
- * This is functionally identical to the definition in udatamem.h
- * Irrelevant fields are marked 'ignored' and should not be used.
- *
- * This definition is copied here so that the result of udata_open()
- * can be used and length-checked without needing to resort to
- * calling internal ICU functions.
- *
- * Note, there is an ICU ticket,
- * https://unicode-org.atlassian.net/browse/ICU-23400
- * to consider whether the API surface should be changed
- * here. If and when this is done, such an API could be used.
- */
-struct UDataMemoryShadow {
- const void* ignored1;
- const void* data; //< pointer to header of data object
- const void* ignored2;
- UBool ignored3;
- void* ignored4;
- void* ignored5;
- int32_t
- length; //< length of entire region pointed to by data if known, else -1
-};
-#endif
-#else
// Defined in builtins-temporal-zoneinfo64-data.cc, generated by
// include-file-as-bytes.py
extern "C" uint32_t zoneinfo64_static_data[];
@@ -58,29 +30,17 @@ ZoneInfo64Provider::ZoneInfo64Provider() {
provider = temporal_rs::Provider::empty();
return;
}
-#ifndef V8_ENABLE_TEMPORAL_SYSTEMICU
// NOT udata_getLength: this ignores the header,
// and we're parsing resb files with the header
auto length = memory->length;
const void* data = udata_getRawMemory(memory);
-#else
- // reinterpret with a local struct
- const UDataMemoryShadow* shadowMemory =
- reinterpret_cast<const UDataMemoryShadow*>(memory);
- // just need the length and data
- auto length = shadowMemory->length;
- auto data = shadowMemory->data;
-#endif
- // This really shouldn't happen: ICU4C pads these files
- // to 4 when baking them in
- DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should pad udata to uint32_t");
- // Length may not be known. If we're not OK with that, don't proceed.
- DCHECK_WITH_MSG(length != -1, "ICU4C usually knows the length");
- if (length % 4 != 0 || length == -1) {
+ DCHECK_WITH_MSG(length % 4 == 0, "ICU4C should align udata to uint32_t");
+ if (length % 4 != 0) {
+ // This really shouldn't happen: ICU4C aligns these files
+ // to 4 when baking them in
provider = temporal_rs::Provider::empty();
return;
}
- DCHECK_WITH_MSG(data != nullptr, "ICU4C returned nullptr");
const uint32_t* data_32 = static_cast<const uint32_t*>(data);
std::span<const uint32_t> data_span(data_32, length / 4);
diff --git a/deps/v8/src/objects/keys.cc b/deps/v8/src/objects/keys.cc
index b53630ba7f2..d4aa5f6155d 100644
--- a/deps/v8/src/objects/keys.cc
+++ b/deps/v8/src/objects/keys.cc
@@ -20,6 +20,7 @@
#include "src/objects/hash-table-inl.h"
#include "src/objects/js-proxy-inl.h"
#include "src/objects/module-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/objects/property-descriptor.h"
@@ -1216,6 +1217,12 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(DirectHandle<JSObject> object) {
}
return Just(false);
}
+
+ if (filter_ & PRIVATE_NAMES_ONLY) {
+ RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectPrivateNames(object));
+ return Just(true);
+ }
+
if (IsJSDeferredModuleNamespace(*object)) [[unlikely]] {
DirectHandle<JSDeferredModuleNamespace> ns =
Cast<JSDeferredModuleNamespace>(object);
@@ -1224,10 +1231,6 @@ Maybe<bool> KeyAccumulator::CollectOwnKeys(DirectHandle<JSObject> object) {
RETURN_EXCEPTION_IF_EXCEPTION(isolate_);
}
}
- if (filter_ & PRIVATE_NAMES_ONLY) {
- RETURN_NOTHING_IF_NOT_SUCCESSFUL(CollectPrivateNames(object));
- return Just(true);
- }
if (may_have_elements_) {
MAYBE_RETURN(CollectOwnElementIndices(object), Nothing<bool>());
diff --git a/deps/v8/src/objects/literal-objects.h b/deps/v8/src/objects/literal-objects.h
index 836a77e74f8..27b5bf5b0dd 100644
--- a/deps/v8/src/objects/literal-objects.h
+++ b/deps/v8/src/objects/literal-objects.h
@@ -49,7 +49,6 @@ V8_OBJECT class PrototypeSharedClosureInfo : public Struct {
TaggedMember<Context> context_;
} V8_OBJECT_END;
-
// ObjectBoilerplateDescription is a list of properties consisting of name
// value pairs. In addition to the properties, it provides the projected number
// of properties in the backing store. This number includes properties with
diff --git a/deps/v8/src/objects/lookup-inl.h b/deps/v8/src/objects/lookup-inl.h
index 4c2ecd19249..a14a9b2e36f 100644
--- a/deps/v8/src/objects/lookup-inl.h
+++ b/deps/v8/src/objects/lookup-inl.h
@@ -18,7 +18,7 @@
#include "src/objects/internal-index.h"
#include "src/objects/map-inl.h"
#include "src/objects/name-inl.h"
-#include "src/objects/objects-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-details.h"
namespace v8 {
@@ -223,6 +223,11 @@ DirectHandle<Name> LookupIterator::name() const {
return name_;
}
+DirectHandle<Name> LookupIterator::name_for_transition() const {
+ DCHECK_IMPLIES(holder_.is_null(), !IsElement());
+ return name_;
+}
+
DirectHandle<Name> LookupIterator::GetName() {
if (name_.is_null()) {
DCHECK(IsElement());
diff --git a/deps/v8/src/objects/lookup.cc b/deps/v8/src/objects/lookup.cc
index 34a116268e1..07834bc499c 100644
--- a/deps/v8/src/objects/lookup.cc
+++ b/deps/v8/src/objects/lookup.cc
@@ -23,6 +23,7 @@
#include "src/objects/js-shared-array.h"
#include "src/objects/js-struct.h"
#include "src/objects/map-updater.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/ordered-hash-table.h"
#include "src/objects/property-details.h"
#include "src/objects/struct-inl.h"
@@ -667,13 +668,13 @@ void LookupIterator::ReconfigureDataProperty(DirectHandle<Object> value,
void LookupIterator::PrepareTransitionToDataProperty(
DirectHandle<JSTransitionableReceiver> receiver, DirectHandle<Object> value,
PropertyAttributes attributes, StoreOrigin store_origin) {
- DCHECK_IMPLIES(IsJSProxy(*receiver), name()->IsAnyPrivate());
+ DCHECK_IMPLIES(IsJSProxy(*receiver), name_for_transition()->IsAnyPrivate());
DCHECK_IMPLIES(!receiver.is_identical_to(GetStoreTarget<JSReceiver>()),
- name()->IsAnyPrivateName());
+ name_for_transition()->IsAnyPrivateName());
DCHECK(!IsAlwaysSharedSpaceJSObject(*receiver));
if (state_ == TRANSITION) return;
- if (!IsElement() && name()->IsAnyPrivate()) {
+ if (!IsElement() && name_for_transition()->IsAnyPrivate()) {
attributes = static_cast<PropertyAttributes>(attributes | DONT_ENUM);
}
@@ -696,7 +697,7 @@ void LookupIterator::PrepareTransitionToDataProperty(
PropertyDetails(PropertyKind::kData, attributes,
PropertyCell::InitialType(isolate_, *value));
transition_ = isolate_->factory()->NewPropertyCell(
- name(), property_details_, value);
+ name_for_transition(), property_details_, value);
has_property_ = true;
} else {
// Don't set enumeration index (it will be set during value store).
@@ -708,9 +709,9 @@ void LookupIterator::PrepareTransitionToDataProperty(
return;
}
- DirectHandle<Map> transition =
- Map::TransitionToDataProperty(isolate_, map, name_, value, attributes,
- PropertyConstness::kConst, store_origin);
+ DirectHandle<Map> transition = Map::TransitionToDataProperty(
+ isolate_, map, name_for_transition(), value, attributes,
+ PropertyConstness::kConst, store_origin);
state_ = TRANSITION;
transition_ = transition;
diff --git a/deps/v8/src/objects/lookup.h b/deps/v8/src/objects/lookup.h
index c41ba1a8335..9ea485f7c69 100644
--- a/deps/v8/src/objects/lookup.h
+++ b/deps/v8/src/objects/lookup.h
@@ -157,6 +157,8 @@ class V8_EXPORT_PRIVATE LookupIterator final {
State state() const { return state_; }
inline DirectHandle<Name> name() const;
+ // Same as name() but with relaxed DCHECKs for transition case.
+ inline DirectHandle<Name> name_for_transition() const;
inline DirectHandle<Name> GetName();
size_t index() const { return index_; }
uint32_t array_index() const {
diff --git a/deps/v8/src/objects/managed-inl.h b/deps/v8/src/objects/managed-inl.h
index 0a9c0a7ee5d..c72e5f9bce8 100644
--- a/deps/v8/src/objects/managed-inl.h
+++ b/deps/v8/src/objects/managed-inl.h
@@ -8,7 +8,15 @@
#include "src/objects/managed.h"
// Include the non-inl header before the rest of the headers.
+#include "include/cppgc/allocation.h"
+#include "include/cppgc/heap.h"
+#include "include/v8-isolate.h"
+#include "include/v8-sandbox.h"
+#include "src/execution/isolate.h"
#include "src/handles/global-handles-inl.h"
+#include "src/heap/factory.h"
+#include "src/heap/heap-write-barrier-inl.h"
+#include "src/objects/heap-object-field-inl.h"
namespace v8::internal {
@@ -27,6 +35,7 @@ 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));
@@ -74,6 +83,74 @@ DirectHandle<TrustedManaged<CppType>> TrustedManaged<CppType>::From(
return handle;
}
+inline CppGCManagedWrapper* CppGCManagedBase::GetWrapper() const {
+ return reinterpret_cast<CppGCManagedWrapper*>(ReadCppHeapPointerField(
+ offsetof(CppGCManagedBase, cpp_gc_wrapper_), Isolate::Current(),
+ CppHeapPointerTag::kCppGCManagedTag));
+}
+
+inline size_t CppGCManagedBase::estimated_size() const {
+ return GetWrapper()->estimated_size();
+}
+
+// static
+template <class CppType>
+Handle<CppGCManaged<CppType>> CppGCManaged<CppType>::Create(
+ Isolate* isolate, size_t estimated_size,
+ std::shared_ptr<CppType> shared_ptr, AllocationType allocation_type) {
+ auto* shared_ptr_ptr = new std::shared_ptr<CppType>(std::move(shared_ptr));
+ auto* destructor = cppgc::MakeGarbageCollected<CppGCManagedWrapper>(
+ reinterpret_cast<v8::Isolate*>(isolate)
+ ->GetCppHeap()
+ ->GetAllocationHandle(),
+ TypeIdForManaged<CppType>::value, estimated_size, shared_ptr_ptr,
+ detail::Destructor<CppType>, reinterpret_cast<v8::Isolate*>(isolate),
+ isolate->cpp_heap_isolate_alive_token());
+ Tagged<CppGCManagedBase> raw =
+ *isolate->factory()->NewCppGCManagedBase(allocation_type);
+ raw->WriteLazilyInitializedCppHeapPointerField(
+ offsetof(CppGCManagedBase, cpp_gc_wrapper_), isolate,
+ reinterpret_cast<Address>(destructor),
+ CppHeapPointerTag::kCppGCManagedTag);
+ WriteBarrier::ForCppHeapPointer(
+ raw,
+ raw->RawCppHeapPointerField(offsetof(CppGCManagedBase, cpp_gc_wrapper_)),
+ destructor);
+ return handle(Cast<CppGCManaged<CppType>>(raw), isolate);
+}
+
+template <class CppType>
+typename CppGCManaged<CppType>::Ptr CppGCManaged<CppType>::ptr() const {
+ return Ptr(get());
+}
+
+template <class CppType>
+CppType* CppGCManaged<CppType>::raw(
+ const DisallowGarbageCollection& no_gc) const {
+ return GetSharedPtr()->get();
+}
+
+template <class CppType>
+std::shared_ptr<CppType> CppGCManaged<CppType>::get() const {
+ return *GetSharedPtr();
+}
+
+template <class CppType>
+std::shared_ptr<CppType>* CppGCManaged<CppType>::GetSharedPtr() const {
+ auto wrapper = GetWrapper();
+ CHECK_EQ(wrapper->type_id(), TypeIdForManaged<CppType>::value);
+ return reinterpret_cast<std::shared_ptr<CppType>*>(wrapper->shared_ptr_ptr());
+}
+
+template <class CppType>
+void CppGCManaged<CppType>::SetManagedObject(
+ std::shared_ptr<CppType> new_managed, Isolate* isolate,
+ size_t new_estimated_size) {
+ CppGCManagedWrapper* wrapper = GetWrapper();
+ *GetSharedPtr() = std::move(new_managed);
+ wrapper->UpdateEstimatedSize(new_estimated_size, isolate);
+}
+
} // namespace v8::internal
#endif // V8_OBJECTS_MANAGED_INL_H_
diff --git a/deps/v8/src/objects/managed-type-id.h b/deps/v8/src/objects/managed-type-id.h
new file mode 100644
index 00000000000..afcad593df0
--- /dev/null
+++ b/deps/v8/src/objects/managed-type-id.h
@@ -0,0 +1,79 @@
+// 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_OBJECTS_MANAGED_TYPE_ID_H_
+#define V8_OBJECTS_MANAGED_TYPE_ID_H_
+
+#include <stdint.h>
+
+#include "include/v8-internal.h"
+
+namespace v8::internal {
+
+constexpr const char* ToString(ManagedTypeId type_id) {
+ switch (type_id) {
+ case ManagedTypeId::kBackingStore:
+ return "BackingStore";
+ case ManagedTypeId::kTestDeleteCounter:
+ return "TestDeleteCounter";
+ case ManagedTypeId::kTestDeleteNative:
+ return "TestDeleteNative";
+ case ManagedTypeId::kWasmStreaming:
+ return "WasmStreaming";
+ case ManagedTypeId::kWasmFuncData:
+ return "WasmFuncData";
+ case ManagedTypeId::kWasmManagedData:
+ 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:
+ return "TemporalInstant";
+ case ManagedTypeId::kTemporalPlainDate:
+ return "TemporalPlainDate";
+ case ManagedTypeId::kTemporalPlainTime:
+ return "TemporalPlainTime";
+ case ManagedTypeId::kTemporalPlainDateTime:
+ return "TemporalPlainDateTime";
+ case ManagedTypeId::kTemporalPlainYearMonth:
+ return "TemporalPlainYearMonth";
+ case ManagedTypeId::kTemporalPlainMonthDay:
+ return "TemporalPlainMonthDay";
+ case ManagedTypeId::kTemporalZonedDateTime:
+ return "TemporalZonedDateTime";
+ case ManagedTypeId::kDisplayNamesInternal:
+ return "DisplayNamesInternal";
+ case ManagedTypeId::kD8Worker:
+ return "D8Worker";
+ case ManagedTypeId::kD8ModuleEmbedderData:
+ return "D8ModuleEmbedderData";
+ case ManagedTypeId::kD8AsyncHooksWrap:
+ return "D8AsyncHooksWrap";
+ }
+}
+
+} // namespace v8::internal
+
+#endif // V8_OBJECTS_MANAGED_TYPE_ID_H_
diff --git a/deps/v8/src/objects/managed.cc b/deps/v8/src/objects/managed.cc
index 8077cbd1cd1..9039ab288d4 100644
--- a/deps/v8/src/objects/managed.cc
+++ b/deps/v8/src/objects/managed.cc
@@ -55,4 +55,19 @@ void ManagedObjectFinalizer(const v8::WeakCallbackInfo<void>& data) {
data.SetSecondPassCallback(&ManagedObjectFinalizerSecondPass);
}
+void CppGCManagedWrapper::UpdateEstimatedSize(size_t new_estimated_size,
+ Isolate* isolate) {
+ if (estimated_size_ == new_estimated_size) return;
+
+ v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate);
+ if (estimated_size_ < new_estimated_size) {
+ external_memory_accounter_.Increase(v8_isolate,
+ new_estimated_size - estimated_size_);
+ } else {
+ external_memory_accounter_.Decrease(v8_isolate,
+ estimated_size_ - new_estimated_size);
+ }
+ estimated_size_ = new_estimated_size;
+}
+
} // namespace v8::internal
diff --git a/deps/v8/src/objects/managed.h b/deps/v8/src/objects/managed.h
index e6dec74690b..a4e40d239c6 100644
--- a/deps/v8/src/objects/managed.h
+++ b/deps/v8/src/objects/managed.h
@@ -8,6 +8,7 @@
#include <memory>
#include <utility>
+#include "include/cppgc/garbage-collected.h"
#include "include/v8-callbacks.h"
#include "include/v8-external-memory-accounter.h"
#include "include/v8-object.h"
@@ -15,8 +16,12 @@
#include "src/base/compiler-specific.h"
#include "src/handles/handles.h"
#include "src/objects/foreign.h"
+#include "src/objects/managed-type-id.h"
#include "src/sandbox/external-pointer-table.h"
+// Has to be the last include (doesn't have include guards):
+#include "src/objects/object-macros.h"
+
namespace v8::internal {
class Isolate;
@@ -45,6 +50,175 @@ class Isolate;
// CppType is only forward declared and the respective header isn't included.
// Note also that this macro must be used inside the v8::internal namespace.
//
+
+class CppGCManagedWrapper final
+ : public cppgc::GarbageCollected<CppGCManagedWrapper> {
+ public:
+ CppGCManagedWrapper(ManagedTypeId type_id, size_t estimated_size,
+ void* shared_ptr_ptr, void (*destructor)(void*),
+ v8::Isolate* isolate,
+ std::shared_ptr<bool> isolate_alive_token)
+ : type_id_(type_id),
+ estimated_size_(estimated_size),
+ shared_ptr_ptr_(shared_ptr_ptr),
+ destructor_(destructor),
+ isolate_(isolate),
+ isolate_alive_token_(std::move(isolate_alive_token)) {
+ if (estimated_size_ > 0 && isolate_) {
+ external_memory_accounter_.Increase(isolate_, estimated_size_);
+ }
+ }
+
+ ~CppGCManagedWrapper() {
+ if (estimated_size_ > 0 && *isolate_alive_token_) {
+ external_memory_accounter_.Decrease(isolate_, estimated_size_);
+ }
+ if (destructor_) destructor_(shared_ptr_ptr_);
+ }
+
+ void Trace(cppgc::Visitor*) const {}
+
+ V8_EXPORT_PRIVATE void UpdateEstimatedSize(size_t new_estimated_size,
+ Isolate* isolate);
+
+ ManagedTypeId type_id() const { return type_id_; }
+
+ size_t estimated_size() const { return estimated_size_; }
+
+ void* shared_ptr_ptr() const { return shared_ptr_ptr_; }
+
+ private:
+ ManagedTypeId type_id_;
+ size_t estimated_size_ = 0;
+ void* shared_ptr_ptr_ = nullptr;
+ void (*destructor_)(void* shared_ptr) = nullptr;
+ v8::Isolate* isolate_ = nullptr;
+ std::shared_ptr<bool> isolate_alive_token_;
+ V8_NO_UNIQUE_ADDRESS ExternalMemoryAccounter external_memory_accounter_;
+};
+
+V8_OBJECT class CppGCManagedBase : public HeapObject {
+ V8_IT_OWN_TYPE;
+
+ public:
+ DECL_VERIFIER(CppGCManagedBase)
+ DECL_PRINTER(CppGCManagedBase)
+
+ CppGCManagedWrapper* GetWrapper() const;
+
+ inline size_t estimated_size() const;
+
+ class BodyDescriptor;
+
+ static const int kHeaderSize;
+ static const int kSize;
+
+ public:
+ CppHeapPointerMember cpp_gc_wrapper_;
+
+} V8_OBJECT_END;
+
+inline constexpr int CppGCManagedBase::kHeaderSize = sizeof(CppGCManagedBase);
+inline constexpr int CppGCManagedBase::kSize = sizeof(CppGCManagedBase);
+
+// {CppGCManaged<T>} is essentially a {std::shared_ptr<T>} allocated on the heap
+// that can be used to manage the lifetime of C++ objects that are shared
+// across multiple isolates.
+// When a {CppGCManaged<T>} object is garbage collected, the {CppGCManaged<T>}
+// deletes its underlying {std::shared_ptr<T>}, thereby decrementing its
+// internal reference count, which will delete the C++ object when the reference
+// count drops to 0.
+V8_OBJECT
+template <class CppType>
+class CppGCManaged : public CppGCManagedBase {
+ public:
+ V8_IT_REUSE_PARENT;
+
+ V8_OBJECT_INNER_CLASS class Ptr final {
+ public:
+ V8_INLINE Ptr() = default;
+
+ V8_INLINE Ptr(Ptr&& other) V8_NOEXCEPT = default;
+ Ptr(const Ptr&) = delete;
+ V8_INLINE Ptr& operator=(Ptr&& other) V8_NOEXCEPT = default;
+ Ptr& operator=(const Ptr&) = delete;
+
+ V8_INLINE CppType* operator->() V8_LIFETIME_BOUND { return ptr_.get(); }
+ V8_INLINE const CppType* operator->() const V8_LIFETIME_BOUND {
+ return ptr_.get();
+ }
+
+ V8_INLINE CppType& operator*() V8_LIFETIME_BOUND { return *ptr_; }
+ V8_INLINE const CppType& operator*() const V8_LIFETIME_BOUND {
+ return *ptr_;
+ }
+
+ V8_INLINE CppType* raw() V8_LIFETIME_BOUND { return ptr_.get(); }
+ V8_INLINE const CppType* raw() const V8_LIFETIME_BOUND {
+ return ptr_.get();
+ }
+ V8_INLINE CppType* get() V8_LIFETIME_BOUND { return ptr_.get(); }
+ V8_INLINE const CppType* get() const V8_LIFETIME_BOUND {
+ return ptr_.get();
+ }
+
+ V8_INLINE std::shared_ptr<CppType> as_shared_ptr() & { return ptr_; }
+ V8_INLINE std::shared_ptr<CppType> as_shared_ptr() && {
+ return std::move(ptr_);
+ }
+
+ V8_INLINE void Reset() { ptr_.reset(); }
+
+ V8_INLINE explicit operator bool() const { return ptr_ != nullptr; }
+ V8_INLINE bool operator==(std::nullptr_t) const { return ptr_ == nullptr; }
+ V8_INLINE bool operator==(const Ptr&) const = default;
+ V8_INLINE bool operator==(const std::shared_ptr<CppType>& other) const {
+ return ptr_ == other;
+ }
+
+ private:
+ friend class CppGCManaged;
+
+ V8_INLINE explicit Ptr(std::shared_ptr<CppType> ptr)
+ : ptr_(std::move(ptr)) {}
+
+ std::shared_ptr<CppType> ptr_;
+ } V8_OBJECT_INNER_CLASS_END;
+
+ inline Ptr ptr() const;
+
+ inline CppType* raw(
+ const DisallowGarbageCollection& no_gc V8_LIFETIME_BOUND) const;
+
+ inline std::shared_ptr<CppType> get() const;
+
+ static Handle<CppGCManaged<CppType>> Create(
+ Isolate* isolate, size_t estimated_size,
+ std::shared_ptr<CppType> shared_ptr,
+ AllocationType allocation_type = AllocationType::kYoung);
+
+ void SetManagedObject(std::shared_ptr<CppType> new_managed, Isolate* isolate,
+ size_t new_estimated_size);
+
+ void UpdateEstimatedSize(size_t new_estimated_size, Isolate* isolate) {
+ GetWrapper()->UpdateEstimatedSize(new_estimated_size, isolate);
+ }
+
+ private:
+ inline std::shared_ptr<CppType>* GetSharedPtr() const;
+} V8_OBJECT_END;
+
+template <typename CppType>
+struct TypeIdForManaged {
+ static constexpr ManagedTypeId value = CppType::kTypeID;
+};
+
+#define ASSIGN_MANAGED_TYPE_ID_FOR_MANAGED(CppType, TypeId) \
+ template <> \
+ struct TypeIdForManaged<CppType> { \
+ static constexpr ManagedTypeId value = TypeId; \
+ };
+
template <typename CppType>
struct TagForManaged {
static constexpr ExternalPointerTag value = CppType::kManagedTag;
@@ -92,16 +266,12 @@ struct ManagedPtrDestructor
V8_EXPORT_PRIVATE void ManagedObjectFinalizer(
const v8::WeakCallbackInfo<void>& data);
-// {Managed<T>} is essentially a {std::shared_ptr<T>} allocated on the heap
-// that can be used to manage the lifetime of C++ objects that are shared
-// across multiple isolates.
-// When a {Managed<T>} object is garbage collected (or an isolate which
-// contains {Managed<T>} is torn down), the {Managed<T>} deletes its underlying
-// {std::shared_ptr<T>}, thereby decrementing its internal reference count,
-// which will delete the C++ object when the reference count drops to 0.
+// The use of {Managed<T>} is deprecated. Use {CppGCManaged<T>} instead.
template <class CppType>
class Managed : public Foreign {
public:
+ V8_IT_REUSE_PARENT;
+
// Exposes the underlying C++ object and keeps the ref counter incremented.
//
// Usage examples:
@@ -225,6 +395,8 @@ class Managed : public Foreign {
template <class CppType>
class TrustedManaged : public TrustedForeign {
public:
+ V8_IT_REUSE_PARENT;
+
// For every object, add a `->` operator which returns a pointer to this
// object. This will allow smoother transition between T and Tagged<T>.
TrustedManaged* operator->() { return this; }
@@ -254,6 +426,7 @@ class TrustedManaged : public TrustedForeign {
destructor->shared_ptr_ptr_);
}
};
+#include "src/objects/object-macros-undef.h"
} // namespace v8::internal
diff --git a/deps/v8/src/objects/managed.tq b/deps/v8/src/objects/managed.tq
new file mode 100644
index 00000000000..bf35c557525
--- /dev/null
+++ b/deps/v8/src/objects/managed.tq
@@ -0,0 +1,8 @@
+// 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.
+
+@cppObjectLayoutDefinition
+extern class CppGCManagedBase extends HeapObject {
+ cpp_gc_wrapper: CppHeapPointer;
+}
diff --git a/deps/v8/src/objects/map.cc b/deps/v8/src/objects/map.cc
index 2a46a136bc6..3745751b01a 100644
--- a/deps/v8/src/objects/map.cc
+++ b/deps/v8/src/objects/map.cc
@@ -397,6 +397,9 @@ VisitorId Map::GetVisitorId(Tagged<Map> map) {
case JS_SPECIAL_API_OBJECT_TYPE:
return kVisitJSApiObject;
+ case CPP_GCMANAGED_BASE_TYPE:
+ return kVisitCppGCManagedBase;
+
case CPP_HEAP_EXTERNAL_OBJECT_TYPE:
return kVisitCppHeapExternalObject;
@@ -452,6 +455,7 @@ VisitorId Map::GetVisitorId(Tagged<Map> map) {
case BREAK_POINT_INFO_TYPE:
case CLASS_BOILERPLATE_TYPE:
case CLASS_POSITIONS_TYPE:
+ case DEBUG_SCRIPT_SCOPE_INFO_TYPE:
case ENUM_CACHE_TYPE:
case ERROR_STACK_DATA_TYPE:
case FUNCTION_TEMPLATE_RARE_DATA_TYPE:
@@ -504,6 +508,10 @@ VisitorId Map::GetVisitorId(Tagged<Map> map) {
#if V8_ENABLE_WEBASSEMBLY
case WASM_ARRAY_TYPE:
return kVisitWasmArray;
+ case WASM_CUSTOM_MAP_TYPE:
+ return kVisitWasmCustomMap;
+ case WASM_CUSTOM_MAP_WRAPPER_TYPE:
+ return kVisitJSObject;
case WASM_FUNC_REF_TYPE:
return kVisitWasmFuncRef;
case WASM_GLOBAL_OBJECT_TYPE:
@@ -2666,6 +2674,11 @@ void Map::SetPrototype(Isolate* isolate, DirectHandle<Map> map,
HeapLayout::InWritableSharedSpace(*prototype));
}
+ if (IsJSInterceptorMap(*map) && map->prototype() != *prototype) {
+ Cast<JSInterceptorMap>(*map)->set_fast_case_validity_cell(
+ ReadOnlyRoots(isolate).invalid_prototype_validity_cell());
+ }
+
WriteBarrierMode wb_mode =
IsNull(*prototype) ? SKIP_WRITE_BARRIER : UPDATE_WRITE_BARRIER;
map->set_prototype(*prototype, wb_mode);
diff --git a/deps/v8/src/objects/map.h b/deps/v8/src/objects/map.h
index 594d4c7c79a..a33c7f01ac1 100644
--- a/deps/v8/src/objects/map.h
+++ b/deps/v8/src/objects/map.h
@@ -62,6 +62,7 @@ enum InstanceType : uint16_t;
V(Context) \
V(ContextCell) \
V(CppHeapExternalObject) \
+ V(CppGCManagedBase) \
V(DataHandler) \
V(DescriptorArray) \
V(DoubleStringCache) \
@@ -120,6 +121,7 @@ enum InstanceType : uint16_t;
V(ThinString) \
V(TransitionArray) \
IF_WASM(V, WasmArray) \
+ IF_WASM(V, WasmCustomMap) \
IF_WASM(V, WasmFuncRef) \
IF_WASM(V, WasmGlobalObject) \
IF_WASM(V, WasmInstanceObject) \
@@ -251,6 +253,8 @@ using MapHandlesSpan = std::span<DirectHandle<Map>>;
// +---------------+-------------------------------------------------+
V8_OBJECT class Map : public HeapObject {
+ V8_IT_OWN_TYPE;
+
public:
// Instance size.
// Size in bytes or kVariableSizeSentinel if instances do not have
@@ -984,52 +988,7 @@ V8_OBJECT class Map : public HeapObject {
inline bool CanTransition() const;
static constexpr std::optional<RootIndex> TryGetMapRootIdxFor(
- InstanceType type) {
- switch (type) {
-#define MAKE_CASE(TYPE, Name, name) \
- case TYPE: \
- return RootIndex::k##Name##Map;
- STRUCT_LIST(MAKE_CASE)
-#undef MAKE_CASE
- case DESCRIPTOR_ARRAY_TYPE:
- return RootIndex::kDescriptorArrayMap;
- case ON_HEAP_BASIC_BLOCK_PROFILER_DATA_TYPE:
- return RootIndex::kOnHeapBasicBlockProfilerDataMap;
- case TURBOFAN_BITSET_TYPE_TYPE:
- return RootIndex::kTurbofanBitsetTypeMap;
- case TURBOFAN_UNION_TYPE_TYPE:
- return RootIndex::kTurbofanUnionTypeMap;
- case TURBOFAN_RANGE_TYPE_TYPE:
- return RootIndex::kTurbofanRangeTypeMap;
- case TURBOFAN_HEAP_CONSTANT_TYPE_TYPE:
- return RootIndex::kTurbofanHeapConstantTypeMap;
- case TURBOFAN_OTHER_NUMBER_CONSTANT_TYPE_TYPE:
- return RootIndex::kTurbofanOtherNumberConstantTypeMap;
- case TURBOSHAFT_WORD32_RANGE_TYPE_TYPE:
- return RootIndex::kTurboshaftWord32RangeTypeMap;
- case TURBOSHAFT_WORD32_SET_TYPE_TYPE:
- return RootIndex::kTurboshaftWord32SetTypeMap;
- case TURBOSHAFT_WORD64_RANGE_TYPE_TYPE:
- return RootIndex::kTurboshaftWord64RangeTypeMap;
- case TURBOSHAFT_WORD64_SET_TYPE_TYPE:
- return RootIndex::kTurboshaftWord64SetTypeMap;
- case TURBOSHAFT_FLOAT64_RANGE_TYPE_TYPE:
- return RootIndex::kTurboshaftFloat64RangeTypeMap;
- case TURBOSHAFT_FLOAT64_SET_TYPE_TYPE:
- return RootIndex::kTurboshaftFloat64SetTypeMap;
- case SORT_STATE_TYPE:
- return RootIndex::kSortStateMap;
-#if V8_ENABLE_WEBASSEMBLY
- case WASM_FAST_API_CALL_DATA_TYPE:
- return RootIndex::kWasmFastApiCallDataMap;
- case WASM_STRING_VIEW_ITER_TYPE:
- return RootIndex::kWasmStringViewIterMap;
-#endif // V8_ENABLE_WEBASSEMBLY
- default:
- break;
- }
- return {};
- }
+ InstanceType type);
static inline Tagged<Map> GetMapFor(ReadOnlyRoots roots, InstanceType type);
bool IsMapInArrayPrototypeChain(Isolate* isolate) const;
@@ -1264,6 +1223,8 @@ static_assert(offsetof(Map, instance_type_) ==
// Base class for Maps with extra fields. Subclasses must be defined with
// @hasSameInstanceTypeAsParent and define padding fields up to kTaggedSize.
V8_ABSTRACT_OBJECT class ExtendedMap : public Map {
+ V8_IT_REUSE_PARENT;
+
public:
// Bit positions for |bit_field_ex|.
struct BitsEx {
@@ -1306,6 +1267,8 @@ inline constexpr int ExtendedMap::kStartOfStrongExtendedFieldsOffset =
// Such maps do not have property descriptors, so a typical program
// needs very limited number of distinct normalized maps.
class NormalizedMapCache : public WeakFixedArray {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
static DirectHandle<NormalizedMapCache> New(Isolate* isolate);
diff --git a/deps/v8/src/objects/microtask.h b/deps/v8/src/objects/microtask.h
index 764637d8b54..a2c981324a4 100644
--- a/deps/v8/src/objects/microtask.h
+++ b/deps/v8/src/objects/microtask.h
@@ -22,6 +22,8 @@ class JSGeneratorObject;
// microtask queue. This class merely serves the purpose of a marker
// interface.
V8_OBJECT class Microtask : public Struct {
+ V8_IT_ABSTRACT;
+
public:
#ifdef V8_ENABLE_CONTINUATION_PRESERVED_EMBEDDER_DATA
inline Tagged<Object> continuation_preserved_embedder_data() const;
diff --git a/deps/v8/src/objects/module.cc b/deps/v8/src/objects/module.cc
index 46175fdda3b..1865ea0a5cb 100644
--- a/deps/v8/src/objects/module.cc
+++ b/deps/v8/src/objects/module.cc
@@ -279,8 +279,8 @@ bool Module::FinishInstantiate(Isolate* isolate, Handle<Module> module,
}
}
-MaybeDirectHandle<Object> Module::Evaluate(Isolate* isolate,
- Handle<Module> module) {
+MaybeDirectHandle<JSPromise> Module::Evaluate(Isolate* isolate,
+ Handle<Module> module) {
#ifdef DEBUG
PrintStatusMessage(*module, "Evaluating module ");
#endif // DEBUG
@@ -472,6 +472,31 @@ MaybeDirectHandle<Object> JSModuleNamespace::GetExport(
return value;
}
+// static
+void JSModuleNamespace::MaybeCountMissingDefaultWithStarExport(
+ LookupIterator* it) {
+ DCHECK_EQ(it->state(), LookupIterator::MODULE_NAMESPACE);
+
+ if (it->IsElement()) return;
+
+ Isolate* isolate = it->isolate();
+ DirectHandle<String> default_string = isolate->factory()->default_string();
+ if (*it->name() != *default_string) return;
+
+ DirectHandle<JSModuleNamespace> ns = it->GetHolder<JSModuleNamespace>();
+ if (ns->HasExport(isolate, default_string)) return;
+
+ {
+ DisallowGarbageCollection no_gc;
+ Tagged<Module> module = ns->module();
+ if (!IsSourceTextModule(module)) return;
+ if (!Cast<SourceTextModule>(module)->info()->HasStarExports()) return;
+ }
+
+ isolate->CountUsage(
+ v8::Isolate::kModuleNamespaceMissingDefaultWithStarExport);
+}
+
Maybe<PropertyAttributes> JSModuleNamespace::GetPropertyAttributes(
LookupIterator* it) {
DirectHandle<JSModuleNamespace> object = it->GetHolder<JSModuleNamespace>();
@@ -513,16 +538,13 @@ void JSDeferredModuleNamespace::EvaluateModuleSync(
return;
}
- MaybeDirectHandle<Object> maybe_result = Module::Evaluate(isolate, module);
- DirectHandle<Object> result;
- if (!maybe_result.ToHandle(&result)) {
+ MaybeDirectHandle<JSPromise> maybe_result = Module::Evaluate(isolate, module);
+ DirectHandle<JSPromise> promise;
+ if (!maybe_result.ToHandle(&promise)) {
return;
}
- // If there's a result, it needs to be a promise with either Reject or
- // Fulfilled status.
- DCHECK(IsJSPromise(*result));
- DirectHandle<JSPromise> promise = Cast<JSPromise>(result);
+ // The result is always the module's top-level capability promise.
// 5. If promise.[[PromiseState]] is rejected, then
if (promise->status() == Promise::kRejected) {
// a. If promise.[[PromiseIsHandled]] is false, perform
diff --git a/deps/v8/src/objects/module.h b/deps/v8/src/objects/module.h
index a955bea8d81..925b7d36166 100644
--- a/deps/v8/src/objects/module.h
+++ b/deps/v8/src/objects/module.h
@@ -29,6 +29,8 @@ class ZoneForwardList;
// to Abstract Module Record.
// https://tc39.es/ecma262/#sec-abstract-module-records
V8_OBJECT class Module : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
DECL_VERIFIER(Module)
DECL_PRINTER(Module)
@@ -72,7 +74,7 @@ V8_OBJECT class Module : public HeapObject {
const UserResolveCallbacks& callbacks);
// Implementation of spec operation ModuleEvaluation.
- static V8_WARN_UNUSED_RESULT MaybeDirectHandle<Object> Evaluate(
+ static V8_WARN_UNUSED_RESULT MaybeDirectHandle<JSPromise> Evaluate(
Isolate* isolate, Handle<Module> module);
// Get the namespace object for [module]. If it doesn't exist yet, it is
@@ -169,6 +171,8 @@ struct ObjectTraits<Module> {
// JSModuleNamespace object (representing module "bar") is created and bound to
// the declared variable (foo). A module can have at most one namespace object.
V8_OBJECT class JSModuleNamespace : public JSSpecialObject {
+ V8_IT_OWN_TYPE;
+
public:
inline Tagged<Module> module() const;
inline void set_module(Tagged<Module> value,
@@ -185,6 +189,15 @@ V8_OBJECT class JSModuleNamespace : public JSSpecialObject {
bool HasExport(Isolate* isolate, DirectHandle<String> name);
+ // Counts an access to a missing `default` export on the namespace [it] starts
+ // at, when that module has an `export * from '...'` statement. Such a
+ // `default` is absent today because `export *` skips it, but would resolve to
+ // the star-exported default (if it exists) under the export-star-default
+ // proposal (https://github.com/tc39/proposal-export-star-default).
+ // Called from [[Get]] and [[HasProperty]]. Only valid while [it] is in the
+ // LookupIterator::MODULE_NAMESPACE state.
+ static void MaybeCountMissingDefaultWithStarExport(LookupIterator* it);
+
// Return the (constant) property attributes for the referenced property,
// which is assumed to correspond to an export. If the export is
// uninitialized, schedule an exception and return Nothing.
diff --git a/deps/v8/src/objects/name.h b/deps/v8/src/objects/name.h
index b69f9ece453..ad2c6d438a5 100644
--- a/deps/v8/src/objects/name.h
+++ b/deps/v8/src/objects/name.h
@@ -82,6 +82,8 @@ V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
// The Name abstract class captures anything that can be used as a property
// name, i.e., strings and symbols. All names store a hash value.
V8_OBJECT class Name : public PrimitiveHeapObject {
+ V8_IT_ABSTRACT;
+
public:
// Tells whether the hash code has been computed.
// Note: Use TryGetHash() whenever you want to use the hash, instead of a
diff --git a/deps/v8/src/objects/number-string-cache.h b/deps/v8/src/objects/number-string-cache.h
index 2d1d446f8fc..6d719314150 100644
--- a/deps/v8/src/objects/number-string-cache.h
+++ b/deps/v8/src/objects/number-string-cache.h
@@ -18,6 +18,8 @@ namespace v8::internal {
// Used for mapping non-zero Smi to Strings.
V8_OBJECT class SmiStringCache : public FixedArray {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
using Super = FixedArray;
@@ -73,6 +75,8 @@ V8_OBJECT class SmiStringCache : public FixedArray {
// Used for mapping raw doubles to Strings.
V8_OBJECT class DoubleStringCache : public HeapObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
V8_OBJECT struct Entry {
UnalignedDoubleMember key_;
diff --git a/deps/v8/src/objects/object-conversions-inl.h b/deps/v8/src/objects/object-conversions-inl.h
new file mode 100644
index 00000000000..5974de215b7
--- /dev/null
+++ b/deps/v8/src/objects/object-conversions-inl.h
@@ -0,0 +1,89 @@
+// 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_OBJECTS_OBJECT_CONVERSIONS_INL_H_
+#define V8_OBJECTS_OBJECT_CONVERSIONS_INL_H_
+
+#include "src/common/globals.h"
+#include "src/numbers/conversions-inl.h"
+#include "src/objects/casting.h"
+#include "src/objects/heap-number-inl.h"
+#include "src/objects/heap-object-inl.h"
+#include "src/objects/objects.h"
+#include "src/objects/smi.h"
+
+namespace v8::internal {
+
+// static
+double Object::NumberValue(Tagged<Number> obj) {
+ if (IsSmi(obj)) {
+ return static_cast<double>(UncheckedCast<Smi>(obj).value());
+ }
+ DCHECK(IsHeapNumber(obj));
+ return UncheckedCast<HeapNumber>(obj)->value();
+}
+// TODO(leszeks): Remove in favour of Tagged<Number>
+// static
+double Object::NumberValue(Tagged<Object> obj) {
+ return NumberValue(UncheckedCast<Number>(obj));
+}
+double Object::NumberValue(Tagged<HeapNumber> obj) {
+ return NumberValue(UncheckedCast<Number>(obj));
+}
+double Object::NumberValue(Tagged<Smi> obj) {
+ return NumberValue(UncheckedCast<Number>(obj));
+}
+
+// static
+bool Object::ToUint32(Tagged<Object> obj, uint32_t* value) {
+ if (IsSmi(obj)) {
+ int num = Smi::ToInt(obj);
+ if (num < 0) return false;
+ *value = static_cast<uint32_t>(num);
+ return true;
+ }
+ if (IsHeapNumber(obj)) {
+ double num = Cast<HeapNumber>(obj)->value();
+ return DoubleToUint32IfEqualToSelf(num, value);
+ }
+ return false;
+}
+
+// static
+bool Object::ToArrayLength(Tagged<Object> obj, uint32_t* index) {
+ return Object::ToUint32(obj, index);
+}
+
+// static
+bool Object::ToArrayIndex(Tagged<Object> obj, uint32_t* index) {
+ return Object::ToUint32(obj, index) && *index != kMaxUInt32;
+}
+
+// static
+bool Object::ToIntegerIndex(Tagged<Object> obj, size_t* index) {
+ if (IsSmi(obj)) {
+ int num = Smi::ToInt(obj);
+ if (num < 0) return false;
+ *index = static_cast<size_t>(num);
+ return true;
+ }
+ if (IsHeapNumber(obj)) {
+ double num = Cast<HeapNumber>(obj)->value();
+ if (!(num >= 0)) return false; // Negation to catch NaNs.
+ constexpr double max =
+ std::min(kMaxSafeInteger,
+ // The maximum size_t is reserved as "invalid" sentinel.
+ static_cast<double>(std::numeric_limits<size_t>::max() - 1));
+ if (num > max) return false;
+ size_t result = static_cast<size_t>(num);
+ if (num != result) return false; // Conversion lost fractional precision.
+ *index = result;
+ return true;
+ }
+ return false;
+}
+
+} // namespace v8::internal
+
+#endif // V8_OBJECTS_OBJECT_CONVERSIONS_INL_H_
diff --git a/deps/v8/src/objects/object-list-macros.h b/deps/v8/src/objects/object-list-macros.h
index 86cf61df79c..33a90aea277 100644
--- a/deps/v8/src/objects/object-list-macros.h
+++ b/deps/v8/src/objects/object-list-macros.h
@@ -6,7 +6,7 @@
#define V8_OBJECTS_OBJECT_LIST_MACROS_H_
#include "src/base/macros.h" // For IF_WASM.
-#include "torque-generated/instance-types.h"
+#include "src/objects/instance-types-gen.h"
namespace v8 {
namespace internal {
@@ -99,6 +99,7 @@ namespace internal {
V(WeakFixedArray) \
V(WeakHomomorphicFixedArray) \
IF_WASM(V, WasmArray) \
+ IF_WASM(V, WasmCustomMap) \
IF_WASM(V, WasmDispatchTable) \
IF_WASM(V, WasmDispatchTableForImports) \
IF_WASM(V, WasmStruct)
@@ -119,6 +120,7 @@ namespace internal {
V(ContextCell) \
V(CoverageInfo) \
V(CppHeapExternalObject) \
+ V(CppGCManagedBase) \
V(DataHandler) \
V(DeoptimizationData) \
V(DependentCode) \
@@ -285,6 +287,9 @@ namespace internal {
V(TurboshaftWord64SetType) \
V(TurboshaftWord64Type) \
IF_WASM(V, WasmArray) \
+ IF_WASM(V, WasmContinuationObject) \
+ IF_WASM(V, WasmCustomMap) \
+ IF_WASM(V, WasmCustomMapWrapper) \
IF_WASM(V, WasmExceptionPackage) \
IF_WASM(V, WasmFastApiCallData) \
IF_WASM(V, WasmFuncRef) \
@@ -295,11 +300,10 @@ namespace internal {
IF_WASM(V, WasmNull) \
IF_WASM(V, WasmObject) \
IF_WASM(V, WasmResumeData) \
+ IF_WASM(V, WasmStackObject) \
IF_WASM(V, WasmStringViewIter) \
IF_WASM(V, WasmStruct) \
IF_WASM(V, WasmSuspendingObject) \
- IF_WASM(V, WasmContinuationObject) \
- IF_WASM(V, WasmStackObject) \
IF_WASM(V, WasmTableObject) \
IF_WASM(V, WasmTagObject) \
IF_WASM(V, WasmTypeInfo) \
diff --git a/deps/v8/src/objects/object-macros-undef.h b/deps/v8/src/objects/object-macros-undef.h
index ad0cdac225c..ebfbe17948d 100644
--- a/deps/v8/src/objects/object-macros-undef.h
+++ b/deps/v8/src/objects/object-macros-undef.h
@@ -13,6 +13,15 @@
#undef V8_OBJECT_END
#undef V8_OBJECT_INNER_CLASS
#undef V8_OBJECT_INNER_CLASS_END
+#undef V8_IT_ABSTRACT
+#undef V8_IT_REUSE_PARENT
+#undef V8_IT_FIXED_VALUE
+#undef V8_IT_FLAG_BITS
+#undef V8_IT_ORDER
+#undef V8_IT_OWN_TYPE
+#undef V8_IT_NO_AUTO_CHECKER
+#undef V8_IT_NO_AUTO_DISPATCH
+#undef V8_IT_MARK
#undef DECL_PRIMITIVE_GETTER
#undef DECL_PRIMITIVE_SETTER
#undef DECL_PRIMITIVE_ACCESSORS
diff --git a/deps/v8/src/objects/object-macros.h b/deps/v8/src/objects/object-macros.h
index d0e3bd3c8f8..0cd9b6fbadf 100644
--- a/deps/v8/src/objects/object-macros.h
+++ b/deps/v8/src/objects/object-macros.h
@@ -75,6 +75,76 @@
; \
V8_OBJECT_PUSH static_assert(true)
+// Instance-type markers for V8_OBJECT classes. They exist solely for the
+// libclang-driven instance-type generator, which harvests them to drive
+// `instance-type.h` emission, and they reach no other build: outside the
+// harvest's parse they expand to a static_assert. Mirror the meanings of
+// the Torque annotations they replace (see `src/torque/...` and the IT
+// solver).
+//
+// Usage -- one per line in the class body, in any order:
+//
+// V8_OBJECT class JSReceiver : public HeapObject {
+// public:
+// V8_IT_ABSTRACT;
+// ...
+// } V8_OBJECT_END;
+//
+// Only the harvest's parse declares anything here, and it has to: an
+// attribute must appertain to a declaration, and a bare `[[...]];` in a
+// class body declares nothing, so the attribute rides an alias -- the
+// carrier that adds no value, enumerator or function to the class.
+// Everywhere else the marker's own `;` terminates a static_assert and
+// the class is left untouched.
+#ifdef V8_METAGEN_GENERATION_PASS
+#define V8_IT_MARK(NAME, PAYLOAD) \
+ using V8IT_##NAME [[clang::annotate(PAYLOAD)]] = void
+#else
+#define V8_IT_MARK(NAME, PAYLOAD) static_assert(true)
+#endif
+#define V8_IT_ABSTRACT V8_IT_MARK(Abstract, "V8_IT_ABSTRACT")
+#define V8_IT_REUSE_PARENT V8_IT_MARK(ReuseParent, "V8_IT_REUSE_PARENT")
+#define V8_IT_FIXED_VALUE(N) V8_IT_MARK(FixedValue, "V8_IT_FIXED_VALUE(" #N ")")
+#define V8_IT_FLAG_BITS(N) V8_IT_MARK(FlagBits, "V8_IT_FLAG_BITS(" #N ")")
+#define V8_IT_ORDER(POS) V8_IT_MARK(Order, "V8_IT_ORDER(" #POS ")")
+// Explicit participation marker for concrete classes that also have
+// concrete subclasses among the IT participants (concrete
+// non-leaves). The default discovery rule -- "leaf in the candidate
+// set OR carries any V8_IT_* annotation" -- treats unannotated
+// intermediates as inheritance bookkeeping, not IT participants. A
+// concrete intermediate that wants its own _TYPE value emitted has
+// to opt in via this annotation.
+//
+// Examples: Map (has Map sub-types as children), JSArray (parent of
+// TemplateLiteralObject), FixedArray (parent of FixedArrayExact),
+// HashTable (parent of EphemeronHashTable / NameToIndexHashTable /
+// RegisteredSymbolTable), etc.
+//
+// Pure-leaf classes don't need this -- they auto-participate.
+// Abstract non-leaves use V8_IT_ABSTRACT (no own value, range
+// markers only). V8_IT_REUSE_PARENT classes share the parent's IT.
+#define V8_IT_OWN_TYPE V8_IT_MARK(OwnType, "V8_IT_OWN_TYPE")
+// Excludes the class from metagen's generated checker bucket lists. By
+// default it also excludes the class from the instance-type harvest entirely,
+// so it gets no instance-type value of its own. Combine it with
+// V8_IT_OWN_TYPE to retain the class and its own instance-type value while
+// suppressing only its generated checker entries.
+//
+// Used for classes with a hand-written `IsX(...)` predicate (in
+// instance-type-checker.h's INSTANCE_TYPE_CHECKERS_CUSTOM list, in the
+// SINGLE/RANGE manual extras, or via DEF_HEAP_OBJECT_PREDICATE across src/)
+// whose auto-emitted definition would collide with it.
+#define V8_IT_NO_AUTO_CHECKER V8_IT_MARK(NoAutoChecker, "V8_IT_NO_AUTO_CHECKER")
+// Excludes the class from the generated
+// HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST even though it declares both
+// Name##Print and Name##Verify. Carriers are dispatched by hand-written
+// cases in HeapObject::HeapObjectPrint (objects-printer.cc) and
+// HeapObject::HeapObjectVerify (objects-debug.cc); without this marker
+// the generated entry would produce a duplicate case label there
+// (which is also the loud failure mode if the marker is forgotten).
+#define V8_IT_NO_AUTO_DISPATCH \
+ V8_IT_MARK(NoAutoDispatch, "V8_IT_NO_AUTO_DISPATCH")
+
#define DECL_PRIMITIVE_GETTER(name, type) inline type name() const;
#define DECL_PRIMITIVE_SETTER(name, type) inline void set_##name(type value);
diff --git a/deps/v8/src/objects/objects-body-descriptors-inl.h b/deps/v8/src/objects/objects-body-descriptors-inl.h
index 5028765848e..cf024e02121 100644
--- a/deps/v8/src/objects/objects-body-descriptors-inl.h
+++ b/deps/v8/src/objects/objects-body-descriptors-inl.h
@@ -78,7 +78,6 @@ void BodyDescriptorBase::IterateJSObjectBodyImpl(Tagged<Map> map,
int start_offset,
int end_offset,
ObjectVisitor* v) {
-#ifdef V8_COMPRESS_POINTERS
static_assert(kEmbedderDataSlotSize == 2 * kTaggedSize);
int header_end_offset = JSObject::GetHeaderSize(map);
int inobject_fields_start_offset = map->GetInObjectPropertyOffset(0);
@@ -92,19 +91,13 @@ void BodyDescriptorBase::IterateJSObjectBodyImpl(Tagged<Map> map,
for (int offset = header_end_offset; offset < inobject_fields_start_offset;
offset += kEmbedderDataSlotSize) {
IteratePointer(obj, offset + EmbedderDataSlot::kTaggedPayloadOffset, v);
- v->VisitExternalPointer(
- obj, obj->RawExternalPointerField(
- offset + EmbedderDataSlot::kExternalPointerOffset,
- {kFirstEmbedderDataTag, kLastEmbedderDataTag}));
+ v->VisitCppHeapPointer(
+ obj, obj->RawCppHeapPointerField(
+ offset + EmbedderDataSlot::kCppHeapPointerOffset));
}
// Proceed processing inobject properties.
start_offset = inobject_fields_start_offset;
}
-#else
- // We store raw aligned pointers as Smis, so it's safe to iterate the whole
- // embedder field area as tagged slots.
- static_assert(kEmbedderDataSlotSize == kTaggedSize);
-#endif
IteratePointers(obj, start_offset, end_offset, v);
}
@@ -966,6 +959,20 @@ class Foreign::BodyDescriptor final : public BodyDescriptorBase {
}
};
+class CppGCManagedBase::BodyDescriptor final : public BodyDescriptorBase {
+ public:
+ template <typename ObjectVisitor>
+ static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
+ int object_size, ObjectVisitor* v) {
+ Tagged<CppGCManagedBase> managed = UncheckedCast<CppGCManagedBase>(obj);
+ v->VisitCppHeapPointer(obj, CppHeapPointerSlot(&managed->cpp_gc_wrapper_));
+ }
+
+ static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
+ return CppGCManagedBase::kSize;
+ }
+};
+
template <typename Derived>
class V8_EXPORT_PRIVATE SmallOrderedHashTableImpl<Derived>::BodyDescriptor final
: public BodyDescriptorBase {
@@ -1652,6 +1659,7 @@ class WasmStruct::BodyDescriptor final : public BodyDescriptorBase {
Tagged<WasmStruct> wasm_struct = UncheckedCast<WasmStruct>(obj);
const wasm::CanonicalStructType* type = WasmStruct::GcSafeType(map);
if (type->is_descriptor()) {
+ DCHECK(!v8_flags.wasm_merged_descriptors);
// The associated Map is stored where the first field would otherwise be.
DCHECK(type->field_count() == 0 || type->field_offset(0) != 0);
v->VisitPointer(wasm_struct, wasm_struct->RawField(0));
@@ -1786,6 +1794,34 @@ class Map::BodyDescriptor final : public BodyDescriptorBase {
}
};
+#if V8_ENABLE_WEBASSEMBLY
+
+class WasmCustomMap::BodyDescriptor final : public BodyDescriptorBase {
+ public:
+ static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
+ int object_size, ObjectVisitor* v) {
+ Map::BodyDescriptor::IterateBody(map, obj, object_size, v);
+ IteratePointer(obj, offsetof(WasmCustomMap, js_wrapper_), v);
+
+ Tagged<WasmCustomMap> wasm_struct = UncheckedCast<WasmCustomMap>(obj);
+ // Not a typo: WasmCustomMap reuses some WasmStruct infrastructure.
+ const wasm::CanonicalStructType* type = WasmStruct::GcSafeType(map);
+ DCHECK(type->is_descriptor());
+ for (uint32_t i = 0; i < type->field_count(); i++) {
+ if (!type->field(i).is_ref()) continue;
+ int offset = static_cast<int>(type->field_offset(i));
+ v->VisitPointer(wasm_struct, wasm_struct->RawField(offset));
+ }
+ }
+
+ static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> obj) {
+ // Not a typo: WasmCustomMap reuses some WasmStruct infrastructure.
+ return WasmStruct::GcSafeSize(map);
+ }
+};
+
+#endif // V8_ENABLE_WEBASSEMBLY
+
class DataHandler::BodyDescriptor final : public BodyDescriptorBase {
public:
template <typename ObjectVisitor>
@@ -1827,14 +1863,8 @@ class NativeContext::BodyDescriptor final : public BodyDescriptorBase {
NativeContext::kEndOfStrongFieldsOffset, v);
IterateCustomWeakPointers(obj, NativeContext::kStartOfWeakFieldsOffset,
NativeContext::kEndOfWeakFieldsOffset, v);
-#ifdef V8_CPPGC_MICROTASK_QUEUE
v->VisitCppHeapPointer(obj,
obj->RawCppHeapPointerField(kMicrotaskQueueOffset));
-#else
- v->VisitExternalPointer(
- obj, obj->RawExternalPointerField(kMicrotaskQueueOffset,
- kNativeContextMicrotaskQueueTag));
-#endif // V8_CPPGC_MICROTASK_QUEUE
}
static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
@@ -1888,23 +1918,14 @@ class EmbedderDataArray::BodyDescriptor final : public BodyDescriptorBase {
template <typename ObjectVisitor>
static inline void IterateBody(Tagged<Map> map, Tagged<HeapObject> obj,
int object_size, ObjectVisitor* v) {
-#ifdef V8_COMPRESS_POINTERS
static_assert(kEmbedderDataSlotSize == 2 * kTaggedSize);
for (int offset = EmbedderDataArray::OffsetOfElementAt(0);
offset < object_size; offset += kEmbedderDataSlotSize) {
IteratePointer(obj, offset + EmbedderDataSlot::kTaggedPayloadOffset, v);
- v->VisitExternalPointer(
- obj, obj->RawExternalPointerField(
- offset + EmbedderDataSlot::kExternalPointerOffset,
- {kFirstEmbedderDataTag, kLastEmbedderDataTag}));
+ v->VisitCppHeapPointer(
+ obj, obj->RawCppHeapPointerField(
+ offset + EmbedderDataSlot::kCppHeapPointerOffset));
}
-
-#else
- // We store raw aligned pointers as Smis, so it's safe to iterate the whole
- // array.
- static_assert(kEmbedderDataSlotSize == kTaggedSize);
- IteratePointers(obj, sizeof(EmbedderDataArray), object_size, v);
-#endif
}
static inline int SizeOf(Tagged<Map> map, Tagged<HeapObject> object) {
diff --git a/deps/v8/src/objects/objects-definitions.h b/deps/v8/src/objects/objects-definitions.h
index a4d13ee6172..ef25f49c705 100644
--- a/deps/v8/src/objects/objects-definitions.h
+++ b/deps/v8/src/objects/objects-definitions.h
@@ -6,7 +6,7 @@
#define V8_OBJECTS_OBJECTS_DEFINITIONS_H_
#include "src/init/heap-symbols.h"
-#include "torque-generated/instance-types.h"
+#include "src/objects/instance-types-gen.h"
namespace v8 {
@@ -161,6 +161,8 @@ namespace internal {
V(_, CLASS_BOILERPLATE_TYPE, ClassBoilerplate, class_boilerplate) \
V(_, CLASS_POSITIONS_TYPE, ClassPositions, class_positions) \
V(_, CODE_WRAPPER_TYPE, CodeWrapper, code_wrapper) \
+ V(_, DEBUG_SCRIPT_SCOPE_INFO_TYPE, DebugScriptScopeInfo, \
+ debug_script_scope_info) \
V(_, ENUM_CACHE_TYPE, EnumCache, enum_cache) \
V(_, ERROR_STACK_DATA_TYPE, ErrorStackData, error_stack_data) \
V(_, FUNCTION_TEMPLATE_RARE_DATA_TYPE, FunctionTemplateRareData, \
diff --git a/deps/v8/src/objects/objects-inl.h b/deps/v8/src/objects/objects-inl.h
index e1b54860260..d77f5622b83 100644
--- a/deps/v8/src/objects/objects-inl.h
+++ b/deps/v8/src/objects/objects-inl.h
@@ -91,6 +91,7 @@ DEF_CAST_TRAITS(Context)
DEF_CAST_TRAITS(ContextCell)
DEF_CAST_TRAITS(CoverageInfo)
DEF_CAST_TRAITS(CppHeapExternalObject)
+DEF_CAST_TRAITS(CppGCManagedBase)
DEF_CAST_TRAITS(DataHandler)
DEF_CAST_TRAITS(DeoptimizationData)
DEF_CAST_TRAITS(DescriptorArray)
@@ -234,6 +235,9 @@ DEF_CAST_TRAITS(TurboshaftWord64SetType)
DEF_CAST_TRAITS(TurboshaftWord64Type)
#if V8_ENABLE_WEBASSEMBLY
DEF_CAST_TRAITS(WasmArray)
+DEF_CAST_TRAITS(WasmContinuationObject)
+DEF_CAST_TRAITS(WasmCustomMap)
+DEF_CAST_TRAITS(WasmCustomMapWrapper)
DEF_CAST_TRAITS(WasmExceptionPackage)
DEF_CAST_TRAITS(WasmFastApiCallData)
DEF_CAST_TRAITS(WasmFuncRef)
@@ -244,11 +248,10 @@ DEF_CAST_TRAITS(WasmModuleObject)
DEF_CAST_TRAITS(WasmNull)
DEF_CAST_TRAITS(WasmObject)
DEF_CAST_TRAITS(WasmResumeData)
+DEF_CAST_TRAITS(WasmStackObject)
DEF_CAST_TRAITS(WasmStringViewIter)
DEF_CAST_TRAITS(WasmStruct)
DEF_CAST_TRAITS(WasmSuspendingObject)
-DEF_CAST_TRAITS(WasmContinuationObject)
-DEF_CAST_TRAITS(WasmStackObject)
DEF_CAST_TRAITS(WasmTableObject)
DEF_CAST_TRAITS(WasmTagObject)
DEF_CAST_TRAITS(WasmTypeInfo)
@@ -356,6 +359,8 @@ struct CastTraits<FieldType> {
template <typename T>
struct CastTraits<Managed<T>> : public CastTraits<Foreign> {};
template <typename T>
+struct CastTraits<CppGCManaged<T>> : public CastTraits<CppGCManagedBase> {};
+template <typename T>
struct CastTraits<TrustedManaged<T>> : public CastTraits<TrustedForeign> {};
template <typename T>
struct CastTraits<PodArray<T>> : public CastTraits<ByteArray> {};
@@ -610,24 +615,6 @@ DEF_HEAP_OBJECT_PREDICATE(IsAccessCheckNeeded) {
return obj->map()->is_access_check_needed();
}
-// static
-double Object::NumberValue(Tagged<Number> obj) {
- DCHECK(IsNumber(obj));
- return IsSmi(obj) ? static_cast<double>(UncheckedCast<Smi>(obj).value())
- : UncheckedCast<HeapNumber>(obj)->value();
-}
-// TODO(leszeks): Remove in favour of Tagged<Number>
-// static
-double Object::NumberValue(Tagged<Object> obj) {
- return NumberValue(Cast<Number>(obj));
-}
-double Object::NumberValue(Tagged<HeapNumber> obj) {
- return NumberValue(Cast<Number>(obj));
-}
-double Object::NumberValue(Tagged<Smi> obj) {
- return NumberValue(Cast<Number>(obj));
-}
-
// static
template <typename T, template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<T>, DirectHandle<T>>)
@@ -743,21 +730,6 @@ bool Object::FitsRepresentation(Tagged<Object> obj,
return true;
}
-// static
-bool Object::ToUint32(Tagged<Object> obj, uint32_t* value) {
- if (IsSmi(obj)) {
- int num = Smi::ToInt(obj);
- if (num < 0) return false;
- *value = static_cast<uint32_t>(num);
- return true;
- }
- if (IsHeapNumber(obj)) {
- double num = Cast<HeapNumber>(obj)->value();
- return DoubleToUint32IfEqualToSelf(num, value);
- }
- return false;
-}
-
// static
template <typename T, template <typename> typename HandleType>
requires(std::is_convertible_v<HandleType<T>, DirectHandle<T>>)
@@ -963,40 +935,6 @@ bool IsCustomElementsReceiverMap(Tagged<Map> map) {
return IsCustomElementsReceiverInstanceType(map->instance_type());
}
-// static
-bool Object::ToArrayLength(Tagged<Object> obj, uint32_t* index) {
- return Object::ToUint32(obj, index);
-}
-
-// static
-bool Object::ToArrayIndex(Tagged<Object> obj, uint32_t* index) {
- return Object::ToUint32(obj, index) && *index != kMaxUInt32;
-}
-
-// static
-bool Object::ToIntegerIndex(Tagged<Object> obj, size_t* index) {
- if (IsSmi(obj)) {
- int num = Smi::ToInt(obj);
- if (num < 0) return false;
- *index = static_cast<size_t>(num);
- return true;
- }
- if (IsHeapNumber(obj)) {
- double num = Cast<HeapNumber>(obj)->value();
- if (!(num >= 0)) return false; // Negation to catch NaNs.
- constexpr double max =
- std::min(kMaxSafeInteger,
- // The maximum size_t is reserved as "invalid" sentinel.
- static_cast<double>(std::numeric_limits<size_t>::max() - 1));
- if (num > max) return false;
- size_t result = static_cast<size_t>(num);
- if (num != result) return false; // Conversion lost fractional precision.
- *index = result;
- return true;
- }
- return false;
-}
-
WriteBarrierModeScope HeapObject::GetWriteBarrierMode(
const DisallowGarbageCollection& promise) {
return WriteBarrier::GetWriteBarrierModeForObject(this, promise);
@@ -1031,7 +969,8 @@ AllocationAlignment HeapObject::RequiredAlignment(InSharedSpace in_shared_space,
#if V8_ENABLE_WEBASSEMBLY
if (in_shared_space && v8_flags.wasm_shared) [[unlikely]] {
int instance_type = map->instance_type();
- if (instance_type == WASM_STRUCT_TYPE) {
+ if (instance_type == WASM_STRUCT_TYPE ||
+ instance_type == WASM_CUSTOM_MAP_TYPE) {
// The map of a shared wasm struct needs to be in the shared space.
DCHECK(HeapLayout::InWritableSharedSpace(map));
return kDoubleAligned;
@@ -1198,7 +1137,8 @@ bool Object::CanBeHeldWeakly(Tagged<Object> obj) {
// to shared values in weak collections. For now, disallow them as weak
// collection keys.
#if V8_ENABLE_WEBASSEMBLY
- if (v8_flags.wasm_shared && (IsWasmStruct(obj) || IsWasmArray(obj)) &&
+ if (v8_flags.wasm_shared &&
+ (IsWasmStruct(obj) || IsWasmCustomMap(obj) || IsWasmArray(obj)) &&
HeapLayout::InAnySharedSpace(Cast<HeapObject>(obj))) {
return false;
}
diff --git a/deps/v8/src/objects/objects.cc b/deps/v8/src/objects/objects.cc
index 33cc19d1541..3ff2dd2f8d5 100644
--- a/deps/v8/src/objects/objects.cc
+++ b/deps/v8/src/objects/objects.cc
@@ -72,6 +72,7 @@
#include "src/objects/megadom-handler-inl.h"
#include "src/objects/microtask-inl.h"
#include "src/objects/module-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/promise-inl.h"
@@ -478,6 +479,16 @@ template <template <typename> typename HandleType>
typename HandleType<String>::MaybeType Object::ConvertToString(
Isolate* isolate, HandleType<Object> input) {
while (true) {
+#if V8_ENABLE_WEBASSEMBLY
+ // We generally don't let the WasmNull escape into the JavaScript world,
+ // but some builtins may encounter it when called directly from Wasm code.
+ // This must be checked first, because WasmNull is entirely inaccessible,
+ // even its map, so we have to compare it by pointer before loading
+ // anything from it.
+ if (IsWasmNull(*input)) {
+ return isolate->factory()->null_string();
+ }
+#endif
if (IsOddball(*input)) {
HandleType<String> result(Cast<Oddball>(input)->to_string(), isolate);
return result;
@@ -491,13 +502,6 @@ typename HandleType<String>::MaybeType Object::ConvertToString(
if (IsBigInt(*input)) {
return BigInt::ToString(isolate, Cast<BigInt>(input));
}
-#if V8_ENABLE_WEBASSEMBLY
- // We generally don't let the WasmNull escape into the JavaScript world,
- // but some builtins may encounter it when called directly from Wasm code.
- if (IsWasmNull(*input)) {
- return isolate->factory()->null_string();
- }
-#endif
ASSIGN_RETURN_ON_EXCEPTION(
isolate, input,
JSReceiver::ToPrimitive(isolate, Cast<JSReceiver>(input),
@@ -1364,6 +1368,7 @@ MaybeHandle<Object> Object::GetProperty(LookupIterator* it,
isolate, it->GetHolder<JSDeferredModuleNamespace>());
RETURN_EXCEPTION_IF_EXCEPTION(isolate);
}
+ JSModuleNamespace::MaybeCountMissingDefaultWithStarExport(it);
continue;
}
case LookupIterator::ACCESSOR:
@@ -2144,6 +2149,10 @@ int HeapObject::SizeFromMap(Tagged<Map> map) const {
if (instance_type == WASM_STRUCT_TYPE) {
return WasmStruct::GcSafeSize(map);
}
+ if (instance_type == WASM_CUSTOM_MAP_TYPE) {
+ // Not a typo: WasmCustomMap reuses some WasmStruct infrastructure.
+ return WasmStruct::GcSafeSize(map);
+ }
if (instance_type == WASM_ARRAY_TYPE) {
return WasmArray::SizeFor(map, UncheckedCast<WasmArray>(this)->length());
}
@@ -4431,7 +4440,18 @@ void WriteChunkListToFlat(Tagged<FixedArray> chunk_list_head,
const uint32_t string_length = string->length();
DCHECK(string_length == 0 || sink < sink_end);
- String::WriteToFlat(string, sink, 0, string_length);
+ // WriteToFlat is not inlined even with PGO and ThinLTO, so we handle
+ // the common sequential cases here to avoid the call overhead.
+ StringShape shape(string);
+ if (shape.IsSequentialOneByte()) {
+ CopyChars(sink, Cast<SeqOneByteString>(string)->GetChars(no_gc),
+ string_length);
+ } else if (shape.IsSequentialTwoByte()) {
+ CopyChars(sink, Cast<SeqTwoByteString>(string)->GetChars(no_gc),
+ string_length);
+ } else {
+ String::WriteToFlat(string, sink, 0, string_length);
+ }
sink += string_length;
// Next string element, needs at least one separator preceding it.
diff --git a/deps/v8/src/objects/oddball-predicates-inl.h b/deps/v8/src/objects/oddball-predicates-inl.h
index ffb0040b073..ec170f7fd2a 100644
--- a/deps/v8/src/objects/oddball-predicates-inl.h
+++ b/deps/v8/src/objects/oddball-predicates-inl.h
@@ -72,6 +72,16 @@ inline bool IsAnyHoleNoSpaceCheck(Tagged<HeapObject> obj) {
return obj->map()->instance_type() == HOLE_TYPE;
#endif
}
+
+inline bool IsWasmNullNoSpaceCheck(Tagged<HeapObject> obj) {
+#if V8_STATIC_ROOTS_BOOL && V8_ENABLE_WEBASSEMBLY
+ return static_cast<Tagged_t>(obj.ptr()) == StaticReadOnlyRoot::kWasmNull;
+#elif V8_ENABLE_WEBASSEMBLY
+ return obj->map()->instance_type() == WASM_NULL_TYPE;
+#else
+ return false;
+#endif
+}
} // namespace detail
bool IsAnyHole(Tagged<Object> obj) {
@@ -91,6 +101,55 @@ bool IsAnyHole(Tagged<HeapObject> obj) {
return false;
}
+inline bool IsWasmNull(Tagged<Object> obj) {
+ Tagged<HeapObject> ho;
+ return TryCast<HeapObject>(obj, &ho) && IsWasmNull(ho);
+}
+
+inline bool IsWasmNull(Tagged<HeapObject> obj) {
+#if V8_ENABLE_WEBASSEMBLY
+ if (detail::IsWasmNullNoSpaceCheck(obj)) {
+#if V8_STATIC_ROOTS_BOOL
+ // Compressed object tests need to be done on a matching compression scheme.
+ // WasmNull is always in the main cage's RO space. If the object is in a
+ // different cage, IsWasmNullNoSpaceCheck may have returned a false positive
+ // due to address aliasing.
+ //
+ // Only check this after the WasmNull check succeeds, to make it cheaper in
+ // the common case that things aren't nulls.
+ if (V8_UNLIKELY(!obj.IsInMainCageBase())) {
+#if defined(DEBUG) && CONTIGUOUS_COMPRESSED_READ_ONLY_SPACE_BOOL
+ // When contiguous compressed RO space is enabled, the trusted space guard
+ // region is large enough (kContiguousReadOnlyReservationSize) to prevent
+ // aliasing with WasmNull. This DCHECK verifies that assumption.
+ DCHECK(obj.IsInTrustedCageBase());
+ DCHECK_GT(TrustedSpaceCompressionScheme::CompressObject(obj.ptr()),
+ StaticReadOnlyRoot::kWasmNull);
+#endif
+ // Object is not in main cage, so it can't be WasmNull (which is in RO
+ // space which is in the main cage).
+ return false;
+ }
+#endif // V8_STATIC_ROOTS_BOOL
+ return true;
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
+ return false;
+}
+
+// Returns true if {obj} is entirely unmapped, so even its map cannot be read.
+inline bool IsInaccessible(Tagged<HeapObject> obj) {
+#if V8_ENABLE_WEBASSEMBLY && \
+ (V8_STATIC_ROOTS_BOOL || V8_STATIC_ROOTS_GENERATION_BOOL)
+ // For now, only WasmNull has an inaccessible map, so this function only
+ // serves to document why we're checking for WasmNull in some places.
+ // More objects may be added here in the future.
+ return IsWasmNull(obj);
+#else
+ return false;
+#endif // V8_ENABLE_WEBASSEMBLY && ...
+}
+
bool IsNullOrUndefined(Tagged<Object> obj, EarlyReadOnlyRoots roots) {
return IsNull(obj, roots) || IsUndefined(obj, roots);
}
diff --git a/deps/v8/src/objects/oddball.h b/deps/v8/src/objects/oddball.h
index 457b5adad0e..d3e3a210c1c 100644
--- a/deps/v8/src/objects/oddball.h
+++ b/deps/v8/src/objects/oddball.h
@@ -15,6 +15,9 @@ namespace internal {
// The Oddball describes objects null, undefined, true, and false.
V8_OBJECT class Oddball : public PrimitiveHeapObject {
+ V8_IT_FIXED_VALUE(0x83);
+ V8_IT_ORDER(LAST);
+
public:
// [to_number_raw]: Cached raw to_number computed at startup.
DECL_PRIMITIVE_ACCESSORS(to_number_raw, double)
@@ -89,20 +92,27 @@ struct ObjectTraits<Oddball> {
};
V8_OBJECT class Null : public Oddball {
+ V8_IT_REUSE_PARENT;
} V8_OBJECT_END;
V8_OBJECT class Undefined : public Oddball {
+ V8_IT_REUSE_PARENT;
} V8_OBJECT_END;
V8_OBJECT class Boolean : public Oddball {
+ V8_IT_REUSE_PARENT;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
V8_INLINE bool ToBool(Isolate* isolate) const;
} V8_OBJECT_END;
V8_OBJECT class True : public Boolean {
+ V8_IT_REUSE_PARENT;
} V8_OBJECT_END;
V8_OBJECT class False : public Boolean {
+ V8_IT_REUSE_PARENT;
} V8_OBJECT_END;
} // namespace internal
diff --git a/deps/v8/src/objects/option-utils.cc b/deps/v8/src/objects/option-utils.cc
index 35abd199564..a6a1f141029 100644
--- a/deps/v8/src/objects/option-utils.cc
+++ b/deps/v8/src/objects/option-utils.cc
@@ -5,6 +5,7 @@
#include "src/objects/option-utils.h"
#include "src/numbers/conversions.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
namespace v8 {
diff --git a/deps/v8/src/objects/ordered-hash-table.cc b/deps/v8/src/objects/ordered-hash-table.cc
index 37a72bd2cdf..170c9f17457 100644
--- a/deps/v8/src/objects/ordered-hash-table.cc
+++ b/deps/v8/src/objects/ordered-hash-table.cc
@@ -9,6 +9,7 @@
#include "src/objects/heap-object-set-map-inl.h"
#include "src/objects/internal-index.h"
#include "src/objects/js-collection-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/roots/roots.h"
diff --git a/deps/v8/src/objects/ordered-hash-table.h b/deps/v8/src/objects/ordered-hash-table.h
index d6919f2bf37..617d6dc5c62 100644
--- a/deps/v8/src/objects/ordered-hash-table.h
+++ b/deps/v8/src/objects/ordered-hash-table.h
@@ -426,6 +426,8 @@ V8_OBJECT class V8_EXPORT_PRIVATE OrderedHashMap
// implementation -- methods using Derived-specific constants -- lives
// on the CRTP SmallOrderedHashTableImpl<Derived> below.
V8_OBJECT class SmallOrderedHashTable : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
static const int kMinCapacity = 4;
static const uint8_t kNotFound = 0xFF;
diff --git a/deps/v8/src/objects/pod-array.h b/deps/v8/src/objects/pod-array.h
index f346bb94cc9..5c69a5ded40 100644
--- a/deps/v8/src/objects/pod-array.h
+++ b/deps/v8/src/objects/pod-array.h
@@ -58,6 +58,8 @@ class PodArrayBase : public Super {
V8_OBJECT
template <class T>
class PodArray : public PodArrayBase<T, ByteArray> {
+ V8_IT_REUSE_PARENT;
+
public:
static Handle<PodArray<T>> New(
Isolate* isolate, uint32_t length,
@@ -70,6 +72,8 @@ class PodArray : public PodArrayBase<T, ByteArray> {
V8_OBJECT
template <class T>
class TrustedPodArray : public PodArrayBase<T, TrustedByteArray> {
+ V8_IT_REUSE_PARENT;
+
public:
static DirectHandle<TrustedPodArray<T>> New(Isolate* isolate,
uint32_t length);
diff --git a/deps/v8/src/objects/primitive-heap-object.h b/deps/v8/src/objects/primitive-heap-object.h
index 79b027de4a2..8c55977e65c 100644
--- a/deps/v8/src/objects/primitive-heap-object.h
+++ b/deps/v8/src/objects/primitive-heap-object.h
@@ -17,6 +17,8 @@ namespace internal {
// other than Smi. It doesn't carry any functionality but allows primitive
// classes to be identified in the type system.
V8_OBJECT class PrimitiveHeapObject : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
DECL_VERIFIER(PrimitiveHeapObject)
} V8_OBJECT_END;
diff --git a/deps/v8/src/objects/promise.h b/deps/v8/src/objects/promise.h
index 24c3c074804..94f50bad7d2 100644
--- a/deps/v8/src/objects/promise.h
+++ b/deps/v8/src/objects/promise.h
@@ -34,6 +34,8 @@ using PromiseReactionHandler =
// classes, which are used to represent either reactions, and we distinguish
// them by their instance types.
V8_OBJECT class PromiseReactionJobTask : public Microtask {
+ V8_IT_ABSTRACT;
+
public:
inline Tagged<Object> argument() const;
inline void set_argument(Tagged<Object> value,
diff --git a/deps/v8/src/objects/property-details.h b/deps/v8/src/objects/property-details.h
index 4458e731da4..0a128827c0e 100644
--- a/deps/v8/src/objects/property-details.h
+++ b/deps/v8/src/objects/property-details.h
@@ -241,8 +241,8 @@ class Representation {
static const int kDescriptorIndexBitCount = 10;
// The maximum bits to describe the first offset of the first field in an
-// object. Limits the header size of JSObjects.
-static const int kFirstInobjectPropertyOffsetBitCount = 7;
+// object. Limits the space available for the header and the embedder fields.
+static const int kFirstInobjectPropertyOffsetBitCount = 8;
// The maximum number of descriptors we want in a descriptor array. It should
// fit in a page and also the following should hold:
// kMaxNumberOfDescriptors + kFieldsAdded <= PropertyArray::kMaxLength.
diff --git a/deps/v8/src/objects/prototype-info-inl.h b/deps/v8/src/objects/prototype-info-inl.h
index 53c48ca1c46..eacf6bcfd88 100644
--- a/deps/v8/src/objects/prototype-info-inl.h
+++ b/deps/v8/src/objects/prototype-info-inl.h
@@ -123,7 +123,7 @@ Tagged<MaybeObject> PrototypeInfo::ObjectCreateMap(AcquireLoadTag tag) {
// Index 0 is the map for object create
Tagged<WeakArrayList> derived_list = Cast<WeakArrayList>(derived);
DCHECK_GT(derived_list->length().value(), 0);
- Tagged<MaybeObject> el = derived_list->Get(0);
+ Tagged<MaybeObject> el = derived_list->get(0, kAcquireLoad);
DCHECK(el.IsWeakOrCleared());
return el;
}
@@ -141,7 +141,7 @@ void PrototypeInfo::SetObjectCreateMap(DirectHandle<PrototypeInfo> info,
Tagged<WeakArrayList> derived = Cast<WeakArrayList>(info->derived_maps());
DCHECK(derived->Get(0).IsCleared());
DCHECK_GT(derived->length().value(), 0);
- derived->Set(0, MakeWeak(*map));
+ derived->set(0, MakeWeak(*map), kReleaseStore);
}
}
diff --git a/deps/v8/src/objects/prototype-info.h b/deps/v8/src/objects/prototype-info.h
index a60859da351..e89c7753126 100644
--- a/deps/v8/src/objects/prototype-info.h
+++ b/deps/v8/src/objects/prototype-info.h
@@ -112,6 +112,8 @@ V8_OBJECT class PrototypeInfo : public Struct {
// A growing array with an additional API for marking slots "empty". When adding
// new elements, we reuse the empty slots instead of growing the array.
class V8_EXPORT_PRIVATE PrototypeUsers : public WeakArrayList {
+ V8_IT_REUSE_PARENT;
+
public:
static Handle<WeakArrayList> Add(Isolate* isolate,
Handle<WeakArrayList> array,
diff --git a/deps/v8/src/objects/regexp-match-info.h b/deps/v8/src/objects/regexp-match-info.h
index c092fbf61c7..76a621aaf3d 100644
--- a/deps/v8/src/objects/regexp-match-info.h
+++ b/deps/v8/src/objects/regexp-match-info.h
@@ -23,8 +23,9 @@ class String;
// all the captured substrings), the invariant is that there are at least two
// capture indices. The array also contains the subject string for the last
// successful match.
-V8_OBJECT class RegExpMatchInfo : public TaggedArrayBase<RegExpMatchInfo, Smi> {
- using Super = TaggedArrayBase<RegExpMatchInfo, Smi>;
+V8_OBJECT class RegExpMatchInfo
+ : public TaggedArrayBase<RegExpMatchInfo, Smi, FixedArrayBase> {
+ using Super = TaggedArrayBase<RegExpMatchInfo, Smi, FixedArrayBase>;
public:
static constexpr RootIndex kMapRootIndex = RootIndex::kRegExpMatchInfoMap;
diff --git a/deps/v8/src/objects/scope-info-inl.h b/deps/v8/src/objects/scope-info-inl.h
index b658631bd3f..d4d690e17d9 100644
--- a/deps/v8/src/objects/scope-info-inl.h
+++ b/deps/v8/src/objects/scope-info-inl.h
@@ -149,13 +149,18 @@ int ScopeInfo::ModuleVariablesOffset() const {
return ModuleInfoOffset() + (is_module ? kTaggedSize : 0);
}
-int ScopeInfo::DependentCodeOffset() const {
+int ScopeInfo::ModuleVariablesHashtableOffset() const {
const bool is_module =
ScopeTypeBits::decode(Flags()) == ScopeType::MODULE_SCOPE;
const int mod_var_count = is_module ? module_variable_count() : 0;
return ModuleVariablesOffset() + mod_var_count * sizeof(ModuleVariableInfo);
}
+int ScopeInfo::DependentCodeOffset() const {
+ return ModuleVariablesHashtableOffset() +
+ (HasModuleVariablesHashtable() ? kTaggedSize : 0);
+}
+
int ScopeInfo::UnusedParameterBitsOffset() const {
const bool has_dependent_code = SloppyEvalCanExtendVarsBit::decode(Flags());
return DependentCodeOffset() + (has_dependent_code ? kTaggedSize : 0);
@@ -386,6 +391,26 @@ void ScopeInfo::set_module_variables_properties(int i, int value) {
data()[slot].store(this, Smi::From31BitPattern(value));
}
+bool ScopeInfo::HasModuleVariablesHashtable() const {
+ return ScopeTypeBits::decode(Flags()) == ScopeType::MODULE_SCOPE &&
+ module_variable_count() >= kScopeInfoMaxInlinedLocalNamesSize;
+}
+
+Tagged<NameToIndexHashTable> ScopeInfo::module_variables_hashtable() const {
+ DCHECK(HasModuleVariablesHashtable());
+ const int slot =
+ scope_info_internal::DataSlotIndex(ModuleVariablesHashtableOffset());
+ return Cast<NameToIndexHashTable>(data()[slot].load());
+}
+
+void ScopeInfo::set_module_variables_hashtable(
+ Tagged<NameToIndexHashTable> value, WriteBarrierMode mode) {
+ DCHECK(HasModuleVariablesHashtable());
+ const int slot =
+ scope_info_internal::DataSlotIndex(ModuleVariablesHashtableOffset());
+ data()[slot].store(this, value, mode);
+}
+
Tagged<DependentCode> ScopeInfo::dependent_code() const {
DCHECK(SloppyEvalCanExtendVarsBit::decode(Flags()));
const int slot = scope_info_internal::DataSlotIndex(DependentCodeOffset());
diff --git a/deps/v8/src/objects/scope-info.cc b/deps/v8/src/objects/scope-info.cc
index 1037ed7d3c3..7462ad88643 100644
--- a/deps/v8/src/objects/scope-info.cc
+++ b/deps/v8/src/objects/scope-info.cc
@@ -47,7 +47,7 @@ bool NameToIndexHashTableEquals(Tagged<NameToIndexHashTable> a,
} // namespace
// TODO(crbug.com/401059828): make it DEBUG only, once investigation is over.
-bool ScopeInfo::Equals(Tagged<ScopeInfo> other, bool is_live_edit_compare,
+bool ScopeInfo::Equals(Tagged<ScopeInfo> other,
int* out_last_checked_field) const {
if (length() != other->length()) return false;
// Fixed header fields.
@@ -57,21 +57,15 @@ bool ScopeInfo::Equals(Tagged<ScopeInfo> other, bool is_live_edit_compare,
if (out_last_checked_field) *out_last_checked_field = kParameterCount;
if (context_local_count() != other->context_local_count()) return false;
if (out_last_checked_field) *out_last_checked_field = kContextLocalCount;
- if (!is_live_edit_compare) {
- if (position_info_start() != other->position_info_start()) return false;
- if (out_last_checked_field) *out_last_checked_field = kPositionInfoStart;
- if (position_info_end() != other->position_info_end()) return false;
- if (out_last_checked_field) *out_last_checked_field = kPositionInfoEnd;
- }
+ if (position_info_start() != other->position_info_start()) return false;
+ if (out_last_checked_field) *out_last_checked_field = kPositionInfoStart;
+ if (position_info_end() != other->position_info_end()) return false;
+ if (out_last_checked_field) *out_last_checked_field = kPositionInfoEnd;
// Variable-part tail.
- const int inferred_function_name_index = InferredFunctionNameIndex();
for (int index = 0; index < length(); ++index) {
if (out_last_checked_field) {
*out_last_checked_field = kVariablePartStart + index;
}
- if (is_live_edit_compare && index == inferred_function_name_index) {
- continue;
- }
Tagged<Object> entry = get(index);
Tagged<Object> other_entry = other->get(index);
if (IsSmi(entry)) {
@@ -86,13 +80,11 @@ bool ScopeInfo::Equals(Tagged<ScopeInfo> other, bool is_live_edit_compare,
return false;
}
} else if (IsScopeInfo(entry)) {
- if (!is_live_edit_compare && !Cast<ScopeInfo>(entry)->Equals(
- Cast<ScopeInfo>(other_entry), false)) {
+ if (!Cast<ScopeInfo>(entry)->Equals(Cast<ScopeInfo>(other_entry))) {
return false;
}
} else if (IsSourceTextModuleInfo(entry)) {
- if (!is_live_edit_compare &&
- !Cast<SourceTextModuleInfo>(entry)->Equals(
+ if (!Cast<SourceTextModuleInfo>(entry)->Equals(
Cast<SourceTextModuleInfo>(other_entry))) {
return false;
}
@@ -103,9 +95,6 @@ bool ScopeInfo::Equals(Tagged<ScopeInfo> other, bool is_live_edit_compare,
}
} else if (IsDependentCode(entry)) {
DCHECK(IsDependentCode(other_entry));
- // Ignore the dependent code field since all the code have to be
- // deoptimized anyway in case of a live-edit.
-
} else if (IsNameToIndexHashTable(entry)) {
if (!NameToIndexHashTableEquals(
Cast<NameToIndexHashTable>(entry),
@@ -237,6 +226,12 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
has_inlined_local_names ? context_local_count : 1;
const int has_dependent_code = sloppy_eval_can_extend_vars;
+ // Module scopes with many module variables also carry a name -> entry
+ // hash table so ModuleIndex() need not scan the entries linearly (same
+ // threshold as the context-local names hashtable).
+ const bool has_module_vars_hashtable =
+ scope->is_module_scope() &&
+ module_vars_count >= kScopeInfoMaxInlinedLocalNamesSize;
const int length =
local_names_container_size + context_local_count +
(should_save_class_variable ? 1 : 0) +
@@ -245,7 +240,8 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
(scope->is_module_scope()
? 2 + kModuleVariableEntryLength * module_vars_count
: 0) +
- (has_dependent_code ? 1 : 0) + (scope->is_function_scope() ? 1 : 0);
+ (has_module_vars_hashtable ? 1 : 0) + (has_dependent_code ? 1 : 0) +
+ (scope->is_function_scope() ? 1 : 0);
// Create hash table if local names are not inlined.
Handle<NameToIndexHashTable> local_names_hashtable;
@@ -253,6 +249,11 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
local_names_hashtable = NameToIndexHashTable::New(
isolate, context_local_count, AllocationType::kOld);
}
+ Handle<NameToIndexHashTable> module_vars_hashtable;
+ if (has_module_vars_hashtable) {
+ module_vars_hashtable = NameToIndexHashTable::New(
+ isolate, module_vars_count, AllocationType::kOld);
+ }
Handle<ScopeInfo> scope_info_handle =
isolate->factory()->NewScopeInfo(length);
@@ -315,6 +316,7 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
int context_local_info_base =
context_local_base + local_names_container_size;
int module_var_entry = scope_info->ModuleVariablesIndex();
+ int module_var_number = 0;
for (Variable* var : *scope->locals()) {
switch (var->location()) {
@@ -388,7 +390,16 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
module_var_entry +
offsetof(ModuleVariableInfo, properties) / kTaggedSize,
Smi::FromInt(properties));
+ if (has_module_vars_hashtable) {
+ // The table was sized for module_vars_count entries, so Add()
+ // never reallocates (and thus never allocates under no_gc).
+ Handle<NameToIndexHashTable> new_table = NameToIndexHashTable::Add(
+ isolate, module_vars_hashtable, var->name(), module_var_number);
+ DCHECK_EQ(*new_table, *module_vars_hashtable);
+ USE(new_table);
+ }
module_var_entry += kModuleVariableEntryLength;
+ ++module_var_number;
break;
}
default:
@@ -467,6 +478,13 @@ Handle<ScopeInfo> ScopeInfo::Create(IsolateT* isolate, Zone* zone, Scope* scope,
DCHECK_EQ(index, scope_info->ModuleVariablesIndex());
// The variable entries themselves have already been written above.
index += kModuleVariableEntryLength * module_vars_count;
+ DCHECK_EQ(index, scope_info->ModuleVariablesHashtableIndex());
+ DCHECK_EQ(has_module_vars_hashtable,
+ scope_info->HasModuleVariablesHashtable());
+ if (has_module_vars_hashtable) {
+ DCHECK_EQ(module_var_number, module_vars_count);
+ scope_info->set(index++, *module_vars_hashtable);
+ }
}
DCHECK_EQ(index, scope_info->DependentCodeIndex());
@@ -995,7 +1013,6 @@ Tagged<String> ScopeInfo::ContextInlinedLocalName(int var) const {
return context_local_names(var);
}
-
VariableMode ScopeInfo::ContextLocalMode(int var) const {
int value = context_local_infos(var);
return VariableModeBits::decode(value);
@@ -1037,6 +1054,7 @@ MaybeAssignedFlag ScopeInfo::ContextLocalMaybeAssignedFlag(int var) const {
return MaybeAssignedFlagBit::decode(value);
}
+// LINT.IfChange(VariableIsSynthetic)
// static
bool ScopeInfo::VariableIsSynthetic(Tagged<String> name) {
// There's currently no flag stored on the ScopeInfo to indicate that a
@@ -1046,6 +1064,7 @@ bool ScopeInfo::VariableIsSynthetic(Tagged<String> name) {
return name->length() == 0 || name->Get(0) == '.' || name->Get(0) == '#' ||
name->Equals(GetReadOnlyRoots().this_string());
}
+// LINT.ThenChange(/src/debug/debug-scope-info.cc:VariableIsSynthetic)
int ScopeInfo::ModuleVariableCount() const {
DCHECK_EQ(scope_type(), MODULE_SCOPE);
@@ -1063,6 +1082,17 @@ int ScopeInfo::ModuleIndex(Tagged<String> name, VariableMode* mode,
DCHECK_NOT_NULL(init_flag);
DCHECK_NOT_NULL(maybe_assigned_flag);
+ if (HasModuleVariablesHashtable()) {
+ int i = module_variables_hashtable()->Lookup(name);
+ if (i == -1) return 0;
+ DCHECK_LT(i, module_variable_count());
+ DCHECK(name->Equals(module_variables_name(i)));
+ int index;
+ ModuleVariable(i, nullptr, &index, mode, init_flag, maybe_assigned_flag,
+ initializer_position);
+ return index;
+ }
+
int module_vars_count = module_variable_count();
for (int i = 0; i < module_vars_count; ++i) {
Tagged<String> var_name = module_variables_name(i);
@@ -1219,6 +1249,10 @@ int ScopeInfo::ModuleVariablesIndex() const {
return ConvertOffsetToIndex(ModuleVariablesOffset());
}
+int ScopeInfo::ModuleVariablesHashtableIndex() const {
+ return ConvertOffsetToIndex(ModuleVariablesHashtableOffset());
+}
+
void ScopeInfo::ModuleVariable(int i, Tagged<String>* name, int* index,
VariableMode* mode,
InitializationFlag* init_flag,
@@ -1443,6 +1477,20 @@ Tagged<FixedArray> SourceTextModuleInfo::RegularExportExportNames(int i) const {
i * kRegularExportLength + kRegularExportExportNamesOffset));
}
+bool SourceTextModuleInfo::HasStarExports() const {
+ DisallowGarbageCollection no_gc;
+ Tagged<FixedArray> exports = special_exports();
+ const uint32_t length = exports->ulength().value();
+ for (uint32_t i = 0; i < length; ++i) {
+ // Star exports are the only special exports without a name.
+ if (IsUndefined(
+ Cast<SourceTextModuleInfoEntry>(exports->get(i))->export_name())) {
+ return true;
+ }
+ }
+ return false;
+}
+
const char* ToString(ScopeType type) {
switch (type) {
case ScopeType::EVAL_SCOPE:
diff --git a/deps/v8/src/objects/scope-info.h b/deps/v8/src/objects/scope-info.h
index f60bbba01a3..5a8754a06b7 100644
--- a/deps/v8/src/objects/scope-info.h
+++ b/deps/v8/src/objects/scope-info.h
@@ -304,14 +304,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
// come from debug evaluate but are different to IsDebugEvaluateScope().
bool IsReplModeScope() const;
- // For LiveEdit we ignore:
- // - position info: "unchanged" functions are allowed to move in a script
- // - module info: SourceTextModuleInfo::Equals compares exact FixedArray
- // addresses which will never match for separate instances.
- // - outer scope info: LiveEdit already analyses outer scopes of unchanged
- // functions. Also checking it here will break in really subtle cases
- // e.g. changing a let to a const in an outer function, which is fine.
- bool Equals(Tagged<ScopeInfo> other, bool is_live_edit_compare = false,
+ bool Equals(Tagged<ScopeInfo> other,
int* out_last_checked_field = nullptr) const;
template <typename IsolateT>
@@ -421,6 +414,19 @@ V8_OBJECT class ScopeInfo : public HeapObject {
inline int module_variables_properties(int i) const;
inline void set_module_variables_properties(int i, int value);
+ // Present only for module scopes with at least
+ // kScopeInfoMaxInlinedLocalNamesSize module variables: maps a module
+ // variable's name to its entry index in module_variables, so ModuleIndex()
+ // does not have to scan the entries linearly. (Bundlers routinely emit
+ // modules with hundreds of imported/exported bindings, and every free
+ // variable of every lazily compiled function inside them is resolved
+ // through ModuleIndex().)
+ inline bool HasModuleVariablesHashtable() const;
+ inline Tagged<NameToIndexHashTable> module_variables_hashtable() const;
+ inline void set_module_variables_hashtable(
+ Tagged<NameToIndexHashTable> value,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
inline Tagged<DependentCode> dependent_code() const;
inline void set_dependent_code(Tagged<DependentCode> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
@@ -441,6 +447,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
inline int OuterScopeInfoOffset() const;
inline int ModuleInfoOffset() const;
inline int ModuleVariablesOffset() const;
+ inline int ModuleVariablesHashtableOffset() const;
inline int DependentCodeOffset() const;
inline int UnusedParameterBitsOffset() const;
@@ -489,6 +496,7 @@ V8_OBJECT class ScopeInfo : public HeapObject {
int ModuleInfoIndex() const;
int ModuleVariableCountIndex() const;
int ModuleVariablesIndex() const;
+ int ModuleVariablesHashtableIndex() const;
int DependentCodeIndex() const;
int UnusedParameterBitsIndex() const;
@@ -546,7 +554,6 @@ V8_OBJECT class ScopeInfo : public HeapObject {
friend class ScopeIterator;
friend class CodeStubAssembler;
friend class TorqueGeneratedBitFieldAsserts;
- friend std::ostream& operator<<(std::ostream& os, VariableAllocationInfo var);
public:
// Relaxed-atomic flags word (ScopeFlags bit layout).
@@ -590,7 +597,8 @@ inline constexpr int ScopeInfo::ConvertOffsetToIndex(int offset) {
return index;
}
-std::ostream& operator<<(std::ostream& os, VariableAllocationInfo var);
+V8_EXPORT_PRIVATE std::ostream& operator<<(std::ostream& os,
+ VariableAllocationInfo var);
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/scope-info.tq b/deps/v8/src/objects/scope-info.tq
index 95273db75f2..64647912f39 100644
--- a/deps/v8/src/objects/scope-info.tq
+++ b/deps/v8/src/objects/scope-info.tq
@@ -185,6 +185,15 @@ extern class ScopeInfo extends HeapObject {
module_variables[flags.scope_type == ScopeType::MODULE_SCOPE ? module_variable_count : 0]:
ModuleVariable;
+ // Maps a module variable's name to its index in module_variables. Only
+ // present when a module scope has enough module variables that a linear
+ // scan in ModuleIndex() would be costly (same threshold as the context
+ // local names hashtable).
+ module_variables_hashtable?
+ [flags.scope_type == ScopeType::MODULE_SCOPE ?
+ kMaxInlinedLocalNamesSize <= Convert<intptr>(module_variable_count) :
+ false]: NameToIndexHashTable;
+
// EmptyContextExtension-dependent code objects.
dependent_code?[flags.sloppy_eval_can_extend_vars]: DependentCode;
diff --git a/deps/v8/src/objects/script-inl.h b/deps/v8/src/objects/script-inl.h
index 270bb3d5886..bc3d052a06e 100644
--- a/deps/v8/src/objects/script-inl.h
+++ b/deps/v8/src/objects/script-inl.h
@@ -9,7 +9,7 @@
// Include the non-inl header before the rest of the headers.
#include "src/objects/heap-object-inl.h"
-#include "src/objects/managed.h"
+#include "src/objects/managed-inl.h"
#include "src/objects/smi-inl.h"
#include "src/objects/string-inl.h"
#include "src/objects/struct-inl.h"
@@ -95,7 +95,8 @@ Tagged<Object> Script::wasm_managed_native_module() const {
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, Foreign>>(value), mode);
+ eval_from_position_.store(this, Cast<UnionOf<Smi, CppGCManagedBase>>(value),
+ mode);
}
Tagged<WeakArrayList> Script::wasm_weak_instance_list() const {
@@ -110,7 +111,30 @@ void Script::set_wasm_weak_instance_list(Tagged<WeakArrayList> value,
#endif // V8_ENABLE_WEBASSEMBLY
bool Script::is_wrapped() const {
- return IsFixedArray(eval_from_shared_or_wrapped_arguments());
+ bool is_wrapped = compilation_kind() == CompilationKind::kWrapped;
+ DCHECK_EQ(is_wrapped, IsFixedArray(eval_from_shared_or_wrapped_arguments()));
+ return is_wrapped;
+}
+
+bool Script::is_eval() const {
+ return compilation_kind() == CompilationKind::kDirectEval ||
+ compilation_kind() == CompilationKind::kIndirectEval;
+}
+
+bool Script::has_eval_origin() const {
+ return is_eval() ||
+ compilation_kind() == CompilationKind::kFunctionConstructor;
+}
+
+bool Script::is_host() const {
+ return compilation_kind() == CompilationKind::kHost;
+}
+
+LanguageMode Script::outer_language_mode() const {
+ return OuterLanguageModeBit::decode(flags());
+}
+void Script::set_outer_language_mode(LanguageMode mode) {
+ set_flags(OuterLanguageModeBit::update(flags(), mode));
}
bool Script::has_eval_from_shared() const {
@@ -119,6 +143,7 @@ bool Script::has_eval_from_shared() const {
void Script::set_wrapped_arguments(Tagged<FixedArray> value,
WriteBarrierMode mode) {
+ DCHECK_EQ(compilation_kind(), CompilationKind::kWrapped);
DCHECK(!has_eval_from_shared());
set_eval_from_shared_or_wrapped_arguments(value, mode);
}
@@ -176,8 +201,9 @@ bool Script::has_wasm_breakpoint_infos() const {
wasm_breakpoint_infos()->ulength().value() > 0;
}
-Managed<wasm::NativeModule>::Ptr Script::wasm_native_module() const {
- return Cast<Managed<wasm::NativeModule>>(wasm_managed_native_module())->ptr();
+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()); }
@@ -189,7 +215,7 @@ void Script::set_break_on_entry(bool value) {
uint32_t Script::flags() const {
// Use a relaxed load since background compile threads read the
- // {compilation_type()} while the foreground thread might update e.g. the
+ // {compilation_kind()} while the foreground thread might update e.g. the
// {origin_options}.
return flags_.Relaxed_Load().value();
}
@@ -199,12 +225,13 @@ void Script::set_flags(uint32_t new_flags) {
flags_.Relaxed_Store(this, Smi::FromInt(new_flags));
}
-Script::CompilationType Script::compilation_type() const {
- return CompilationTypeBit::decode(flags());
+Script::CompilationKind Script::compilation_kind() const {
+ return CompilationKindBits::decode(flags());
}
-void Script::set_compilation_type(CompilationType type) {
- set_flags(CompilationTypeBit::update(flags(), type));
+void Script::set_compilation_kind(CompilationKind kind) {
+ set_flags(CompilationKindBits::update(flags(), kind));
}
+
Script::CompilationState Script::compilation_state() {
return CompilationStateBit::decode(flags());
}
diff --git a/deps/v8/src/objects/script.cc b/deps/v8/src/objects/script.cc
index 21cce51f8ca..f7378a63183 100644
--- a/deps/v8/src/objects/script.cc
+++ b/deps/v8/src/objects/script.cc
@@ -31,16 +31,6 @@ const char* ToString(Script::Type type) {
UNREACHABLE();
}
-const char* ToString(Script::CompilationType type) {
- switch (type) {
- case Script::CompilationType::kHost:
- return "host";
- case Script::CompilationType::kEval:
- return "eval";
- }
- UNREACHABLE();
-}
-
const char* ToString(Script::CompilationState type) {
switch (type) {
case Script::CompilationState::kInitial:
@@ -51,6 +41,22 @@ const char* ToString(Script::CompilationState type) {
UNREACHABLE();
}
+const char* ToString(Script::CompilationKind type) {
+ switch (type) {
+ case Script::CompilationKind::kHost:
+ return "host";
+ case Script::CompilationKind::kDirectEval:
+ return "direct-eval";
+ case Script::CompilationKind::kIndirectEval:
+ return "indirect-eval";
+ case Script::CompilationKind::kFunctionConstructor:
+ return "function-constructor";
+ case Script::CompilationKind::kWrapped:
+ return "wrapped";
+ }
+ UNREACHABLE();
+}
+
template <typename IsolateT>
MaybeHandle<SharedFunctionInfo> Script::FindSharedFunctionInfo(
DirectHandle<Script> script, IsolateT* isolate,
@@ -101,7 +107,7 @@ Tagged<Script> Script::Iterator::Next() {
// static
int Script::GetEvalPosition(Isolate* isolate, DirectHandle<Script> script) {
- DCHECK(script->compilation_type() == Script::CompilationType::kEval);
+ DCHECK(script->has_eval_origin());
int position = script->eval_from_position();
if (position < 0) {
// Due to laziness, the position may not have been translated from code
@@ -467,7 +473,8 @@ bool Script::GetPositionInfo(int position, PositionInfo* info,
// For wasm, we use the byte offset as the column.
if (type() == Script::Type::kWasm) {
DCHECK_LE(0, position);
- Managed<wasm::NativeModule>::Ptr native_module = wasm_native_module();
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
+ wasm_native_module();
const wasm::WasmModule* module = native_module->module();
if (module->functions.empty()) return false;
info->line = 0;
diff --git a/deps/v8/src/objects/script.h b/deps/v8/src/objects/script.h
index b7819b1fdc7..a00960ed486 100644
--- a/deps/v8/src/objects/script.h
+++ b/deps/v8/src/objects/script.h
@@ -51,12 +51,18 @@ V8_OBJECT class Script : public Struct {
kInspector = 4
};
- // Script compilation types.
- enum class CompilationType { kHost = 0, kEval = 1 };
-
// Script compilation state.
enum class CompilationState { kInitial = 0, kCompiled = 1 };
+ // Script compilation kinds.
+ enum class CompilationKind {
+ kHost = 0,
+ kDirectEval = 1,
+ kIndirectEval = 2,
+ kFunctionConstructor = 3,
+ kWrapped = 4,
+ };
+
// [source]: the script source.
inline Tagged<UnionOf<String, Undefined>> source() const;
inline void set_source(Tagged<UnionOf<String, Undefined>> value,
@@ -112,6 +118,25 @@ V8_OBJECT class Script : public Struct {
// Whether the script is implicitly wrapped in a function.
inline bool is_wrapped() const;
+ // Whether the script was compiled via eval (direct or indirect).
+ inline bool is_eval() const;
+
+ // Whether the script originated from an eval or Function constructor.
+ inline bool has_eval_origin() const;
+
+ // Whether the script is a top-level host script.
+ inline bool is_host() const;
+
+ // [compilation_kind]: how the script was compiled (host, direct/indirect
+ // eval, Function constructor, or wrapped). Encoded in the 'flags' field.
+ inline CompilationKind compilation_kind() const;
+ inline void set_compilation_kind(CompilationKind kind);
+
+ // [outer_language_mode]: the lexical language mode of the enclosing scope.
+ // Encoded in the 'flags' field.
+ inline LanguageMode outer_language_mode() const;
+ inline void set_outer_language_mode(LanguageMode mode);
+
// Whether the eval_from_shared field is set with a shared function info
// for the eval site.
inline bool has_eval_from_shared() const;
@@ -150,7 +175,7 @@ V8_OBJECT class Script : public Struct {
inline void set_wasm_managed_native_module(
Tagged<Object> value, WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Managed<wasm::NativeModule>::Ptr wasm_native_module() const;
+ inline 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.
@@ -174,11 +199,6 @@ V8_OBJECT class Script : public Struct {
inline uint32_t flags() const;
inline void set_flags(uint32_t new_flags);
- // [compilation_type]: how the script was compiled. Encoded in the
- // 'flags' field.
- inline CompilationType compilation_type() const;
- inline void set_compilation_type(CompilationType type);
-
inline bool produce_compile_hints() const;
inline void set_produce_compile_hints(bool produce_compile_hints);
@@ -367,7 +387,7 @@ V8_OBJECT class Script : public Struct {
TaggedMember<UnionOf<FixedArray, Smi>> line_ends_;
TaggedMember<Smi> id_;
TaggedMember<Object> eval_from_shared_or_wrapped_arguments_;
- TaggedMember<UnionOf<Smi, Foreign>> eval_from_position_;
+ TaggedMember<UnionOf<Smi, CppGCManagedBase>> eval_from_position_;
TaggedMember<UnionOf<ScopeInfo, Undefined>> eval_from_scope_info_;
TaggedMember<UnionOf<WeakFixedArray, WeakArrayList>> infos_;
TaggedMember<UnionOf<ArrayList, Undefined>> compiled_lazy_function_positions_;
@@ -393,15 +413,16 @@ V8_OBJECT class Script : public Struct {
friend class TorqueGeneratedBitFieldAsserts;
// Bit positions in the flags field.
- using CompilationTypeBit =
- base::BitField<Script::CompilationType, 0, 1, uint32_t>;
+ using CompilationKindBits =
+ base::BitField<Script::CompilationKind, 0, 3, uint32_t>;
using CompilationStateBit =
- CompilationTypeBit::Next<Script::CompilationState, 1>;
+ CompilationKindBits::Next<Script::CompilationState, 1>;
using IsReplModeBit = CompilationStateBit::Next<bool, 1>;
using OriginOptionsBits = IsReplModeBit::Next<int32_t, 4>;
using BreakOnEntryBit = OriginOptionsBits::Next<bool, 1>;
using ProduceCompileHintsBit = BreakOnEntryBit::Next<bool, 1>;
using DeserializedBit = ProduceCompileHintsBit::Next<bool, 1>;
+ using OuterLanguageModeBit = DeserializedBit::Next<LanguageMode, 1>;
template <typename IsolateT>
EXPORT_TEMPLATE_DECLARE(V8_EXPORT_PRIVATE)
@@ -410,8 +431,8 @@ V8_OBJECT class Script : public Struct {
} V8_OBJECT_END;
V8_EXPORT_PRIVATE const char* ToString(Script::Type type);
-V8_EXPORT_PRIVATE const char* ToString(Script::CompilationType type);
V8_EXPORT_PRIVATE const char* ToString(Script::CompilationState type);
+V8_EXPORT_PRIVATE const char* ToString(Script::CompilationKind type);
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/objects/script.tq b/deps/v8/src/objects/script.tq
index 15329dafb03..77e68e24da2 100644
--- a/deps/v8/src/objects/script.tq
+++ b/deps/v8/src/objects/script.tq
@@ -2,12 +2,12 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-type CompilationType extends int32 constexpr 'Script::CompilationType';
type CompilationState extends int32 constexpr 'Script::CompilationState';
+type CompilationKind extends int32 constexpr 'Script::CompilationKind';
@cppScope('Script')
bitfield struct ScriptFlags extends uint31 {
- compilation_type: CompilationType: 1 bit;
+ compilation_kind: CompilationKind: 3 bit;
compilation_state: CompilationState: 1 bit;
is_repl_mode: bool: 1 bit;
origin_options: int32: 4 bit;
@@ -15,6 +15,7 @@ bitfield struct ScriptFlags extends uint31 {
break_on_entry: bool: 1 bit;
produce_compile_hints: bool: 1 bit;
deserialized: bool: 1 bit;
+ outer_language_mode: LanguageMode: 1 bit;
}
@cppObjectLayoutDefinition
@@ -48,7 +49,8 @@ extern class Script extends Struct {
// the arguments.
eval_from_shared_or_wrapped_arguments: SharedFunctionInfo|FixedArray|
Undefined;
- eval_from_position: Smi|Foreign; // Smi or Managed<wasm::NativeModule>
+ eval_from_position: Smi|
+ CppGCManagedBase; // Smi or CppGCManaged<wasm::NativeModule>
eval_from_scope_info: ScopeInfo|Undefined;
infos: WeakFixedArray|WeakArrayList;
diff --git a/deps/v8/src/objects/shared-function-info-inl.h b/deps/v8/src/objects/shared-function-info-inl.h
index 5b001304389..b3a8d4c7f3b 100644
--- a/deps/v8/src/objects/shared-function-info-inl.h
+++ b/deps/v8/src/objects/shared-function-info-inl.h
@@ -28,7 +28,6 @@
#include "src/objects/heap-object-set-map-inl.h"
#include "src/objects/hole.h"
#include "src/objects/instance-type-inl.h"
-#include "src/objects/objects-inl.h"
#include "src/objects/oddball-predicates-inl.h"
#include "src/objects/scope-info-inl.h"
#include "src/objects/script-inl.h"
@@ -384,8 +383,7 @@ void SharedFunctionInfo::SetName(Tagged<String> name) {
bool SharedFunctionInfo::is_script() const {
return scope_info(kAcquireLoad)->is_script_scope() &&
- Cast<Script>(script())->compilation_type() ==
- Script::CompilationType::kHost;
+ Cast<Script>(script())->is_host();
}
bool SharedFunctionInfo::needs_script_context() const {
@@ -503,8 +501,6 @@ BIT_FIELD_ACCESSORS(SharedFunctionInfo, relaxed_flags, properties_are_final,
BIT_FIELD_ACCESSORS(SharedFunctionInfo, relaxed_flags,
private_name_lookup_skips_outer_class,
SharedFunctionInfo::PrivateNameLookupSkipsOuterClassBit)
-BIT_FIELD_ACCESSORS(SharedFunctionInfo, relaxed_flags, live_edited,
- SharedFunctionInfo::LiveEditedBit)
BIT_FIELD_ACCESSORS(SharedFunctionInfo, relaxed_flags, is_hoisted_in_context,
SharedFunctionInfo::IsHoistedInContextBit)
@@ -1122,8 +1118,7 @@ void SharedFunctionInfo::set_builtin_id(Builtin builtin) {
}
bool SharedFunctionInfo::HasUncompiledData(IsolateForSandbox isolate) const {
- return !HasUnpublishedTrustedData(isolate) &&
- IsUncompiledData(GetTrustedData(isolate));
+ return IsUncompiledData(GetTrustedData(isolate));
}
Tagged<UncompiledData> SharedFunctionInfo::uncompiled_data(
diff --git a/deps/v8/src/objects/shared-function-info.cc b/deps/v8/src/objects/shared-function-info.cc
index 7702d3b7d63..1d731687dc6 100644
--- a/deps/v8/src/objects/shared-function-info.cc
+++ b/deps/v8/src/objects/shared-function-info.cc
@@ -30,6 +30,7 @@ V8_EXPORT_PRIVATE constexpr Tagged<Smi>
Tagged<Union<Smi, TrustedObject>> SharedFunctionInfo::GetTrustedData(
IsolateForSandbox isolate) const {
+ if (HasUnpublishedTrustedData(isolate)) return Smi::zero();
return TrustedPointerField::ReadMaybeEmptyTrustedPointerField<
kTrustedDataIndirectPointerRange>(
Tagged<HeapObject>(this),
@@ -222,17 +223,17 @@ void SharedFunctionInfo::SetScript(IsolateForSandbox isolate,
// Remove shared function info from old script's list.
Tagged<Script> old_script = Cast<Script>(script());
-
- // Due to liveedit, it might happen that the old_script doesn't know
- // about the SharedFunctionInfo, so we have to guard against that.
- Tagged<WeakFixedArray> infos = old_script->infos();
- if (static_cast<uint32_t>(function_literal_id) < infos->ulength().value()) {
- Tagged<MaybeObject> raw = old_script->infos()->get(function_literal_id);
- Tagged<HeapObject> heap_object;
- if (raw.GetHeapObjectIfWeak(&heap_object) && heap_object == this) {
- old_script->infos()->set(function_literal_id, roots.undefined_value());
- }
+ Tagged<WeakFixedArray> list = old_script->infos();
+#ifdef DEBUG
+ DCHECK_LT(static_cast<uint32_t>(function_literal_id),
+ list->ulength().value());
+ Tagged<MaybeObject> maybe_object = list->get(function_literal_id);
+ Tagged<HeapObject> heap_object;
+ if (maybe_object.GetHeapObjectIfWeak(&heap_object)) {
+ DCHECK_EQ(heap_object, this);
}
+#endif
+ list->set(function_literal_id, roots.undefined_value());
}
// Finally set new script.
@@ -819,43 +820,6 @@ int SharedFunctionInfo::EndPosition() const {
return kNoSourcePosition;
}
-void SharedFunctionInfo::UpdateFromFunctionLiteralForLiveEdit(
- IsolateForSandbox isolate, FunctionLiteral* lit) {
- Tagged<Object> maybe_scope_info = name_or_scope_info(kAcquireLoad);
- // TODO(crbug.com/401059828): remove once crashes are gone.
- set_live_edited(true);
-
- if (IsScopeInfo(maybe_scope_info)) {
- // Updating the ScopeInfo is safe since they are identical modulo
- // source positions.
- Tagged<ScopeInfo> new_scope_info = *lit->scope()->scope_info();
- Tagged<ScopeInfo> old_scope_info = Cast<ScopeInfo>(maybe_scope_info);
- DCHECK(new_scope_info->Equals(old_scope_info, true));
- old_scope_info->SetPositionInfo(new_scope_info->position_info_start(),
- new_scope_info->position_info_end());
- } else if (!is_compiled()) {
- CHECK(HasUncompiledData(isolate));
- if (HasUncompiledDataWithPreparseData(isolate)) {
- ClearPreparseData(isolate);
- }
- uncompiled_data(isolate)->set_start_position(lit->start_position());
- uncompiled_data(isolate)->set_end_position(lit->end_position());
-
- if (!is_toplevel()) {
- Scope* outer_scope = lit->scope()->GetOuterScopeWithContext();
- if (outer_scope) {
- // Use the raw accessor since we have to replace the existing outer
- // scope.
- set_raw_outer_scope_info_or_feedback_metadata(
- *outer_scope->scope_info());
- }
- }
- }
- SetFunctionTokenPosition(lit->function_token_position(),
- lit->start_position());
- set_is_hoisted_in_context(lit->scope()->is_hoisted_in_context());
-}
-
CachedTieringDecision SharedFunctionInfo::cached_tiering_decision() {
return CachedTieringDecisionBits::decode(flags2());
}
@@ -942,6 +906,7 @@ bool SharedFunctionInfo::UniqueIdsAreUnique(Isolate* isolate) {
std::unordered_set<uint32_t> ids({isolate->next_unique_sfi_id()});
CombinedHeapObjectIterator it(isolate->heap());
for (Tagged<HeapObject> o = it.Next(); !o.is_null(); o = it.Next()) {
+ if (IsInaccessible(o)) continue;
if (!IsSharedFunctionInfo(o)) continue;
auto result = ids.emplace(Cast<SharedFunctionInfo>(o)->unique_id());
// If previously inserted...
diff --git a/deps/v8/src/objects/shared-function-info.h b/deps/v8/src/objects/shared-function-info.h
index a30a685b1d5..a4b91056a48 100644
--- a/deps/v8/src/objects/shared-function-info.h
+++ b/deps/v8/src/objects/shared-function-info.h
@@ -137,6 +137,8 @@ static_assert(IsAligned(OFFSET_OF_DATA_START(PreparseData),
// Abstract class representing extra data for an uncompiled function, which is
// not stored in the SharedFunctionInfo.
V8_OBJECT class UncompiledData : public ExposedTrustedObject {
+ V8_IT_ABSTRACT;
+
public:
inline Tagged<String> inferred_name() const;
inline void set_inferred_name(Tagged<String> value,
@@ -169,6 +171,8 @@ V8_OBJECT class UncompiledData : public ExposedTrustedObject {
// data from the pre-parser, either because it's a leaf function or because the
// pre-parser bailed out.
V8_OBJECT class UncompiledDataWithoutPreparseData : public UncompiledData {
+ V8_IT_OWN_TYPE;
+
public:
DECL_PRINTER(UncompiledDataWithoutPreparseData)
DECL_VERIFIER(UncompiledDataWithoutPreparseData)
@@ -179,6 +183,8 @@ V8_OBJECT class UncompiledDataWithoutPreparseData : public UncompiledData {
// Class representing data for an uncompiled function that has pre-parsed scope
// data.
V8_OBJECT class UncompiledDataWithPreparseData : public UncompiledData {
+ V8_IT_OWN_TYPE;
+
public:
inline Tagged<PreparseData> preparse_data() const;
inline void set_preparse_data(Tagged<PreparseData> value,
@@ -283,7 +289,6 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
PropertiesAreFinalBit::Next<bool, 1>;
using IsHoistedInContextBit =
PrivateNameLookupSkipsOuterClassBit::Next<bool, 1>;
- using LiveEditedBit = IsHoistedInContextBit::Next<bool, 1>;
// Bit positions in |flags2|.
using ClassScopeHasPrivateBrandBit = base::BitField<bool, 0, 1, uint8_t>;
using HasStaticPrivateMethodsOrAccessorsBit =
@@ -396,9 +401,6 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
// Start position of this function in the script source.
V8_EXPORT_PRIVATE int StartPosition() const;
- V8_EXPORT_PRIVATE void UpdateFromFunctionLiteralForLiveEdit(
- IsolateForSandbox isolate, FunctionLiteral* lit);
-
// [outer scope info | feedback metadata] Shared storage for outer scope info
// (on uncompiled functions) and feedback metadata (on compiled functions).
DECL_ACCESSORS(raw_outer_scope_info_or_feedback_metadata,
@@ -701,9 +703,6 @@ V8_OBJECT class SharedFunctionInfo : public HeapObject {
// closest outer class scope.
DECL_BOOLEAN_ACCESSORS(private_name_lookup_skips_outer_class)
- // Indicates that the shared function info was live-edited.
- DECL_BOOLEAN_ACCESSORS(live_edited)
-
// Indicates that the function is a hoisted-in-context declaration.
DECL_BOOLEAN_ACCESSORS(is_hoisted_in_context)
diff --git a/deps/v8/src/objects/shared-function-info.tq b/deps/v8/src/objects/shared-function-info.tq
index 4ec3a6005bb..f4949b0bc77 100644
--- a/deps/v8/src/objects/shared-function-info.tq
+++ b/deps/v8/src/objects/shared-function-info.tq
@@ -42,9 +42,6 @@ bitfield struct SharedFunctionInfoFlags extends uint32 {
properties_are_final: bool: 1 bit;
private_name_lookup_skips_outer_class: bool: 1 bit;
is_hoisted_in_context: bool: 1 bit;
-
- // TODO(crbug.com/401059828): remove once crashes are gone.
- live_edited: bool: 1 bit;
}
@cppScope('SharedFunctionInfo')
diff --git a/deps/v8/src/objects/simd.cc b/deps/v8/src/objects/simd.cc
index 64f76803f17..be351a7b80c 100644
--- a/deps/v8/src/objects/simd.cc
+++ b/deps/v8/src/objects/simd.cc
@@ -349,11 +349,8 @@ uintptr_t fast_search_avx(T* array, uintptr_t array_len, uintptr_t index,
#endif // ifdef __SSE3__
// When built with other toolchains, do not count on it to expose
-// __builtin_sve_* on a per-function basis. Clang only supports
-// mangling SVE types with the Microsoft C++ ABI since version 21.
-// Fallback to Neon in cases where SVE is not supported.
-#if defined(NEON64) && defined(__clang__) && \
- (!defined(V8_TARGET_OS_WIN) || __clang_major__ >= 21)
+// __builtin_sve_* on a per-function basis. Fallback to Neon.
+#if defined(NEON64) && defined(__clang__)
#define V8_ENABLE_SIMD_SVE 1
template <typename ScalarType>
@@ -634,8 +631,7 @@ TARGET_SVE inline uintptr_t fast_search_sve(T* array, uintptr_t array_len,
return no_match;
}
-#endif // defined(NEON64) && defined(__clang__) &&
- // (!defined(V8_TARGET_OS_WIN) || __clang_major__ >= 21)
+#endif // defined(NEON64) && defined(__clang__)
#undef IS_CLANG_WIN
#undef VECTORIZED_LOOP_Neon
diff --git a/deps/v8/src/objects/slots-inl.h b/deps/v8/src/objects/slots-inl.h
index d96c3a5a350..77e9d702777 100644
--- a/deps/v8/src/objects/slots-inl.h
+++ b/deps/v8/src/objects/slots-inl.h
@@ -321,6 +321,11 @@ void CppHeapPointerSlot::Release_StoreHandle(
return base::AsAtomic32::Release_Store(location(), handle);
}
+void CppHeapPointerSlot::Relaxed_StoreHandle(
+ CppHeapPointerHandle handle) const {
+ return base::AsAtomic32::Relaxed_Store(location(), handle);
+}
+
#else
void CppHeapPointerSlot::store(Address value) const {
@@ -350,7 +355,7 @@ CppHeapPointerSlot::GetAndClearContentForSerialization(
#else
Address content = ReadMaybeUnalignedValue<Address>(address());
WriteMaybeUnalignedValue<Address>(address(), kNullAddress);
-#endif // V8_CPPGC_MICROTASK_QUEUE
+#endif // V8_COMPRESS_POINTERS
return content;
}
@@ -361,7 +366,7 @@ void CppHeapPointerSlot::RestoreContentAfterSerialization(
Release_StoreHandle(content);
#else
WriteMaybeUnalignedValue<Address>(address(), content);
-#endif // V8_CPPGC_MICROTASK_QUEUE
+#endif // V8_COMPRESS_POINTERS
}
Tagged<Object> IndirectPointerSlot::load(IsolateForSandbox isolate) const {
diff --git a/deps/v8/src/objects/slots.h b/deps/v8/src/objects/slots.h
index 3678801720c..5705a3b14c4 100644
--- a/deps/v8/src/objects/slots.h
+++ b/deps/v8/src/objects/slots.h
@@ -425,8 +425,11 @@ class CppHeapPointerSlot
// should generally be accessed atomically as they may be accessed from other
// threads, for example GC marking threads.
inline CppHeapPointerHandle Relaxed_LoadHandle() const;
+
inline void Release_StoreHandle(CppHeapPointerHandle handle) const;
+ inline void Relaxed_StoreHandle(CppHeapPointerHandle handle) const;
+
#else
inline void store(Address value) const;
diff --git a/deps/v8/src/objects/source-text-module.cc b/deps/v8/src/objects/source-text-module.cc
index 242ec8bf6df..a11192bf788 100644
--- a/deps/v8/src/objects/source-text-module.cc
+++ b/deps/v8/src/objects/source-text-module.cc
@@ -970,7 +970,7 @@ bool SourceTextModule::MaybeHandleEvaluationException(
}
// https://tc39.es/ecma262/#sec-moduleevaluation
-MaybeDirectHandle<Object> SourceTextModule::Evaluate(
+MaybeDirectHandle<JSPromise> SourceTextModule::Evaluate(
Isolate* isolate, Handle<SourceTextModule> module) {
CHECK(module->status() == kLinked || module->status() == kEvaluatingAsync ||
module->status() == kEvaluated || module->status() == kErrored);
@@ -1001,8 +1001,18 @@ MaybeDirectHandle<Object> SourceTextModule::Evaluate(
if (InnerModuleEvaluation(isolate, module, &stack, &dfs_index).is_null()) {
if (!module->MaybeHandleEvaluationException(isolate, &stack)) return {};
CHECK(try_catch.HasCaught());
+
+ // We are clearing the internal exception here because JSPromise::Reject can
+ // call Isolate::ReportPromiseReject that will trap to a host defined hook
+ // and given we are already registering this exception on promise
+ // capability, we shouldn't keep it as pending on isolate. This is important
+ // because host might have paths that call `Isolate::ReportPendingMessages`
+ // while `AllowExceptions::IsAllowed` is `false` and leaving such exception
+ // pending will cause a DCHECK failure.
+ isolate->clear_internal_exception();
// d. Perform ! Call(capability.[[Reject]], undefined,
// «result.[[Value]]»).
+
JSPromise::Reject(capability, direct_handle(module->exception(), isolate));
} else { // 10. Else,
// a. Assert: module.[[Status]] is either EVALUATING-ASYNC or EVALUATED.
@@ -1512,6 +1522,26 @@ MaybeDirectHandle<Object> SourceTextModule::InnerModuleEvaluation(
return result;
}
+bool SourceTextModule::IsModuleSCCEvaluated(Handle<SourceTextModule> module) {
+ // It's necessary to check if [[CycleRoot]] is not empty here because:
+ // 1. A module starts with its [[CycleRoot]] as `TheHole` and it's set
+ // once the cycle is detected, or when the module finishes its evaluation
+ // without errors.
+ // 2. GatherAsynchronousTransitiveDependencies can be called with a module
+ // where it's `[[CycleRoot]]` is not set yet, and since it depends on
+ // `IsModuleSCCEvaluated`, we need such guard. A later call from
+ // `ReadyForSyncExecution` for the same module will have its `[[CycleRoot]]`
+ // set, unless its evaluation errored.
+ if (!IsTheHole(module->cycle_root())) {
+ Tagged<SourceTextModule> cycle_root =
+ Cast<SourceTextModule>(module->cycle_root());
+ return cycle_root->status() == Module::kEvaluated ||
+ cycle_root->status() == Module::kErrored;
+ }
+ return module->status() == Module::kEvaluated ||
+ module->status() == Module::kErrored;
+}
+
// https://tc39.es/proposal-defer-import-eval/#sec-GatherAsynchronousTransitiveDependencies
void SourceTextModule::GatherAsynchronousTransitiveDependencies(
Isolate* isolate, Handle<Module> module, UnorderedModuleSet* evaluation_set,
@@ -1527,7 +1557,7 @@ void SourceTextModule::GatherAsynchronousTransitiveDependencies(
Handle<SourceTextModule> source_text_module = Cast<SourceTextModule>(module);
if (source_text_module->status() == kEvaluating ||
- module->status() == kEvaluatingAsync || module->status() == kEvaluated) {
+ IsModuleSCCEvaluated(source_text_module)) {
return;
}
@@ -1573,7 +1603,7 @@ bool SourceTextModule::ReadyForSyncExecution(Isolate* isolate,
}
Handle<SourceTextModule> source_text_module = Cast<SourceTextModule>(module);
- if (source_text_module->status() == kEvaluated) {
+ if (IsModuleSCCEvaluated(source_text_module)) {
return true;
}
diff --git a/deps/v8/src/objects/source-text-module.h b/deps/v8/src/objects/source-text-module.h
index f6281fb11e5..d473613ec20 100644
--- a/deps/v8/src/objects/source-text-module.h
+++ b/deps/v8/src/objects/source-text-module.h
@@ -87,6 +87,11 @@ V8_OBJECT class SourceTextModule : public Module {
DirectHandleVector<JSMessageObject>>
GetStalledTopLevelAwaitMessages(Isolate* isolate);
+ // https://tc39.es/proposal-defer-import-eval/#sec-IsModuleSCCEvaluated
+ // This function checks if the Strongly Connected Component (SCC) that the
+ // module participates is evaluated.
+ static bool IsModuleSCCEvaluated(Handle<SourceTextModule> module);
+
static void GatherAsynchronousTransitiveDependencies(
Isolate* isolate, Handle<Module> module,
UnorderedModuleSet* evaluation_set,
@@ -236,7 +241,7 @@ V8_OBJECT class SourceTextModule : public Module {
AvailableAncestorsSet* exec_list);
// Implementation of spec concrete method Evaluate.
- static V8_WARN_UNUSED_RESULT MaybeDirectHandle<Object> Evaluate(
+ static V8_WARN_UNUSED_RESULT MaybeDirectHandle<JSPromise> Evaluate(
Isolate* isolate, Handle<SourceTextModule> module);
// Implementation of spec abstract operation InnerModuleEvaluation.
@@ -302,6 +307,8 @@ struct ObjectTraits<SourceTextModule> {
// SourceTextModuleInfo is to SourceTextModuleDescriptor what ScopeInfo is to
// Scope.
class SourceTextModuleInfo : public FixedArray {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
template <typename IsolateT>
V8_EXPORT_PRIVATE static DirectHandle<SourceTextModuleInfo> New(
@@ -321,6 +328,9 @@ class SourceTextModuleInfo : public FixedArray {
inline bool Equals(Tagged<SourceTextModuleInfo> other) const;
+ // Whether the module has at least one `export * from '...'` statement.
+ bool HasStarExports() const;
+
private:
template <typename Impl>
friend class FactoryBase;
diff --git a/deps/v8/src/objects/string-inl.h b/deps/v8/src/objects/string-inl.h
index 7d53c78785d..58c882719ad 100644
--- a/deps/v8/src/objects/string-inl.h
+++ b/deps/v8/src/objects/string-inl.h
@@ -13,8 +13,8 @@
#include "absl/functional/overload.h"
#include "include/v8config.h"
-#include "src/base/logging.h"
#include "simdutf.h"
+#include "src/base/logging.h"
#include "src/common/assert-scope.h"
#include "src/common/globals.h"
#include "src/execution/isolate-utils-inl.h"
@@ -1499,16 +1499,33 @@ uint32_t ExternalString::GetResourceRefForDeserialization() {
return static_cast<uint32_t>(resource_.load_encoded());
}
-void ExternalString::SetResourceRefForSerialization(uint32_t ref) {
+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;
+ 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;
- Address value = resource_.load(isolate);
+ Address value = resource_.exchange(isolate, kNullAddress);
v8::String::ExternalStringResourceBase* resource =
reinterpret_cast<v8::String::ExternalStringResourceBase*>(value);
@@ -1519,7 +1536,6 @@ void ExternalString::DisposeResource(Isolate* isolate) {
}
DisableGCMole no_gc_mole;
resource->Dispose();
- resource_.store(isolate, kNullAddress);
}
}
diff --git a/deps/v8/src/objects/string-set.h b/deps/v8/src/objects/string-set.h
index cdd4ad25e27..a2a98724d43 100644
--- a/deps/v8/src/objects/string-set.h
+++ b/deps/v8/src/objects/string-set.h
@@ -30,6 +30,8 @@ class StringSetShape : public BaseShape<Tagged<String>> {
EXTERN_DECLARE_HASH_TABLE(StringSet, StringSetShape)
V8_OBJECT class StringSet : public HashTable<StringSet, StringSetShape> {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
V8_EXPORT_PRIVATE static Handle<StringSet> New(Isolate* isolate);
V8_EXPORT_PRIVATE static Handle<StringSet> Add(Isolate* isolate,
diff --git a/deps/v8/src/objects/string.cc b/deps/v8/src/objects/string.cc
index ad86de5941e..ccce48db658 100644
--- a/deps/v8/src/objects/string.cc
+++ b/deps/v8/src/objects/string.cc
@@ -2100,15 +2100,17 @@ SeqString::DataAndPaddingSizes SeqString::GetDataAndPaddingSizes() const {
SeqString::DataAndPaddingSizes SeqOneByteString::GetDataAndPaddingSizes()
const {
- int data_size = sizeof(SeqOneByteString) + length() * kOneByteSize;
- int padding_size = SizeFor(length()) - data_size;
+ uint32_t len = length();
+ int data_size = DataSizeFor(len);
+ int padding_size = SizeFor(len) - data_size;
return DataAndPaddingSizes{data_size, padding_size};
}
SeqString::DataAndPaddingSizes SeqTwoByteString::GetDataAndPaddingSizes()
const {
- int data_size = sizeof(SeqTwoByteString) + length() * base::kUC16Size;
- int padding_size = SizeFor(length()) - data_size;
+ uint32_t len = length();
+ int data_size = DataSizeFor(len);
+ int padding_size = SizeFor(len) - data_size;
return DataAndPaddingSizes{data_size, padding_size};
}
diff --git a/deps/v8/src/objects/string.h b/deps/v8/src/objects/string.h
index 1c376b110d4..5e435ab8e3c 100644
--- a/deps/v8/src/objects/string.h
+++ b/deps/v8/src/objects/string.h
@@ -121,6 +121,8 @@ class StringShape {
// All string values have a length field.
V8_OBJECT class String : public Name {
public:
+ V8_IT_ABSTRACT;
+ V8_IT_FLAG_BITS(7);
enum Encoding { ONE_BYTE_ENCODING, TWO_BYTE_ENCODING };
// Representation of the flat content of a String.
@@ -633,11 +635,7 @@ V8_OBJECT class String : public Name {
// Check aligned words.
static_assert(unibrow::Latin1::kMaxChar == 0xFF);
-#ifdef V8_TARGET_LITTLE_ENDIAN
const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFFFF * 0xFF00;
-#else
- const uintptr_t non_one_byte_mask = kUintptrAllBitsSet / 0xFFFF * 0x00FF;
-#endif
while (chars + sizeof(uintptr_t) <= limit) {
if (*reinterpret_cast<const uintptr_t*>(chars) & non_one_byte_mask) {
break;
@@ -861,6 +859,9 @@ class SubStringRange {
// The SeqString abstract class captures sequential string values.
class SeqString : public String {
+ V8_IT_ABSTRACT;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
// Truncate the string in-place if possible and return the result.
// In case of new_length == 0, the empty string is returned without
@@ -885,12 +886,15 @@ class SeqString : public String {
};
V8_OBJECT class InternalizedString : public String {
+ V8_IT_NO_AUTO_CHECKER;
// TODO(neis): Possibly move some stuff from String here.
} V8_OBJECT_END;
// The OneByteString class captures sequential one-byte string objects.
// Each character in the OneByteString is an one-byte character.
V8_OBJECT class SeqOneByteString : public SeqString {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
static const bool kHasOneByteEncoding = true;
using Char = uint8_t;
@@ -968,6 +972,8 @@ struct ObjectTraits<SeqOneByteString> {
// The TwoByteString class captures sequential unicode string objects.
// Each character in the TwoByteString is a two-byte uint16_t.
V8_OBJECT class SeqTwoByteString : public SeqString {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
static const bool kHasOneByteEncoding = false;
using Char = uint16_t;
@@ -1047,6 +1053,8 @@ struct ObjectTraits<SeqTwoByteString> {
// a ConsString can be obtained by concatenating the leaf string
// values in a left-to-right depth-first traversal of the tree.
V8_OBJECT class ConsString : public String {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
inline Tagged<String> first() const;
inline void set_first(Tagged<String> value,
@@ -1102,7 +1110,6 @@ V8_OBJECT class ConsString : public String {
TaggedMember<String> second_;
} V8_OBJECT_END;
-
template <>
struct ObjectTraits<ConsString> {
using BodyDescriptor =
@@ -1118,6 +1125,8 @@ struct ObjectTraits<ConsString> {
// In terms of memory layout and most algorithms operating on strings,
// ThinStrings can be thought of as "one-part cons strings".
V8_OBJECT class ThinString : public String {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
inline Tagged<InternalizedString> actual() const;
inline void set_actual(Tagged<InternalizedString> value,
@@ -1168,6 +1177,8 @@ struct ObjectTraits<ThinString> {
// Currently missing features are:
// - truncating sliced string to enable otherwise unneeded parent to be GC'ed.
V8_OBJECT class SlicedString : public String {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
inline Tagged<String> parent() const;
inline void set_parent(Tagged<String> parent,
@@ -1211,8 +1222,13 @@ struct ObjectTraits<SlicedString> {
// TODO(leszeks): Build this out into a full V8 class.
V8_OBJECT class UncachedExternalString : public String {
+ V8_IT_REUSE_PARENT;
+
protected:
ExternalPointerMember<kExternalStringResourceTag> resource_;
+
+ // To get the offset of the protected resource_ field.
+ friend class SandboxTesting;
} V8_OBJECT_END;
// The ExternalString class describes string values that are backed by
@@ -1225,6 +1241,9 @@ V8_OBJECT class UncachedExternalString : public String {
// The API expects that all ExternalStrings are created through the
// API. Therefore, ExternalStrings should not be used internally.
V8_OBJECT class ExternalString : public UncachedExternalString {
+ V8_IT_ABSTRACT;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
class BodyDescriptor;
@@ -1246,7 +1265,14 @@ V8_OBJECT class ExternalString : public UncachedExternalString {
inline Address resource_as_address() const;
inline void set_address_as_resource(Isolate* isolate, Address address);
inline uint32_t GetResourceRefForDeserialization();
- inline void SetResourceRefForSerialization(uint32_t ref);
+ // 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);
// Disposes string's resource object if it has not already been disposed.
inline void DisposeResource(Isolate* isolate);
@@ -1260,6 +1286,8 @@ V8_OBJECT class ExternalString : public UncachedExternalString {
friend class CodeStubAssembler;
friend class compiler::AccessBuilder;
friend class TorqueGeneratedExternalStringAsserts;
+ // To get the offset of the protected resource_data_ field.
+ friend class SandboxTesting;
protected:
ExternalPointerMember<kExternalStringResourceDataTag> resource_data_;
@@ -1276,6 +1304,8 @@ struct ObjectTraits<ExternalString> {
// The ExternalOneByteString class is an external string backed by an
// one-byte string.
V8_OBJECT class ExternalOneByteString : public ExternalString {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
static const bool kHasOneByteEncoding = true;
using Char = uint8_t;
@@ -1310,6 +1340,8 @@ static_assert(sizeof(ExternalOneByteString) == sizeof(ExternalString));
// The ExternalTwoByteString class is an external string backed by a UTF-16
// encoded string.
V8_OBJECT class ExternalTwoByteString : public ExternalString {
+ V8_IT_NO_AUTO_CHECKER;
+
public:
static const bool kHasOneByteEncoding = false;
using Char = uint16_t;
diff --git a/deps/v8/src/objects/struct-inl.h b/deps/v8/src/objects/struct-inl.h
index 283f813204b..2d5e5472420 100644
--- a/deps/v8/src/objects/struct-inl.h
+++ b/deps/v8/src/objects/struct-inl.h
@@ -30,6 +30,13 @@ void Tuple2::set_value1(Tagged<Object> value, RelaxedStoreTag,
WriteBarrierMode mode) {
value1_.Relaxed_Store(this, value, mode);
}
+Tagged<Object> Tuple2::value1(AcquireLoadTag) const {
+ return value1_.Acquire_Load();
+}
+void Tuple2::set_value1(Tagged<Object> value, ReleaseStoreTag,
+ WriteBarrierMode mode) {
+ value1_.Release_Store(this, value, mode);
+}
Tagged<Object> Tuple2::value2() const { return value2_.load(); }
void Tuple2::set_value2(Tagged<Object> value, WriteBarrierMode mode) {
diff --git a/deps/v8/src/objects/struct.h b/deps/v8/src/objects/struct.h
index b794601651b..dd17c72c40f 100644
--- a/deps/v8/src/objects/struct.h
+++ b/deps/v8/src/objects/struct.h
@@ -20,6 +20,8 @@ class StructBodyDescriptor;
// It doesn't carry any functionality but allows struct classes to be
// identified in the type system.
V8_OBJECT class Struct : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
void BriefPrintDetails(std::ostream& os);
@@ -28,6 +30,8 @@ V8_OBJECT class Struct : public HeapObject {
static_assert(sizeof(Struct) == sizeof(HeapObject));
V8_OBJECT class Tuple2 : public Struct {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
void BriefPrintDetails(std::ostream& os);
@@ -37,6 +41,9 @@ V8_OBJECT class Tuple2 : public Struct {
inline Tagged<Object> value1(RelaxedLoadTag) const;
inline void set_value1(Tagged<Object> value, RelaxedStoreTag,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+ inline Tagged<Object> value1(AcquireLoadTag) const;
+ inline void set_value1(Tagged<Object> value, ReleaseStoreTag,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<Object> value2() const;
inline void set_value2(Tagged<Object> value,
@@ -62,6 +69,8 @@ V8_OBJECT class Tuple2 : public Struct {
// * undefined: considered an accessor by the spec, too, strangely enough
// * null: an accessor which has not been set
V8_OBJECT class AccessorPair : public Struct {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
static DirectHandle<AccessorPair> Copy(Isolate* isolate,
DirectHandle<AccessorPair> pair);
@@ -109,6 +118,8 @@ V8_OBJECT class AccessorPair : public Struct {
} V8_OBJECT_END;
V8_OBJECT class ClassPositions : public Struct {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
inline int start() const;
inline void set_start(int value);
diff --git a/deps/v8/src/objects/synthetic-module.cc b/deps/v8/src/objects/synthetic-module.cc
index 45271559478..d9018debc87 100644
--- a/deps/v8/src/objects/synthetic-module.cc
+++ b/deps/v8/src/objects/synthetic-module.cc
@@ -5,6 +5,7 @@
#include "src/objects/synthetic-module.h"
#include "src/api/api-inl.h"
+#include "src/base/macros.h"
#include "src/builtins/accessors.h"
#include "src/objects/js-generator-inl.h"
#include "src/objects/module-inl.h"
@@ -106,41 +107,39 @@ bool SyntheticModule::FinishInstantiate(Isolate* isolate,
// Implements Synthetic Module Record's Evaluate concrete method:
// https://heycam.github.io/webidl/#smr-evaluate
-MaybeDirectHandle<Object> SyntheticModule::Evaluate(
+// The callback may have been created through the deprecated
+// v8::Module::LegacySyntheticModuleEvaluationSteps overload, in which case it
+// actually returns a v8::MaybeLocal<v8::Value> and is called here through a
+// mismatching signature. Both return types are pointer-sized, trivially
+// copyable handle wrappers, so this is safe in practice, but it does trip
+// CFI's and UBSan's indirect call checks.
+// TODO(https://crbug.com/545375591): Remove DISABLE_CFI_ICALL once the
+// deprecated overload is gone.
+DISABLE_CFI_ICALL
+MaybeDirectHandle<JSPromise> SyntheticModule::Evaluate(
Isolate* isolate, DirectHandle<SyntheticModule> module) {
module->SetStatus(kEvaluating);
v8::Module::SyntheticModuleEvaluationSteps evaluation_steps =
FUNCTION_CAST<v8::Module::SyntheticModuleEvaluationSteps>(
module->evaluation_steps()->foreign_address<kSyntheticModuleTag>());
+ // Deliberately received as a v8::Local<v8::Value>: the deprecated callback
+ // signature only promises a Promise, it doesn't guarantee one.
v8::Local<v8::Value> result;
if (!evaluation_steps(Utils::ToLocal(isolate->native_context()),
Utils::ToLocal(Cast<Module>(module)))
.ToLocal(&result)) {
module->RecordError(isolate, isolate->exception());
- return MaybeDirectHandle<Object>();
+ return MaybeDirectHandle<JSPromise>();
}
module->SetStatus(kEvaluated);
DirectHandle<Object> result_from_callback = Utils::OpenDirectHandle(*result);
-
- DirectHandle<JSPromise> capability;
- if (IsJSPromise(*result_from_callback)) {
- capability = Cast<JSPromise>(result_from_callback);
- } else {
- // The host's evaluation steps should have returned a resolved Promise,
- // but as an allowance to hosts that have not yet finished the migration
- // to top-level await, create a Promise if the callback result didn't give
- // us one.
- capability = isolate->factory()->NewJSPromise();
- JSPromise::Resolve(capability, isolate->factory()->undefined_value())
- .ToHandleChecked();
- }
-
+ CHECK(IsJSPromise(*result_from_callback));
+ DirectHandle<JSPromise> capability = Cast<JSPromise>(result_from_callback);
module->set_top_level_capability(*capability);
-
- return result_from_callback;
+ return capability;
}
} // namespace internal
diff --git a/deps/v8/src/objects/synthetic-module.h b/deps/v8/src/objects/synthetic-module.h
index e6c7791f446..0a2cef18d9d 100644
--- a/deps/v8/src/objects/synthetic-module.h
+++ b/deps/v8/src/objects/synthetic-module.h
@@ -70,7 +70,7 @@ V8_OBJECT class SyntheticModule : public Module {
static V8_WARN_UNUSED_RESULT bool FinishInstantiate(
Isolate* isolate, DirectHandle<SyntheticModule> module);
- static V8_WARN_UNUSED_RESULT MaybeDirectHandle<Object> Evaluate(
+ static V8_WARN_UNUSED_RESULT MaybeDirectHandle<JSPromise> Evaluate(
Isolate* isolate, DirectHandle<SyntheticModule> module);
public:
diff --git a/deps/v8/src/objects/templates.cc b/deps/v8/src/objects/templates.cc
index 469dbbb8012..87a5b463b25 100644
--- a/deps/v8/src/objects/templates.cc
+++ b/deps/v8/src/objects/templates.cc
@@ -8,6 +8,7 @@
#include <algorithm>
#include <cstdint>
+#include <limits>
#include <optional>
#include <span>
@@ -27,6 +28,7 @@
#include "src/objects/managed-inl.h"
#include "src/objects/map-inl.h"
#include "src/objects/name-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/shared-function-info-inl.h"
#include "src/objects/string-inl.h"
@@ -79,15 +81,6 @@ bool FunctionTemplateInfo::IsTemplateFor(Tagged<Map> map) const {
// There is a constraint on the object; check.
if (!IsJSObjectMap(map)) return false;
- if (v8_flags.experimental_embedder_instance_types) {
- DCHECK_IMPLIES(allowed_receiver_instance_type_range_start() == 0,
- allowed_receiver_instance_type_range_end() == 0);
- if (base::IsInRange(map->instance_type(),
- allowed_receiver_instance_type_range_start(),
- allowed_receiver_instance_type_range_end())) {
- return true;
- }
- }
// Fetch the constructor function of the object.
Tagged<Object> cons_obj = map->GetConstructor();
@@ -299,9 +292,12 @@ DirectHandle<JSObject> DictionaryTemplateInfo::NewInstance(
if (details.representation().Equals(Representation::Double())) {
// We allowed coercion in `FitsRepresentation` above which means that
// we may deal with a Smi here.
- property_values[i] =
- ToApiHandle<v8::Object>(isolate->factory()->NewHeapNumber(
- Object::NumberValue(Cast<Number>(*value))));
+ double value_as_double = Object::NumberValue(Cast<Number>(*value));
+ if (std::isnan(value_as_double)) {
+ value_as_double = std::numeric_limits<double>::quiet_NaN();
+ }
+ property_values[i] = ToApiHandle<v8::Object>(
+ isolate->factory()->NewHeapNumber(value_as_double));
}
}
if (V8_LIKELY(can_use_cached_map)) {
diff --git a/deps/v8/src/objects/templates.h b/deps/v8/src/objects/templates.h
index 281887ef718..2f7c880c1f1 100644
--- a/deps/v8/src/objects/templates.h
+++ b/deps/v8/src/objects/templates.h
@@ -38,6 +38,8 @@ struct CFunctionWithSignature {
};
V8_OBJECT class TemplateInfo : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
static const int kFastTemplateInstantiationsCacheSize = 1 * KB;
@@ -104,6 +106,8 @@ V8_OBJECT class TemplateInfo : public HeapObject {
} V8_OBJECT_END;
V8_OBJECT class TemplateInfoWithProperties : public TemplateInfo {
+ V8_IT_ABSTRACT;
+
public:
inline int number_of_properties() const;
inline void set_number_of_properties(int value);
diff --git a/deps/v8/src/objects/transitions.h b/deps/v8/src/objects/transitions.h
index c3c6d0f60fe..408bcaf0f4e 100644
--- a/deps/v8/src/objects/transitions.h
+++ b/deps/v8/src/objects/transitions.h
@@ -312,6 +312,8 @@ class V8_EXPORT_PRIVATE TransitionsAccessor {
// TODO(olivf): The slots for prototype transitions and side-steps could be
// shared.
V8_OBJECT class TransitionArray : public WeakFixedArray {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
// Do linear search for small arrays, and for searches in the background
// thread.
diff --git a/deps/v8/src/objects/trusted-object.h b/deps/v8/src/objects/trusted-object.h
index 7ab4e002498..26a21cf5615 100644
--- a/deps/v8/src/objects/trusted-object.h
+++ b/deps/v8/src/objects/trusted-object.h
@@ -29,6 +29,8 @@ namespace internal {
// objects stored inside the sandbox. However, ExposedTrustedObject can be
// referenced via indirect pointers, which guarantee memory-safe access.
V8_OBJECT class TrustedObject : public HeapObject {
+ V8_IT_ABSTRACT;
+
public:
DECL_VERIFIER(TrustedObject)
@@ -99,6 +101,8 @@ V8_OBJECT class TrustedObject : public HeapObject {
// utility objects on top of this class, but hopefully this comment serves to
// document the potential pitfalls when doing so.
V8_OBJECT class ExposedTrustedObject : public TrustedObject {
+ V8_IT_ABSTRACT;
+
public:
// Initializes this object by allocating its pointer table entry. This
// initializer function immediately makes the trusted object accessible from
diff --git a/deps/v8/src/objects/turbofan-types.h b/deps/v8/src/objects/turbofan-types.h
index cd26776b7c6..e3e40914ecb 100644
--- a/deps/v8/src/objects/turbofan-types.h
+++ b/deps/v8/src/objects/turbofan-types.h
@@ -108,6 +108,7 @@ class TurbofanTypeHighBits {
};
V8_OBJECT class TurbofanType : public HeapObject {
+ V8_IT_ABSTRACT;
} V8_OBJECT_END;
V8_OBJECT class TurbofanBitsetType : public TurbofanType {
diff --git a/deps/v8/src/objects/turboshaft-types.h b/deps/v8/src/objects/turboshaft-types.h
index b6a1182bb57..6a69afa9b0d 100644
--- a/deps/v8/src/objects/turboshaft-types.h
+++ b/deps/v8/src/objects/turboshaft-types.h
@@ -22,9 +22,12 @@ class TurboshaftFloatSpecialValues {
};
V8_OBJECT class TurboshaftType : public HeapObject {
+ V8_IT_ABSTRACT;
} V8_OBJECT_END;
V8_OBJECT class TurboshaftWord32Type : public TurboshaftType {
+ V8_IT_ABSTRACT;
+
public:
DECL_VERIFIER(TurboshaftWord32Type)
} V8_OBJECT_END;
@@ -77,6 +80,8 @@ constexpr int TurboshaftWord32SetType::SizeFor(int set_size) {
}
V8_OBJECT class TurboshaftWord64Type : public TurboshaftType {
+ V8_IT_ABSTRACT;
+
public:
DECL_VERIFIER(TurboshaftWord64Type)
} V8_OBJECT_END;
@@ -139,6 +144,8 @@ constexpr int TurboshaftWord64SetType::SizeFor(int set_size) {
}
V8_OBJECT class TurboshaftFloat64Type : public TurboshaftType {
+ V8_IT_ABSTRACT;
+
public:
inline uint32_t special_values() const;
inline void set_special_values(uint32_t value);
diff --git a/deps/v8/src/objects/value-serializer.cc b/deps/v8/src/objects/value-serializer.cc
index 0a0555f4553..2c3434f3de2 100644
--- a/deps/v8/src/objects/value-serializer.cc
+++ b/deps/v8/src/objects/value-serializer.cc
@@ -30,6 +30,7 @@
#include "src/objects/js-shared-array.h"
#include "src/objects/js-struct.h"
#include "src/objects/map-updater.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/oddball-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
@@ -188,6 +189,9 @@ enum class SerializationTag : uint8_t {
kArrayBuffer = 'B',
// Immutable array buffer. byteLength:uint32_t, then raw data.
kImmutableArrayBuffer = 'C',
+ // Shared immutable array buffer (zero-copy for postMessage).
+ // backingStoreID:uint32_t
+ kSharedImmutableArrayBuffer = 'E',
// Resizable array buffer. byteLength:uint32_t, maxLength:uint32_t, raw data.
kResizableArrayBuffer = '~',
// Array buffer (transferred). transferID:uint32_t
@@ -297,14 +301,21 @@ enum class WasmMemoryArrayBufferTag : uint8_t {
} // namespace
-ValueSerializer::ValueSerializer(Isolate* isolate,
- v8::ValueSerializer::Delegate* delegate)
+ValueSerializer::ValueSerializer(
+ Isolate* isolate, v8::ValueSerializer::SharedImmutableArrayBufferMode
+ share_immutable_array_buffer)
+ : ValueSerializer(isolate, nullptr, share_immutable_array_buffer) {}
+
+ValueSerializer::ValueSerializer(
+ Isolate* isolate, v8::ValueSerializer::Delegate* delegate,
+ v8::ValueSerializer::SharedImmutableArrayBufferMode
+ share_immutable_array_buffer)
: isolate_(isolate),
delegate_(delegate),
zone_(isolate->allocator(), ZONE_NAME),
id_map_(isolate->heap(), ZoneAllocationPolicy(&zone_)),
- array_buffer_transfer_map_(isolate->heap(),
- ZoneAllocationPolicy(&zone_)) {
+ array_buffer_transfer_map_(isolate->heap(), ZoneAllocationPolicy(&zone_)),
+ share_immutable_array_buffer_(share_immutable_array_buffer) {
if (delegate_) {
v8::Isolate* v8_isolate = reinterpret_cast<v8::Isolate*>(isolate_);
has_custom_host_objects_ = delegate_->HasCustomHostObject(v8_isolate);
@@ -312,6 +323,12 @@ ValueSerializer::ValueSerializer(Isolate* isolate,
}
ValueSerializer::~ValueSerializer() {
+ DCHECK_IMPLIES(
+ !buffer_ && !out_of_memory_ &&
+ share_immutable_array_buffer_ ==
+ v8::ValueSerializer::SharedImmutableArrayBufferMode::kEnabled &&
+ v8_flags.js_postmessage_share_immutable_arraybuffer,
+ shared_immutable_backing_stores_.empty());
if (buffer_) {
if (delegate_) {
delegate_->FreeBufferMemory(buffer_);
@@ -1061,9 +1078,28 @@ Maybe<bool> ValueSerializer::WriteJSArrayBuffer(
}
if (array_buffer->is_immutable()) {
- // TODO(olivf): Since the AB is not mutable we could share the backing
- // store in postMessage. Needs a ForStorage flag for the ValueSerializer to
- // know when sharing is possible.
+ if (share_immutable_array_buffer_ ==
+ v8::ValueSerializer::SharedImmutableArrayBufferMode::kEnabled &&
+ v8_flags.js_postmessage_share_immutable_arraybuffer) {
+ auto backing_store = array_buffer->GetBackingStore();
+ DCHECK_IMPLIES(!backing_store, byte_length == 0);
+ if (backing_store) {
+ uint32_t id = 0;
+ auto it =
+ std::find(shared_immutable_backing_stores_.begin(),
+ shared_immutable_backing_stores_.end(), backing_store);
+ if (it != shared_immutable_backing_stores_.end()) {
+ id = static_cast<uint32_t>(it -
+ shared_immutable_backing_stores_.begin());
+ } else {
+ id = static_cast<uint32_t>(shared_immutable_backing_stores_.size());
+ shared_immutable_backing_stores_.push_back(backing_store);
+ }
+ WriteTag(SerializationTag::kSharedImmutableArrayBuffer);
+ WriteVarint<uint32_t>(id);
+ return ThrowIfOutOfMemory();
+ }
+ }
WriteTag(SerializationTag::kImmutableArrayBuffer);
} else {
WriteTag(SerializationTag::kArrayBuffer);
@@ -1224,8 +1260,6 @@ Maybe<bool> ValueSerializer::WriteWasmMemory(
return ThrowDataCloneError(MessageTemplate::kDataCloneError, object);
}
- GlobalBackingStoreRegistry::Register(shared_ab->GetBackingStore());
-
WriteTag(SerializationTag::kWasmMemoryTransfer);
WriteZigZag<int32_t>(object->maximum_pages());
WriteByte(object->is_memory64() ? 1 : 0);
@@ -1740,6 +1774,9 @@ MaybeDirectHandle<Object> ValueDeserializer::ReadObjectInternal() {
return ReadJSArrayBuffer(SharedFlag{false}, ResizableFlag{false},
/*is_immutable*/ true);
}
+ case SerializationTag::kSharedImmutableArrayBuffer: {
+ return ReadSharedImmutableJSArrayBuffer();
+ }
case SerializationTag::kArrayBufferTransfer: {
return ReadTransferredJSArrayBuffer();
}
@@ -2241,6 +2278,29 @@ ValueDeserializer::ReadTransferredJSArrayBuffer() {
return array_buffer;
}
+MaybeDirectHandle<JSArrayBuffer>
+ValueDeserializer::ReadSharedImmutableJSArrayBuffer() {
+ uint32_t id = next_id_++;
+ uint32_t backing_store_id;
+ if (!ReadVarint<uint32_t>().To(&backing_store_id)) {
+ return MaybeDirectHandle<JSArrayBuffer>();
+ }
+ if (backing_store_id >= shared_immutable_backing_stores_.size()) {
+ return MaybeDirectHandle<JSArrayBuffer>();
+ }
+ std::shared_ptr<BackingStore> backing_store =
+ shared_immutable_backing_stores_[backing_store_id];
+ if (!backing_store) {
+ return MaybeDirectHandle<JSArrayBuffer>();
+ }
+ CHECK(!backing_store->is_resizable_by_js());
+ DirectHandle<JSArrayBuffer> array_buffer =
+ isolate_->factory()->NewJSArrayBuffer(std::move(backing_store));
+ array_buffer->MakeImmutable(isolate_);
+ AddObjectWithID(id, array_buffer);
+ return array_buffer;
+}
+
MaybeDirectHandle<JSArrayBufferView> ValueDeserializer::ReadJSArrayBufferView(
DirectHandle<JSArrayBuffer> buffer) {
size_t buffer_byte_length = buffer->GetByteLength();
@@ -2510,7 +2570,8 @@ MaybeDirectHandle<WasmMemoryObject> ValueDeserializer::ReadWasmMemory() {
// buffer is stale. If it grows between the registration and the check, we
// will see it's stale. If it grows after the check, we will receive a
// broadcast and refresh the buffer on the next access.
- backing_store->AttachSharedWasmMemoryObject(isolate_, result);
+ GlobalBackingStoreRegistry::AddSharedWasmMemoryObject(isolate_, backing_store,
+ result);
if (buffer->GetByteLength() >= backing_store->byte_length()) {
// Link the two.
diff --git a/deps/v8/src/objects/value-serializer.h b/deps/v8/src/objects/value-serializer.h
index 0329d4e5bc2..1f2d2006254 100644
--- a/deps/v8/src/objects/value-serializer.h
+++ b/deps/v8/src/objects/value-serializer.h
@@ -51,7 +51,16 @@ enum class SerializationTag : uint8_t;
*/
class ValueSerializer {
public:
- ValueSerializer(Isolate* isolate, v8::ValueSerializer::Delegate* delegate);
+ explicit ValueSerializer(
+ Isolate* isolate,
+ v8::ValueSerializer::SharedImmutableArrayBufferMode
+ share_immutable_array_buffer =
+ v8::ValueSerializer::SharedImmutableArrayBufferMode::kDisabled);
+ ValueSerializer(
+ Isolate* isolate, v8::ValueSerializer::Delegate* delegate,
+ v8::ValueSerializer::SharedImmutableArrayBufferMode
+ share_immutable_array_buffer =
+ v8::ValueSerializer::SharedImmutableArrayBufferMode::kDisabled);
~ValueSerializer();
ValueSerializer(const ValueSerializer&) = delete;
ValueSerializer& operator=(const ValueSerializer&) = delete;
@@ -99,6 +108,11 @@ class ValueSerializer {
*/
void SetTreatArrayBufferViewsAsHostObjects(bool mode);
+ std::vector<std::shared_ptr<BackingStore>>
+ ReleaseSharedImmutableBackingStores() {
+ return std::move(shared_immutable_backing_stores_);
+ }
+
private:
// Managing allocations of the internal buffer.
Maybe<bool> ExpandBuffer(size_t required_capacity);
@@ -196,6 +210,11 @@ class ValueSerializer {
// The conveyor used to keep shared objects alive.
SharedObjectConveyorHandles* shared_object_conveyor_ = nullptr;
+
+ v8::ValueSerializer::SharedImmutableArrayBufferMode
+ share_immutable_array_buffer_ =
+ v8::ValueSerializer::SharedImmutableArrayBufferMode::kDisabled;
+ std::vector<std::shared_ptr<BackingStore>> shared_immutable_backing_stores_;
};
/*
@@ -245,6 +264,11 @@ class ValueDeserializer {
void TransferArrayBuffer(uint32_t transfer_id,
DirectHandle<JSArrayBuffer> array_buffer);
+ void SetSharedImmutableBackingStores(
+ std::vector<std::shared_ptr<BackingStore>> stores) {
+ shared_immutable_backing_stores_ = std::move(stores);
+ }
+
/*
* Publicly exposed wire format writing methods.
* These are intended for use within the delegate's WriteHostObject method.
@@ -307,6 +331,8 @@ class ValueDeserializer {
bool is_immutable) V8_WARN_UNUSED_RESULT;
MaybeDirectHandle<JSArrayBuffer> ReadTransferredJSArrayBuffer()
V8_WARN_UNUSED_RESULT;
+ MaybeDirectHandle<JSArrayBuffer> ReadSharedImmutableJSArrayBuffer()
+ V8_WARN_UNUSED_RESULT;
MaybeDirectHandle<JSArrayBufferView> ReadJSArrayBufferView(
DirectHandle<JSArrayBuffer> buffer) V8_WARN_UNUSED_RESULT;
bool ValidateJSArrayBufferViewFlags(
@@ -348,6 +374,8 @@ class ValueDeserializer {
// The conveyor used to keep shared objects alive.
const SharedObjectConveyorHandles* shared_object_conveyor_ = nullptr;
+
+ std::vector<std::shared_ptr<BackingStore>> shared_immutable_backing_stores_;
};
} // namespace internal
diff --git a/deps/v8/src/parsing/parse-info.cc b/deps/v8/src/parsing/parse-info.cc
index 31c278f4c65..ae0644a059c 100644
--- a/deps/v8/src/parsing/parse-info.cc
+++ b/deps/v8/src/parsing/parse-info.cc
@@ -67,14 +67,20 @@ UnoptimizedCompileFlags UnoptimizedCompileFlags::ForScriptCompile(
UnoptimizedCompileFlags flags(isolate, script->id());
flags.SetFlagsForToplevelCompile(
- script->IsUserJavaScript(), flags.outer_language_mode(),
+ script->IsUserJavaScript(), script->outer_language_mode(),
construct_repl_mode(script->is_repl_mode()),
script->origin_options().IsModule() ? ScriptType::kModule
: 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);
+ flags.set_is_eval(true);
}
return flags;
@@ -145,8 +151,7 @@ void UnoptimizedCompileFlags::SetFlagsForFunctionFromScript(
Tagged<Script> script) {
DCHECK_EQ(script_id(), script->id());
- set_is_eval(is_toplevel() &&
- script->compilation_type() == Script::CompilationType::kEval);
+ set_is_eval(is_toplevel() && script->has_eval_origin());
set_is_module(script->origin_options().IsModule());
DCHECK_IMPLIES(is_eval(), !is_module());
@@ -263,13 +268,15 @@ Handle<Script> ParseInfo::CreateScript(
}
raw_script->set_origin_options(origin_options);
raw_script->set_is_repl_mode(flags().is_repl_mode());
+ raw_script->set_outer_language_mode(flags().outer_language_mode());
DCHECK_EQ(is_wrapped_as_function(), !maybe_wrapped_arguments.is_null());
if (is_wrapped_as_function()) {
+ raw_script->set_compilation_kind(Script::CompilationKind::kWrapped);
raw_script->set_wrapped_arguments(
*maybe_wrapped_arguments.ToHandleChecked());
} else if (flags().is_eval()) {
- raw_script->set_compilation_type(Script::CompilationType::kEval);
+ raw_script->set_compilation_kind(Script::CompilationKind::kDirectEval);
}
CheckFlagsForToplevelCompileFromScript(raw_script);
@@ -316,8 +323,7 @@ void ParseInfo::CheckFlagsForFunctionFromScript(Tagged<Script> script) {
// We set "is_eval" for wrapped scripts to get an outer declaration scope.
// This is a bit hacky, but ok since we can't be both eval and wrapped.
DCHECK_EQ(flags().is_eval() && !script->is_wrapped(),
- flags().is_toplevel() &&
- script->compilation_type() == Script::CompilationType::kEval);
+ flags().is_toplevel() && script->has_eval_origin());
DCHECK_EQ(flags().is_module(), script->origin_options().IsModule());
DCHECK_IMPLIES(flags().block_coverage_enabled() && script->IsUserJavaScript(),
source_range_map() != nullptr);
diff --git a/deps/v8/src/parsing/parser-base.h b/deps/v8/src/parsing/parser-base.h
index db7a75291d1..54dde689b45 100644
--- a/deps/v8/src/parsing/parser-base.h
+++ b/deps/v8/src/parsing/parser-base.h
@@ -1209,42 +1209,36 @@ class ParserBase {
//
// `of`: for ( [lookahead ≠ using of] ForDeclaration[?Yield, ?Await, +Using]
// of AssignmentExpression[+In, ?Yield, ?Await] )
- //
- // If `using` is not considered a keyword, it is parsed as an identifier.
Token::Value token_after_using =
is_await_using ? PeekAheadAhead() : PeekAhead();
- if (v8_flags.js_explicit_resource_management) {
- switch (token_after_using) {
- case Token::kIdentifier:
- case Token::kStatic:
- case Token::kLet:
- case Token::kYield:
- case Token::kAwait:
- case Token::kGet:
- case Token::kSet:
- case Token::kUsing:
- case Token::kAccessor:
- case Token::kAsync:
+ switch (token_after_using) {
+ case Token::kIdentifier:
+ case Token::kStatic:
+ case Token::kLet:
+ case Token::kYield:
+ case Token::kAwait:
+ case Token::kGet:
+ case Token::kSet:
+ case Token::kUsing:
+ case Token::kAccessor:
+ case Token::kAsync:
+ return true;
+ case Token::kOf:
+ if (is_await_using) {
return true;
- case Token::kOf:
- if (is_await_using) {
- return true;
- } else {
- // In the case of synchronous `using`, `of` is disallowed as well
- // with a negative lookahead for for-of loops. But, cursedly,
- // `using of` is allowed as the initializer of C-style for loops,
- // e.g. `for (using of = null;;)` parses.
- Token::Value token_after_of = PeekAheadAhead();
- return token_after_of == Token::kAssign;
- }
- case Token::kFutureStrictReservedWord:
- case Token::kEscapedStrictReservedWord:
- return is_sloppy(language_mode());
- default:
- return false;
- }
- } else {
- return false;
+ } else {
+ // In the case of synchronous `using`, `of` is disallowed as well
+ // with a negative lookahead for for-of loops. But, cursedly,
+ // `using of` is allowed as the initializer of C-style for loops,
+ // e.g. `for (using of = null;;)` parses.
+ Token::Value token_after_of = PeekAheadAhead();
+ return token_after_of == Token::kAssign;
+ }
+ case Token::kFutureStrictReservedWord:
+ case Token::kEscapedStrictReservedWord:
+ return is_sloppy(language_mode());
+ default:
+ return false;
}
}
bool IfStartsWithUsingOrAwaitUsingKeyword() {
@@ -4557,7 +4551,6 @@ void ParserBase<Impl>::ParseVariableDeclarations(
// using [no LineTerminator here] BindingList[?In, ?Yield, ?Await,
// ~Pattern] ;
Consume(Token::kUsing);
- DCHECK(v8_flags.js_explicit_resource_management);
DCHECK_NE(var_context, kStatement);
DCHECK(is_using_allowed());
DCHECK(!scanner()->HasLineTerminatorBeforeNext());
@@ -4569,7 +4562,6 @@ void ParserBase<Impl>::ParseVariableDeclarations(
// CoverAwaitExpressionAndAwaitUsingDeclarationHead[?Yield] [no
// LineTerminator here] BindingList[?In, ?Yield, +Await, ~Pattern];
Consume(Token::kAwait);
- DCHECK(v8_flags.js_explicit_resource_management);
DCHECK_NE(var_context, kStatement);
DCHECK(is_using_allowed());
DCHECK(is_await_allowed());
@@ -5846,7 +5838,6 @@ ParserBase<Impl>::ParseStatementListItem() {
}
break;
case Token::kUsing:
- if (!v8_flags.js_explicit_resource_management) break;
if (!is_using_allowed()) break;
if (!(scanner()->HasLineTerminatorAfterNext()) &&
Token::IsAnyIdentifier(PeekAhead())) {
@@ -5854,7 +5845,6 @@ ParserBase<Impl>::ParseStatementListItem() {
}
break;
case Token::kAwait:
- if (!v8_flags.js_explicit_resource_management) break;
if (!is_await_allowed()) break;
if (!is_using_allowed()) break;
if (!(scanner()->HasLineTerminatorAfterNext()) &&
diff --git a/deps/v8/src/parsing/parser.cc b/deps/v8/src/parsing/parser.cc
index a80275f796e..00dab82d04b 100644
--- a/deps/v8/src/parsing/parser.cc
+++ b/deps/v8/src/parsing/parser.cc
@@ -778,12 +778,6 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info,
DCHECK_EQ(parsing_on_main_thread_, isolate != nullptr);
DCHECK_NULL(scope_);
- std::optional<base::ElapsedTimer> timer;
- if (v8_flags.enable_parser_ablation && base::TimeTicks::IsHighResolution()) {
- timer.emplace();
- timer->Start();
- }
-
ScopedModification<Mode> mode_scope(
&mode_, allow_lazy_ ? PARSE_LAZILY : PARSE_EAGERLY);
ResetInfoId(kFunctionLiteralIdTopLevel);
@@ -892,16 +886,6 @@ FunctionLiteral* Parser::DoParseProgram(Isolate* isolate, ParseInfo* info,
RecordFunctionLiteralSourceRange(result);
- if (timer && timer->Elapsed().InNanoseconds() > 0) {
- auto end = timer->Elapsed();
- end += std::min(base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromMicroseconds(
- static_cast<double>(end.InMicroseconds()) *
- v8_flags.parser_ablation_amount));
- while (timer->Elapsed() < end) {
- }
- }
-
return result;
}
@@ -926,7 +910,9 @@ void Parser::PostProcessParseResult(IsolateT* isolate, ParseInfo* info,
if (scope->is_script_scope()) {
for (Variable* var : *scope->locals()) {
var->set_is_used();
- var->SetMaybeAssigned();
+ if (var->mode() != VariableMode::kConst || flags().is_repl_mode()) {
+ var->SetMaybeAssigned();
+ }
}
}
@@ -957,6 +943,8 @@ ZonePtrList<const AstRawString>* Parser::PrepareWrappedArguments(
DirectHandle<FixedArray> arguments =
maybe_wrapped_arguments_.ToHandleChecked();
uint32_t arguments_length = arguments->ulength().value();
+ SBXCHECK_LE(arguments_length, static_cast<uint32_t>(Code::kMaxArguments -
+ kJSArgcReceiverSlots));
ZonePtrList<const AstRawString>* arguments_for_wrapped_function =
zone->New<ZonePtrList<const AstRawString>>(arguments_length, zone);
for (uint32_t i = 0; i < arguments_length; i++) {
@@ -1157,12 +1145,6 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
DCHECK_NOT_NULL(raw_name);
DCHECK_NULL(scope_);
- std::optional<base::ElapsedTimer> timer;
- if (v8_flags.enable_parser_ablation && base::TimeTicks::IsHighResolution()) {
- timer.emplace();
- timer->Start();
- }
-
DCHECK(ast_value_factory());
fni_.PushEnclosingName(raw_name);
@@ -1276,16 +1258,6 @@ FunctionLiteral* Parser::DoParseFunction(Isolate* isolate, ParseInfo* info,
info->set_max_info_id(GetLastInfoId());
- if (timer && timer->Elapsed().InNanoseconds() > 0) {
- auto end = timer->Elapsed();
- end += std::min(base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromMicroseconds(
- static_cast<double>(end.InMicroseconds()) *
- v8_flags.parser_ablation_amount));
- while (timer->Elapsed() < end) {
- }
- }
-
DCHECK_IMPLIES(result, function_literal_id == result->function_literal_id());
return result;
}
@@ -1772,18 +1744,22 @@ void Parser::ParseImportDeclaration() {
if (module_namespace_binding != nullptr) {
DCHECK(import_phase == ModuleImportPhase::kEvaluation ||
import_phase == ModuleImportPhase::kDefer);
- module()->AddStarImport(
+ bool is_new = module()->AddStarImport(
module_namespace_binding, module_specifier, import_phase,
import_attributes, module_namespace_binding_loc, specifier_loc, zone());
+ USE(is_new);
+ DCHECK_IMPLIES(!is_new, has_error());
}
if (import_default_binding != nullptr) {
DCHECK_IMPLIES(import_phase == ModuleImportPhase::kSource,
v8_flags.js_source_phase_imports);
- module()->AddImport(ast_value_factory()->default_string(),
- import_default_binding, module_specifier, import_phase,
- import_attributes, import_default_binding_loc,
- specifier_loc, zone());
+ bool is_new = module()->AddImport(
+ ast_value_factory()->default_string(), import_default_binding,
+ module_specifier, import_phase, import_attributes,
+ import_default_binding_loc, specifier_loc, zone());
+ USE(is_new);
+ DCHECK_IMPLIES(!is_new, has_error());
}
if (named_imports != nullptr) {
@@ -1793,9 +1769,12 @@ void Parser::ParseImportDeclaration() {
specifier_loc, zone());
} else {
for (const NamedImport* import : *named_imports) {
- module()->AddImport(import->import_name, import->local_name,
- module_specifier, import_phase, import_attributes,
- import->location, specifier_loc, zone());
+ bool is_new = module()->AddImport(
+ import->import_name, import->local_name, module_specifier,
+ import_phase, import_attributes, import->location, specifier_loc,
+ zone());
+ USE(is_new);
+ DCHECK_IMPLIES(!is_new, has_error());
}
}
}
@@ -1921,9 +1900,11 @@ void Parser::ParseExportStar() {
const ImportAttributes* import_attributes = ParseImportWithOrAssertClause();
ExpectSemicolon();
- module()->AddStarImport(local_name, module_specifier,
- ModuleImportPhase::kEvaluation, import_attributes,
- local_name_loc, specifier_loc, zone());
+ bool is_new = module()->AddStarImport(
+ local_name, module_specifier, ModuleImportPhase::kEvaluation,
+ import_attributes, local_name_loc, specifier_loc, zone());
+ USE(is_new);
+ DCHECK(is_new);
module()->AddExport(local_name, export_name, export_name_loc, zone());
}
@@ -3115,13 +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");
- std::optional<base::ElapsedTimer> timer;
- if (v8_flags.enable_preparser_ablation &&
- base::TimeTicks::IsHighResolution()) {
- timer.emplace();
- timer->Start();
- }
-
reusable_preparser()->set_has_generator_in_scope_chain(
has_generator_in_scope_chain());
reusable_preparser()->set_max_drift(this->max_drift());
@@ -3129,16 +3103,6 @@ bool Parser::SkipFunction(int function_literal_id,
function_literal_id, function_name, kind, function_syntax_kind,
function_scope, use_counts_, produced_preparse_data);
- if (timer && timer->Elapsed().InNanoseconds() > 0) {
- auto end = timer->Elapsed();
- end += std::min(base::TimeDelta::FromSeconds(1),
- base::TimeDelta::FromMicroseconds(
- static_cast<double>(end.InMicroseconds()) *
- v8_flags.preparser_ablation_amount));
- while (timer->Elapsed() < end) {
- }
- }
-
if (result == PreParser::kPreParseStackOverflow) {
// Propagate stack overflow.
set_stack_overflow();
diff --git a/deps/v8/src/parsing/token.h b/deps/v8/src/parsing/token.h
index 1dd1eefc99c..a851946acd5 100644
--- a/deps/v8/src/parsing/token.h
+++ b/deps/v8/src/parsing/token.h
@@ -305,6 +305,10 @@ class V8_EXPORT_PRIVATE Token {
return base::IsInRange(op, kBitOr, kSub);
}
+ static bool IsUnaryOpWithEmbeddedFeedback(Value op) {
+ return op == kSub || op == kBitNot || op == kInc || op == kDec;
+ }
+
static bool IsOrderedRelationalCompareOp(Value op) {
return base::IsInRange(op, kLessThan, kGreaterThanEq);
}
diff --git a/deps/v8/src/profiler/heap-profiler.cc b/deps/v8/src/profiler/heap-profiler.cc
index 1bc589b71c0..f7598197881 100644
--- a/deps/v8/src/profiler/heap-profiler.cc
+++ b/deps/v8/src/profiler/heap-profiler.cc
@@ -365,6 +365,7 @@ void HeapProfiler::QueryObjects(DirectHandle<Context> context,
heap(), HeapObjectIterator::kFilterUnreachable);
for (Tagged<HeapObject> heap_obj = heap_iterator.Next();
!heap_obj.is_null(); heap_obj = heap_iterator.Next()) {
+ if (IsInaccessible(heap_obj)) continue;
if (IsFeedbackVector(heap_obj)) {
Cast<FeedbackVector>(heap_obj)->ClearSlots(isolate());
} else if (IsJSTypedArray(heap_obj) &&
@@ -388,6 +389,7 @@ void HeapProfiler::QueryObjects(DirectHandle<Context> context,
heap(), HeapObjectIterator::kFilterUnreachable);
for (Tagged<HeapObject> heap_obj = heap_iterator.Next();
!heap_obj.is_null(); heap_obj = heap_iterator.Next()) {
+ if (IsInaccessible(heap_obj)) continue;
if (!IsJSObject(heap_obj) || IsJSExternalObject(heap_obj)) continue;
v8::Local<v8::Object> v8_obj(
Utils::ToLocal(direct_handle(Cast<JSObject>(heap_obj), isolate())));
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.cc b/deps/v8/src/profiler/heap-snapshot-generator.cc
index c4068641bba..1683d0f8430 100644
--- a/deps/v8/src/profiler/heap-snapshot-generator.cc
+++ b/deps/v8/src/profiler/heap-snapshot-generator.cc
@@ -45,8 +45,11 @@
#include "src/objects/js-regexp-inl.h"
#include "src/objects/js-weak-refs-inl.h"
#include "src/objects/literal-objects-inl.h"
+#include "src/objects/managed-inl.h"
#include "src/objects/map-inl.h"
#include "src/objects/name-inl.h"
+#include "src/objects/object-conversions-inl.h"
+#include "src/objects/objects-body-descriptors-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/prototype.h"
#include "src/objects/slots-inl.h"
@@ -779,9 +782,12 @@ void HeapObjectsMap::AddMergedNativeEntry(NativeObject addr,
ComputeAddressHash(canonical_addr));
auto result = merged_native_entries_map_.insert(
{addr, reinterpret_cast<size_t>(entry->value)});
- if (!result.second) {
- result.first->second = reinterpret_cast<size_t>(entry->value);
- }
+ DCHECK(result.second);
+ USE(result);
+}
+
+void HeapObjectsMap::ClearMergedNativeEntries() {
+ merged_native_entries_map_.clear();
}
void HeapObjectsMap::StopHeapObjectsTracking() { time_intervals_.clear(); }
@@ -798,6 +804,7 @@ void HeapObjectsMap::UpdateHeapObjectsMap() {
obj = iterator.Next()) {
FindOrAddEntry(obj.address(), SizeForSnapshot(obj));
if (v8_flags.heap_profiler_trace_objects) {
+ if (IsInaccessible(obj)) continue;
int object_size = obj->Size();
PrintF("Update object : %p %6d. Next address is %p\n",
reinterpret_cast<void*>(obj.address()), object_size,
@@ -997,6 +1004,9 @@ void V8HeapExplorer::ExtractLocationForJSFunction(HeapEntry* entry,
}
HeapEntry* V8HeapExplorer::AddEntry(Tagged<HeapObject> object) {
+ if (IsWasmNull(object)) {
+ return AddEntry(object, HeapEntry::kNative, "null (wasm)");
+ }
InstanceType instance_type = object->map()->instance_type();
if (InstanceTypeChecker::IsJSObject(instance_type)) {
if (InstanceTypeChecker::IsJSFunction(instance_type)) {
@@ -1063,8 +1073,9 @@ HeapEntry* V8HeapExplorer::AddEntry(Tagged<HeapObject> object) {
} else if (IsSlicedString(string)) {
return AddEntry(object, HeapEntry::kSlicedString, "(sliced string)");
} else {
- return AddEntry(object, HeapEntry::kString,
- names_->GetName(Cast<String>(object)));
+ const char* name = IsScriptSource(string) ? names_->GetUntruncated(string)
+ : names_->GetName(string);
+ return AddEntry(object, HeapEntry::kString, name);
}
} else if (InstanceTypeChecker::IsSymbol(instance_type)) {
if (Cast<Symbol>(object)->is_any_private()) {
@@ -1136,6 +1147,23 @@ HeapEntry* V8HeapExplorer::AddEntry(Tagged<HeapObject> object) {
}
#endif // V8_ENABLE_WEBASSEMBLY
+ if (InstanceTypeChecker::IsCppGCManagedBase(instance_type)) {
+ size_t size = SizeForSnapshot(object);
+ Tagged<CppGCManagedBase> managed = Cast<CppGCManagedBase>(object);
+ const char* tag_name = ToString(managed->GetWrapper()->type_id());
+ const char* name =
+ names_->GetFormatted("system / CppGCManaged (%s)", tag_name);
+#if V8_ENABLE_WEBASSEMBLY
+ if (managed->GetWrapper()->type_id() == ManagedTypeId::kWasmNativeModule) {
+ DisallowGarbageCollection no_gc;
+ size = Cast<CppGCManaged<wasm::NativeModule>>(managed)
+ ->raw(no_gc)
+ ->EstimateCurrentMemoryConsumption();
+ }
+#endif // V8_ENABLE_WEBASSEMBLY
+ return AddEntry(object.address(), HeapEntry::kNative, name, size);
+ }
+
if (InstanceTypeChecker::IsForeign(instance_type)) {
Tagged<Foreign> foreign = Cast<Foreign>(object);
ExternalPointerTag tag = foreign->GetTag();
@@ -1146,14 +1174,6 @@ HeapEntry* V8HeapExplorer::AddEntry(Tagged<HeapObject> object) {
if (kAnyManagedExternalPointerTagRange.Contains(tag)) {
const char* tag_name = ToString(tag);
name = names_->GetFormatted("system / Managed (%s)", tag_name);
-#if V8_ENABLE_WEBASSEMBLY
- if (tag == kWasmNativeModuleTag) {
- DisallowGarbageCollection no_gc;
- size = Cast<Managed<wasm::NativeModule>>(foreign)
- ->raw(no_gc)
- ->EstimateCurrentMemoryConsumption();
- }
-#endif // V8_ENABLE_WEBASSEMBLY
} else if (kAnyForeignExternalPointerTagRange.Contains(tag)) {
// Only sandbox configurations set tags properly, so we cannot CHECK here
// but merely improve the tag if present.
@@ -1217,10 +1237,8 @@ const char* V8HeapExplorer::GetSystemEntryName(Tagged<HeapObject> object) {
// The following lists include every non-String instance type.
// This includes a few types that already have non-"system" names assigned
// by AddEntry, but this is a convenient way to avoid manual upkeep here.
- TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
- TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(MAKE_TORQUE_CASE)
- TORQUE_INSTANCE_CHECKERS_SINGLE_ONLY_DECLARED(MAKE_TORQUE_CASE)
- TORQUE_INSTANCE_CHECKERS_MULTIPLE_ONLY_DECLARED(MAKE_TORQUE_CASE)
+ INSTANCE_TYPE_LIST_SINGLE(MAKE_TORQUE_CASE)
+ INSTANCE_TYPE_LIST_MULTIPLE(MAKE_TORQUE_CASE)
#undef MAKE_TORQUE_CASE
// Strings were already handled by AddEntry.
@@ -1229,6 +1247,11 @@ const char* V8HeapExplorer::GetSystemEntryName(Tagged<HeapObject> object) {
UNREACHABLE();
STRING_TYPE_LIST(MAKE_STRING_CASE)
#undef MAKE_STRING_CASE
+
+#if V8_ENABLE_WEBASSEMBLY
+ case WASM_NULL_TYPE:
+ return "system / WasmNull";
+#endif // V8_ENABLE_WEBASSEMBLY
}
// Avoid undefined behavior for enum values not handled by the exhaustive
@@ -1304,6 +1327,30 @@ void V8HeapExplorer::PopulateLineEnds() {
}
}
+void V8HeapExplorer::RecordScriptSources() {
+ Script::Iterator iterator(isolate());
+ for (Tagged<Script> script = iterator.Next(); !script.is_null();
+ script = iterator.Next()) {
+ Tagged<Object> source = script->source();
+ if (!IsString(source)) continue;
+ // While script sources are flattened, the source isn't guaranteed to be a
+ // sequential string. A ConsString for example flattens to
+ // ConsString(<flattened>, "").
+ Tagged<String> current = Cast<String>(source);
+ while (script_sources_.insert(current).second) {
+ if (IsConsString(current)) {
+ current = Cast<ConsString>(current)->first();
+ } else if (IsSlicedString(current)) {
+ current = Cast<SlicedString>(current)->parent();
+ } else if (IsThinString(current)) {
+ current = Cast<ThinString>(current)->actual();
+ } else {
+ break;
+ }
+ }
+ }
+}
+
uint32_t V8HeapExplorer::EstimateObjectsCount() {
CombinedHeapObjectIterator it(heap_, HeapObjectIterator::kNoFiltering);
uint32_t objects_count = 0;
@@ -1369,24 +1416,6 @@ class IndexedReferencesExtractor : public ObjectVisitorWithCageBases {
VisitSlotImpl(code_cage_base(), slot);
}
- void VisitCodeTarget(Tagged<InstructionStream> host,
- RelocInfo* rinfo) override {
- Tagged<InstructionStream> target =
- InstructionStream::FromTargetAddress(rinfo->target_address());
- VisitHeapObjectImpl(target, -1);
- }
-
- void VisitEmbeddedPointer(Tagged<InstructionStream> host,
- RelocInfo* rinfo) override {
- Tagged<HeapObject> object = rinfo->target_object();
- Tagged<Code> code = UncheckedCast<Code>(host->raw_code(kAcquireLoad));
- if (code->IsWeakObject(object)) {
- generator_->SetWeakReference(parent_, next_index_++, object, {});
- } else {
- VisitHeapObjectImpl(object, -1);
- }
- }
-
void VisitIndirectPointer(Tagged<HeapObject> host, IndirectPointerSlot slot,
IndirectPointerMode mode) override {
VisitSlotImpl(generator_->isolate(), slot);
@@ -1566,6 +1595,8 @@ void V8HeapExplorer::ExtractReferences(HeapEntry* entry,
ExtractScopeInfoReferences(entry, Cast<ScopeInfo>(obj));
} else if (IsCppHeapExternalObject(obj)) {
ExtractCppHeapExternalReferences(entry, Cast<CppHeapExternalObject>(obj));
+ } else if (IsCppGCManagedBase(obj)) {
+ ExtractCppGCManagedBaseReferences(entry, Cast<CppGCManagedBase>(obj));
#if V8_ENABLE_WEBASSEMBLY
} else if (IsWasmStruct(obj)) {
ExtractWasmStructReferences(Cast<WasmStruct>(obj), entry);
@@ -1737,7 +1768,7 @@ class ExternalStringRecorder
void V8HeapExplorer::ExtractStringReferences(HeapEntry* entry,
Tagged<String> string) {
AddIntEdge(entry, HeapGraphEdge::kInternal, "length", string->length());
- if (names_->NeedsTruncation(string->length())) {
+ if (names_->NeedsTruncation(string->length()) && !IsScriptSource(string)) {
AddBoolEdge(entry, HeapGraphEdge::kInternal, "truncated", true);
AddIntEdge(entry, HeapGraphEdge::kInternal, "hash",
static_cast<int>(string->EnsureHash()));
@@ -1844,7 +1875,7 @@ static const struct {
void V8HeapExplorer::ExtractContextReferences(HeapEntry* entry,
Tagged<Context> context) {
DisallowGarbageCollection no_gc;
- if (!IsNativeContext(context) && context->is_declaration_context()) {
+ if (!IsNativeContext(context)) {
Tagged<ScopeInfo> scope_info = context->scope_info();
// Add context allocated locals.
for (auto it : ScopeInfo::IterateLocalNames(scope_info, no_gc)) {
@@ -2060,10 +2091,10 @@ void V8HeapExplorer::ExtractScriptReferences(HeapEntry* entry,
static_cast<int>(script->type()));
AddStringEdge(entry, HeapGraphEdge::kInternal, "script_type_name",
ToString(script->type()));
- AddIntEdge(entry, HeapGraphEdge::kInternal, "compilation_type",
- static_cast<int>(script->compilation_type()));
- AddStringEdge(entry, HeapGraphEdge::kInternal, "compilation_type_name",
- ToString(script->compilation_type()));
+ AddIntEdge(entry, HeapGraphEdge::kInternal, "compilation_kind",
+ static_cast<int>(script->compilation_kind()));
+ AddStringEdge(entry, HeapGraphEdge::kInternal, "compilation_kind_name",
+ ToString(script->compilation_kind()));
AddIntEdge(entry, HeapGraphEdge::kInternal, "compilation_state",
static_cast<int>(script->compilation_state()));
AddStringEdge(entry, HeapGraphEdge::kInternal, "compilation_state_name",
@@ -2238,6 +2269,29 @@ void V8HeapExplorer::ExtractInstructionStreamReferences(
HeapEntry::kCode);
SetInternalReference(entry, "relocation_info", istream->relocation_info(),
InstructionStream::kRelocationInfoOffset);
+
+ if (istream->IsFullyInitialized()) {
+ int reloc_index = 0;
+ for (RelocIterator it(istream,
+ InstructionStream::BodyDescriptor::kRelocModeMask);
+ !it.done(); it.next()) {
+ RelocInfo* rinfo = it.rinfo();
+ if (RelocInfo::IsCodeTargetMode(rinfo->rmode())) {
+ Tagged<InstructionStream> target =
+ InstructionStream::FromTargetAddress(rinfo->target_address());
+ SetHiddenReference(istream, entry, reloc_index++, target,
+ -1 * kTaggedSize);
+ } else if (RelocInfo::IsEmbeddedObjectMode(rinfo->rmode())) {
+ Tagged<HeapObject> object = rinfo->target_object();
+ if (code->IsWeakObject(object)) {
+ SetWeakReference(entry, reloc_index++, object, {});
+ } else {
+ SetHiddenReference(istream, entry, reloc_index++, object,
+ -1 * kTaggedSize);
+ }
+ }
+ }
+ }
}
void V8HeapExplorer::ExtractCellReferences(HeapEntry* entry,
@@ -2338,6 +2392,8 @@ void V8HeapExplorer::ExtractJSGeneratorObjectReferences(
SetInternalReference(entry, "parameters_and_registers",
generator->parameters_and_registers(),
offsetof(JSGeneratorObject, parameters_and_registers_));
+ AddIntEdge(entry, HeapGraphEdge::kInternal, "continuation",
+ generator->continuation());
}
void V8HeapExplorer::ExtractFixedArrayReferences(HeapEntry* entry,
@@ -2394,6 +2450,8 @@ void V8HeapExplorer::ExtractScopeInfoReferences(HeapEntry* entry,
AddIntEdge(entry, HeapGraphEdge::kInternal, "scope_type", info->scope_type());
AddStringEdge(entry, HeapGraphEdge::kInternal, "scope_type_name",
ToString(info->scope_type()));
+ AddIntEdge(entry, HeapGraphEdge::kInternal, "scope_id",
+ info->UniqueIdInScript());
AddIntEdge(entry, HeapGraphEdge::kInternal, "context_local_count",
info->ContextLocalCount());
AddIntEdge(entry, HeapGraphEdge::kInternal, "parameter_count",
@@ -2607,6 +2665,11 @@ void V8HeapExplorer::ExtractCppHeapExternalReferences(
generator_->GetCppHeapWrappers().insert(obj);
}
+void V8HeapExplorer::ExtractCppGCManagedBaseReferences(
+ HeapEntry* entry, Tagged<CppGCManagedBase> obj) {
+ generator_->GetCppHeapWrappers().insert(obj);
+}
+
#if V8_ENABLE_WEBASSEMBLY
void V8HeapExplorer::ExtractWasmStructReferences(Tagged<WasmStruct> obj,
@@ -2834,6 +2897,9 @@ bool V8HeapExplorer::IterateAndExtractReferences(
obj = iterator.Next(), progress_->ProgressStep()) {
if (interrupted) continue;
+ // There's nothing interesting to see for inaccessible objects anyway.
+ if (IsInaccessible(obj)) continue;
+
max_pointers_ = obj->Size() / kTaggedSize;
if (max_pointers_ > visited_fields_.size()) {
// Reallocate to right size.
@@ -2887,8 +2953,8 @@ bool V8HeapExplorer::IsEssentialObject(Tagged<Object> object) {
}
Isolate* isolate = heap_->isolate();
ReadOnlyRoots roots(isolate);
- return !IsAnyHole(object) && !IsOddball(object) &&
- object != roots.empty_byte_array() &&
+ return !IsInaccessible(Cast<HeapObject>(object)) && !IsAnyHole(object) &&
+ !IsOddball(object) && object != roots.empty_byte_array() &&
object != roots.empty_fixed_array() &&
object != roots.empty_weak_fixed_array() &&
object != roots.empty_descriptor_array() &&
@@ -3512,6 +3578,11 @@ bool NativeObjectsExplorer::IterateAndExtractReferences(
DisallowGarbageCollection no_gc;
HandleScope scope(isolate_);
+ // Native objects can be replaced while their JS wrapper survives.
+ // Rebuild these associations each snapshot instead of retaining
+ // 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_,
@@ -3676,6 +3747,7 @@ bool HeapSnapshotGenerator::GenerateSnapshot() {
snapshot_->AddSyntheticRootEntries();
v8_heap_explorer_.PopulateLineEnds();
+ v8_heap_explorer_.RecordScriptSources();
if (!FillReferences()) return false;
snapshot_->FillChildren();
@@ -3711,6 +3783,7 @@ bool HeapSnapshotGenerator::GenerateSnapshotAfterGC() {
std::move(temporary_native_context_tags));
snapshot_->AddSyntheticRootEntries();
v8_heap_explorer_.PopulateLineEnds();
+ v8_heap_explorer_.RecordScriptSources();
if (!FillReferences()) return false;
snapshot_->FillChildren();
snapshot_->RememberLastJSObjectId();
diff --git a/deps/v8/src/profiler/heap-snapshot-generator.h b/deps/v8/src/profiler/heap-snapshot-generator.h
index 8488c9a7f0b..afb3175da35 100644
--- a/deps/v8/src/profiler/heap-snapshot-generator.h
+++ b/deps/v8/src/profiler/heap-snapshot-generator.h
@@ -14,6 +14,7 @@
#include <vector>
#include "absl/container/flat_hash_map.h"
+#include "absl/container/flat_hash_set.h"
#include "include/v8-profiler.h"
#include "src/base/platform/time.h"
#include "src/execution/isolate.h"
@@ -365,6 +366,7 @@ class HeapObjectsMap {
IsNativeObject is_native_object = IsNativeObject::kNo);
SnapshotObjectId FindMergedNativeEntry(NativeObject addr);
void AddMergedNativeEntry(NativeObject addr, Address canonical_addr);
+ void ClearMergedNativeEntries();
V8_EXPORT_PRIVATE bool ContainsEntryWithIdForTesting(
SnapshotObjectId id) const;
@@ -458,6 +460,7 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
HeapEntry* AllocateEntry(Tagged<Smi> smi) override;
uint32_t EstimateObjectsCount();
void PopulateLineEnds();
+ void RecordScriptSources();
bool IterateAndExtractReferences(HeapSnapshotGenerator* generator);
struct NativeContextTagInfo {
@@ -574,6 +577,8 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
void ExtractInternalReferences(Tagged<JSObject> js_obj, HeapEntry* entry);
void ExtractCppHeapExternalReferences(HeapEntry* entry,
Tagged<CppHeapExternalObject> obj);
+ void ExtractCppGCManagedBaseReferences(HeapEntry* entry,
+ Tagged<CppGCManagedBase> obj);
#if V8_ENABLE_WEBASSEMBLY
void ExtractWasmStructReferences(Tagged<WasmStruct> obj, HeapEntry* entry);
@@ -637,6 +642,9 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
HeapEntry::Type type, int recursion_limit);
HeapEntry* GetEntry(Tagged<Object> obj);
+ bool IsScriptSource(Tagged<String> string) const {
+ return script_sources_.contains(string);
+ }
Heap* heap_;
HeapSnapshot* snapshot_;
@@ -648,6 +656,8 @@ class V8_EXPORT_PRIVATE V8HeapExplorer : public HeapEntriesAllocator {
native_context_tag_map_;
UnorderedHeapObjectMap<const char*> strong_gc_subroot_names_;
std::unordered_set<Tagged<NativeContext>, Object::Hasher> user_roots_;
+ absl::flat_hash_set<Tagged<String>, Object::Hasher, Object::KeyEqualSafe>
+ script_sources_;
v8::HeapProfiler::ContextNameResolver* native_context_name_resolver_;
std::vector<bool> visited_fields_;
diff --git a/deps/v8/src/profiler/output-stream-writer.h b/deps/v8/src/profiler/output-stream-writer.h
index 94b417bb6c1..0b776f95967 100644
--- a/deps/v8/src/profiler/output-stream-writer.h
+++ b/deps/v8/src/profiler/output-stream-writer.h
@@ -74,7 +74,10 @@ class OutputStreamWriter {
if (chunk_pos_ != 0) {
WriteChunk();
}
- stream_->EndOfStream();
+ // Writing the final chunk above may itself have been aborted by the
+ // stream. v8::OutputStream guarantees that EndOfStream() is not called
+ // once writing was aborted.
+ if (!aborted_) stream_->EndOfStream();
}
private:
diff --git a/deps/v8/src/profiler/strings-storage.cc b/deps/v8/src/profiler/strings-storage.cc
index a24615b3dc0..47e90196b35 100644
--- a/deps/v8/src/profiler/strings-storage.cc
+++ b/deps/v8/src/profiler/strings-storage.cc
@@ -107,6 +107,12 @@ const char* StringsStorage::GetName(Tagged<Name> name) {
return "";
}
+const char* StringsStorage::GetUntruncated(Tagged<String> string) {
+ size_t data_length = 0;
+ std::unique_ptr<char[]> data = string->ToCString(&data_length);
+ return AddOrDisposeString(data.release(), data_length);
+}
+
const char* StringsStorage::GetName(int index) {
return GetFormatted("%d", index);
}
diff --git a/deps/v8/src/profiler/strings-storage.h b/deps/v8/src/profiler/strings-storage.h
index 3e5d57aab5f..0b2aa5385bc 100644
--- a/deps/v8/src/profiler/strings-storage.h
+++ b/deps/v8/src/profiler/strings-storage.h
@@ -36,6 +36,8 @@ class V8_EXPORT_PRIVATE StringsStorage {
PRINTF_FORMAT(2, 3) const char* GetFormatted(const char* format, ...);
// Returns a stored string resulting from name, or "<symbol>" for a symbol.
const char* GetName(Tagged<Name> name);
+ // Returns a stored string resulting from string without truncation.
+ const char* GetUntruncated(Tagged<String> string);
// Returns the string representation of the int from the store.
const char* GetName(int index);
// Appends string resulting from name to prefix, then returns the stored
diff --git a/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc b/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc
index 950e2dc738b..df7e96afffe 100644
--- a/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc
+++ b/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.cc
@@ -143,6 +143,15 @@ void RegExpMacroAssemblerLOONG64::AdvanceRegister(int reg, int by) {
}
void RegExpMacroAssemblerLOONG64::Backtrack() {
+ // Defer to the shared backtrack block bound in GetCode: only there, with
+ // the body fully emitted, is it known whether anything was ever pushed.
+ // If nothing was, the only value a pop could yield is the fail label,
+ // so the block reduces to Fail() and the backtrack stack (including the
+ // fail label itself) is elided entirely.
+ __ jmp(&backtrack_label_);
+}
+
+void RegExpMacroAssemblerLOONG64::EmitBacktrack() {
CheckPreemption();
if (has_backtrack_limit()) {
Label next;
@@ -200,6 +209,7 @@ void RegExpMacroAssemblerLOONG64::CheckCharacterLT(base::uc16 limit,
}
void RegExpMacroAssemblerLOONG64::CheckFixedLengthLoop(Label* on_equal) {
+ set_backtrack_stack_used();
Label backtrack_non_equal;
__ Ld_w(a0, MemOperand(backtrack_stackpointer(), 0));
__ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
@@ -711,14 +721,25 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
kBacktrackCountOffset - kSystemPointerSize);
__ Push(a0); // The regexp stack base ptr.
- // Initialize backtrack stack pointer. It must not be clobbered from here
- // on. Note the backtrack_stackpointer is callee-saved.
- static_assert(backtrack_stackpointer() == s7);
- LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ // The body has been fully emitted, so backtrack_stack_used() is now final:
+ // it is true iff some op pushed, popped, or transferred the backtrack stack
+ // pointer. Patterns that never do skip the backtrack stack setup, the fail
+ // label, and the teardown below.
+ if (backtrack_stack_used()) {
+ // Initialize backtrack stack pointer. It must not be clobbered from here
+ // on. Note the backtrack_stackpointer is callee-saved.
+ static_assert(backtrack_stackpointer() == s7);
+ LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
- // Store the regexp base pointer - we'll later restore it / write it to
- // memory when returning from this irregexp code object.
- PushRegExpBasePointer(backtrack_stackpointer(), a1);
+ // Store the regexp base pointer - we'll later restore it / write it to
+ // memory when returning from this irregexp code object. Captured with an
+ // empty stack (delta 0), before the fail label is pushed below, so the
+ // teardown on exit and between global iterations restores to the same
+ // point (regexp::StackScope verifies this delta is unchanged).
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ PushRegExpBasePointer(backtrack_stackpointer(), scratch);
+ }
// Skip the JS stack guard check for patterns whose register file fits
// within the stack limit's guaranteed slack: allocating it then can never
@@ -751,12 +772,19 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
__ jmp(&return_v0);
__ bind(&stack_limit_hit);
- StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
+ // Without a backtrack stack, backtrack_stackpointer() was never
+ // initialized above; storing it would corrupt the saved stack pointer
+ // (regexp::StackScope verifies it is unchanged across the exec call).
+ if (backtrack_stack_used()) {
+ StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
+ }
CallCheckStackGuardState(a0, extra_space_for_variables);
// If returned value is non-zero, we exit with the returned value as
// result.
__ Branch(&return_v0, ne, a0, Operand(zero_reg));
- LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ if (backtrack_stack_used()) {
+ LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ }
__ bind(&stack_ok);
}
@@ -818,6 +846,13 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
}
}
+ if (backtrack_stack_used() && fail_label() != nullptr) {
+ // Push the fail label (see set_fail_label / prologue_pushes_fail_label).
+ // Global matches re-enter here per iteration, each having restored the
+ // stack to base via PopRegExpBasePointer first, so it is refreshed.
+ PushBacktrack(fail_label());
+ }
+
__ jmp(&start_label_);
// Exit code:
@@ -886,9 +921,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
__ Add_d(a2, a2, num_saved_registers_ * kIntSize);
__ St_d(a2, MemOperand(frame_pointer(), kRegisterOutputOffset));
- // Restore the original regexp stack pointer value (effectively, pop the
- // stored base pointer).
- PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ if (backtrack_stack_used()) {
+ // Restore the original regexp stack pointer value (effectively, pop
+ // the stored base pointer).
+ PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ }
Label reload_string_start_minus_one;
@@ -926,9 +963,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
}
__ bind(&return_v0);
- // Restore the original regexp stack pointer value (effectively, pop the
- // stored base pointer).
- PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ if (backtrack_stack_used()) {
+ // Restore the original regexp stack pointer value (effectively, pop the
+ // stored base pointer).
+ PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ }
// Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer());
@@ -939,7 +978,15 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
// Backtrack code (branch target for conditional backtracks).
if (backtrack_label_.is_linked()) {
__ bind(&backtrack_label_);
- Backtrack();
+ if (backtrack_stack_used()) {
+ EmitBacktrack();
+ } else {
+ // Nothing was pushed, so the only possible backtrack target is the fail
+ // label. Fail directly instead of popping a stack that was never set
+ // up. Reached e.g. by the bounds check of a single character class like
+ // /[abc]/.
+ Fail();
+ }
}
Label exit_with_exception;
@@ -947,6 +994,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerLOONG64::GetCode(
// Preempt-code.
if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_);
+
+ // Only EmitBacktrack() (which pops the backtrack stack) links this label,
+ // so a linked preempt target implies the backtrack stack is live and its
+ // pointer is initialized for the store/reload below.
+ DCHECK(backtrack_stack_used());
// Put regexp engine registers on stack.
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
@@ -1097,6 +1149,7 @@ void RegExpMacroAssemblerLOONG64::ReadCurrentPositionFromRegister(int reg) {
}
void RegExpMacroAssemblerLOONG64::WriteStackPointerToRegister(int reg) {
+ set_backtrack_stack_used();
ExternalReference stack_top_address =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, stack_top_address);
@@ -1106,6 +1159,7 @@ void RegExpMacroAssemblerLOONG64::WriteStackPointerToRegister(int reg) {
}
void RegExpMacroAssemblerLOONG64::ReadStackPointerFromRegister(int reg) {
+ set_backtrack_stack_used();
ExternalReference stack_top_address =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(backtrack_stackpointer(), stack_top_address);
@@ -1287,6 +1341,7 @@ void RegExpMacroAssemblerLOONG64::SafeCallTarget(Label* name) {
void RegExpMacroAssemblerLOONG64::Push(Register source) {
DCHECK(source != backtrack_stackpointer());
+ set_backtrack_stack_used();
__ Add_d(backtrack_stackpointer(), backtrack_stackpointer(),
Operand(-kIntSize));
__ St_w(source, MemOperand(backtrack_stackpointer(), 0));
@@ -1294,6 +1349,7 @@ void RegExpMacroAssemblerLOONG64::Push(Register source) {
void RegExpMacroAssemblerLOONG64::Pop(Register target) {
DCHECK(target != backtrack_stackpointer());
+ set_backtrack_stack_used();
__ Ld_w(target, MemOperand(backtrack_stackpointer(), 0));
__ Add_d(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize);
}
diff --git a/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.h b/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.h
index 835d1a5270f..655e2ae2b21 100644
--- a/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.h
+++ b/deps/v8/src/regexp/loong64/regexp-macro-assembler-loong64.h
@@ -63,6 +63,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
void CheckSpecialClassRanges(StandardCharacterSet type,
Label* on_no_match) override;
void Fail() override;
+ bool prologue_pushes_fail_label() const override { return true; }
DirectHandle<HeapObject> GetCode(DirectHandle<RegExpData> re_data,
Flags flags) override;
void GoTo(Label* label) override;
@@ -201,6 +202,12 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerLOONG64
// Register holding pointer to the current code object.
static constexpr Register code_pointer() { return s1; }
+ // The real backtrack dispatch (pop a code offset and jump to it), emitted
+ // once in GetCode at backtrack_label_ when the backtrack stack is used.
+ // Backtrack() itself only jumps there, so emitting it does not by itself
+ // mark the backtrack stack as used.
+ void EmitBacktrack();
+
// Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack.
void BranchOrBacktrack(Label* to, Condition condition, Register rs,
diff --git a/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc b/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc
index 7342de68cd1..f98a5286fdf 100644
--- a/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc
+++ b/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.cc
@@ -179,6 +179,15 @@ void RegExpMacroAssemblerMIPS::AdvanceRegister(int reg, int by) {
}
void RegExpMacroAssemblerMIPS::Backtrack() {
+ // Defer to the shared backtrack block bound in GetCode: only there, with
+ // the body fully emitted, is it known whether anything was ever pushed.
+ // If nothing was, the only value a pop could yield is the fail label,
+ // so the block reduces to Fail() and the backtrack stack (including the
+ // fail label itself) is elided entirely.
+ __ jmp(&backtrack_label_);
+}
+
+void RegExpMacroAssemblerMIPS::EmitBacktrack() {
CheckPreemption();
if (has_backtrack_limit()) {
Label next;
@@ -235,6 +244,7 @@ void RegExpMacroAssemblerMIPS::CheckCharacterLT(base::uc16 limit,
}
void RegExpMacroAssemblerMIPS::CheckFixedLengthLoop(Label* on_equal) {
+ set_backtrack_stack_used();
Label backtrack_non_equal;
__ Lw(a0, MemOperand(backtrack_stackpointer(), 0));
__ Branch(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
@@ -745,14 +755,25 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
kBacktrackCountOffset - kSystemPointerSize);
__ push(a0); // The regexp stack base ptr.
- // Initialize backtrack stack pointer. It must not be clobbered from here
- // on. Note the backtrack_stackpointer is callee-saved.
- static_assert(backtrack_stackpointer() == s7);
- LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ // The body has been fully emitted, so backtrack_stack_used() is now final:
+ // it is true iff some op pushed, popped, or transferred the backtrack stack
+ // pointer. Patterns that never do skip the backtrack stack setup, the fail
+ // label, and the teardown below.
+ if (backtrack_stack_used()) {
+ // Initialize backtrack stack pointer. It must not be clobbered from here
+ // on. Note the backtrack_stackpointer is callee-saved.
+ static_assert(backtrack_stackpointer() == s7);
+ LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
- // Store the regexp base pointer - we'll later restore it / write it to
- // memory when returning from this irregexp code object.
- PushRegExpBasePointer(backtrack_stackpointer(), a1);
+ // Store the regexp base pointer - we'll later restore it / write it to
+ // memory when returning from this irregexp code object. Captured with an
+ // empty stack (delta 0), before the fail label is pushed below, so the
+ // teardown on exit and between global iterations restores to the same
+ // point (regexp::StackScope verifies this delta is unchanged).
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ PushRegExpBasePointer(backtrack_stackpointer(), scratch);
+ }
// Skip the JS stack guard check for patterns whose register file fits
// within the stack limit's guaranteed slack: allocating it then can never
@@ -785,12 +806,19 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
__ jmp(&return_v0);
__ bind(&stack_limit_hit);
- StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
+ // Without a backtrack stack, backtrack_stackpointer() was never
+ // initialized above; storing it would corrupt the saved stack pointer
+ // (regexp::StackScope verifies it is unchanged across the exec call).
+ if (backtrack_stack_used()) {
+ StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
+ }
CallCheckStackGuardState(a0, extra_space_for_variables);
// If returned value is non-zero, we exit with the returned value as
// result.
__ Branch(&return_v0, ne, v0, Operand(zero_reg));
- LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ if (backtrack_stack_used()) {
+ LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ }
__ bind(&stack_ok);
}
@@ -851,6 +879,13 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
}
}
+ if (backtrack_stack_used() && fail_label() != nullptr) {
+ // Push the fail label (see set_fail_label / prologue_pushes_fail_label).
+ // Global matches re-enter here per iteration, each having restored the
+ // stack to base via PopRegExpBasePointer first, so it is refreshed.
+ PushBacktrack(fail_label());
+ }
+
__ jmp(&start_label_);
// Exit code:
@@ -919,9 +954,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
__ Daddu(a2, a2, num_saved_registers_ * kIntSize);
__ Sd(a2, MemOperand(frame_pointer(), kRegisterOutputOffset));
- // Restore the original regexp stack pointer value (effectively, pop the
- // stored base pointer).
- PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ if (backtrack_stack_used()) {
+ // Restore the original regexp stack pointer value (effectively, pop
+ // the stored base pointer).
+ PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ }
Label reload_string_start_minus_one;
@@ -959,9 +996,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
}
__ bind(&return_v0);
- // Restore the original regexp stack pointer value (effectively, pop the
- // stored base pointer).
- PopRegExpBasePointer(backtrack_stackpointer(), a1);
+ if (backtrack_stack_used()) {
+ // Restore the original regexp stack pointer value (effectively, pop the
+ // stored base pointer).
+ PopRegExpBasePointer(backtrack_stackpointer(), a1);
+ }
// Skip sp past regexp registers and local variables..
__ mov(sp, frame_pointer());
@@ -972,7 +1011,15 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
// Backtrack code (branch target for conditional backtracks).
if (backtrack_label_.is_linked()) {
__ bind(&backtrack_label_);
- Backtrack();
+ if (backtrack_stack_used()) {
+ EmitBacktrack();
+ } else {
+ // Nothing was pushed, so the only possible backtrack target is the fail
+ // label. Fail directly instead of popping a stack that was never set
+ // up. Reached e.g. by the bounds check of a single character class like
+ // /[abc]/.
+ Fail();
+ }
}
Label exit_with_exception;
@@ -980,6 +1027,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerMIPS::GetCode(
// Preempt-code.
if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_);
+
+ // Only EmitBacktrack() (which pops the backtrack stack) links this label,
+ // so a linked preempt target implies the backtrack stack is live and its
+ // pointer is initialized for the store/reload below.
+ DCHECK(backtrack_stack_used());
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a0);
CallCheckStackGuardState(a0);
@@ -1127,6 +1179,7 @@ void RegExpMacroAssemblerMIPS::ReadCurrentPositionFromRegister(int reg) {
}
void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
+ set_backtrack_stack_used();
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, Operand(ref));
@@ -1136,6 +1189,7 @@ void RegExpMacroAssemblerMIPS::WriteStackPointerToRegister(int reg) {
}
void RegExpMacroAssemblerMIPS::ReadStackPointerFromRegister(int reg) {
+ set_backtrack_stack_used();
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, Operand(ref));
@@ -1319,6 +1373,7 @@ void RegExpMacroAssemblerMIPS::SafeCallTarget(Label* name) {
void RegExpMacroAssemblerMIPS::Push(Register source) {
DCHECK(source != backtrack_stackpointer());
+ set_backtrack_stack_used();
__ Daddu(backtrack_stackpointer(),
backtrack_stackpointer(),
Operand(-kIntSize));
@@ -1327,6 +1382,7 @@ void RegExpMacroAssemblerMIPS::Push(Register source) {
void RegExpMacroAssemblerMIPS::Pop(Register target) {
DCHECK(target != backtrack_stackpointer());
+ set_backtrack_stack_used();
__ Lw(target, MemOperand(backtrack_stackpointer()));
__ Daddu(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize);
}
diff --git a/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.h b/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.h
index ce6f5175bc9..c633cf08124 100644
--- a/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.h
+++ b/deps/v8/src/regexp/mips64/regexp-macro-assembler-mips64.h
@@ -63,6 +63,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
void CheckSpecialClassRanges(StandardCharacterSet type,
Label* on_no_match) override;
void Fail() override;
+ bool prologue_pushes_fail_label() const override { return true; }
DirectHandle<HeapObject> GetCode(DirectHandle<RegExpData> re_data,
Flags flags) override;
void GoTo(Label* label) override;
@@ -200,6 +201,12 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerMIPS
// Register holding pointer to the current code object.
static constexpr Register code_pointer() { return s1; }
+ // The real backtrack dispatch (pop a code offset and jump to it), emitted
+ // once in GetCode at backtrack_label_ when the backtrack stack is used.
+ // Backtrack() itself only jumps there, so emitting it does not by itself
+ // mark the backtrack stack as used.
+ void EmitBacktrack();
+
// Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack.
void BranchOrBacktrack(Label* to,
diff --git a/deps/v8/src/regexp/regexp-compiler-tonode.cc b/deps/v8/src/regexp/regexp-compiler-tonode.cc
index d19a8bfd9ad..cfdfad0159b 100644
--- a/deps/v8/src/regexp/regexp-compiler-tonode.cc
+++ b/deps/v8/src/regexp/regexp-compiler-tonode.cc
@@ -84,7 +84,7 @@ Node* Tree::ToNode(Compiler* compiler, Node* on_success) {
// We can always return this even though it may not be the expected
// subclass because all call sites already have to check for this case.
Zone* zone = compiler->zone();
- return zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ return zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
}
return ToNodeImpl(compiler, on_success);
}
@@ -93,10 +93,11 @@ Node* Atom::ToNodeImpl(Compiler* compiler, Node* on_success) {
Zone* zone = compiler->zone();
ZoneList<TextElement>* elms = zone->New<ZoneList<TextElement>>(1, zone);
elms->Add(TextElement::FromAtom(this), zone);
- TextNode* result =
- zone->New<TextNode>(elms, compiler->read_backward(), on_success);
+ TextNode* result = zone->New<TextNode>(elms, compiler->read_backward(),
+ on_success, compiler->flags());
if (compiler->one_byte() && !result->CanMatchLatin1(compiler)) {
- Node* backtrack = zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ Node* backtrack =
+ zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
REGISTER_NODE(backtrack);
return backtrack;
}
@@ -107,10 +108,11 @@ Node* Atom::ToNodeImpl(Compiler* compiler, Node* on_success) {
Node* Text::ToNodeImpl(Compiler* compiler, Node* on_success) {
Zone* zone = compiler->zone();
- TextNode* result =
- zone->New<TextNode>(elements(), compiler->read_backward(), on_success);
+ TextNode* result = zone->New<TextNode>(elements(), compiler->read_backward(),
+ on_success, compiler->flags());
if (compiler->one_byte() && !result->CanMatchLatin1(compiler)) {
- Node* backtrack = zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ Node* backtrack =
+ zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
REGISTER_NODE(backtrack);
return backtrack;
}
@@ -286,7 +288,8 @@ void AddBmpCharacters(Compiler* compiler, ChoiceNode* result, Node* on_success,
ToCanonicalZoneList(splitter->bmp(), compiler->zone());
if (bmp == nullptr) return;
Node* node = TextNode::CreateForCharacterRanges(
- compiler->zone(), bmp, compiler->read_backward(), on_success);
+ compiler->zone(), bmp, compiler->read_backward(), on_success,
+ compiler->flags());
REGISTER_NODE(node);
result->AddAlternative(GuardedAlternative(node));
}
@@ -387,7 +390,7 @@ void AddNonBmpSurrogatePairs(Compiler* compiler, ChoiceNode* result,
Node* node = TextNode::CreateForSurrogatePair(
zone, leading_with_full_trailing_range,
CharacterRange::Range(kTrailSurrogateStart, kTrailSurrogateEnd),
- compiler->read_backward(), on_success);
+ compiler->read_backward(), on_success, compiler->flags());
REGISTER_NODE(node);
result->AddAlternative(GuardedAlternative(node));
}
@@ -396,9 +399,9 @@ void AddNonBmpSurrogatePairs(Compiler* compiler, ChoiceNode* result,
CharacterRange::Range(ExtractFrom(it.first), ExtractTo(it.first));
ZoneList<CharacterRange>* trailing_ranges = it.second;
CharacterRange::Canonicalize(trailing_ranges);
- Node* node =
- TextNode::CreateForSurrogatePair(zone, leading_range, trailing_ranges,
- compiler->read_backward(), on_success);
+ Node* node = TextNode::CreateForSurrogatePair(
+ zone, leading_range, trailing_ranges, compiler->read_backward(),
+ on_success, compiler->flags());
REGISTER_NODE(node);
result->AddAlternative(GuardedAlternative(node));
}
@@ -409,14 +412,15 @@ Node* NegativeLookaroundAgainstReadDirectionAndMatch(
ZoneList<CharacterRange>* match, Node* on_success, bool read_backward) {
Zone* zone = compiler->zone();
Node* match_node = TextNode::CreateForCharacterRanges(
- zone, match, read_backward, on_success);
+ zone, match, read_backward, on_success, compiler->flags());
REGISTER_NODE(match_node);
int stack_register = compiler->UnicodeLookaroundStackRegister();
int position_register = compiler->UnicodeLookaroundPositionRegister();
Lookaround::Builder lookaround(false, match_node, compiler, stack_register,
position_register);
Node* negative_match = TextNode::CreateForCharacterRanges(
- zone, lookbehind, !read_backward, lookaround.on_match_success());
+ zone, lookbehind, !read_backward, lookaround.on_match_success(),
+ compiler->flags());
REGISTER_NODE(negative_match);
return lookaround.ForMatch(compiler, negative_match);
}
@@ -430,11 +434,12 @@ Node* MatchAndNegativeLookaroundInReadDirection(
Lookaround::Builder lookaround(false, on_success, compiler, stack_register,
position_register);
Node* negative_match = TextNode::CreateForCharacterRanges(
- zone, lookahead, read_backward, lookaround.on_match_success());
+ zone, lookahead, read_backward, lookaround.on_match_success(),
+ compiler->flags());
REGISTER_NODE(negative_match);
Node* node = TextNode::CreateForCharacterRanges(
- zone, match, read_backward,
- lookaround.ForMatch(compiler, negative_match));
+ zone, match, read_backward, lookaround.ForMatch(compiler, negative_match),
+ compiler->flags());
REGISTER_NODE(node);
return node;
}
@@ -494,7 +499,8 @@ void AddLoneTrailSurrogates(Compiler* compiler, ChoiceNode* result,
Node* UnanchoredAdvance(Compiler* compiler, Node* on_success) {
// This implements ES2015 21.2.5.2.3, AdvanceStringIndex.
DCHECK(!compiler->read_backward());
- Node* node = compiler->zone()->New<UnanchoredAdvanceNode>(on_success);
+ Node* node = compiler->zone()->New<UnanchoredAdvanceNode>(on_success,
+ compiler->flags());
REGISTER_NODE(node);
return node;
}
@@ -548,10 +554,11 @@ Node* ClassRanges::ToNodeImpl(Compiler* compiler, Node* on_success) {
if (!IsEitherUnicode(compiler->flags()) || compiler->one_byte() ||
contains_split_surrogate()) {
- TextNode* result =
- zone->New<TextNode>(this, compiler->read_backward(), on_success);
+ TextNode* result = zone->New<TextNode>(this, compiler->read_backward(),
+ on_success, compiler->flags());
if (compiler->one_byte() && !result->CanMatchLatin1(compiler)) {
- Node* backtrack = zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ Node* backtrack =
+ zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
REGISTER_NODE(backtrack);
return backtrack;
}
@@ -592,7 +599,8 @@ Node* ClassRanges::ToNodeImpl(Compiler* compiler, Node* on_success) {
}
if (ranges->length() == 0) {
- Node* backtrack = zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ Node* backtrack =
+ zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
REGISTER_NODE(backtrack);
return backtrack;
}
@@ -607,7 +615,7 @@ Node* ClassRanges::ToNodeImpl(Compiler* compiler, Node* on_success) {
// units (irregexp operates only on code units).
// - Lone surrogates: these require lookarounds to ensure we don't match in
// the middle of a surrogate pair.
- ChoiceNode* result = zone->New<ChoiceNode>(2, zone);
+ ChoiceNode* result = zone->New<ChoiceNode>(2, compiler->flags(), zone);
UnicodeRangeSplitter splitter(ranges);
AddBmpCharacters(compiler, result, on_success, &splitter);
AddNonBmpSurrogatePairs(compiler, result, on_success, &splitter);
@@ -632,7 +640,8 @@ Node* ClassSetOperand::ToNodeImpl(Compiler* compiler, Node* on_success) {
if (size == 0) {
// If neither ranges nor strings are present, the operand is equal to an
// empty range (matching nothing).
- Node* backtrack = zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ Node* backtrack =
+ zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
REGISTER_NODE(backtrack);
return backtrack;
}
@@ -1137,8 +1146,8 @@ Node* Disjunction::ToNodeImpl(Compiler* compiler, Node* on_success) {
int length = alternatives->length();
- ChoiceNode* result =
- compiler->zone()->New<ChoiceNode>(length, compiler->zone());
+ ChoiceNode* result = compiler->zone()->New<ChoiceNode>(
+ length, compiler->flags(), compiler->zone());
for (int i = 0; i < length; i++) {
GuardedAlternative alternative(
alternatives->at(i)->ToNode(compiler, on_success));
@@ -1151,7 +1160,8 @@ Node* Disjunction::ToNodeImpl(Compiler* compiler, Node* on_success) {
if (node_length >= 2) return result;
if (node_length == 1) return result->alternatives()->at(0).node();
Zone* zone = on_success->zone();
- Node* backtrack = zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ Node* backtrack =
+ zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
REGISTER_NODE(backtrack);
return backtrack;
}
@@ -1173,7 +1183,7 @@ Node* BoundaryAssertionAsLookaround(Compiler* compiler, Node* on_success,
zone);
int stack_register = compiler->UnicodeLookaroundStackRegister();
int position_register = compiler->UnicodeLookaroundPositionRegister();
- ChoiceNode* result = zone->New<ChoiceNode>(2, zone);
+ ChoiceNode* result = zone->New<ChoiceNode>(2, compiler->flags(), zone);
// Add two choices. The (non-)boundary could start with a word or
// a non-word-character.
for (int i = 0; i < 2; i++) {
@@ -1186,14 +1196,16 @@ Node* BoundaryAssertionAsLookaround(Compiler* compiler, Node* on_success,
Lookaround::Builder lookbehind(lookbehind_for_word, on_success, compiler,
stack_register, position_register);
Node* backward = TextNode::CreateForCharacterRanges(
- zone, word_range, true, lookbehind.on_match_success());
+ zone, word_range, true, lookbehind.on_match_success(),
+ compiler->flags());
REGISTER_NODE(backward);
// Look to the right.
Lookaround::Builder lookahead(lookahead_for_word,
lookbehind.ForMatch(compiler, backward),
compiler, stack_register, position_register);
Node* forward = TextNode::CreateForCharacterRanges(
- zone, word_range, false, lookahead.on_match_success());
+ zone, word_range, false, lookahead.on_match_success(),
+ compiler->flags());
REGISTER_NODE(forward);
result->AddAlternative(
GuardedAlternative(lookahead.ForMatch(compiler, forward)));
@@ -1209,33 +1221,35 @@ Node* Assertion::ToNodeImpl(Compiler* compiler, Node* on_success) {
switch (assertion_type()) {
case Type::START_OF_LINE: {
- Node* node = AssertionNode::AfterNewline(on_success);
+ Node* node = AssertionNode::AfterNewline(on_success, compiler->flags());
REGISTER_NODE(node);
return node;
}
case Type::START_OF_INPUT: {
- Node* node = AssertionNode::AtStart(on_success);
+ Node* node = AssertionNode::AtStart(on_success, compiler->flags());
REGISTER_NODE(node);
return node;
}
case Type::BOUNDARY: {
- Node* node = NeedsUnicodeCaseEquivalents(compiler->flags())
- ? BoundaryAssertionAsLookaround(compiler, on_success,
- Type::BOUNDARY)
- : AssertionNode::AtBoundary(on_success);
+ Node* node =
+ NeedsUnicodeCaseEquivalents(compiler->flags())
+ ? BoundaryAssertionAsLookaround(compiler, on_success,
+ Type::BOUNDARY)
+ : AssertionNode::AtBoundary(on_success, compiler->flags());
REGISTER_NODE(node);
return node;
}
case Type::NON_BOUNDARY: {
- Node* node = NeedsUnicodeCaseEquivalents(compiler->flags())
- ? BoundaryAssertionAsLookaround(compiler, on_success,
- Type::NON_BOUNDARY)
- : AssertionNode::AtNonBoundary(on_success);
+ Node* node =
+ NeedsUnicodeCaseEquivalents(compiler->flags())
+ ? BoundaryAssertionAsLookaround(compiler, on_success,
+ Type::NON_BOUNDARY)
+ : AssertionNode::AtNonBoundary(on_success, compiler->flags());
REGISTER_NODE(node);
return node;
}
case Type::END_OF_INPUT: {
- Node* node = AssertionNode::AtEnd(on_success);
+ Node* node = AssertionNode::AtEnd(on_success, compiler->flags());
REGISTER_NODE(node);
return node;
}
@@ -1260,20 +1274,24 @@ Node* Assertion::ToNodeImpl(Compiler* compiler, Node* on_success) {
ZoneList<TextElement>* crlf_elms =
zone->New<ZoneList<TextElement>>(1, zone);
crlf_elms->Add(TextElement::FromAtom(crlf_atom), zone);
- AssertionNode* crlf_at_end = AssertionNode::AtEnd(submatch_success);
+ AssertionNode* crlf_at_end =
+ AssertionNode::AtEnd(submatch_success, compiler->flags());
REGISTER_NODE(crlf_at_end);
TextNode* crlf_matcher =
- zone->New<TextNode>(crlf_elms, false, crlf_at_end);
+ zone->New<TextNode>(crlf_elms, false, crlf_at_end, compiler->flags());
REGISTER_NODE(crlf_matcher);
// Alt B: [LF CR LS PS] then AT_END.
ClassRanges* lt_atom =
zone->New<ClassRanges>(StandardCharacterSet::kLineTerminator);
- AssertionNode* lt_at_end = AssertionNode::AtEnd(submatch_success);
+ AssertionNode* lt_at_end =
+ AssertionNode::AtEnd(submatch_success, compiler->flags());
REGISTER_NODE(lt_at_end);
- TextNode* lt_matcher = zone->New<TextNode>(lt_atom, false, lt_at_end);
+ TextNode* lt_matcher =
+ zone->New<TextNode>(lt_atom, false, lt_at_end, compiler->flags());
REGISTER_NODE(lt_matcher);
// Inner choice: CRLF first, then single LT.
- ChoiceNode* inner_choice = zone->New<ChoiceNode>(2, zone);
+ ChoiceNode* inner_choice =
+ zone->New<ChoiceNode>(2, compiler->flags(), zone);
inner_choice->AddAlternative(GuardedAlternative(crlf_matcher));
inner_choice->AddAlternative(GuardedAlternative(lt_matcher));
REGISTER_NODE(inner_choice);
@@ -1281,10 +1299,10 @@ Node* Assertion::ToNodeImpl(Compiler* compiler, Node* on_success) {
Node* lookahead_node = lookahead.ForMatch(compiler, inner_choice);
// Outer choice: either the trailing-terminator lookahead matches, or
// we're already at end-of-input.
- ChoiceNode* result = zone->New<ChoiceNode>(2, zone);
+ ChoiceNode* result = zone->New<ChoiceNode>(2, compiler->flags(), zone);
result->AddAlternative(GuardedAlternative(lookahead_node));
- result->AddAlternative(
- GuardedAlternative(AssertionNode::AtEnd(on_success)));
+ result->AddAlternative(GuardedAlternative(
+ AssertionNode::AtEnd(on_success, compiler->flags())));
REGISTER_NODE(result);
return result;
}
@@ -1295,7 +1313,7 @@ Node* Assertion::ToNodeImpl(Compiler* compiler, Node* on_success) {
int stack_pointer_register = compiler->AllocateRegister();
int position_register = compiler->AllocateRegister();
// The ChoiceNode to distinguish between a newline and end-of-input.
- ChoiceNode* result = zone->New<ChoiceNode>(2, zone);
+ ChoiceNode* result = zone->New<ChoiceNode>(2, compiler->flags(), zone);
// Create a newline atom.
ZoneList<CharacterRange>* newline_ranges =
zone->New<ZoneList<CharacterRange>>(3, zone);
@@ -1305,22 +1323,23 @@ Node* Assertion::ToNodeImpl(Compiler* compiler, Node* on_success) {
stack_pointer_register, position_register,
0, // No captures inside.
-1, // Ignored if no captures.
- on_success);
+ on_success, compiler->flags());
REGISTER_NODE(submatch_success);
ClassRanges* newline_atom =
zone->New<ClassRanges>(StandardCharacterSet::kLineTerminator);
- TextNode* newline_matcher =
- zone->New<TextNode>(newline_atom, false, submatch_success);
+ TextNode* newline_matcher = zone->New<TextNode>(
+ newline_atom, false, submatch_success, compiler->flags());
REGISTER_NODE(newline_matcher);
// Create an end-of-input matcher.
Node* end_of_line = ActionNode::BeginPositiveSubmatch(
stack_pointer_register, position_register, newline_matcher,
- submatch_success);
+ submatch_success, compiler->flags());
REGISTER_NODE(end_of_line);
// Add the two alternatives to the ChoiceNode.
GuardedAlternative eol_alternative(end_of_line);
result->AddAlternative(eol_alternative);
- GuardedAlternative end_alternative(AssertionNode::AtEnd(on_success));
+ GuardedAlternative end_alternative(
+ AssertionNode::AtEnd(on_success, compiler->flags()));
result->AddAlternative(end_alternative);
REGISTER_NODE(result);
return result;
@@ -1339,7 +1358,7 @@ Node* BackReference::ToNodeImpl(Compiler* compiler, Node* on_success) {
backref_node = compiler->zone()->New<BackReferenceNode>(
Capture::StartRegister(capture->index()),
Capture::EndRegister(capture->index()), compiler->read_backward(),
- backref_node);
+ backref_node, compiler->flags());
REGISTER_NODE(backref_node);
}
return backref_node;
@@ -1367,22 +1386,8 @@ class V8_NODISCARD ModifiersScope {
} // namespace
Node* Group::ToNodeImpl(Compiler* compiler, Node* on_success) {
- // If no flags are modified, simply convert and return the body.
- if (flags() == compiler->flags()) {
- return body_->ToNode(compiler, on_success);
- }
- // Reset flags for successor node.
- const Flags old_flags = compiler->flags();
- on_success = ActionNode::ModifyFlags(old_flags, on_success);
-
- // Convert body using modifier.
ModifiersScope modifiers_scope(compiler, flags());
- Node* body = body_->ToNode(compiler, on_success);
- if (body->IsBacktrack()) return body;
-
- // Wrap body into modifier node.
- Node* modified_body = ActionNode::ModifyFlags(flags(), body);
- return modified_body;
+ return body_->ToNode(compiler, on_success);
}
Lookaround::Builder::Builder(bool is_positive, Node* on_success,
@@ -1396,12 +1401,12 @@ Lookaround::Builder::Builder(bool is_positive, Node* on_success,
if (is_positive_) {
on_match_success_ = ActionNode::PositiveSubmatchSuccess(
stack_pointer_register, position_register, capture_register_count,
- capture_register_start, on_success_);
+ capture_register_start, on_success_, compiler->flags());
} else {
Zone* zone = on_success_->zone();
on_match_success_ = zone->New<NegativeSubmatchSuccess>(
stack_pointer_register, position_register, capture_register_count,
- capture_register_start, zone);
+ capture_register_start, compiler->flags(), zone);
}
REGISTER_NODE(on_match_success_);
}
@@ -1410,7 +1415,8 @@ Node* Lookaround::Builder::ForMatch(Compiler* compiler, Node* match) {
if (is_positive_) {
ActionNode* on_match_success = on_match_success_->AsActionNode();
Node* node = ActionNode::BeginPositiveSubmatch(
- stack_pointer_register_, position_register_, match, on_match_success);
+ stack_pointer_register_, position_register_, match, on_match_success,
+ compiler->flags());
REGISTER_NODE(node);
return node;
} else {
@@ -1421,10 +1427,12 @@ Node* Lookaround::Builder::ForMatch(Compiler* compiler, Node* match) {
// NegativeLookaroundChoiceNode is a special ChoiceNode that ignores the
// first exit when calculating quick checks.
ChoiceNode* choice_node = zone->New<NegativeLookaroundChoiceNode>(
- GuardedAlternative(match), GuardedAlternative(on_success_), zone);
+ GuardedAlternative(match), GuardedAlternative(on_success_),
+ compiler->flags(), zone);
REGISTER_NODE(choice_node);
Node* node = ActionNode::BeginNegativeSubmatch(
- stack_pointer_register_, position_register_, choice_node);
+ stack_pointer_register_, position_register_, choice_node,
+ compiler->flags());
REGISTER_NODE(node);
return node;
}
@@ -1466,11 +1474,13 @@ Node* Capture::ToNode(Tree* body, int index, Compiler* compiler,
int start_reg = Capture::StartRegister(index);
int end_reg = Capture::EndRegister(index);
if (compiler->read_backward()) std::swap(start_reg, end_reg);
- Node* store_end = ActionNode::StorePosition(end_reg, on_success);
+ Node* store_end =
+ ActionNode::StorePosition(end_reg, on_success, compiler->flags());
REGISTER_NODE(store_end);
Node* body_node = body->ToNode(compiler, store_end);
if (body_node->IsBacktrack()) return body_node;
- Node* node = ActionNode::StorePosition(start_reg, body_node);
+ Node* node =
+ ActionNode::StorePosition(start_reg, body_node, compiler->flags());
REGISTER_NODE(node);
return node;
}
@@ -2250,7 +2260,7 @@ Node* Quantifier::ToNode(int min, int max, bool is_greedy, Tree* body,
body->CaptureRegisters(StackLimiter(Node::kRecursionBudget));
if (!capture_registers.is_valid()) {
compiler->SetRegExpTooBig();
- return zone->New<EndNode>(EndNode::BACKTRACK, zone);
+ return zone->New<EndNode>(EndNode::BACKTRACK, compiler->flags(), zone);
}
// At the start of the next iteration of a quantifier the captures must be
@@ -2295,7 +2305,8 @@ Node* Quantifier::ToNode(int min, int max, bool is_greedy, Tree* body,
Node* answer = on_success;
for (int i = 0; i < max; i++) {
TRACE("* Iteration " << i + 1 << " / " << max);
- ChoiceNode* alternation = zone->New<ChoiceNode>(2, zone);
+ ChoiceNode* alternation =
+ zone->New<ChoiceNode>(2, compiler->flags(), zone);
if (is_greedy) {
alternation->AddAlternative(
GuardedAlternative(body->ToNode(compiler, answer)));
@@ -2320,19 +2331,21 @@ Node* Quantifier::ToNode(int min, int max, bool is_greedy, Tree* body,
bool needs_counter = has_min || has_max;
int reg_ctr =
needs_counter ? compiler->AllocateRegister() : Compiler::kNoRegister;
- LoopChoiceNode* center = zone->New<LoopChoiceNode>(
- body->min_match() == 0, compiler->read_backward(), zone);
+ LoopChoiceNode* center = zone->New<LoopChoiceNode>(body->min_match() == 0,
+ compiler->read_backward(),
+ compiler->flags(), zone);
if (not_at_start && !compiler->read_backward()) center->set_not_at_start();
Node* loop_return = center;
if (needs_counter) {
- loop_return = ActionNode::IncrementRegister(reg_ctr, loop_return);
+ loop_return =
+ ActionNode::IncrementRegister(reg_ctr, loop_return, compiler->flags());
REGISTER_NODE(loop_return);
}
if (body_can_be_empty) {
// If the body can be empty we need to check if it was and then
// backtrack.
- loop_return =
- ActionNode::EmptyMatchCheck(body_start_reg, reg_ctr, min, loop_return);
+ loop_return = ActionNode::EmptyMatchCheck(body_start_reg, reg_ctr, min,
+ loop_return, compiler->flags());
REGISTER_NODE(loop_return);
}
Node* body_node = body->ToNode(compiler, loop_return);
@@ -2348,12 +2361,14 @@ Node* Quantifier::ToNode(int min, int max, bool is_greedy, Tree* body,
if (body_can_be_empty) {
// If the body can be empty we need to store the start position
// so we can bail out if it was empty.
- body_node = ActionNode::RestorePosition(body_start_reg, body_node);
+ body_node = ActionNode::RestorePosition(body_start_reg, body_node,
+ compiler->flags());
REGISTER_NODE(body_node);
}
if (needs_capture_clearing) {
// Before entering the body of this loop we need to clear captures.
- body_node = ActionNode::ClearCaptures(capture_registers, body_node);
+ body_node = ActionNode::ClearCaptures(capture_registers, body_node,
+ compiler->flags());
REGISTER_NODE(body_node);
}
GuardedAlternative body_alt(body_node);
@@ -2378,11 +2393,12 @@ Node* Quantifier::ToNode(int min, int max, bool is_greedy, Tree* body,
if (min > 0 && body->min_match() > 0 && !compiler->read_backward()) {
uint8_t eats = base::saturated_cast<uint8_t>(
std::min(256, min) * std::min(256, body->min_match()));
- result = ActionNode::EatsAtLeast(eats, result);
+ result = ActionNode::EatsAtLeast(eats, result, compiler->flags());
REGISTER_NODE(result);
}
if (needs_counter) {
- result = ActionNode::SetRegisterForLoop(reg_ctr, 0, result);
+ result =
+ ActionNode::SetRegisterForLoop(reg_ctr, 0, result, compiler->flags());
REGISTER_NODE(result);
}
return result;
diff --git a/deps/v8/src/regexp/regexp-compiler.cc b/deps/v8/src/regexp/regexp-compiler.cc
index 09c78c29a0c..ca1bae72c33 100644
--- a/deps/v8/src/regexp/regexp-compiler.cc
+++ b/deps/v8/src/regexp/regexp-compiler.cc
@@ -4,6 +4,7 @@
#include "src/regexp/regexp-compiler.h"
+#include <algorithm>
#include <optional>
#include <string_view>
@@ -30,6 +31,13 @@ namespace v8::internal::regexp {
using namespace compiler_constants; // NOLINT(build/namespaces)
+NonAssertingLabel::~NonAssertingLabel() {
+ if (V8_UNLIKELY(compiler_ != nullptr && compiler_->IsRegExpTooBig())) {
+ UnuseNear();
+ Unuse();
+ }
+}
+
#ifdef V8_ENABLE_REGEXP_DIAGNOSTICS
#define TRACE_COMPILER(compiler, msg) \
do { \
@@ -334,7 +342,7 @@ Compiler::Compiler(Isolate* isolate, Zone* zone, int capture_count, Flags flags,
frequency_collator_(),
isolate_(isolate),
zone_(zone) {
- accept_ = zone->New<EndNode>(EndNode::ACCEPT, zone);
+ accept_ = zone->New<EndNode>(EndNode::ACCEPT, flags, zone);
DCHECK_GE(RegExpMacroAssembler::kMaxRegister, next_register_ - 1);
}
@@ -348,9 +356,9 @@ Compiler::CompilationResult Compiler::Assemble(
return CompilationResult::RegExpTooBig();
};
- ZoneVector<Node*> work_list(zone());
+ ZoneVector<WorkItem> work_list(zone());
work_list_ = &work_list;
- Label fail;
+ NonAssertingLabel fail(this);
macro_assembler_->set_fail_label(&fail);
if (!macro_assembler_->prologue_pushes_fail_label()) {
// The fail label sits at the bottom of the backtrack stack: exhausting all
@@ -364,14 +372,13 @@ Compiler::CompilationResult Compiler::Assemble(
Trace new_trace;
if (start->Emit(this, &new_trace).IsError()) {
work_list_ = nullptr;
- fail.UnuseNear();
- fail.Unuse();
return ReportError();
}
macro_assembler_->BindJumpTarget(&fail);
macro_assembler_->Fail();
while (!work_list.empty()) {
- Node* node = work_list.back();
+ WorkItem item = work_list.back();
+ Node* node = item.node;
TRACE_WITH_NODE(this, "Popping from worklist ", node);
work_list.pop_back();
node->set_on_work_list(false);
@@ -390,27 +397,7 @@ Compiler::CompilationResult Compiler::Assemble(
DirectHandle<HeapObject> code = macro_assembler_->GetCode(re_data, flags_);
work_list_ = nullptr;
-#ifdef V8_TARGET_LITTLE_ENDIAN
- // Generate a bitmask of valid characters for fast rejection.
- // Skip for multiline regexps as match attempts are less likely to be
- // rejected early based on the first few characters.
- constexpr bool kPossiblyAtStart = false;
- constexpr int kMinChars = 1;
- constexpr int kMaxChars = 4;
- int eats_at_least = start->EatsAtLeast(kPossiblyAtStart);
- if (one_byte_ && eats_at_least >= kMinChars && !IsMultiline(flags_)) {
- int chars = std::min(eats_at_least, kMaxChars);
- QuickCheckDetails quick_check(chars);
- start->GetQuickCheckDetails(&quick_check, this, 0, kPossiblyAtStart,
- Node::kRecursionBudget);
-
- if (!quick_check.cannot_match()) {
- quick_check.Rationalize(one_byte_);
- re_data->set_quick_check_mask(quick_check.mask());
- re_data->set_quick_check_value(quick_check.value());
- }
- }
-#endif
+ ComputeQuickCheckFilters(start, re_data);
return {code, next_register_};
}
@@ -760,7 +747,7 @@ EmitResult Trace::Flush(Compiler* compiler, Node* successor,
const bool uniform_prefix =
parked_grant() == ParkedGrant::kParkedUniformPrefix ||
parked_grant() == ParkedGrant::kParkedNonEmptyUniformPrefix;
- switch (loop->atomic_loop_kind(compiler->flags())) {
+ switch (loop->atomic_loop_kind()) {
case AtomicLoopKind::kNone:
break;
case AtomicLoopKind::kAtEnd:
@@ -841,16 +828,12 @@ EmitResult Trace::Flush(Compiler* compiler, Node* successor,
}
// Create a new trivial state and generate the node with that.
- Label undo;
+ NonAssertingLabel undo(compiler);
assembler->PushBacktrack(&undo);
if (successor->KeepRecursing(compiler)) {
Trace new_state;
EmitResult r = successor->Emit(compiler, &new_state);
if (V8_UNLIKELY(r.IsError())) {
- // TODO(jgruber): If this pattern emerges elsewhere, let's wrap affected
- // labels in a scope object and add a convenience macro.
- undo.UnuseNear();
- undo.Unuse();
return r;
}
} else {
@@ -934,34 +917,41 @@ void GuardedAlternative::AddGuard(Guard* guard, Zone* zone) {
guards_->Add(guard, zone);
}
-ActionNode* ActionNode::SetRegisterForLoop(int reg, int val, Node* on_success) {
+ActionNode* ActionNode::SetRegisterForLoop(int reg, int val, Node* on_success,
+ Flags flags) {
return on_success->zone()->New<ActionNode>(SET_REGISTER_FOR_LOOP, on_success,
- reg, reg, val);
+ flags, reg, reg, val);
}
-ActionNode* ActionNode::IncrementRegister(int reg, Node* on_success) {
+ActionNode* ActionNode::IncrementRegister(int reg, Node* on_success,
+ Flags flags) {
return on_success->zone()->New<ActionNode>(INCREMENT_REGISTER, on_success,
- reg);
+ flags, reg);
}
-ActionNode* ActionNode::StorePosition(int reg, Node* on_success) {
- return on_success->zone()->New<ActionNode>(STORE_POSITION, on_success, reg);
+ActionNode* ActionNode::StorePosition(int reg, Node* on_success, Flags flags) {
+ return on_success->zone()->New<ActionNode>(STORE_POSITION, on_success, flags,
+ reg);
}
-ActionNode* ActionNode::RestorePosition(int reg, Node* on_success) {
- return on_success->zone()->New<ActionNode>(RESTORE_POSITION, on_success, reg);
+ActionNode* ActionNode::RestorePosition(int reg, Node* on_success,
+ Flags flags) {
+ return on_success->zone()->New<ActionNode>(RESTORE_POSITION, on_success,
+ flags, reg);
}
-ActionNode* ActionNode::ClearCaptures(Interval range, Node* on_success) {
- return on_success->zone()->New<ActionNode>(CLEAR_CAPTURES, on_success,
+ActionNode* ActionNode::ClearCaptures(Interval range, Node* on_success,
+ Flags flags) {
+ return on_success->zone()->New<ActionNode>(CLEAR_CAPTURES, on_success, flags,
range.from(), range.to());
}
ActionNode* ActionNode::BeginPositiveSubmatch(int stack_reg, int position_reg,
Node* body,
- ActionNode* success_node) {
+ ActionNode* success_node,
+ Flags flags) {
ActionNode* result =
- body->zone()->New<ActionNode>(BEGIN_POSITIVE_SUBMATCH, body);
+ body->zone()->New<ActionNode>(BEGIN_POSITIVE_SUBMATCH, body, flags);
result->data_.u_submatch.stack_pointer_register = stack_reg;
result->data_.u_submatch.current_position_register = position_reg;
result->data_.u_submatch.success_node = success_node;
@@ -969,9 +959,9 @@ ActionNode* ActionNode::BeginPositiveSubmatch(int stack_reg, int position_reg,
}
ActionNode* ActionNode::BeginNegativeSubmatch(int stack_reg, int position_reg,
- Node* on_success) {
- ActionNode* result =
- on_success->zone()->New<ActionNode>(BEGIN_NEGATIVE_SUBMATCH, on_success);
+ Node* on_success, Flags flags) {
+ ActionNode* result = on_success->zone()->New<ActionNode>(
+ BEGIN_NEGATIVE_SUBMATCH, on_success, flags);
result->data_.u_submatch.stack_pointer_register = stack_reg;
result->data_.u_submatch.current_position_register = position_reg;
return result;
@@ -980,9 +970,9 @@ ActionNode* ActionNode::BeginNegativeSubmatch(int stack_reg, int position_reg,
ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg, int position_reg,
int clear_register_count,
int clear_register_from,
- Node* on_success) {
+ Node* on_success, Flags flags) {
ActionNode* result = on_success->zone()->New<ActionNode>(
- POSITIVE_SUBMATCH_SUCCESS, on_success);
+ POSITIVE_SUBMATCH_SUCCESS, on_success, flags);
result->data_.u_submatch.stack_pointer_register = stack_reg;
result->data_.u_submatch.current_position_register = position_reg;
result->data_.u_submatch.clear_register_count = clear_register_count;
@@ -992,26 +982,20 @@ ActionNode* ActionNode::PositiveSubmatchSuccess(int stack_reg, int position_reg,
ActionNode* ActionNode::EmptyMatchCheck(int start_register,
int repetition_register,
- int repetition_limit,
- Node* on_success) {
+ int repetition_limit, Node* on_success,
+ Flags flags) {
ActionNode* result =
- on_success->zone()->New<ActionNode>(EMPTY_MATCH_CHECK, on_success);
+ on_success->zone()->New<ActionNode>(EMPTY_MATCH_CHECK, on_success, flags);
result->data_.u_empty_match_check.start_register = start_register;
result->data_.u_empty_match_check.repetition_register = repetition_register;
result->data_.u_empty_match_check.repetition_limit = repetition_limit;
return result;
}
-ActionNode* ActionNode::ModifyFlags(Flags flags, Node* on_success) {
- ActionNode* result =
- on_success->zone()->New<ActionNode>(MODIFY_FLAGS, on_success);
- result->data_.u_modify_flags.flags = flags;
- return result;
-}
-
-ActionNode* ActionNode::EatsAtLeast(int characters, Node* on_success) {
+ActionNode* ActionNode::EatsAtLeast(int characters, Node* on_success,
+ Flags flags) {
ActionNode* result =
- on_success->zone()->New<ActionNode>(EATS_AT_LEAST, on_success);
+ on_success->zone()->New<ActionNode>(EATS_AT_LEAST, on_success, flags);
result->data_.u_eats_at_least.characters = characters;
return result;
}
@@ -1052,139 +1036,6 @@ bool ContainsOnlyUtf16CodeUnits(unibrow::uchar* chars, int length) {
}
#endif // DEBUG
-// Returns the number of characters in the equivalence class, omitting those
-// that cannot occur in the source string because it is Latin1. This is called
-// both for unicode modes /ui and /vi, and also for legacy case independent
-// mode /i. In the case of Unicode modes we handled surrogate pair expansions
-// earlier so at this point it's all about single-code-unit expansions.
-int GetCaseIndependentLetters(Isolate* isolate, base::uc16 character,
- Compiler* compiler, unibrow::uchar* letters,
- int letter_length) {
- bool one_byte_subject = compiler->one_byte();
- bool unicode = IsEitherUnicode(compiler->flags());
- static const base::uc16 kMaxAscii = 0x7f;
- if (!unicode && character <= kMaxAscii) {
- // Fast case for common characters.
- base::uc16 upper = character & ~0x20;
- if ('A' <= upper && upper <= 'Z') {
- letters[0] = upper;
- letters[1] = upper | 0x20;
- return 2;
- }
- letters[0] = character;
- return 1;
- }
-#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);
- }
-
- int32_t range_count = set.getRangeCount();
- int items = 0;
- for (int32_t i = 0; i < range_count; i++) {
- UChar32 start = set.getRangeStart(i);
- UChar32 end = set.getRangeEnd(i);
- 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);
- }
- }
- DCHECK(ContainsOnlyUtf16CodeUnits(letters, items));
- return items;
-#else
- int length =
- isolate->jsregexp_uncanonicalize()->get(character, '\0', letters);
- // Unibrow returns 0 or 1 for characters where case independence is
- // trivial.
- if (length == 0) {
- letters[0] = character;
- length = 1;
- }
-
- if (one_byte_subject) {
- int new_length = 0;
- for (int i = 0; i < length; i++) {
- if (letters[i] <= String::kMaxOneByteCharCode) {
- letters[new_length++] = letters[i];
- }
- }
- length = new_length;
- }
-
- DCHECK(ContainsOnlyUtf16CodeUnits(letters, length));
- return length;
-#endif // V8_INTL_SUPPORT
-}
-
-inline bool EmitSimpleCharacter(Isolate* isolate, Compiler* compiler,
- base::uc16 c, Label* on_failure, int cp_offset,
- bool check, bool preloaded) {
- RegExpMacroAssembler* assembler = compiler->macro_assembler();
- bool bound_checked = false;
- if (!preloaded) {
- assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
- bound_checked = true;
- }
- assembler->CheckNotCharacter(c, on_failure);
- return bound_checked;
-}
-
-// Only emits non-letters (things that don't have case). Only used for case
-// independent matches.
-inline bool EmitAtomNonLetter(Isolate* isolate, Compiler* compiler,
- base::uc16 c, Label* on_failure, int cp_offset,
- bool check, bool preloaded) {
- RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
- bool one_byte = compiler->one_byte();
- unibrow::uchar chars[4];
- int length = GetCaseIndependentLetters(isolate, c, compiler, chars, 4);
- if (length < 1) {
- // This can't match. Must be an one-byte subject and a non-one-byte
- // character. We do not need to do anything since the one-byte pass
- // already handled this.
- CHECK(one_byte);
- return false; // Bounds not checked.
- }
- bool checked = false;
- // We handle the length > 1 case in a later pass.
- if (length == 1) {
- // GetCaseIndependentLetters promises not to return characters that can't
- // match because of the subject encoding. This case is already handled by
- // the one-byte pass.
- CHECK_IMPLIES(one_byte, chars[0] <= String::kMaxOneByteCharCodeU);
- if (!preloaded) {
- macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
- checked = check;
- }
- macro_assembler->CheckNotCharacter(chars[0], on_failure);
- }
- return checked;
-}
-
bool ShortCutEmitCharacterPair(RegExpMacroAssembler* macro_assembler,
bool one_byte, base::uc16 c1, base::uc16 c2,
Label* on_failure) {
@@ -1214,49 +1065,6 @@ bool ShortCutEmitCharacterPair(RegExpMacroAssembler* macro_assembler,
return false;
}
-// Only emits letters (things that have case). Only used for case independent
-// matches.
-inline bool EmitAtomLetter(Isolate* isolate, Compiler* compiler, base::uc16 c,
- Label* on_failure, int cp_offset, bool check,
- bool preloaded) {
- RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
- bool one_byte = compiler->one_byte();
- unibrow::uchar chars[4];
- int length = GetCaseIndependentLetters(isolate, c, compiler, chars, 4);
- // The 0 and 1 case are handled by earlier passes.
- if (length <= 1) return false;
- // We may not need to check against the end of the input string
- // if this character lies before a character that matched.
- if (!preloaded) {
- macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
- }
- Label ok;
- switch (length) {
- case 2: {
- if (ShortCutEmitCharacterPair(macro_assembler, one_byte, chars[0],
- chars[1], on_failure)) {
- } else {
- macro_assembler->CheckCharacter(chars[0], &ok);
- macro_assembler->CheckNotCharacter(chars[1], on_failure);
- macro_assembler->Bind(&ok);
- }
- break;
- }
- case 4:
- macro_assembler->CheckCharacter(chars[3], &ok);
- [[fallthrough]];
- case 3:
- macro_assembler->CheckCharacter(chars[0], &ok);
- macro_assembler->CheckCharacter(chars[1], &ok);
- macro_assembler->CheckNotCharacter(chars[2], on_failure);
- macro_assembler->Bind(&ok);
- break;
- default:
- UNREACHABLE();
- }
- return true;
-}
-
void EmitBoundaryTest(RegExpMacroAssembler* masm, int border,
Label* fall_through, Label* above_or_equal,
Label* below) {
@@ -1721,6 +1529,183 @@ void EmitClassRanges(Compiler* compiler, RegExpMacroAssembler* macro_assembler,
} // namespace
+// Returns the number of characters in the equivalence class, omitting those
+// that cannot occur in the source string because it is Latin1. This is called
+// both for unicode modes /ui and /vi, and also for legacy case independent
+// mode /i. In the case of Unicode modes we handled surrogate pair expansions
+// earlier so at this point it's all about single-code-unit expansions.
+int TextNode::GetCaseIndependentLetters(Compiler* compiler,
+ base::uc16 character,
+ unibrow::uchar* letters,
+ int letter_length) const {
+ const bool one_byte_subject = compiler->one_byte();
+ const bool unicode = IsEitherUnicode(flags());
+ static const base::uc16 kMaxAscii = 0x7f;
+ if (!unicode && character <= kMaxAscii) {
+ // Fast case for common characters.
+ base::uc16 upper = character & ~0x20;
+ if ('A' <= upper && upper <= 'Z') {
+ letters[0] = upper;
+ letters[1] = upper | 0x20;
+ return 2;
+ }
+ letters[0] = character;
+ return 1;
+ }
+#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);
+ }
+
+ int32_t range_count = set.getRangeCount();
+ int items = 0;
+ for (int32_t i = 0; i < range_count; i++) {
+ UChar32 start = set.getRangeStart(i);
+ UChar32 end = set.getRangeEnd(i);
+ 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);
+ }
+ }
+ DCHECK(ContainsOnlyUtf16CodeUnits(letters, items));
+ return items;
+#else
+ int length = compiler->isolate()->jsregexp_uncanonicalize()->get(
+ character, '\0', letters);
+ // Unibrow returns 0 or 1 for characters where case independence is
+ // trivial.
+ if (length == 0) {
+ letters[0] = character;
+ length = 1;
+ }
+
+ if (one_byte_subject) {
+ int new_length = 0;
+ for (int i = 0; i < length; i++) {
+ if (letters[i] <= String::kMaxOneByteCharCode) {
+ letters[new_length++] = letters[i];
+ }
+ }
+ length = new_length;
+ }
+
+ DCHECK(ContainsOnlyUtf16CodeUnits(letters, length));
+ return length;
+#endif // V8_INTL_SUPPORT
+}
+
+bool TextNode::EmitSimpleCharacter(Compiler* compiler, base::uc16 c,
+ Label* on_failure, int cp_offset, bool check,
+ bool preloaded) {
+ RegExpMacroAssembler* assembler = compiler->macro_assembler();
+ bool bound_checked = false;
+ if (!preloaded) {
+ assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
+ bound_checked = true;
+ }
+ assembler->CheckNotCharacter(c, on_failure);
+ return bound_checked;
+}
+
+// Only emits non-letters (things that don't have case). Only used for case
+// independent matches.
+bool TextNode::EmitAtomNonLetter(Compiler* compiler, base::uc16 c,
+ Label* on_failure, int cp_offset, bool check,
+ bool preloaded) {
+ RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+ bool one_byte = compiler->one_byte();
+ unibrow::uchar chars[4];
+ int length = GetCaseIndependentLetters(compiler, c, chars, 4);
+ if (length < 1) {
+ // This can't match. Must be an one-byte subject and a non-one-byte
+ // character. We do not need to do anything since the one-byte pass
+ // already handled this.
+ CHECK(one_byte);
+ return false; // Bounds not checked.
+ }
+ bool checked = false;
+ // We handle the length > 1 case in a later pass.
+ if (length == 1) {
+ // GetCaseIndependentLetters promises not to return characters that can't
+ // match because of the subject encoding. This case is already handled by
+ // the one-byte pass.
+ CHECK_IMPLIES(one_byte, chars[0] <= String::kMaxOneByteCharCodeU);
+ if (!preloaded) {
+ macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
+ checked = check;
+ }
+ macro_assembler->CheckNotCharacter(chars[0], on_failure);
+ }
+ return checked;
+}
+
+// Only emits letters (things that have case). Only used for case independent
+// matches.
+bool TextNode::EmitAtomLetter(Compiler* compiler, base::uc16 c,
+ Label* on_failure, int cp_offset, bool check,
+ bool preloaded) {
+ RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
+ bool one_byte = compiler->one_byte();
+ unibrow::uchar chars[4];
+ int length = GetCaseIndependentLetters(compiler, c, chars, 4);
+ // The 0 and 1 case are handled by earlier passes.
+ if (length <= 1) return false;
+ // We may not need to check against the end of the input string
+ // if this character lies before a character that matched.
+ if (!preloaded) {
+ macro_assembler->LoadCurrentCharacter(cp_offset, on_failure, check);
+ }
+ Label ok;
+ switch (length) {
+ case 2: {
+ if (ShortCutEmitCharacterPair(macro_assembler, one_byte, chars[0],
+ chars[1], on_failure)) {
+ } else {
+ macro_assembler->CheckCharacter(chars[0], &ok);
+ macro_assembler->CheckNotCharacter(chars[1], on_failure);
+ macro_assembler->Bind(&ok);
+ }
+ break;
+ }
+ case 4:
+ macro_assembler->CheckCharacter(chars[3], &ok);
+ [[fallthrough]];
+ case 3:
+ macro_assembler->CheckCharacter(chars[0], &ok);
+ macro_assembler->CheckCharacter(chars[1], &ok);
+ macro_assembler->CheckNotCharacter(chars[2], on_failure);
+ macro_assembler->Bind(&ok);
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return true;
+}
+
Node::~Node() = default;
Node::LimitResult Node::LimitVersions(Compiler* compiler, Trace* trace) {
@@ -1784,13 +1769,6 @@ void ActionNode::FillInBMInfo(Isolate* isolate, int offset, int budget,
case EATS_AT_LEAST:
on_success()->FillInBMInfo(isolate, offset, budget - 1, bm, not_at_start);
break;
- case MODIFY_FLAGS: {
- std::optional<Flags> old_flags = bm->compiler()->flags();
- bm->compiler()->set_flags(flags());
- on_success()->FillInBMInfo(isolate, offset, budget - 1, bm, not_at_start);
- bm->compiler()->set_flags(*old_flags);
- break;
- }
case BEGIN_POSITIVE_SUBMATCH:
// We use the node after the lookaround to fill in the eats_at_least info
// so we have to use the same node to fill in the Boyer-Moore info.
@@ -1821,14 +1799,6 @@ void ActionNode::GetQuickCheckDetails(QuickCheckDetails* details,
on_success()->GetQuickCheckDetails(details, compiler, filled_in,
not_at_start, budget - 1);
break;
- case MODIFY_FLAGS: {
- std::optional<Flags> old_flags = compiler->flags();
- compiler->set_flags(flags());
- on_success()->GetQuickCheckDetails(details, compiler, filled_in,
- not_at_start, budget - 1);
- compiler->set_flags(*old_flags);
- break;
- }
case BEGIN_POSITIVE_SUBMATCH:
// We use the node after the lookaround to fill in the eats_at_least info
// so we have to use the same node to fill in the QuickCheck info.
@@ -2112,7 +2082,6 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
// Do not collect any quick check details if the text node reads backward,
// since it reads in the opposite direction than we use for quick checks.
if (read_backward()) return;
- Isolate* isolate = compiler->isolate();
DCHECK(characters_filled_in < details->characters());
int characters = details->characters();
const uint32_t char_mask = CharMask(compiler->one_byte());
@@ -2124,10 +2093,9 @@ void TextNode::GetQuickCheckDetails(QuickCheckDetails* details,
QuickCheckDetails::Position* pos =
details->positions(characters_filled_in);
base::uc16 c = quarks[i];
- if (IsIgnoreCase(compiler->flags())) {
+ if (IsIgnoreCase(flags())) {
unibrow::uchar chars[4];
- int length =
- GetCaseIndependentLetters(isolate, c, compiler, chars, 4);
+ int length = GetCaseIndependentLetters(compiler, c, chars, 4);
if (length == 0) {
// This can happen because all case variants are non-Latin1, but we
// know the input is Latin1.
@@ -2338,7 +2306,7 @@ bool RangesContainLatin1Equivalents(ZoneList<CharacterRange>* ranges) {
} // namespace
bool TextNode::CanMatchLatin1(Compiler* compiler) {
- Flags flags = compiler->flags();
+ Flags flags = this->flags();
int element_count = elements()->length();
for (int i = 0; i < element_count; i++) {
TextElement elm = elements()->at(i);
@@ -2350,8 +2318,7 @@ bool TextNode::CanMatchLatin1(Compiler* compiler) {
if (c > String::kMaxOneByteCharCode) return false;
} else {
unibrow::uchar chars[4];
- int length = GetCaseIndependentLetters(compiler->isolate(), c,
- compiler, chars, 4);
+ int length = GetCaseIndependentLetters(compiler, c, chars, 4);
if (length == 0 || chars[0] > String::kMaxOneByteCharCode) {
return false;
}
@@ -2515,8 +2482,8 @@ EmitResult AssertionNode::EmitBoundaryCheck(Compiler* compiler, Trace* trace) {
}
bool at_boundary = (assertion_type_ == AssertionNode::AT_BOUNDARY);
if (next_is_word_character == Trace::UNKNOWN) {
- Label before_non_word;
- Label before_word;
+ NonAssertingLabel before_non_word(compiler);
+ NonAssertingLabel before_word(compiler);
if (trace->characters_preloaded() != 1) {
assembler->LoadCurrentCharacter(trace->cp_offset(), &before_non_word);
}
@@ -2524,7 +2491,7 @@ EmitResult AssertionNode::EmitBoundaryCheck(Compiler* compiler, Trace* trace) {
EmitWordCheck(assembler, &before_word, &before_non_word, false);
// Next character is not a word character.
assembler->Bind(&before_non_word);
- Label ok;
+ NonAssertingLabel ok(compiler);
RETURN_IF_ERROR(BacktrackIfPrevious(compiler, trace,
at_boundary ? kIsNonWord : kIsWord));
assembler->GoTo(&ok);
@@ -2685,7 +2652,6 @@ void TextNode::TextEmitPass(Compiler* compiler, TextEmitPassType pass,
bool preloaded, Trace* trace,
bool first_element_checked, int* checked_up_to) {
RegExpMacroAssembler* assembler = compiler->macro_assembler();
- Isolate* isolate = assembler->isolate();
bool one_byte = compiler->one_byte();
Label* backtrack = trace->backtrack();
const QuickCheckDetails* quick_check = trace->quick_check_performed();
@@ -2706,14 +2672,13 @@ void TextNode::TextEmitPass(Compiler* compiler, TextEmitPassType pass,
switch (pass) {
case NON_LATIN1_MATCH: {
DCHECK(one_byte); // This pass is only done in one-byte mode.
- if (IsIgnoreCase(compiler->flags())) {
+ if (IsIgnoreCase(flags())) {
// We are compiling for a one-byte subject, case independent mode.
// We have to check whether any of the case alternatives are in
// the one-byte range.
unibrow::uchar chars[4];
// Only returns characters that are in the one-byte range.
- int length =
- GetCaseIndependentLetters(isolate, quark, compiler, chars, 4);
+ int length = GetCaseIndependentLetters(compiler, quark, chars, 4);
if (length == 0) {
assembler->GoTo(backtrack);
return;
@@ -2729,18 +2694,18 @@ void TextNode::TextEmitPass(Compiler* compiler, TextEmitPassType pass,
}
case NON_LETTER_CHARACTER_MATCH:
bounds_checked =
- EmitAtomNonLetter(isolate, compiler, quark, backtrack,
- cp_offset + j, needs_bounds_check, preloaded);
+ EmitAtomNonLetter(compiler, quark, backtrack, cp_offset + j,
+ needs_bounds_check, preloaded);
break;
case SIMPLE_CHARACTER_MATCH:
- bounds_checked = EmitSimpleCharacter(isolate, compiler, quark,
- backtrack, cp_offset + j,
- needs_bounds_check, preloaded);
+ bounds_checked =
+ EmitSimpleCharacter(compiler, quark, backtrack, cp_offset + j,
+ needs_bounds_check, preloaded);
break;
case CASE_CHARACTER_MATCH:
bounds_checked =
- EmitAtomLetter(isolate, compiler, quark, backtrack,
- cp_offset + j, needs_bounds_check, preloaded);
+ EmitAtomLetter(compiler, quark, backtrack, cp_offset + j,
+ needs_bounds_check, preloaded);
break;
default:
break;
@@ -2776,17 +2741,17 @@ int TextNode::Length() {
TextNode* TextNode::CreateForCharacterRanges(Zone* zone,
ZoneList<CharacterRange>* ranges,
bool read_backward,
- Node* on_success) {
+ Node* on_success, Flags flags) {
DCHECK_NOT_NULL(ranges);
// TODO(jgruber): There's no fundamental need to create this
// ClassRanges; we could refactor to avoid the allocation.
return zone->New<TextNode>(zone->New<ClassRanges>(zone, ranges),
- read_backward, on_success);
+ read_backward, on_success, flags);
}
TextNode* TextNode::CreateForSurrogatePair(
Zone* zone, CharacterRange lead, ZoneList<CharacterRange>* trail_ranges,
- bool read_backward, Node* on_success) {
+ bool read_backward, Node* on_success, Flags flags) {
ZoneList<TextElement>* elms = zone->New<ZoneList<TextElement>>(2, zone);
if (lead.from() == lead.to()) {
ZoneList<base::uc16> lead_surrogate(1, zone);
@@ -2802,12 +2767,12 @@ TextNode* TextNode::CreateForSurrogatePair(
elms->Add(
TextElement::FromClassRanges(zone->New<ClassRanges>(zone, trail_ranges)),
zone);
- return zone->New<TextNode>(elms, read_backward, on_success);
+ return zone->New<TextNode>(elms, read_backward, on_success, flags);
}
TextNode* TextNode::CreateForSurrogatePair(
Zone* zone, ZoneList<CharacterRange>* lead_ranges, CharacterRange trail,
- bool read_backward, Node* on_success) {
+ bool read_backward, Node* on_success, Flags flags) {
ZoneList<CharacterRange>* trail_ranges = CharacterRange::List(zone, trail);
ZoneList<TextElement>* elms = zone->New<ZoneList<TextElement>>(2, zone);
elms->Add(
@@ -2816,7 +2781,7 @@ TextNode* TextNode::CreateForSurrogatePair(
elms->Add(
TextElement::FromClassRanges(zone->New<ClassRanges>(zone, trail_ranges)),
zone);
- return zone->New<TextNode>(elms, read_backward, on_success);
+ return zone->New<TextNode>(elms, read_backward, on_success, flags);
}
// This generates the code to match a text node. A text node can contain
@@ -2868,7 +2833,7 @@ EmitResult TextNode::Emit(Compiler* compiler, Trace* trace) {
for (int twice = 0; twice < 2; twice++) {
bool is_preloaded_pass = twice == 0;
if (is_preloaded_pass && trace->characters_preloaded() != 1) continue;
- if (IsIgnoreCase(compiler->flags())) {
+ if (IsIgnoreCase(flags())) {
TextEmitPass(compiler, NON_LETTER_CHARACTER_MATCH, is_preloaded_pass,
trace, first_elt_done, &bound_checked_to);
TextEmitPass(compiler, CASE_CHARACTER_MATCH, is_preloaded_pass, trace,
@@ -2916,13 +2881,12 @@ EmitResult Trace::AdvanceCurrentPositionInTrace(int by, Compiler* compiler) {
return EmitResult::Success();
}
-void TextNode::MakeCaseIndependent(Isolate* isolate, bool is_one_byte,
- Flags flags) {
- if (!IsIgnoreCase(flags)) return;
+void TextNode::MakeCaseIndependent(Isolate* isolate, bool is_one_byte) {
+ if (!IsIgnoreCase(flags())) return;
#ifdef V8_INTL_SUPPORT
// This is done in an earlier step when generating the nodes from the AST
// because we may have to split up into separate nodes.
- if (NeedsUnicodeCaseEquivalents(flags)) return;
+ if (NeedsUnicodeCaseEquivalents(flags())) return;
#endif
int element_count = elements()->length();
@@ -3010,6 +2974,247 @@ void AppendClassRangesMatchSet(ClassRanges* cr, Zone* node_zone, Zone* zone,
for (int i = 0; i < negated.length(); i++) out->Add(negated.at(i), zone);
}
+// Collects FIRST(start): a superset of the characters that can begin a match,
+// so a character absent from it can be rejected without running the engine.
+//
+// Superset, never subset: a character omitted here is one the filter wrongly
+// rejects, turning a real match into null. A node we cannot analyze must
+// therefore give up the whole filter by returning false, never add nothing,
+// which reads as "this node matches nothing". Budget exhaustion likewise.
+//
+// TryBuildFirstCharacterTable computes a similar set, but its Boyer-Moore map
+// indexes 128 entries modulo 128 and widens negated classes to SetAll, so
+// latin-1 characters alias. Harmless there, where the body re-checks in full;
+// fatal here, where nothing does.
+//
+// TODO(jgruber): Unify the two by having TryBuildFirstCharacterTable project
+// this set onto its 128-entry table. That direction works now that atoms
+// carry their case closure, but needs a benchmark run: the two disagree on
+// when to bail, and the table's selectivity heuristic is tuned against the
+// wider Boyer-Moore sets.
+class FirstCharacterSetBuilder {
+ public:
+ FirstCharacterSetBuilder(Compiler* compiler, Zone* zone,
+ ZoneList<CharacterRange>* out)
+ : compiler_(compiler), zone_(zone), out_(out) {}
+
+ bool Build(Node* start) { return AddNode(start, 0); }
+
+ private:
+ static constexpr int kBudget = 500;
+
+ bool AddNode(Node* node, int depth) {
+ if (node == nullptr) return false;
+ if (depth > Compiler::kMaxRecursion) return false;
+ if (--budget_ < 0) return false;
+
+ if (AssertionNode* assertion = node->AsAssertionNode()) {
+ // Zero-width, so it cannot change which character is consumed first.
+ return AddNode(assertion->on_success(), depth + 1);
+ }
+ if (ActionNode* action = node->AsActionNode()) {
+ return AddAction(action, depth);
+ }
+ if (ChoiceNode* choice = node->AsChoiceNode()) {
+ return AddChoice(choice, depth);
+ }
+ if (TextNode* text = node->AsTextNode()) return AddText(text);
+ if (EndNode* end = node->AsEndNode()) {
+ // A backtrack always fails, so contributing nothing is exact rather than
+ // a guess. Worth distinguishing: a one-byte compile turns any class
+ // that cannot match latin-1 into a backtrack, so giving up here would
+ // lose the [abc] filter in /(?=[\u{1F600}])[abc]/u.
+ if (end->IsBacktrack()) return true;
+ // Any other end matches without consuming.
+ return false;
+ }
+ // BackReferenceNode matches previously captured text, unknown at compile
+ // time. UnanchoredAdvance moves the position.
+ DCHECK(node->AsBackReferenceNode() != nullptr ||
+ node->AsUnanchoredAdvanceNode() != nullptr);
+ return false;
+ }
+
+ bool AddAction(ActionNode* action, int depth) {
+ switch (action->action_type()) {
+ // Pure bookkeeping: no effect on the first consumed character.
+ case ActionNode::STORE_POSITION:
+ case ActionNode::CLEAR_CAPTURES:
+ case ActionNode::SET_REGISTER_FOR_LOOP:
+ case ActionNode::INCREMENT_REGISTER:
+ case ActionNode::EATS_AT_LEAST:
+ return AddNode(action->on_success(), depth + 1);
+ // Reached when the body matched without consuming, as in /^(?=a*)b/, so
+ // the continuation is what supplies the first character. on_success()
+ // is that continuation.
+ case ActionNode::POSITIVE_SUBMATCH_SUCCESS:
+ return AddNode(action->on_success(), depth + 1);
+ case ActionNode::BEGIN_POSITIVE_SUBMATCH:
+ // on_success() is the lookaround body, success_node()->on_success()
+ // the continuation after it. A lookahead body has to match at the
+ // position, so its set is the tighter answer; a lookbehind body reads
+ // leftwards, so that walk gives up and the continuation answers
+ // instead, [a-c] in /(?<=x)[a-c]/. The position is restored either
+ // way, so the continuation is what consumes at it. A failed body walk
+ // may have left entries in out_, and we keep them: extra entries only
+ // widen the set, which weakens the filter rather than breaking it.
+ if (AddNode(action->on_success(), depth + 1)) return true;
+ return AddNode(action->success_node()->on_success(), depth + 1);
+ case ActionNode::BEGIN_NEGATIVE_SUBMATCH:
+ // The body has to fail, so it contributes nothing and only the
+ // continuation constrains: /(?!x)[a-c]/ still starts with [a-c].
+ // on_success() is the choice node below, which walks just that.
+ return AddNode(action->on_success(), depth + 1);
+ // Both fail or move the position depending on runtime state.
+ case ActionNode::EMPTY_MATCH_CHECK:
+ case ActionNode::RESTORE_POSITION:
+ return false;
+ }
+ UNREACHABLE();
+ }
+
+ bool AddChoice(ChoiceNode* choice, int depth) {
+ // A negative lookaround's first alternative must *fail*, so it says nothing
+ // about what can start a match; only the continue branch does.
+ if (NegativeLookaroundChoiceNode* negative =
+ choice->AsNegativeLookaroundChoiceNode()) {
+ return AddNode(negative->continue_node(), depth + 1);
+ }
+ // The match can go down any alternative, so the answer is their union and
+ // one that gives up sinks the rest. Guards decide whether an alternative
+ // is taken, not which character it consumes, so guarded ones count too.
+ DCHECK(!choice->alternatives()->is_empty());
+ for (GuardedAlternative& alt : *choice->alternatives()) {
+ if (!AddNode(alt.node(), depth + 1)) return false;
+ }
+ return true;
+ }
+
+ bool AddText(TextNode* text) {
+ // A backward-matching node consumes to the left of the position, so its
+ // characters are not the match's first.
+ if (text->read_backward()) return false;
+ if (text->elements()->is_empty()) return false;
+ // Only the first element can supply the first character.
+ TextElement& elm = text->elements()->at(0);
+ if (elm.text_type() == TextElement::CLASS_RANGES) {
+ // Class ranges have their case equivalents materialized during analysis
+ // (TextNode::MakeCaseIndependent), so the listed ranges are complete.
+ AppendClassRangesMatchSet(elm.class_ranges(), text->zone(), zone_, out_);
+ return true;
+ }
+ DCHECK_EQ(elm.text_type(), TextElement::ATOM);
+ base::Vector<const base::uc16> data = elm.atom()->data();
+ if (data.empty()) return false;
+ const base::uc16 c = data[0];
+ if (!IsIgnoreCase(text->flags())) {
+ out_->Add(CharacterRange::Singleton(c), zone_);
+ return true;
+ }
+ // Atoms keep the character as written and only get their case variants at
+ // emission time, so add the same closure emission uses.
+ unibrow::uchar letters[4];
+ int length = text->GetCaseIndependentLetters(compiler_, c, letters, 4);
+ // Zero variants means none fit the subject encoding. Unlike a backtrack,
+ // that is a gap in our knowledge rather than a proof of no match, so give
+ // up instead of contributing the empty set.
+ if (length == 0) return false;
+ for (int i = 0; i < length; i++) {
+ out_->Add(CharacterRange::Singleton(letters[i]), zone_);
+ }
+ return true;
+ }
+
+ Compiler* const compiler_;
+ Zone* const zone_;
+ ZoneList<CharacterRange>* const out_;
+ int budget_ = kBudget;
+};
+
+// Appends FIRST(start) to |out| and returns true, or returns false if the set
+// is not statically known. On false |out| may hold a partial set and must not
+// be used. See FirstCharacterSetBuilder for the soundness contract.
+bool ComputeFirstCharacterSet(Node* start, Compiler* compiler, Zone* zone,
+ ZoneList<CharacterRange>* out) {
+ FirstCharacterSetBuilder builder(compiler, zone, out);
+ if (!builder.Build(start)) return false;
+ CharacterRange::Canonicalize(out);
+ return true;
+}
+
+// The mask keeps only bits all four candidate characters agree on, so an
+// alternation over dissimilar characters erodes it; the bitset is exact but
+// covers one character. Neither dominates, so store both and let the runtime
+// chain them.
+//
+// Skip for multiline regexps as match attempts are less likely to be rejected
+// early based on the first few characters.
+void Compiler::ComputeQuickCheckFilters(Node* start,
+ DirectHandle<RegExpData> re_data) {
+ // Both filters describe the character at the match position, so they say
+ // nothing unless the match has to start there. Otherwise PreprocessRegExp
+ // prepended the `.*?` search loop and every walk below hits it and returns
+ // "anything goes"; answer that up front rather than rediscovering it.
+ if (has_search_prefix()) return;
+
+ constexpr bool kPossiblyAtStart = false;
+ constexpr int kMinChars = 1;
+ constexpr int kMaxChars = 4;
+ int eats_at_least = start->EatsAtLeast(kPossiblyAtStart);
+ if (!one_byte() || eats_at_least < kMinChars || IsMultiline(flags())) {
+ return;
+ }
+
+ bool has_filter = false;
+
+ // Little-endian only: the mask is compared against four characters loaded as
+ // one word, so byte order matters. The bitset below indexes by character
+ // value instead and works everywhere.
+#ifdef V8_TARGET_LITTLE_ENDIAN
+ int chars = std::min(eats_at_least, kMaxChars);
+ QuickCheckDetails quick_check(chars);
+ start->GetQuickCheckDetails(&quick_check, this, 0, kPossiblyAtStart,
+ Node::kRecursionBudget);
+ if (!quick_check.cannot_match()) {
+ quick_check.Rationalize(one_byte());
+ if (quick_check.mask() != 0) {
+ re_data->set_quick_check_mask(quick_check.mask());
+ re_data->set_quick_check_value(quick_check.value());
+ has_filter = true;
+ }
+ }
+#else
+ USE(kMaxChars);
+#endif
+
+ // Store the inverse of the collected set, since the exec path rejects on a
+ // set bit. A pattern that can start with anything inverts to all zeroes,
+ // which rejects nothing and so does not count as a filter.
+ ZoneList<CharacterRange> first_set(2, zone());
+ if (ComputeFirstCharacterSet(start, this, zone(), &first_set)) {
+ uint32_t accept[RegExpData::kQuickCheckBitsetWords] = {};
+ for (const CharacterRange& range : first_set) {
+ base::uc32 to = std::min<base::uc32>(
+ range.to(), RegExpData::kQuickCheckBitsetChars - 1);
+ for (base::uc32 c = range.from(); c <= to; c++) {
+ auto [word, bit] = RegExpData::QuickCheckBitsetBit(c);
+ accept[word] |= bit;
+ }
+ }
+ bool rejects_anything = false;
+ for (int i = 0; i < RegExpData::kQuickCheckBitsetWords; i++) {
+ re_data->set_quick_check_reject_bitset_word(i, ~accept[i]);
+ rejects_anything |= ~accept[i] != 0;
+ }
+ has_filter |= rejects_anything;
+ }
+
+ if (has_filter) {
+ re_data->set_internal_flags(re_data->internal_flags() |
+ RegExpData::kHasQuickCheck);
+ }
+}
+
// Returns true iff every character in |ranges| (canonical) is in
// |special_class|, a [from, to+1) pair table terminated by kRangeEndMarker
// (e.g. kWordRanges). Each range must fit inside a single table entry.
@@ -3077,7 +3282,7 @@ bool AppendTextElementMatchSet(TextElement& elm, Zone* node_zone, Flags flags,
// position can hold, since every such position was consumed by a body
// iteration.
AtomicLoopBodyAnalysis AnalyzeAtomicLoopBody(
- GuardedAlternative* alt, Node* loop, Flags flags, Zone* zone,
+ GuardedAlternative* alt, Node* loop, Zone* zone,
ZoneList<CharacterRange>* body_set) {
AtomicLoopBodyAnalysis result;
Node* node = alt->node();
@@ -3098,8 +3303,8 @@ AtomicLoopBodyAnalysis AnalyzeAtomicLoopBody(
} else {
ZoneList<TextElement>* elms = text->elements();
for (int i = 0; i < elms->length(); i++) {
- if (!AppendTextElementMatchSet(elms->at(i), text->zone(), flags, zone,
- body_set)) {
+ if (!AppendTextElementMatchSet(elms->at(i), text->zone(), text->flags(),
+ zone, body_set)) {
result.set_known = false;
}
}
@@ -3144,7 +3349,6 @@ bool ContinuationAlwaysSucceeds(Node* node, int depth, int* budget) {
case ActionNode::CLEAR_CAPTURES:
case ActionNode::SET_REGISTER_FOR_LOOP:
case ActionNode::INCREMENT_REGISTER:
- case ActionNode::MODIFY_FLAGS:
case ActionNode::EATS_AT_LEAST:
case ActionNode::RESTORE_POSITION:
case ActionNode::POSITIVE_SUBMATCH_SUCCESS:
@@ -3225,8 +3429,7 @@ struct AtomicLoopContinuationAnalysis {
};
AtomicLoopContinuationAnalysis AnalyzeAtomicLoopContinuation(
- GuardedAlternative* alt, Flags flags, Zone* zone,
- ZoneList<CharacterRange>* first_set) {
+ GuardedAlternative* alt, Zone* zone, ZoneList<CharacterRange>* first_set) {
AtomicLoopContinuationAnalysis result;
if (alt->guards() != nullptr && alt->guards()->length() != 0) return result;
Node* node = alt->node();
@@ -3266,7 +3469,6 @@ AtomicLoopContinuationAnalysis AnalyzeAtomicLoopContinuation(
// characters match, so the FIRST walk stops.
case ActionNode::SET_REGISTER_FOR_LOOP:
case ActionNode::INCREMENT_REGISTER:
- case ActionNode::MODIFY_FLAGS:
first_alive = false;
break;
// RESTORE_POSITION rewrites the position; submatch actions consume
@@ -3300,7 +3502,7 @@ AtomicLoopContinuationAnalysis AnalyzeAtomicLoopContinuation(
AppendClassRangesMatchSet(elm.class_ranges(), text->zone(), zone,
first_set);
result.first_set_known = true;
- } else if (!IsIgnoreCase(flags)) {
+ } else if (!IsIgnoreCase(text->flags())) {
DCHECK_EQ(elm.text_type(), TextElement::ATOM);
first_set->Add(CharacterRange::Singleton(elm.atom()->data().at(0)),
zone);
@@ -3316,7 +3518,7 @@ AtomicLoopContinuationAnalysis AnalyzeAtomicLoopContinuation(
// Classifies |loop| as an atomic loop: alt 0 a fixed-length greedy body
// chain back to |loop|, alt 1 a continuation that provably cannot benefit
// from retreating (per kind; see AtomicLoopKind).
-AtomicLoopKind ClassifyAtomicLoop(LoopChoiceNode* loop, Flags flags) {
+AtomicLoopKind ClassifyAtomicLoop(LoopChoiceNode* loop) {
if (loop->alternatives()->length() != 2) return AtomicLoopKind::kNone;
GuardedAlternative* body = &loop->alternatives()->at(0);
GuardedAlternative* continuation = &loop->alternatives()->at(1);
@@ -3324,12 +3526,12 @@ AtomicLoopKind ClassifyAtomicLoop(LoopChoiceNode* loop, Flags flags) {
ZoneList<CharacterRange> body_set(4, zone);
AtomicLoopBodyAnalysis body_info =
- AnalyzeAtomicLoopBody(body, loop, flags, zone, &body_set);
+ AnalyzeAtomicLoopBody(body, loop, zone, &body_set);
if (!body_info.fixed_length_eligible) return AtomicLoopKind::kNone;
ZoneList<CharacterRange> first_set(2, zone);
AtomicLoopContinuationAnalysis cont =
- AnalyzeAtomicLoopContinuation(continuation, flags, zone, &first_set);
+ AnalyzeAtomicLoopContinuation(continuation, zone, &first_set);
// Mutually exclusive: a leading AT_END fails the always-succeeds walk (it
// stops at the assertion), so only one of these fires.
@@ -3359,10 +3561,9 @@ AtomicLoopKind ClassifyAtomicLoop(LoopChoiceNode* loop, Flags flags) {
return AtomicLoopKind::kNone;
}
-AtomicLoopKind LoopChoiceNode::atomic_loop_kind(Flags flags) {
- if (!atomic_loop_kind_valid_ || atomic_loop_kind_flags_ != flags) {
- atomic_loop_kind_ = ClassifyAtomicLoop(this, flags);
- atomic_loop_kind_flags_ = flags;
+AtomicLoopKind LoopChoiceNode::atomic_loop_kind() {
+ if (!atomic_loop_kind_valid_) {
+ atomic_loop_kind_ = ClassifyAtomicLoop(this);
atomic_loop_kind_valid_ = true;
}
return atomic_loop_kind_;
@@ -3384,11 +3585,10 @@ AtomicLoopKind LoopChoiceNode::atomic_loop_kind(Flags flags) {
// start position that matches (/(?:aa)+c/ on "aaaaac" must match "aaaac"@1).
// The restore modes have no such restriction: they restore the position, so
// they stay valid at any body width.
-DrainMode ChooseFixedLengthLoopDrainMode(ChoiceNode* choice, Trace* trace,
- Flags flags) {
+DrainMode ChooseFixedLengthLoopDrainMode(ChoiceNode* choice, Trace* trace) {
LoopChoiceNode* loop = choice->AsLoopChoiceNode();
if (loop == nullptr) return DrainMode::kFull;
- const AtomicLoopKind kind = loop->atomic_loop_kind(flags);
+ const AtomicLoopKind kind = loop->atomic_loop_kind();
// Parking is unsound for a multi-code-unit body (see above); such loops fall
// back to their widest reduced mode below.
const bool parkable = kind != AtomicLoopKind::kNone &&
@@ -3490,16 +3690,16 @@ int ChoiceNode::CalculatePreloadCharacters(Compiler* compiler,
// This class is used when generating the alternatives in a choice node. It
// records the way the alternative is being code generated.
-class AlternativeGeneration : public Malloced {
+class AlternativeGeneration : public ZoneObject {
public:
- AlternativeGeneration()
- : possible_success(),
+ explicit AlternativeGeneration(Compiler* compiler)
+ : possible_success(compiler),
expects_preload(false),
- after(),
+ after(compiler),
quick_check_details() {}
- Label possible_success;
+ NonAssertingLabel possible_success;
bool expects_preload;
- Label after;
+ NonAssertingLabel after;
QuickCheckDetails quick_check_details;
};
@@ -3508,37 +3708,22 @@ class AlternativeGeneration : public Malloced {
class AlternativeGenerationList {
public:
AlternativeGenerationList(int count, Compiler* compiler)
- : alt_gens_(count, compiler->zone()), compiler_(compiler) {
+ : alt_gens_(count, compiler->zone()) {
Zone* zone = compiler->zone();
- for (int i = 0; i < count && i < kAFew; i++) {
- alt_gens_.Add(a_few_alt_gens_ + i, zone);
- }
- for (int i = kAFew; i < count; i++) {
- alt_gens_.Add(new AlternativeGeneration(), zone);
+ for (int i = 0; i < count; i++) {
+ alt_gens_.Add(zone->New<AlternativeGeneration>(compiler), zone);
}
}
~AlternativeGenerationList() {
- if (V8_UNLIKELY(compiler_->IsRegExpTooBig())) {
- for (int i = 0; i < alt_gens_.length(); i++) {
- alt_gens_[i]->possible_success.UnuseNear();
- alt_gens_[i]->possible_success.Unuse();
- alt_gens_[i]->after.UnuseNear();
- alt_gens_[i]->after.Unuse();
- }
- }
- for (int i = kAFew; i < alt_gens_.length(); i++) {
- delete alt_gens_[i];
- alt_gens_[i] = nullptr;
+ for (int i = 0; i < alt_gens_.length(); i++) {
+ alt_gens_[i]->~AlternativeGeneration();
}
}
AlternativeGeneration* at(int i) { return alt_gens_[i]; }
private:
- static const int kAFew = 10;
ZoneList<AlternativeGeneration*> alt_gens_;
- AlternativeGeneration a_few_alt_gens_[kAFew];
- Compiler* compiler_;
};
void BoyerMoorePositionInfo::Set(int character) {
@@ -3975,9 +4160,11 @@ bool BoyerMooreLookahead::BuildSkipTable(RegExpMacroAssembler* masm,
* S2--/
*/
-SpecialLoopState::SpecialLoopState(bool not_at_start,
+SpecialLoopState::SpecialLoopState(Compiler* compiler, bool not_at_start,
ChoiceNode* loop_choice_node)
- : loop_choice_node_(loop_choice_node) {
+ : step_label_(compiler),
+ loop_top_label_(compiler),
+ loop_choice_node_(loop_choice_node) {
backtrack_trace_.set_backtrack(&step_label_);
if (not_at_start) backtrack_trace_.set_at_start(Trace::FALSE_VALUE);
}
@@ -4049,20 +4236,15 @@ EmitResult ChoiceNode::Emit(Compiler* compiler, Trace* trace) {
preload.init();
// This must be outside the 'if' because the trace we use for what
// comes after the special_loop is inside it and needs the lifetime.
- SpecialLoopState special_loop_state(not_at_start(), this);
+ SpecialLoopState special_loop_state(compiler, not_at_start(), this);
int text_length = FixedLengthLoopLengthForAlternative(&alternatives_->at(0));
AlternativeGenerationList alt_gens(choice_count, compiler);
- // Flags need to be reset to the state of the ChoiceNode at the beginning
- // of each alternative (in-line and out-of-line), as flags might be modified
- // when emitting an alternative.
- Flags flags = compiler->flags();
// Grant the search-loop body its parked-position grant (see
- // ComputeSearchBodyParkedGrant, Trace::parked_grant). Computed once here
+ // ComputeSearchBodyParkedGrant, Trace::parked_grant). Computed once here
// rather than at each of its two consumers below (inline emission in
- // EmitChoices and the out-of-line continuation loop), since compiler->flags()
- // is reset per alternative and would no longer reflect this node.
+ // EmitChoices and the out-of-line continuation loop).
LoopChoiceNode* loop_choice = AsLoopChoiceNode();
const ParkedGrant body_parked_grant =
loop_choice != nullptr
@@ -4072,8 +4254,7 @@ EmitResult ChoiceNode::Emit(Compiler* compiler, Trace* trace) {
// If the continuation is provably retreat-insensitive, the drain
// epilogue can be reduced or omitted entirely; see DrainMode and
// ChooseFixedLengthLoopDrainMode. Covers /\s+$/, /\w+\b=/, /[abc]*d/.
- const DrainMode drain_mode =
- ChooseFixedLengthLoopDrainMode(this, trace, flags);
+ const DrainMode drain_mode = ChooseFixedLengthLoopDrainMode(this, trace);
// A reduced drain reaches here only on a fresh trace (cp_offset() == 0):
// the trivial post-flush trace, or Trace::Flush's direct granted emission.
// A pending cp advance would break the marker-equals-entry reasoning the
@@ -4086,12 +4267,12 @@ EmitResult ChoiceNode::Emit(Compiler* compiler, Trace* trace) {
// Non-kFull only for a LoopChoiceNode, so AsLoopChoiceNode() is non-null.
TRACE("* Atomic loop drain reduced: "
<< DrainModeName(drain_mode) << " (kind "
- << AtomicLoopKindName(AsLoopChoiceNode()->atomic_loop_kind(flags))
+ << AtomicLoopKindName(AsLoopChoiceNode()->atomic_loop_kind())
<< ", grant " << ParkedGrantName(trace->parked_grant()) << ")");
}
trace = EmitFixedLengthLoop(compiler, trace, &alt_gens, &preload,
- &special_loop_state, text_length, flags,
- drain_mode, body_parked_grant);
+ &special_loop_state, text_length, drain_mode,
+ body_parked_grant);
if (trace == nullptr) return EmitResult::Error();
} else {
bool bm_scan_emitted = false;
@@ -4119,7 +4300,7 @@ EmitResult ChoiceNode::Emit(Compiler* compiler, Trace* trace) {
}
}
- RETURN_IF_ERROR(EmitChoices(compiler, &alt_gens, 0, trace, &preload, flags,
+ RETURN_IF_ERROR(EmitChoices(compiler, &alt_gens, 0, trace, &preload,
body_parked_grant));
}
@@ -4128,7 +4309,6 @@ EmitResult ChoiceNode::Emit(Compiler* compiler, Trace* trace) {
// label was bound.
int new_flush_budget = trace->flush_budget() / choice_count;
for (int i = 0; i < choice_count; i++) {
- compiler->set_flags(flags);
AlternativeGeneration* alt_gen = alt_gens.at(i);
Trace new_trace(*trace);
// If there are actions to be flushed we have to limit how many times
@@ -4154,8 +4334,7 @@ EmitResult ChoiceNode::Emit(Compiler* compiler, Trace* trace) {
Trace* ChoiceNode::EmitFixedLengthLoop(
Compiler* compiler, Trace* trace, AlternativeGenerationList* alt_gens,
PreloadState* preload, SpecialLoopState* fixed_length_loop_state,
- int text_length, Flags flags, DrainMode drain_mode,
- ParkedGrant body_parked_grant) {
+ int text_length, DrainMode drain_mode, ParkedGrant body_parked_grant) {
TRACE("* Emit fixed length loop");
RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
// Here we have special handling for greedy loops containing only text nodes
@@ -4216,8 +4395,8 @@ Trace* ChoiceNode::EmitFixedLengthLoop(
// In a fixed length loop there is only one other choice, which is what
// comes after the greedy quantifer. Try to match that now.
- result = EmitChoices(compiler, alt_gens, 1, new_trace, preload, flags,
- body_parked_grant);
+ result =
+ EmitChoices(compiler, alt_gens, 1, new_trace, preload, body_parked_grant);
if (result.IsError()) return nullptr;
// kOmit emitted no marker and no step label; everything below is the
@@ -4282,6 +4461,7 @@ namespace {
struct UniformTextSource {
ClassRanges* class_ranges = nullptr;
base::uc16 atom_char = 0;
+ Flags flags = {};
bool is_atom = false;
bool is_empty = true;
@@ -4289,6 +4469,14 @@ struct UniformTextSource {
// second source (a different class node, or a different literal character).
bool Accumulate(TextNode* text) {
if (text->read_backward()) return false;
+ // Atoms are identified by their raw character, but the set one accepts
+ // also depends on case folding, which a modifier group can change
+ // between the prefix and the loop body.
+ if (is_empty) {
+ flags = text->flags();
+ } else if (IsIgnoreCase(text->flags()) != IsIgnoreCase(flags)) {
+ return false;
+ }
ZoneList<TextElement>* elms = text->elements();
for (int i = 0; i < elms->length(); i++) {
TextElement& elm = elms->at(i);
@@ -4360,7 +4548,7 @@ ParkedGrant LoopChoiceNode::ComputeSearchBodyParkedGrant(Compiler* compiler) {
}
if (ActionNode* action = node->AsActionNode()) {
// Only register-only actions keep the prefix uniform; others reposition
- // (RESTORE_POSITION, submatches) or change what matches (MODIFY_FLAGS).
+ // (RESTORE_POSITION, submatches).
if (!action->IsRegisterOnlyAction()) return ParkedGrant::kParked;
node = action->on_success();
continue;
@@ -4371,8 +4559,7 @@ ParkedGrant LoopChoiceNode::ComputeSearchBodyParkedGrant(Compiler* compiler) {
continue;
}
LoopChoiceNode* loop = node->AsLoopChoiceNode();
- if (loop == nullptr ||
- loop->atomic_loop_kind(compiler->flags()) == AtomicLoopKind::kNone) {
+ if (loop == nullptr || loop->atomic_loop_kind() == AtomicLoopKind::kNone) {
return ParkedGrant::kParked;
}
// The loop body must draw from the same source as the prefix.
@@ -4616,7 +4803,8 @@ std::optional<EmitResult> ChoiceNode::EmitSkipUntilOneOfMaskedSearch(
// The scan reads the candidate at offset 0 and steps forward one char.
constexpr int kScanCpOffset = 0;
constexpr int kScanAdvanceBy = 1;
- Label loop, advance, retry_alt1, alt0_body, alt1_body, fail;
+ NonAssertingLabel loop(compiler), advance(compiler), retry_alt1(compiler),
+ alt0_body(compiler), alt1_body(compiler), fail(compiler);
masm->Bind(&loop);
masm->SkipUntilOneOfMasked(kScanCpOffset, kScanAdvanceBy, union_qc.value(),
@@ -5059,7 +5247,7 @@ bool ChoiceNode::MaybeEmitFixedLengthConsumeScan(Compiler* compiler,
// code point (a surrogate pair), so the loop's one-code-unit step-back could
// land mid-pair. One-byte subjects (latin1, all BMP) and non-unicode two-byte
// subjects (each code unit independent) are both fine.
- if (!compiler->one_byte() && IsEitherUnicode(compiler->flags())) {
+ if (!compiler->one_byte() && IsEitherUnicode(flags())) {
TRACE("* No consume scan (two-byte unicode: surrogate step-back unsafe)");
return false;
}
@@ -5155,7 +5343,7 @@ bool ChoiceNode::MaybeEmitFixedLengthConsumeScan(Compiler* compiler,
// choice is not eligible (the caller falls through to the linear chain).
std::optional<EmitResult> ChoiceNode::TryEmitMaskedValueDispatch(
Compiler* compiler, AlternativeGenerationList* alt_gens, Trace* trace,
- PreloadState* preload, Flags flags) {
+ PreloadState* preload) {
static constexpr int kMinAlternatives = 4;
static constexpr int kMinGroups = 3;
@@ -5419,7 +5607,6 @@ std::optional<EmitResult> ChoiceNode::TryEmitMaskedValueDispatch(
}
for (int i = 0; i < choice_count; i++) {
if (group_of_alt[i] != g) continue;
- compiler->set_flags(flags);
Trace new_trace(*trace);
new_trace.set_characters_preloaded(preload_characters);
new_trace.set_bound_checked_up_to(preload_characters);
@@ -5463,15 +5650,15 @@ std::optional<EmitResult> ChoiceNode::TryEmitMaskedValueDispatch(
EmitResult ChoiceNode::EmitChoices(Compiler* compiler,
AlternativeGenerationList* alt_gens,
int first_choice, Trace* trace,
- PreloadState* preload, Flags flags,
+ PreloadState* preload,
ParkedGrant body_parked_grant) {
TRACE("* Emit Choices");
RegExpMacroAssembler* macro_assembler = compiler->macro_assembler();
SetUpPreLoad(compiler, trace, preload);
if (first_choice == 0) {
- if (std::optional<EmitResult> dispatched = TryEmitMaskedValueDispatch(
- compiler, alt_gens, trace, preload, flags)) {
+ if (std::optional<EmitResult> dispatched =
+ TryEmitMaskedValueDispatch(compiler, alt_gens, trace, preload)) {
return *dispatched;
}
}
@@ -5487,7 +5674,7 @@ EmitResult ChoiceNode::EmitChoices(Compiler* compiler,
// Landing stub for parked loop-exit backtracks from the body's inline
// emission; see its use below and the binding after the loop.
- Label parked_reentry;
+ NonAssertingLabel parked_reentry(compiler);
// An inherited parked-position grant may flow into an alternative only if no
// sibling can match at a position the park skips (/:|\w*\s/ on "c:" must
@@ -5506,7 +5693,6 @@ EmitResult ChoiceNode::EmitChoices(Compiler* compiler,
}
for (int i = first_choice; i < choice_count; i++) {
- compiler->set_flags(flags);
bool is_last = i == choice_count - 1;
bool fall_through_on_failure = !is_last;
GuardedAlternative alternative = alternatives_->at(i);
@@ -5630,8 +5816,8 @@ EmitResult ChoiceNode::EmitOutOfLineContinuation(
if (not_at_start_) out_of_line_trace.set_at_start(Trace::FALSE_VALUE);
const ZoneList<Guard*>* guards = alternative.guards();
int guard_count = (guards == nullptr) ? 0 : guards->length();
- Label reload_current_char;
- Label parked_landing;
+ NonAssertingLabel reload_current_char(compiler);
+ NonAssertingLabel parked_landing(compiler);
if (parked_grant != ParkedGrant::kNone) {
// Parked loop-exit backtracks arrive with the position moved -- up to and
// including the subject end (a kDisjoint or kBoundary continuation can fail
@@ -5767,7 +5953,7 @@ EmitResult ActionNode::Emit(Compiler* compiler, Trace* trace) {
return on_success()->Emit(compiler, trace);
}
int clear_registers_from = data_.u_submatch.clear_register_from;
- Label clear_registers_backtrack;
+ NonAssertingLabel clear_registers_backtrack(compiler);
Trace new_trace = *trace;
new_trace.set_backtrack(&clear_registers_backtrack);
RETURN_IF_ERROR(on_success()->Emit(compiler, &new_trace));
@@ -5780,11 +5966,6 @@ EmitResult ActionNode::Emit(Compiler* compiler, Trace* trace) {
assembler->Backtrack();
return EmitResult::Success();
}
- case MODIFY_FLAGS: {
- compiler->set_flags(flags());
- RETURN_IF_ERROR(on_success()->Emit(compiler, trace));
- break;
- }
default:
UNREACHABLE();
}
@@ -5796,8 +5977,7 @@ EmitResult UnanchoredAdvanceNode::Emit(Compiler* compiler, Trace* trace) {
if (!trace->is_trivial()) {
return trace->Flush(compiler, this);
}
- assembler->UnanchoredAdvance(IsEitherUnicode(compiler->flags()),
- trace->backtrack());
+ assembler->UnanchoredAdvance(IsEitherUnicode(flags()), trace->backtrack());
Trace successor_trace(*trace);
successor_trace.InvalidateCurrentCharacter();
@@ -5837,8 +6017,8 @@ EmitResult BackReferenceNode::Emit(Compiler* compiler, Trace* trace) {
RecursionCheck rc(compiler);
DCHECK_EQ(start_reg_ + 1, end_reg_);
- if (IsIgnoreCase(compiler->flags())) {
- bool unicode = IsEitherUnicode(compiler->flags());
+ if (IsIgnoreCase(flags())) {
+ bool unicode = IsEitherUnicode(flags());
assembler->CheckNotBackReferenceIgnoreCase(start_reg_, read_backward(),
unicode, trace->backtrack());
} else {
@@ -5849,7 +6029,7 @@ EmitResult BackReferenceNode::Emit(Compiler* compiler, Trace* trace) {
if (read_backward()) trace->set_at_start(Trace::UNKNOWN);
// Check that the back reference does not end inside a surrogate pair.
- if (IsEitherUnicode(compiler->flags()) && !compiler->one_byte()) {
+ if (IsEitherUnicode(flags()) && !compiler->one_byte()) {
assembler->CheckNotInSurrogatePair(trace->cp_offset(), trace->backtrack());
}
return on_success()->Emit(compiler, trace);
@@ -6041,11 +6221,8 @@ class EatsAtLeastPropagator : public AllStatic {
template <typename... Propagators>
class Analysis : public NodeVisitor {
public:
- Analysis(Isolate* isolate, bool is_one_byte, Flags flags)
- : isolate_(isolate),
- is_one_byte_(is_one_byte),
- flags_(flags),
- error_(Error::kNone) {}
+ Analysis(Isolate* isolate, bool is_one_byte)
+ : isolate_(isolate), is_one_byte_(is_one_byte), error_(Error::kNone) {}
void EnsureAnalyzed(Node* that) {
StackLimitCheck check(isolate());
@@ -6082,7 +6259,7 @@ class Analysis : public NodeVisitor {
} while (false)
void VisitText(TextNode* that) override {
- that->MakeCaseIndependent(isolate(), is_one_byte_, flags());
+ that->MakeCaseIndependent(isolate(), is_one_byte_);
EnsureAnalyzed(that->on_success());
if (has_failed()) return;
that->CalculateOffsets();
@@ -6090,9 +6267,6 @@ class Analysis : public NodeVisitor {
}
void VisitAction(ActionNode* that) override {
- if (that->action_type() == ActionNode::MODIFY_FLAGS) {
- set_flags(that->flags());
- }
EnsureAnalyzed(that->on_success());
if (has_failed()) return;
STATIC_FOR_EACH(Propagators::VisitAction(that));
@@ -6105,13 +6279,8 @@ class Analysis : public NodeVisitor {
}
void VisitChoice(ChoiceNode* that) override {
- // Flags need to be reset to the state of the ChoiceNode at the beginning
- // of each alternative, as flags might be modified when visiting an
- // alternative.
- Flags header_flags = flags();
for (int i = 0; i < that->alternatives()->length(); i++) {
EnsureAnalyzed(that->alternatives()->at(i).node());
- set_flags(header_flags);
if (has_failed()) return;
STATIC_FOR_EACH(Propagators::VisitChoice(that, i));
}
@@ -6121,28 +6290,15 @@ class Analysis : public NodeVisitor {
DCHECK_EQ(that->alternatives()->length(), 2); // Just loop and continue.
// First propagate all information from the continuation node.
- // Due to the unusual visitation order, we need to manage the flags manually
- // as if we were visiting the loop node before visiting the continuation.
- Flags orig_flags = flags();
-
EnsureAnalyzed(that->continue_node());
if (has_failed()) return;
- // Propagators don't access global state (including flags), so we don't need
- // to reset them here.
STATIC_FOR_EACH(Propagators::VisitLoopChoiceContinueNode(that));
- Flags continuation_flags = flags();
-
// Check the loop last since it may need the value of this node
// to get a correct result.
- set_flags(orig_flags);
EnsureAnalyzed(that->loop_node());
if (has_failed()) return;
- // Propagators don't access global state (including flags), so we don't need
- // to reset them here.
STATIC_FOR_EACH(Propagators::VisitLoopChoiceLoopNode(that));
-
- set_flags(continuation_flags);
}
void VisitNegativeLookaroundChoice(
@@ -6175,21 +6331,16 @@ class Analysis : public NodeVisitor {
#undef STATIC_FOR_EACH
private:
- Flags flags() const { return flags_; }
- void set_flags(Flags flags) { flags_ = flags; }
-
Isolate* isolate_;
const bool is_one_byte_;
- Flags flags_;
Error error_;
DISALLOW_IMPLICIT_CONSTRUCTORS(Analysis);
};
-Error AnalyzeRegExp(Isolate* isolate, bool is_one_byte, Flags flags,
- Node* node) {
- Analysis<AssertionPropagator, EatsAtLeastPropagator> analysis(
- isolate, is_one_byte, flags);
+Error AnalyzeRegExp(Isolate* isolate, bool is_one_byte, Node* node) {
+ Analysis<AssertionPropagator, EatsAtLeastPropagator> analysis(isolate,
+ is_one_byte);
DCHECK_EQ(node->info()->been_analyzed, false);
analysis.EnsureAnalyzed(node);
DCHECK_IMPLIES(analysis.has_failed(), analysis.error() != Error::kNone);
@@ -6245,10 +6396,10 @@ void TextNode::FillInBMInfo(Isolate* isolate, int initial_offset, int budget,
return;
}
base::uc16 character = atom->data()[j];
- if (IsIgnoreCase(bm->compiler()->flags())) {
+ if (IsIgnoreCase(flags())) {
unibrow::uchar chars[4];
- int length = GetCaseIndependentLetters(isolate, character,
- bm->compiler(), chars, 4);
+ int length =
+ GetCaseIndependentLetters(bm->compiler(), character, chars, 4);
for (int k = 0; k < length; k++) {
bm->Set(offset, chars[k]);
}
@@ -6290,17 +6441,17 @@ Node* Compiler::OptionallyStepBackToLeadSurrogate(Node* on_success) {
ZoneList<CharacterRange>* trail_surrogates = CharacterRange::List(
zone(), CharacterRange::Range(kTrailSurrogateStart, kTrailSurrogateEnd));
- ChoiceNode* optional_step_back = zone()->New<ChoiceNode>(2, zone());
+ ChoiceNode* optional_step_back = zone()->New<ChoiceNode>(2, flags(), zone());
int stack_register = UnicodeLookaroundStackRegister();
int position_register = UnicodeLookaroundPositionRegister();
- Node* step_back = TextNode::CreateForCharacterRanges(zone(), lead_surrogates,
- true, on_success);
+ Node* step_back = TextNode::CreateForCharacterRanges(
+ zone(), lead_surrogates, true, on_success, flags());
Lookaround::Builder builder(true, step_back, this, stack_register,
position_register);
REGISTER_NODE(step_back);
Node* match_trail = TextNode::CreateForCharacterRanges(
- zone(), trail_surrogates, false, builder.on_match_success());
+ zone(), trail_surrogates, false, builder.on_match_success(), flags());
REGISTER_NODE(match_trail);
optional_step_back->AddAlternative(
@@ -6325,6 +6476,7 @@ Node* Compiler::PreprocessRegExp(CompileData* data, bool is_one_byte) {
// Add a .*? at the beginning, outside the body capture, unless
// this expression is anchored at the beginning or sticky.
TRACE_GRAPH("* Add .*? at beginning of unanchored, non-sticky RegExp");
+ has_search_prefix_ = true;
Node* loop_node = Quantifier::ToNode(
0, Tree::kInfinity, false,
zone()->New<ClassRanges>(StandardCharacterSet::kEverything), this,
@@ -6334,11 +6486,11 @@ Node* Compiler::PreprocessRegExp(CompileData* data, bool is_one_byte) {
// Unroll loop once, to take care of the case that might start
// at the start of input.
TRACE_GRAPH("* Unroll loop once");
- ChoiceNode* first_step_node = zone()->New<ChoiceNode>(2, zone());
+ ChoiceNode* first_step_node = zone()->New<ChoiceNode>(2, flags(), zone());
first_step_node->AddAlternative(GuardedAlternative(captured_body));
first_step_node->AddAlternative(GuardedAlternative(zone()->New<TextNode>(
zone()->New<ClassRanges>(StandardCharacterSet::kEverything), false,
- loop_node)));
+ loop_node, flags())));
REGISTER_NODE(first_step_node);
node = first_step_node;
} else {
diff --git a/deps/v8/src/regexp/regexp-compiler.h b/deps/v8/src/regexp/regexp-compiler.h
index fb6e6be6261..d029f9ee6a4 100644
--- a/deps/v8/src/regexp/regexp-compiler.h
+++ b/deps/v8/src/regexp/regexp-compiler.h
@@ -11,6 +11,7 @@
#include "src/base/bit-field.h"
#include "src/base/small-vector.h"
#include "src/base/strings.h"
+#include "src/codegen/label.h"
#include "src/regexp/regexp-flags.h"
#include "src/regexp/regexp-nodes.h"
@@ -25,6 +26,15 @@ class Diagnostics;
class DynamicBitSet;
class SpecialLoopState;
+class NonAssertingLabel : public Label {
+ public:
+ explicit NonAssertingLabel(Compiler* compiler) : compiler_(compiler) {}
+ ~NonAssertingLabel();
+
+ private:
+ Compiler* compiler_;
+};
+
namespace compiler_constants {
// The '2' variant is has inclusive from and exclusive to.
@@ -503,7 +513,8 @@ class Trace {
// regexp).
class SpecialLoopState {
public:
- explicit SpecialLoopState(bool not_at_start, ChoiceNode* loop_choice_node);
+ SpecialLoopState(Compiler* compiler, bool not_at_start,
+ ChoiceNode* loop_choice_node);
void BindStepLabel(RegExpMacroAssembler* macro_assembler);
void BindLoopTopLabel(RegExpMacroAssembler* macro_assembler);
@@ -514,8 +525,8 @@ class SpecialLoopState {
private:
// Step backwards (fixed length greed loop) or forwards (non-greedy
// omnivourous loop.
- Label step_label_;
- Label loop_top_label_;
+ NonAssertingLabel step_label_;
+ NonAssertingLabel loop_top_label_;
ChoiceNode* loop_choice_node_;
Trace backtrack_trace_;
};
@@ -532,8 +543,7 @@ struct PreloadState {
// Analysis performs assertion propagation and computes eats_at_least_ values.
// See the comments on AssertionPropagator and EatsAtLeastPropagator for more
// details.
-Error AnalyzeRegExp(Isolate* isolate, bool is_one_byte, Flags flags,
- Node* node);
+Error AnalyzeRegExp(Isolate* isolate, bool is_one_byte, Node* node);
class FrequencyCollator {
public:
@@ -641,10 +651,14 @@ class V8_EXPORT_PRIVATE Compiler {
// lead surrogate and start matching from there.
Node* OptionallyStepBackToLeadSurrogate(Node* on_success);
+ struct WorkItem {
+ Node* node;
+ };
+
inline void AddWork(Node* node) {
if (!node->on_work_list() && !node->label()->is_bound()) {
node->set_on_work_list(true);
- work_list_->push_back(node);
+ work_list_->push_back({node});
}
}
@@ -682,6 +696,7 @@ class V8_EXPORT_PRIVATE Compiler {
}
bool read_backward() { return read_backward_; }
void set_read_backward(bool value) { read_backward_ = value; }
+ bool has_search_prefix() const { return has_search_prefix_; }
FrequencyCollator* frequency_collator() { return &frequency_collator_; }
int current_expansion_factor() { return current_expansion_factor_; }
@@ -711,11 +726,16 @@ class V8_EXPORT_PRIVATE Compiler {
static const int kNoRegister = -1;
private:
+ // Computes the filters that let RegExpExecInternal reject a match attempt
+ // without entering the engine. Defined next to the match-set helpers it
+ // shares.
+ void ComputeQuickCheckFilters(Node* start, DirectHandle<RegExpData> re_data);
+
EndNode* accept_;
int next_register_;
int unicode_lookaround_stack_register_;
int unicode_lookaround_position_register_;
- ZoneVector<Node*>* work_list_;
+ ZoneVector<WorkItem>* work_list_;
int recursion_depth_;
Flags flags_;
RegExpMacroAssembler* macro_assembler_;
@@ -725,6 +745,8 @@ class V8_EXPORT_PRIVATE Compiler {
int to_node_overflow_check_ticks_ = 0;
bool optimize_;
bool read_backward_;
+ // Set by PreprocessRegExp when it prepends the `.*?` search loop.
+ bool has_search_prefix_ = false;
int current_expansion_factor_;
FrequencyCollator frequency_collator_;
#ifdef V8_ENABLE_REGEXP_DIAGNOSTICS
diff --git a/deps/v8/src/regexp/regexp-dotprinter.cc b/deps/v8/src/regexp/regexp-dotprinter.cc
index 69f9070ab2d..2c5702a1140 100644
--- a/deps/v8/src/regexp/regexp-dotprinter.cc
+++ b/deps/v8/src/regexp/regexp-dotprinter.cc
@@ -257,10 +257,6 @@ void DotPrinterImpl::VisitAction(ActionNode* that) {
<< that->register_to() << "\", shape=septagon";
break;
}
- case ActionNode::MODIFY_FLAGS: {
- os_ << "label=\"flags $" << that->flags() << "\", shape=septagon";
- break;
- }
case ActionNode::EATS_AT_LEAST: {
os_ << "label=\"eats at least $" << that->stored_eats_at_least()
<< "\", shape=septagon";
diff --git a/deps/v8/src/regexp/regexp-macro-assembler.cc b/deps/v8/src/regexp/regexp-macro-assembler.cc
index b28b2f35a81..3bdde3288ba 100644
--- a/deps/v8/src/regexp/regexp-macro-assembler.cc
+++ b/deps/v8/src/regexp/regexp-macro-assembler.cc
@@ -15,6 +15,7 @@
#include "src/regexp/regexp-stack.h"
#include "src/regexp/regexp.h"
#include "src/regexp/special-case.h"
+#include "src/sandbox/check.h"
#include "src/strings/unicode-inl.h"
#ifdef V8_INTL_SUPPORT
@@ -592,7 +593,7 @@ int NativeRegExpMacroAssembler::CheckStackGuardState(
// Returns a {Result} sentinel, or the number of successful matches.
int NativeRegExpMacroAssembler::Match(DirectHandle<IrRegExpData> regexp_data,
DirectHandle<String> subject,
- int* offsets_vector,
+ bool is_one_byte, int* offsets_vector,
int offsets_vector_length,
int previous_index, Isolate* isolate) {
DCHECK(subject->IsFlat());
@@ -622,8 +623,6 @@ int NativeRegExpMacroAssembler::Match(DirectHandle<IrRegExpData> regexp_data,
if (StringShape(subject_ptr).IsThin()) {
subject_ptr = Cast<ThinString>(subject_ptr)->actual();
}
- // Ensure that an underlying string has the same representation.
- bool is_one_byte = subject_ptr->IsOneByteRepresentation();
DCHECK(IsExternalString(subject_ptr) || IsSeqString(subject_ptr));
// String is now either Sequential or External
int char_size_shift = is_one_byte ? 0 : 1;
@@ -640,8 +639,8 @@ int NativeRegExpMacroAssembler::Match(DirectHandle<IrRegExpData> regexp_data,
}
#endif // V8_ENABLE_REGEXP_DIAGNOSTICS
int res =
- Execute(*subject, start_offset, input_start, input_end, offsets_vector,
- offsets_vector_length, isolate, *regexp_data);
+ Execute(*subject, start_offset, input_start, input_end, is_one_byte,
+ offsets_vector, offsets_vector_length, isolate, *regexp_data);
#ifdef V8_ENABLE_REGEXP_DIAGNOSTICS
if (V8_UNLIKELY(v8_flags.trace_regexp_exec)) {
RegExp::TraceExecutionEnd(reinterpret_cast<Address>(isolate),
@@ -658,8 +657,9 @@ int NativeRegExpMacroAssembler::ExecuteForTesting(
const uint8_t* input_end, int* output, int output_size, Isolate* isolate,
Tagged<JSRegExp> regexp) {
Tagged<RegExpData> data = regexp->data(isolate);
- return Execute(input, start_offset, input_start, input_end, output,
- output_size, isolate, SbxCast<IrRegExpData>(data));
+ bool is_one_byte = String::IsOneByteRepresentationUnderneath(input);
+ return Execute(input, start_offset, input_start, input_end, is_one_byte,
+ output, output_size, isolate, SbxCast<IrRegExpData>(data));
}
// Returns a {Result} sentinel, or the number of successful matches.
@@ -667,10 +667,12 @@ int NativeRegExpMacroAssembler::Execute(
Tagged<String>
input, // This needs to be the unpacked (sliced, cons) string.
int start_offset, const uint8_t* input_start, const uint8_t* input_end,
- int* output, int output_size, Isolate* isolate,
+ bool is_one_byte, int* output, int output_size, Isolate* isolate,
Tagged<IrRegExpData> regexp_data) {
- bool is_one_byte = String::IsOneByteRepresentationUnderneath(input);
Tagged<Code> code = regexp_data->code(isolate, is_one_byte);
+ // Ensure code is in sync with subject strings 1-byte/2-byte.
+ // Code should always be RegExp JIT code (no trampoline).
+ SBXCHECK_EQ(code->kind(), CodeKind::REGEXP);
RegExp::CallOrigin call_origin = RegExp::CallOrigin::kFromRuntime;
using RegexpMatcherSig =
diff --git a/deps/v8/src/regexp/regexp-macro-assembler.h b/deps/v8/src/regexp/regexp-macro-assembler.h
index d04f2a9cae7..d513bec6db7 100644
--- a/deps/v8/src/regexp/regexp-macro-assembler.h
+++ b/deps/v8/src/regexp/regexp-macro-assembler.h
@@ -477,9 +477,9 @@ class NativeRegExpMacroAssembler : public RegExpMacroAssembler {
// Returns a {Result} sentinel, or the number of successful matches.
static int Match(DirectHandle<IrRegExpData> regexp_data,
- DirectHandle<String> subject, int* offsets_vector,
- int offsets_vector_length, int previous_index,
- Isolate* isolate);
+ DirectHandle<String> subject, bool is_one_byte,
+ int* offsets_vector, int offsets_vector_length,
+ int previous_index, Isolate* isolate);
V8_EXPORT_PRIVATE static int ExecuteForTesting(
Tagged<String> input, int start_offset, const uint8_t* input_start,
@@ -517,8 +517,8 @@ class NativeRegExpMacroAssembler : public RegExpMacroAssembler {
// Returns a {Result} sentinel, or the number of successful matches.
static int Execute(Tagged<String> input, int start_offset,
const uint8_t* input_start, const uint8_t* input_end,
- int* output, int output_size, Isolate* isolate,
- Tagged<IrRegExpData> regexp_data);
+ bool is_one_byte, int* output, int output_size,
+ Isolate* isolate, Tagged<IrRegExpData> regexp_data);
ZoneUnorderedMap<uint32_t, IndirectHandle<FixedUInt16Array>>
range_array_cache_;
diff --git a/deps/v8/src/regexp/regexp-node-printer.cc b/deps/v8/src/regexp/regexp-node-printer.cc
index 0981a2236b3..9949755f2ed 100644
--- a/deps/v8/src/regexp/regexp-node-printer.cc
+++ b/deps/v8/src/regexp/regexp-node-printer.cc
@@ -103,9 +103,6 @@ void NodePrinter<Node>::VisitAction(ActionNode* node) {
os() << "clear captures " << node->register_from() << " -- "
<< node->register_to();
break;
- case ActionNode::MODIFY_FLAGS:
- os() << "modify flags " << Flags(node->data_.u_modify_flags.flags);
- break;
case ActionNode::EATS_AT_LEAST:
os() << "eats at least " << node->data_.u_eats_at_least.characters;
break;
diff --git a/deps/v8/src/regexp/regexp-nodes.h b/deps/v8/src/regexp/regexp-nodes.h
index 48c8e3b88a0..82d79366d4f 100644
--- a/deps/v8/src/regexp/regexp-nodes.h
+++ b/deps/v8/src/regexp/regexp-nodes.h
@@ -8,7 +8,9 @@
#include <optional>
#include "src/codegen/label.h"
+#include "src/regexp/regexp-flags.h"
#include "src/regexp/regexp-macro-assembler.h"
+#include "src/strings/unicode.h"
#include "src/zone/zone.h"
namespace v8 {
@@ -287,8 +289,9 @@ enum class ParkedGrant : uint8_t {
class V8_EXPORT_PRIVATE Node : public ZoneObject {
public:
- explicit Node(Zone* zone)
+ explicit Node(Flags flags, Zone* zone)
: replacement_(nullptr),
+ flags_(flags),
on_work_list_(false),
trace_count_(0),
zone_(zone) {
@@ -394,6 +397,7 @@ class V8_EXPORT_PRIVATE Node : public ZoneObject {
virtual SeqNode* AsSeqNode() { return nullptr; }
Zone* zone() const { return zone_; }
+ Flags flags() const { return flags_; }
virtual bool IsBacktrack() const { return false; }
@@ -410,6 +414,7 @@ class V8_EXPORT_PRIVATE Node : public ZoneObject {
private:
static const int kFirstCharBudget = 10;
Label label_;
+ Flags flags_;
bool on_work_list_;
NodeInfo info_;
@@ -430,8 +435,8 @@ class V8_EXPORT_PRIVATE Node : public ZoneObject {
class V8_EXPORT_PRIVATE SeqNode : public Node {
public:
- explicit SeqNode(Node* on_success)
- : Node(on_success->zone()), on_success_(on_success) {}
+ SeqNode(Node* on_success, Flags flags)
+ : Node(flags, on_success->zone()), on_success_(on_success) {}
Node* on_success() const { return on_success_; }
void set_on_success(Node* node) { on_success_ = node; }
void FillInBMInfo(Isolate* isolate, int offset, int budget,
@@ -457,29 +462,32 @@ class ActionNode : public SeqNode {
POSITIVE_SUBMATCH_SUCCESS,
EMPTY_MATCH_CHECK,
CLEAR_CAPTURES,
- MODIFY_FLAGS,
EATS_AT_LEAST,
};
- static ActionNode* SetRegisterForLoop(int reg, int val, Node* on_success);
- static ActionNode* IncrementRegister(int reg, Node* on_success);
- static ActionNode* StorePosition(int reg, Node* on_success);
- static ActionNode* RestorePosition(int reg, Node* on_success);
- static ActionNode* ClearCaptures(Interval range, Node* on_success);
+ static ActionNode* SetRegisterForLoop(int reg, int val, Node* on_success,
+ Flags flags);
+ static ActionNode* IncrementRegister(int reg, Node* on_success, Flags flags);
+ static ActionNode* StorePosition(int reg, Node* on_success, Flags flags);
+ static ActionNode* RestorePosition(int reg, Node* on_success, Flags flags);
+ static ActionNode* ClearCaptures(Interval range, Node* on_success,
+ Flags flags);
static ActionNode* BeginPositiveSubmatch(int stack_pointer_reg,
int position_reg, Node* body,
- ActionNode* success_node);
+ ActionNode* success_node,
+ Flags flags);
static ActionNode* BeginNegativeSubmatch(int stack_pointer_reg,
- int position_reg, Node* on_success);
+ int position_reg, Node* on_success,
+ Flags flags);
static ActionNode* PositiveSubmatchSuccess(int stack_pointer_reg,
int restore_reg,
int clear_capture_count,
int clear_capture_from,
- Node* on_success);
+ Node* on_success, Flags flags);
static ActionNode* EmptyMatchCheck(int start_register,
int repetition_register,
- int repetition_limit, Node* on_success);
- static ActionNode* ModifyFlags(Flags flags, Node* on_success);
- static ActionNode* EatsAtLeast(int characters, Node* on_success);
+ int repetition_limit, Node* on_success,
+ Flags flags);
+ static ActionNode* EatsAtLeast(int characters, Node* on_success, Flags flags);
ActionNode* AsActionNode() override { return this; }
void Accept(NodeVisitor* visitor) override;
V8_WARN_UNUSED_RESULT EmitResult Emit(Compiler* compiler,
@@ -494,10 +502,6 @@ class ActionNode : public SeqNode {
int FixedLengthLoopLength() override {
return kNodeIsTooComplexForFixedLengthLoops;
}
- Flags flags() const {
- DCHECK_EQ(action_type(), MODIFY_FLAGS);
- return Flags{data_.u_modify_flags.flags};
- }
ActionNode* success_node() const {
DCHECK_EQ(action_type(), BEGIN_POSITIVE_SUBMATCH);
return data_.u_submatch.success_node;
@@ -541,12 +545,12 @@ class ActionNode : public SeqNode {
int register_to() const { return data_.u_simple.register_to; }
protected:
- ActionNode(ActionType action_type, Node* on_success)
- : SeqNode(on_success), action_type_(action_type) {}
+ ActionNode(ActionType action_type, Node* on_success, Flags flags)
+ : SeqNode(on_success, flags), action_type_(action_type) {}
- ActionNode(ActionType action_type, Node* on_success, int from, int to = -1,
- int value = 0)
- : SeqNode(on_success), action_type_(action_type) {
+ ActionNode(ActionType action_type, Node* on_success, Flags flags, int from,
+ int to = -1, int value = 0)
+ : SeqNode(on_success, flags), action_type_(action_type) {
data_.u_simple.register_from = from;
data_.u_simple.register_to = to == -1 ? from : to;
data_.u_simple.value = value;
@@ -572,9 +576,6 @@ class ActionNode : public SeqNode {
int repetition_register;
int repetition_limit;
} u_empty_match_check;
- struct {
- int flags;
- } u_modify_flags;
struct {
int characters;
} u_eats_at_least;
@@ -588,10 +589,13 @@ class ActionNode : public SeqNode {
class V8_EXPORT_PRIVATE TextNode : public SeqNode {
public:
- TextNode(ZoneList<TextElement>* elms, bool read_backward, Node* on_success)
- : SeqNode(on_success), elms_(elms), read_backward_(read_backward) {}
- TextNode(ClassRanges* that, bool read_backward, Node* on_success)
- : SeqNode(on_success),
+ TextNode(ZoneList<TextElement>* elms, bool read_backward, Node* on_success,
+ Flags flags)
+ : SeqNode(on_success, flags),
+ elms_(elms),
+ read_backward_(read_backward) {}
+ TextNode(ClassRanges* that, bool read_backward, Node* on_success, Flags flags)
+ : SeqNode(on_success, flags),
elms_(zone()->New<ZoneList<TextElement>>(1, zone())),
read_backward_(read_backward) {
elms_->Add(TextElement::FromClassRanges(that), zone());
@@ -600,16 +604,17 @@ class V8_EXPORT_PRIVATE TextNode : public SeqNode {
static TextNode* CreateForCharacterRanges(Zone* zone,
ZoneList<CharacterRange>* ranges,
bool read_backward,
- Node* on_success);
+ Node* on_success, Flags flags);
// Create TextNode for a surrogate pair (i.e. match a sequence of two uc16
// code unit ranges).
static TextNode* CreateForSurrogatePair(
Zone* zone, CharacterRange lead, ZoneList<CharacterRange>* trail_ranges,
- bool read_backward, Node* on_success);
+ bool read_backward, Node* on_success, Flags flags);
static TextNode* CreateForSurrogatePair(Zone* zone,
ZoneList<CharacterRange>* lead_ranges,
CharacterRange trail,
- bool read_backward, Node* on_success);
+ bool read_backward, Node* on_success,
+ Flags flags);
TextNode* AsTextNode() override { return this; }
void Accept(NodeVisitor* visitor) override;
V8_WARN_UNUSED_RESULT EmitResult Emit(Compiler* compiler,
@@ -619,7 +624,7 @@ class V8_EXPORT_PRIVATE TextNode : public SeqNode {
int budget) override;
ZoneList<TextElement>* elements() { return elms_; }
bool read_backward() const { return read_backward_; }
- void MakeCaseIndependent(Isolate* isolate, bool is_one_byte, Flags flags);
+ void MakeCaseIndependent(Isolate* isolate, bool is_one_byte);
int FixedLengthLoopLength() override;
Node* GetSuccessorOfOmnivorousTextNode(Compiler* compiler) override;
void FillInBMInfo(Isolate* isolate, int offset, int budget,
@@ -627,10 +632,23 @@ class V8_EXPORT_PRIVATE TextNode : public SeqNode {
void CalculateOffsets();
int Length();
+ // Returns the number of characters in the equivalence class, omitting those
+ // that cannot occur in the source string because it is Latin1.
+ int GetCaseIndependentLetters(Compiler* compiler, base::uc16 character,
+ unibrow::uchar* letters,
+ int letter_length) const;
+
// Returns false if the text node can't match in one-byte mode.
bool CanMatchLatin1(Compiler* compiler);
private:
+ bool EmitSimpleCharacter(Compiler* compiler, base::uc16 c, Label* on_failure,
+ int cp_offset, bool check, bool preloaded);
+ bool EmitAtomNonLetter(Compiler* compiler, base::uc16 c, Label* on_failure,
+ int cp_offset, bool check, bool preloaded);
+ bool EmitAtomLetter(Compiler* compiler, base::uc16 c, Label* on_failure,
+ int cp_offset, bool check, bool preloaded);
+
enum TextEmitPassType {
NON_LATIN1_MATCH, // Check for characters that can never match.
SIMPLE_CHARACTER_MATCH, // Case-dependent single character check.
@@ -654,20 +672,23 @@ class AssertionNode : public SeqNode {
AT_NON_BOUNDARY,
AFTER_NEWLINE
};
- static AssertionNode* AtEnd(Node* on_success) {
- return on_success->zone()->New<AssertionNode>(AT_END, on_success);
+ static AssertionNode* AtEnd(Node* on_success, Flags flags) {
+ return on_success->zone()->New<AssertionNode>(AT_END, on_success, flags);
}
- static AssertionNode* AtStart(Node* on_success) {
- return on_success->zone()->New<AssertionNode>(AT_START, on_success);
+ static AssertionNode* AtStart(Node* on_success, Flags flags) {
+ return on_success->zone()->New<AssertionNode>(AT_START, on_success, flags);
}
- static AssertionNode* AtBoundary(Node* on_success) {
- return on_success->zone()->New<AssertionNode>(AT_BOUNDARY, on_success);
+ static AssertionNode* AtBoundary(Node* on_success, Flags flags) {
+ return on_success->zone()->New<AssertionNode>(AT_BOUNDARY, on_success,
+ flags);
}
- static AssertionNode* AtNonBoundary(Node* on_success) {
- return on_success->zone()->New<AssertionNode>(AT_NON_BOUNDARY, on_success);
+ static AssertionNode* AtNonBoundary(Node* on_success, Flags flags) {
+ return on_success->zone()->New<AssertionNode>(AT_NON_BOUNDARY, on_success,
+ flags);
}
- static AssertionNode* AfterNewline(Node* on_success) {
- return on_success->zone()->New<AssertionNode>(AFTER_NEWLINE, on_success);
+ static AssertionNode* AfterNewline(Node* on_success, Flags flags) {
+ return on_success->zone()->New<AssertionNode>(AFTER_NEWLINE, on_success,
+ flags);
}
AssertionNode* AsAssertionNode() override { return this; }
void Accept(NodeVisitor* visitor) override;
@@ -688,16 +709,16 @@ class AssertionNode : public SeqNode {
enum IfPrevious { kIsNonWord, kIsWord };
V8_WARN_UNUSED_RESULT EmitResult BacktrackIfPrevious(
Compiler* compiler, Trace* trace, IfPrevious backtrack_if_previous);
- AssertionNode(AssertionType t, Node* on_success)
- : SeqNode(on_success), assertion_type_(t) {}
+ AssertionNode(AssertionType t, Node* on_success, Flags flags)
+ : SeqNode(on_success, flags), assertion_type_(t) {}
AssertionType assertion_type_;
};
class BackReferenceNode : public SeqNode {
public:
BackReferenceNode(int start_reg, int end_reg, bool read_backward,
- Node* on_success)
- : SeqNode(on_success),
+ Node* on_success, Flags flags)
+ : SeqNode(on_success, flags),
start_reg_(start_reg),
end_reg_(end_reg),
read_backward_(read_backward) {}
@@ -724,7 +745,8 @@ class BackReferenceNode : public SeqNode {
class UnanchoredAdvanceNode : public SeqNode {
public:
- explicit UnanchoredAdvanceNode(Node* on_success) : SeqNode(on_success) {}
+ explicit UnanchoredAdvanceNode(Node* on_success, Flags flags)
+ : SeqNode(on_success, flags) {}
UnanchoredAdvanceNode* AsUnanchoredAdvanceNode() override { return this; }
void Accept(NodeVisitor* visitor) override;
V8_WARN_UNUSED_RESULT EmitResult Emit(Compiler* compiler,
@@ -739,7 +761,8 @@ class UnanchoredAdvanceNode : public SeqNode {
class V8_EXPORT_PRIVATE EndNode : public Node {
public:
enum Action { ACCEPT, BACKTRACK, NEGATIVE_SUBMATCH_SUCCESS };
- EndNode(Action action, Zone* zone) : Node(zone), action_(action) {
+ EndNode(Action action, Flags flags, Zone* zone)
+ : Node(flags, zone), action_(action) {
EatsAtLeastInfo large(kLargeEatsAtLeastValue);
if (action == BACKTRACK) set_eats_at_least_info(large);
}
@@ -764,8 +787,8 @@ class NegativeSubmatchSuccess : public EndNode {
public:
NegativeSubmatchSuccess(int stack_pointer_reg, int position_reg,
int clear_capture_count, int clear_capture_start,
- Zone* zone)
- : EndNode(NEGATIVE_SUBMATCH_SUCCESS, zone),
+ Flags flags, Zone* zone)
+ : EndNode(NEGATIVE_SUBMATCH_SUCCESS, flags, zone),
stack_pointer_register_(stack_pointer_reg),
current_position_register_(position_reg),
clear_capture_count_(clear_capture_count),
@@ -816,8 +839,8 @@ class AlternativeGeneration;
class ChoiceNode : public Node {
public:
- explicit ChoiceNode(int expected_size, Zone* zone)
- : Node(zone),
+ ChoiceNode(int expected_size, Flags flags, Zone* zone)
+ : Node(flags, zone),
alternatives_(
zone->New<ZoneList<GuardedAlternative>>(expected_size, zone)),
not_at_start_(false),
@@ -916,17 +939,15 @@ class ChoiceNode : public Node {
V8_WARN_UNUSED_RESULT Trace* EmitFixedLengthLoop(
Compiler* compiler, Trace* trace, AlternativeGenerationList* alt_gens,
PreloadState* preloads, SpecialLoopState* fixed_length_loop_state,
- int text_length, Flags flags, DrainMode drain_mode,
- ParkedGrant body_parked_grant);
- V8_WARN_UNUSED_RESULT EmitResult
- EmitChoices(Compiler* compiler, AlternativeGenerationList* alt_gens,
- int first_choice, Trace* trace, PreloadState* preloads,
- Flags flags, ParkedGrant body_parked_grant);
+ int text_length, DrainMode drain_mode, ParkedGrant body_parked_grant);
+ V8_WARN_UNUSED_RESULT EmitResult EmitChoices(
+ Compiler* compiler, AlternativeGenerationList* alt_gens, int first_choice,
+ Trace* trace, PreloadState* preloads, ParkedGrant body_parked_grant);
// Emits the choice as a dispatch over a shared masked quick-check value
// when all alternatives agree on the mask; nullopt if not eligible.
std::optional<EmitResult> TryEmitMaskedValueDispatch(
Compiler* compiler, AlternativeGenerationList* alt_gens, Trace* trace,
- PreloadState* preload, Flags flags);
+ PreloadState* preload);
// If true, this node is never checked at the start of the input.
// Allows a new trace to start with at_start() set to false.
@@ -936,10 +957,10 @@ class ChoiceNode : public Node {
class NegativeLookaroundChoiceNode : public ChoiceNode {
public:
- explicit NegativeLookaroundChoiceNode(GuardedAlternative this_must_fail,
- GuardedAlternative then_do_this,
- Zone* zone)
- : ChoiceNode(2, zone) {
+ NegativeLookaroundChoiceNode(GuardedAlternative this_must_fail,
+ GuardedAlternative then_do_this, Flags flags,
+ Zone* zone)
+ : ChoiceNode(2, flags, zone) {
AddAlternative(this_must_fail);
AddAlternative(then_do_this);
}
@@ -974,8 +995,9 @@ class NegativeLookaroundChoiceNode : public ChoiceNode {
class LoopChoiceNode : public ChoiceNode {
public:
- LoopChoiceNode(bool body_can_be_zero_length, bool read_backward, Zone* zone)
- : ChoiceNode(2, zone),
+ LoopChoiceNode(bool body_can_be_zero_length, bool read_backward, Flags flags,
+ Zone* zone)
+ : ChoiceNode(2, flags, zone),
loop_node_(nullptr),
continue_node_(nullptr),
body_can_be_zero_length_(body_can_be_zero_length),
@@ -995,10 +1017,8 @@ class LoopChoiceNode : public ChoiceNode {
bool read_backward() const override { return read_backward_; }
LoopChoiceNode* AsLoopChoiceNode() override { return this; }
void Accept(NodeVisitor* visitor) override;
- // The atomic-loop classification of this node (see AtomicLoopKind),
- // memoized per |flags|: group modifiers (MODIFY_FLAGS) and work-list
- // re-emission can legitimately emit the same node under different flags.
- AtomicLoopKind atomic_loop_kind(Flags flags);
+ // The atomic-loop classification of this node (see AtomicLoopKind).
+ AtomicLoopKind atomic_loop_kind();
// The fixed match length of one body iteration, or
// kNodeIsTooComplexForFixedLengthLoops. Meaningful when atomic_loop_kind()
// is not kNone (the body is then a fixed-length chain).
@@ -1031,7 +1051,6 @@ class LoopChoiceNode : public ChoiceNode {
// Memo for atomic_loop_kind.
bool atomic_loop_kind_valid_ = false;
AtomicLoopKind atomic_loop_kind_ = AtomicLoopKind::kNone;
- Flags atomic_loop_kind_flags_ = {};
};
class NodeVisitor {
diff --git a/deps/v8/src/regexp/regexp-parser.cc b/deps/v8/src/regexp/regexp-parser.cc
index c80cee11419..34aad759d58 100644
--- a/deps/v8/src/regexp/regexp-parser.cc
+++ b/deps/v8/src/regexp/regexp-parser.cc
@@ -1583,10 +1583,6 @@ ParserState<mode>* ParserImpl<CharT, mode>::ParseOpenParenthesis(
base::uc32 next = Next();
switch (next) {
case '-':
- if (!v8_flags.js_regexp_modifiers) {
- ReportError(Error::kInvalidGroup);
- return nullptr;
- }
Advance();
parsing_modifiers = true;
if (modifiers_polarity == false) {
@@ -1598,10 +1594,6 @@ ParserState<mode>* ParserImpl<CharT, mode>::ParseOpenParenthesis(
case 'm':
case 'i':
case 's': {
- if (!v8_flags.js_regexp_modifiers) {
- ReportError(Error::kInvalidGroup);
- return nullptr;
- }
Advance();
parsing_modifiers = true;
Flag flag = TryFlagFromChar(next).value();
@@ -1621,7 +1613,6 @@ ParserState<mode>* ParserImpl<CharT, mode>::ParseOpenParenthesis(
case '=':
Advance(2);
if (parsing_modifiers) {
- DCHECK(v8_flags.js_regexp_modifiers);
ReportError(Error::kInvalidGroup);
return nullptr;
}
@@ -1631,7 +1622,6 @@ ParserState<mode>* ParserImpl<CharT, mode>::ParseOpenParenthesis(
case '!':
Advance(2);
if (parsing_modifiers) {
- DCHECK(v8_flags.js_regexp_modifiers);
ReportError(Error::kInvalidGroup);
return nullptr;
}
@@ -1641,7 +1631,6 @@ ParserState<mode>* ParserImpl<CharT, mode>::ParseOpenParenthesis(
case '<':
Advance();
if (parsing_modifiers) {
- DCHECK(v8_flags.js_regexp_modifiers);
ReportError(Error::kInvalidGroup);
return nullptr;
}
@@ -1919,46 +1908,39 @@ bool ParserImpl<CharT, mode>::CreateNamedCaptureAtIndex(
// Check for duplicates and bail if we find any.
const auto& named_capture_it = named_captures_->find(capture);
if (named_capture_it != named_captures_->end()) {
- if (v8_flags.js_regexp_duplicate_named_groups) {
- ZoneList<int>* named_capture_indices = named_capture_it->second;
- DCHECK_NOT_NULL(named_capture_indices);
- DCHECK(!named_capture_indices->is_empty());
- for (int named_index : *named_capture_indices) {
- bool is_duplicate = true;
- for (Interval interval : non_participating_capture_group_intervals) {
- DCHECK(!interval.is_empty());
- // We can stop as soon as we are inside one non-participating
- // interval. There can't be a non-participating and participating
- // interval, as intervals are never decreasing.
- if (interval.Contains(named_index)) {
- is_duplicate = false;
- break;
- }
- // Intervals are ordered strictly increasing, so we can stop early
- // when the current interval is past the current index.
- if (named_index <= interval.from()) {
- break;
- }
+ ZoneList<int>* named_capture_indices = named_capture_it->second;
+ DCHECK_NOT_NULL(named_capture_indices);
+ DCHECK(!named_capture_indices->is_empty());
+ for (int named_index : *named_capture_indices) {
+ bool is_duplicate = true;
+ for (Interval interval : non_participating_capture_group_intervals) {
+ DCHECK(!interval.is_empty());
+ // We can stop as soon as we are inside one non-participating
+ // interval. There can't be a non-participating and participating
+ // interval, as intervals are never decreasing.
+ if (interval.Contains(named_index)) {
+ is_duplicate = false;
+ break;
}
- if (is_duplicate) {
- ReportError(Error::kDuplicateCaptureGroupName);
- return false;
+ // Intervals are ordered strictly increasing, so we can stop early
+ // when the current interval is past the current index.
+ if (named_index <= interval.from()) {
+ break;
}
}
- } else {
- ReportError(Error::kDuplicateCaptureGroupName);
- return false;
+ if (is_duplicate) {
+ ReportError(Error::kDuplicateCaptureGroupName);
+ return false;
+ }
}
}
}
- if (v8_flags.js_regexp_duplicate_named_groups) {
- // Check for nested named captures. This is necessary to find duplicate
- // named captures within the same disjunct.
- ParserState<mode>* parent_state = state->previous_state();
- if (parent_state && parent_state->IsInsideCaptureGroup(name)) {
- ReportError(Error::kDuplicateCaptureGroupName);
- return false;
- }
+ // Check for nested named captures. This is necessary to find duplicate
+ // named captures within the same disjunct.
+ ParserState<mode>* parent_state = state->previous_state();
+ if (parent_state && parent_state->IsInsideCaptureGroup(name)) {
+ ReportError(Error::kDuplicateCaptureGroupName);
+ return false;
}
auto entry = named_captures_->try_emplace(
@@ -2027,8 +2009,6 @@ void ParserImpl<CharT, mode>::PatchNamedBackReferences() {
return;
}
- DCHECK_IMPLIES(!v8_flags.js_regexp_duplicate_named_groups,
- capture_it->second->length() == 1);
if constexpr (mode == ParseMode::kBuildAST) {
for (int index : *capture_it->second) {
ref->add_capture(GetCapture(index), zone());
@@ -2065,8 +2045,6 @@ ZoneVector<Capture*>* ParserImpl<CharT, mode>::GetNamedCaptures() {
ZoneVector<Capture*>* flattened_named_captures =
zone()->template New<ZoneVector<Capture*>>(zone());
for (auto capture : *named_captures_) {
- DCHECK_IMPLIES(!v8_flags.js_regexp_duplicate_named_groups,
- capture.second->length() == 1);
for (int index : *capture.second) {
flattened_named_captures->push_back(GetCapture(index));
}
diff --git a/deps/v8/src/regexp/regexp.cc b/deps/v8/src/regexp/regexp.cc
index 156824ba776..feb4d60f4f8 100644
--- a/deps/v8/src/regexp/regexp.cc
+++ b/deps/v8/src/regexp/regexp.cc
@@ -6,6 +6,7 @@
#include "src/base/strings.h"
#include "src/codegen/compilation-cache.h"
+#include "src/common/synchronization-point-support.h"
#include "src/diagnostics/code-tracer.h"
#include "src/execution/interrupts-scope.h"
#include "src/handles/global-handles-inl.h"
@@ -1210,11 +1211,13 @@ int RegExpImpl::IrregexpExecRaw(Isolate* isolate,
if (!regexp_data->ShouldProduceBytecode()) {
do {
EnsureCompiledIrregexp(isolate, regexp_data, subject, is_one_byte);
+ SYNCHRONIZATION_POINT("IrregexpExecRaw_JIT");
// The stack is used to allocate registers for the compiled regexp code.
// This means that in case of failure, the output registers array is left
// untouched and contains the capture results from the previous successful
// match. We can use that to set the last match info lazily.
- int res = NativeRegExpMacroAssembler::Match(regexp_data, subject, output,
+ int res = NativeRegExpMacroAssembler::Match(regexp_data, subject,
+ is_one_byte, output,
output_size, index, isolate);
if (res != NativeRegExpMacroAssembler::RETRY) {
DCHECK(res != NativeRegExpMacroAssembler::EXCEPTION ||
@@ -1311,6 +1314,8 @@ std::optional<int> RegExpImpl::IrregexpExec(
}
}
+ const bool is_one_byte = String::IsOneByteRepresentationUnderneath(*subject);
+ const bool had_code = regexp_data->has_code(is_one_byte);
int output_register_count =
RegExpImpl::IrregexpPrepare(isolate, regexp_data, subject);
if (output_register_count < 0) {
@@ -1318,6 +1323,18 @@ std::optional<int> RegExpImpl::IrregexpExec(
return {};
}
+ // The call above is what fills in the filters, so this exec already passed
+ // the builtin's check while they were still empty. Check it here instead,
+ // so that the exec which compiles rejects like every later one.
+ if (!had_code && regexp_data->has_code(is_one_byte)) {
+ DisallowGarbageCollection no_gc;
+ String::FlatContent content = subject->GetFlatContent(no_gc);
+ if (content.IsOneByte() && regexp_data->QuickCheckRejects(
+ content.ToOneByteVector(), previous_index)) {
+ return 0;
+ }
+ }
+
// TODO(jgruber): Consider changing these into DCHECKs once we're convinced
// the conditions hold.
CHECK_EQ(original_register_count, output_register_count);
@@ -1408,7 +1425,7 @@ bool RegExpImpl::Compile(Isolate* isolate, Zone* zone, CompileData* data,
if (data->error != Error::kNone) {
return false;
}
- data->error = AnalyzeRegExp(isolate, is_one_byte, flags, data->node);
+ data->error = AnalyzeRegExp(isolate, is_one_byte, data->node);
if (data->error != Error::kNone) {
return false;
}
@@ -1668,6 +1685,23 @@ int32_t* GlobalExecRunner::LastSuccessfulMatch() const {
return ®ister_array_[index];
}
+namespace {
+
+// The split cache is by far the largest of the regexp caches, so it is
+// allocated on first use rather than deserialized into every isolate. Enter is
+// the only place that has to materialize it: a lookup cannot hit before
+// something was entered, so it just misses.
+DirectHandle<FixedArray> EnsureRegExpSplitCache(Isolate* isolate) {
+ DirectHandle<FixedArray> cache = isolate->factory()->regexp_split_cache();
+ if (*cache != ReadOnlyRoots(isolate).empty_fixed_array()) return cache;
+ cache = isolate->factory()->NewFixedArrayWithZeroes(
+ ResultsCache::kRegExpSplitResultsCacheSize, AllocationType::kOld);
+ isolate->heap()->SetRegExpSplitCache(*cache);
+ return cache;
+}
+
+} // namespace
+
Tagged<Object> ResultsCache::Lookup(Heap* heap, Tagged<String> key_string,
Tagged<Object> key_pattern,
Tagged<FixedArray>* last_match_cache,
@@ -1675,23 +1709,30 @@ Tagged<Object> ResultsCache::Lookup(Heap* heap, Tagged<String> key_string,
if (V8_UNLIKELY(!v8_flags.regexp_results_cache)) return Smi::zero();
Tagged<FixedArray> cache;
if (!IsInternalizedString(key_string)) return Smi::zero();
- if (type == STRING_SPLIT_SUBSTRINGS) {
- DCHECK(IsString(key_pattern));
- if (!IsInternalizedString(key_pattern)) return Smi::zero();
- cache = heap->string_split_cache();
- } else {
- DCHECK(type == REGEXP_MULTIPLE_INDICES);
- DCHECK(IsRegExpDataWrapper(key_pattern));
- cache = heap->regexp_multiple_cache();
+ switch (type) {
+ case STRING_SPLIT_SUBSTRINGS:
+ DCHECK(IsString(key_pattern));
+ if (!IsInternalizedString(key_pattern)) return Smi::zero();
+ cache = heap->string_split_cache();
+ break;
+ case REGEXP_SPLIT_SUBSTRINGS:
+ DCHECK(IsRegExpDataWrapper(key_pattern));
+ cache = heap->regexp_split_cache();
+ if (cache == ReadOnlyRoots(heap).empty_fixed_array()) return Smi::zero();
+ break;
+ case REGEXP_MULTIPLE_INDICES:
+ DCHECK(IsRegExpDataWrapper(key_pattern));
+ cache = heap->regexp_multiple_cache();
+ break;
}
+ const int cache_size = SizeForType(type);
uint32_t hash = key_string->hash();
- uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
- ~(kArrayEntriesPerCacheEntry - 1));
+ uint32_t index =
+ ((hash & (cache_size - 1)) & ~(kArrayEntriesPerCacheEntry - 1));
if (cache->get(index + kStringOffset) != key_string ||
cache->get(index + kPatternOffset) != key_pattern) {
- index =
- ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
+ index = ((index + kArrayEntriesPerCacheEntry) & (cache_size - 1));
if (cache->get(index + kStringOffset) != key_string ||
cache->get(index + kPatternOffset) != key_pattern) {
return Smi::zero();
@@ -1711,27 +1752,33 @@ void ResultsCache::Enter(Isolate* isolate, DirectHandle<String> key_string,
Factory* factory = isolate->factory();
DirectHandle<FixedArray> cache;
if (!IsInternalizedString(*key_string)) return;
- if (type == STRING_SPLIT_SUBSTRINGS) {
- DCHECK(IsString(*key_pattern));
- if (!IsInternalizedString(*key_pattern)) return;
- cache = factory->string_split_cache();
- } else {
- DCHECK(type == REGEXP_MULTIPLE_INDICES);
- DCHECK(IsRegExpDataWrapper(*key_pattern));
- cache = factory->regexp_multiple_cache();
+ switch (type) {
+ case STRING_SPLIT_SUBSTRINGS:
+ DCHECK(IsString(*key_pattern));
+ if (!IsInternalizedString(*key_pattern)) return;
+ cache = factory->string_split_cache();
+ break;
+ case REGEXP_SPLIT_SUBSTRINGS:
+ DCHECK(IsRegExpDataWrapper(*key_pattern));
+ cache = EnsureRegExpSplitCache(isolate);
+ break;
+ case REGEXP_MULTIPLE_INDICES:
+ DCHECK(IsRegExpDataWrapper(*key_pattern));
+ cache = factory->regexp_multiple_cache();
+ break;
}
+ const int cache_size = SizeForType(type);
uint32_t hash = key_string->hash();
- uint32_t index = ((hash & (kRegExpResultsCacheSize - 1)) &
- ~(kArrayEntriesPerCacheEntry - 1));
+ uint32_t index =
+ ((hash & (cache_size - 1)) & ~(kArrayEntriesPerCacheEntry - 1));
if (cache->get(index + kStringOffset) == Smi::zero()) {
cache->set(index + kStringOffset, *key_string);
cache->set(index + kPatternOffset, *key_pattern);
cache->set(index + kArrayOffset, *value_array);
cache->set(index + kLastMatchOffset, *last_match_cache);
} else {
- uint32_t index2 =
- ((index + kArrayEntriesPerCacheEntry) & (kRegExpResultsCacheSize - 1));
+ uint32_t index2 = ((index + kArrayEntriesPerCacheEntry) & (cache_size - 1));
if (cache->get(index2 + kStringOffset) == Smi::zero()) {
cache->set(index2 + kStringOffset, *key_string);
cache->set(index2 + kPatternOffset, *key_pattern);
@@ -1763,8 +1810,36 @@ void ResultsCache::Enter(Isolate* isolate, DirectHandle<String> key_string,
isolate, ReadOnlyRoots(isolate).fixed_cow_array_map());
}
+// static
+Address ResultsCache::EnterRaw(Isolate* isolate, Address raw_key_string,
+ Address raw_pattern, Address raw_value_array,
+ Address raw_last_match_cache) {
+ // Entering may allocate the cache, and allocation is allowed in a fast C
+ // call, so every argument has to be handlified before that can happen.
+ HandleScope scope(isolate);
+ DirectHandle<String> key_string(Cast<String>(Tagged<Object>(raw_key_string)),
+ isolate);
+ DirectHandle<JSRegExp> pattern(Cast<JSRegExp>(Tagged<Object>(raw_pattern)),
+ isolate);
+ DirectHandle<JSArray> value_array(
+ Cast<JSArray>(Tagged<Object>(raw_value_array)), isolate);
+ DirectHandle<FixedArray> last_match_cache(
+ Cast<FixedArray>(Tagged<Object>(raw_last_match_cache)), isolate);
+
+ // The elements are cached as-is, so they must hold exactly the split parts.
+ // ToJSArray has already shrunk to fit, so no trimming is needed here.
+ DirectHandle<FixedArray> elements(Cast<FixedArray>(value_array->elements()),
+ isolate);
+ DCHECK_EQ(elements->length().value(), Smi::ToInt(value_array->length()));
+
+ Enter(isolate, key_string,
+ direct_handle(pattern->data(isolate)->wrapper(), isolate), elements,
+ last_match_cache, REGEXP_SPLIT_SUBSTRINGS);
+ return ReadOnlyRoots(isolate).undefined_value().ptr();
+}
+
void ResultsCache::Clear(Tagged<FixedArray> cache) {
- for (int i = 0; i < kRegExpResultsCacheSize; i++) {
+ for (int i = 0, length = cache->length().value(); i < length; i++) {
cache->set(i, Smi::zero());
}
}
diff --git a/deps/v8/src/regexp/regexp.h b/deps/v8/src/regexp/regexp.h
index 8c579bf2951..77b802ee0af 100644
--- a/deps/v8/src/regexp/regexp.h
+++ b/deps/v8/src/regexp/regexp.h
@@ -5,6 +5,7 @@
#ifndef V8_REGEXP_REGEXP_H_
#define V8_REGEXP_REGEXP_H_
+#include "src/base/bits.h"
#include "src/common/assert-scope.h"
#include "src/handles/handles.h"
#include "src/regexp/regexp-error.h"
@@ -238,7 +239,11 @@ class GlobalExecRunner final {
// @@split.
class ResultsCache final : public AllStatic {
public:
- enum ResultsCacheType { REGEXP_MULTIPLE_INDICES, STRING_SPLIT_SUBSTRINGS };
+ enum ResultsCacheType {
+ REGEXP_MULTIPLE_INDICES,
+ STRING_SPLIT_SUBSTRINGS,
+ REGEXP_SPLIT_SUBSTRINGS
+ };
// Attempt to retrieve a cached result. On failure, 0 is returned as a Smi.
// On success, the returned result is guaranteed to be a COW-array.
@@ -256,13 +261,37 @@ class ResultsCache final : public AllStatic {
static void Clear(Tagged<FixedArray> cache);
static constexpr int kRegExpResultsCacheSize = 0x100;
+ // Splits reuse many more distinct (subject, pattern) pairs than the other
+ // cache types.
+ static constexpr int kRegExpSplitResultsCacheSize = 0x400;
+
+ // Sizes are used as masks.
+ static_assert(base::bits::IsPowerOfTwo(kRegExpResultsCacheSize));
+ static_assert(base::bits::IsPowerOfTwo(kRegExpSplitResultsCacheSize));
- private:
static constexpr int kStringOffset = 0;
static constexpr int kPatternOffset = 1;
static constexpr int kArrayOffset = 2;
static constexpr int kLastMatchOffset = 3;
static constexpr int kArrayEntriesPerCacheEntry = 4;
+ static_assert(base::bits::IsPowerOfTwo(kArrayEntriesPerCacheEntry));
+
+ static constexpr int SizeForType(ResultsCacheType type) {
+ switch (type) {
+ case REGEXP_SPLIT_SUBSTRINGS:
+ return kRegExpSplitResultsCacheSize;
+ case REGEXP_MULTIPLE_INDICES:
+ case STRING_SPLIT_SUBSTRINGS:
+ return kRegExpResultsCacheSize;
+ }
+ }
+
+ // Enter, for generated code. {raw_pattern} is a JSRegExp, keyed on its
+ // RegExpData wrapper; {raw_value_array} a JSArray, cached by its elements.
+ // Does not allocate.
+ static Address EnterRaw(Isolate* isolate, Address raw_key_string,
+ Address raw_pattern, Address raw_value_array,
+ Address raw_last_match_cache);
};
// Caches results of RegExpPrototypeMatch when:
diff --git a/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.cc b/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.cc
index ec227acb1a2..5bb72cf147a 100644
--- a/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.cc
+++ b/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.cc
@@ -150,6 +150,15 @@ void RegExpMacroAssemblerRISCV::AdvanceRegister(int reg, int by) {
}
void RegExpMacroAssemblerRISCV::Backtrack() {
+ // Defer to the shared backtrack block bound in GetCode: only there, with
+ // the body fully emitted, is it known whether anything was ever pushed.
+ // If nothing was, the only value a pop could yield is the fail label,
+ // so the block reduces to Fail() and the backtrack stack (including the
+ // fail label itself) is elided entirely.
+ __ jmp(&backtrack_label_);
+}
+
+void RegExpMacroAssemblerRISCV::EmitBacktrack() {
CheckPreemption();
if (has_backtrack_limit()) {
Label next;
@@ -207,6 +216,7 @@ void RegExpMacroAssemblerRISCV::CheckCharacterLT(base::uc16 limit,
}
void RegExpMacroAssemblerRISCV::CheckFixedLengthLoop(Label* on_equal) {
+ set_backtrack_stack_used();
Label backtrack_non_equal;
__ Lw(a0, MemOperand(backtrack_stackpointer(), 0));
__ BranchShort(&backtrack_non_equal, ne, current_input_offset(), Operand(a0));
@@ -847,13 +857,24 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
kBacktrackCountOffset - kSystemPointerSize);
__ push(a0); // The regexp stack base ptr.
- // Initialize backtrack stack pointer. It must not be clobbered from here
- // on. Note the backtrack_stackpointer is callee-saved.
- static_assert(backtrack_stackpointer() == s8);
- LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
- // Store the regexp base pointer - we'll later restore it / write it to
- // memory when returning from this irregexp code object.
- PushRegExpBasePointer(backtrack_stackpointer(), a1);
+ // The body has been fully emitted, so backtrack_stack_used() is now final:
+ // it is true iff some op pushed, popped, or transferred the backtrack stack
+ // pointer. Patterns that never do skip the backtrack stack setup, the fail
+ // label, and the teardown below.
+ if (backtrack_stack_used()) {
+ // Initialize backtrack stack pointer. It must not be clobbered from here
+ // on. Note the backtrack_stackpointer is callee-saved.
+ static_assert(backtrack_stackpointer() == s8);
+ LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ // Store the regexp base pointer - we'll later restore it / write it to
+ // memory when returning from this irregexp code object. Captured with an
+ // empty stack (delta 0), before the fail label is pushed below, so the
+ // teardown on exit and between global iterations restores to the same
+ // point (regexp::StackScope verifies this delta is unchanged).
+ UseScratchRegisterScope temps(masm());
+ Register scratch = temps.Acquire();
+ PushRegExpBasePointer(backtrack_stackpointer(), scratch);
+ }
// Skip the JS stack guard check for patterns whose register file fits within
// the stack limit's guaranteed slack: allocating it then can never push the
@@ -885,12 +906,19 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
__ jmp(&return_a0);
__ bind(&stack_limit_hit);
- StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
+ // Without a backtrack stack, backtrack_stackpointer() was never
+ // initialized above; storing it would corrupt the saved stack pointer
+ // (regexp::StackScope verifies it is unchanged across the exec call).
+ if (backtrack_stack_used()) {
+ StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
+ }
CallCheckStackGuardState(a0, extra_space_for_variables);
// If returned value is non-zero, we exit with the returned value as
// result.
__ Branch(&return_a0, ne, a0, Operand(zero_reg));
- LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ if (backtrack_stack_used()) {
+ LoadRegExpStackPointerFromMemory(backtrack_stackpointer());
+ }
__ bind(&stack_ok);
}
@@ -951,6 +979,13 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
}
}
+ if (backtrack_stack_used() && fail_label() != nullptr) {
+ // Push the fail label (see set_fail_label / prologue_pushes_fail_label).
+ // Global matches re-enter here per iteration, each having restored the
+ // stack to base via PopRegExpBasePointer first, so it is refreshed.
+ PushBacktrack(fail_label());
+ }
+
__ jmp(&start_label_);
// Exit code:
@@ -1018,9 +1053,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
__ AddWord(a2, a2, num_saved_registers_ * kIntSize);
__ StoreWord(a2, MemOperand(frame_pointer(), kRegisterOutputOffset));
- // Restore the original regexp stack pointer value (effectively, pop the
- // stored base pointer).
- PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ if (backtrack_stack_used()) {
+ // Restore the original regexp stack pointer value (effectively, pop
+ // the stored base pointer).
+ PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ }
Label reload_string_start_minus_one;
@@ -1057,9 +1094,12 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
}
__ bind(&return_a0);
- // Restore the original regexp stack pointer value (effectively, pop the
- // stored base pointer).
- PopRegExpBasePointer(backtrack_stackpointer(), a1);
+
+ if (backtrack_stack_used()) {
+ // Restore the original regexp stack pointer value (effectively, pop the
+ // stored base pointer).
+ PopRegExpBasePointer(backtrack_stackpointer(), a2);
+ }
// Skip sp past regexp registers and local variables..
__ mv(sp, frame_pointer());
@@ -1073,7 +1113,15 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
// Backtrack code (branch target for conditional backtracks).
if (backtrack_label_.is_linked()) {
__ bind(&backtrack_label_);
- Backtrack();
+ if (backtrack_stack_used()) {
+ EmitBacktrack();
+ } else {
+ // Nothing was pushed, so the only possible backtrack target is the fail
+ // label. Fail directly instead of popping a stack that was never set
+ // up. Reached e.g. by the bounds check of a single character class like
+ // /[abc]/.
+ Fail();
+ }
}
Label exit_with_exception;
@@ -1081,6 +1129,11 @@ DirectHandle<HeapObject> RegExpMacroAssemblerRISCV::GetCode(
// Preempt-code.
if (check_preempt_label_.is_linked()) {
SafeCallTarget(&check_preempt_label_);
+ // Only EmitBacktrack() (which pops the backtrack stack) links this label,
+ // so a linked preempt target implies the backtrack stack is live and its
+ // pointer is initialized for the store/reload below.
+ DCHECK(backtrack_stack_used());
+
StoreRegExpStackPointerToMemory(backtrack_stackpointer(), a1);
// Put regexp engine registers on stack.
CallCheckStackGuardState(a0);
@@ -1216,6 +1269,7 @@ void RegExpMacroAssemblerRISCV::ReadCurrentPositionFromRegister(int reg) {
}
void RegExpMacroAssemblerRISCV::WriteStackPointerToRegister(int reg) {
+ set_backtrack_stack_used();
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a0, ref);
@@ -1225,6 +1279,7 @@ void RegExpMacroAssemblerRISCV::WriteStackPointerToRegister(int reg) {
}
void RegExpMacroAssemblerRISCV::ReadStackPointerFromRegister(int reg) {
+ set_backtrack_stack_used();
ExternalReference ref =
ExternalReference::address_of_regexp_stack_memory_top_address(isolate());
__ li(a1, ref);
@@ -1426,6 +1481,7 @@ void RegExpMacroAssemblerRISCV::SafeCallTarget(Label* name) {
void RegExpMacroAssemblerRISCV::Push(Register source) {
DCHECK(source != backtrack_stackpointer());
+ set_backtrack_stack_used();
__ AddWord(backtrack_stackpointer(), backtrack_stackpointer(),
Operand(-kIntSize));
__ Sw(source, MemOperand(backtrack_stackpointer()));
@@ -1433,6 +1489,7 @@ void RegExpMacroAssemblerRISCV::Push(Register source) {
void RegExpMacroAssemblerRISCV::Pop(Register target) {
DCHECK(target != backtrack_stackpointer());
+ set_backtrack_stack_used();
__ Lw(target, MemOperand(backtrack_stackpointer()));
__ AddWord(backtrack_stackpointer(), backtrack_stackpointer(), kIntSize);
}
diff --git a/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.h b/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.h
index ae0cef9108e..406d693933b 100644
--- a/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.h
+++ b/deps/v8/src/regexp/riscv/regexp-macro-assembler-riscv.h
@@ -67,6 +67,7 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
void CheckSpecialClassRanges(StandardCharacterSet type,
Label* on_no_match) override;
void Fail() override;
+ bool prologue_pushes_fail_label() const override { return true; }
DirectHandle<HeapObject> GetCode(DirectHandle<RegExpData> re_data,
Flags flags) override;
void GoTo(Label* label) override;
@@ -206,6 +207,12 @@ class V8_EXPORT_PRIVATE RegExpMacroAssemblerRISCV
// Register holding pointer to the current code object.
static constexpr Register code_pointer() { return s1; }
+ // The real backtrack dispatch (pop a code offset and jump to it), emitted
+ // once in GetCode at backtrack_label_ when the backtrack stack is used.
+ // Backtrack() itself only jumps there, so emitting it does not by itself
+ // mark the backtrack stack as used.
+ void EmitBacktrack();
+
// Equivalent to a conditional branch to the label, unless the label
// is nullptr, in which case it is a conditional Backtrack.
void BranchOrBacktrack(Label* to, Condition condition, Register rs,
diff --git a/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc b/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc
index ff9fb46c093..769d2d5ff0f 100644
--- a/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc
+++ b/deps/v8/src/regexp/x64/regexp-macro-assembler-x64.cc
@@ -835,7 +835,7 @@ void RegExpMacroAssemblerX64::SkipUntilCharAndSimd(
__ j(not_zero, &found, Label::kNear);
AdvanceCurrentPosition(kCharsPerVector);
- __ cmpl(rdi, Immediate(-check_offset * char_size()));
+ __ Cmp(rdi, -check_offset * char_size());
__ j(less, &simd_loop, Label::kNear);
__ jmp(&scalar, Label::kNear);
@@ -921,7 +921,7 @@ void RegExpMacroAssemblerX64::SkipUntilCharSimd(int cp_offset, int advance_by,
__ j(not_zero, &found, Label::kNear);
AdvanceCurrentPosition(kCharsPerVector);
- __ cmpl(rdi, Immediate(-check_offset * char_size()));
+ __ Cmp(rdi, -check_offset * char_size());
__ j(less, &simd_loop, Label::kNear);
__ jmp(&scalar, Label::kNear);
@@ -982,7 +982,7 @@ void RegExpMacroAssemblerX64::SkipUntilCharOrCharSimd(
__ j(not_zero, &found, Label::kNear);
AdvanceCurrentPosition(kCharsPerVector);
- __ cmpl(rdi, Immediate(-check_offset * char_size()));
+ __ Cmp(rdi, -check_offset * char_size());
__ j(less, &simd_loop, Label::kNear);
__ jmp(&scalar, Label::kNear);
@@ -2091,7 +2091,7 @@ void RegExpMacroAssemblerX64::ReadStackPointerFromRegister(int reg) {
void RegExpMacroAssemblerX64::SetCurrentPositionFromEnd(int by) {
Label after_position;
- __ cmpq(rdi, Immediate(-by * char_size()));
+ __ Cmpq(rdi, -by * char_size());
__ j(greater_equal, &after_position, Label::kNear);
__ Move(rdi, -by * char_size());
// On RegExp code entry (where this operation is used), the character before
@@ -2213,7 +2213,7 @@ Operand RegExpMacroAssemblerX64::register_location(int register_index) {
void RegExpMacroAssemblerX64::CheckPosition(int cp_offset,
Label* on_outside_input) {
if (cp_offset >= 0) {
- __ cmpl(rdi, Immediate(-cp_offset * char_size()));
+ __ Cmp(rdi, -cp_offset * char_size());
BranchOrBacktrack(greater_equal, on_outside_input);
} else {
__ leaq(rax, Operand(rdi, cp_offset * char_size()));
diff --git a/deps/v8/src/roots/roots.h b/deps/v8/src/roots/roots.h
index 7de969981d2..73296da9753 100644
--- a/deps/v8/src/roots/roots.h
+++ b/deps/v8/src/roots/roots.h
@@ -419,6 +419,8 @@ class RootVisitor;
/* Caches */ \
V(SmiStringCache, smi_string_cache, SmiStringCache) \
V(DoubleStringCache, double_string_cache, DoubleStringCache) \
+ /* Allocated on first use, so it must be loaded rather than baked in. */ \
+ V(FixedArray, regexp_split_cache, RegExpSplitCache) \
/* undefined or BigInt. Caching divisors used for modulo divisions. */ \
V(Object, cached_bigint_divisor, CachedBigIntDivisor) \
V(Object, next_cached_bigint_divisor, NextCachedBigIntDivisor) \
@@ -447,6 +449,9 @@ class RootVisitor;
V(HeapObject, locals_block_list_cache, DebugLocalsBlockListCache) \
IF_WASM(V, WeakFixedArray, js_to_wasm_wrappers, JSToWasmWrappers) \
IF_WASM(V, WeakFixedArray, wasm_canonical_rtts, WasmCanonicalRtts) \
+ /* Only updated/used on the shared-space isolate */ \
+ IF_WASM(V, WeakFixedArray, wasm_shared_canonical_rtts, \
+ WasmSharedCanonicalRtts) \
/* Internal SharedFunctionInfos */ \
V(FunctionTemplateInfo, error_stack_getter_fun_template, \
ErrorStackGetterSharedFun) \
@@ -504,20 +509,21 @@ class RootVisitor;
#define ACCESSOR_INFO_ROOT_LIST(V) \
ACCESSOR_INFO_LIST_GENERATOR(ACCESSOR_INFO_ROOT_LIST_ADAPTER, V)
-#define READ_ONLY_ROOT_LIST(V) \
- STRONG_READ_ONLY_ROOT_LIST(V) \
- INTERNALIZED_STRING_ROOT_LIST(V) \
- PRIVATE_SYMBOL_ROOT_LIST(V) \
- PUBLIC_SYMBOL_ROOT_LIST(V) \
- WELL_KNOWN_SYMBOL_ROOT_LIST(V) \
- STRUCT_MAPS_LIST(V) \
- ALLOCATION_SITE_MAPS_LIST(V) \
- NAME_FOR_PROTECTOR_ROOT_LIST(V) \
- DATA_HANDLER_MAPS_LIST(V) \
- /* Maps */ \
- V(Map, external_map, ExternalMap) \
- V(Map, message_object_map, JSMessageObjectMap) \
- V(Map, cpp_heap_external_map, CppHeapExternalMap)
+#define READ_ONLY_ROOT_LIST(V) \
+ STRONG_READ_ONLY_ROOT_LIST(V) \
+ INTERNALIZED_STRING_ROOT_LIST(V) \
+ PRIVATE_SYMBOL_ROOT_LIST(V) \
+ PUBLIC_SYMBOL_ROOT_LIST(V) \
+ WELL_KNOWN_SYMBOL_ROOT_LIST(V) \
+ STRUCT_MAPS_LIST(V) \
+ ALLOCATION_SITE_MAPS_LIST(V) \
+ NAME_FOR_PROTECTOR_ROOT_LIST(V) \
+ DATA_HANDLER_MAPS_LIST(V) \
+ /* Maps */ \
+ V(Map, external_map, ExternalMap) \
+ V(Map, message_object_map, JSMessageObjectMap) \
+ V(Map, cpp_heap_external_map, CppHeapExternalMap) \
+ V(Map, cpp_gc_managed_base_map, CppGCManagedBaseMap)
#define MUTABLE_ROOT_LIST(V) \
STRONG_MUTABLE_IMMOVABLE_ROOT_LIST(V) \
diff --git a/deps/v8/src/roots/static-roots-intl-nowasm.h b/deps/v8/src/roots/static-roots-intl-nowasm.h
index c36578af390..dbb438d29ab 100644
--- a/deps/v8/src/roots/static-roots-intl-nowasm.h
+++ b/deps/v8/src/roots/static-roots-intl-nowasm.h
@@ -205,7 +205,8 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kClassBoilerplateMap = kBytecodeWrapperMap + 40;
static constexpr Tagged_t kClassPositionsMap = kClassBoilerplateMap + 40;
static constexpr Tagged_t kCodeWrapperMap = kClassPositionsMap + 40;
- static constexpr Tagged_t kErrorStackDataMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kDebugScriptScopeInfoMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kErrorStackDataMap = kDebugScriptScopeInfoMap + 40;
static constexpr Tagged_t kFunctionTemplateRareDataMap =
kErrorStackDataMap + 40;
static constexpr Tagged_t kModuleRequestMap =
@@ -1213,17 +1214,18 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kJSMessageObjectMap = 0x180011;
static constexpr Tagged_t kExternalMap = 0x180039;
static constexpr Tagged_t kCppHeapExternalMap = 0x180061;
- static constexpr Tagged_t kJSSharedArrayMap = 0x180089;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1800cd;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x1800f5;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x18011d;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x180171;
+ 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 kFirstAllocatedRoot = 0x11;
- static constexpr Tagged_t kLastAllocatedRoot = 0x180171;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x180199;
};
-static constexpr std::array<Tagged_t, 1021> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 1023> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -2201,6 +2203,7 @@ static constexpr std::array<Tagged_t, 1021> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kClassBoilerplateMap,
StaticReadOnlyRoot::kClassPositionsMap,
StaticReadOnlyRoot::kCodeWrapperMap,
+ StaticReadOnlyRoot::kDebugScriptScopeInfoMap,
StaticReadOnlyRoot::kEnumCacheMap,
StaticReadOnlyRoot::kErrorStackDataMap,
StaticReadOnlyRoot::kFunctionTemplateRareDataMap,
@@ -2245,6 +2248,7 @@ static constexpr std::array<Tagged_t, 1021> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kExternalMap,
StaticReadOnlyRoot::kJSMessageObjectMap,
StaticReadOnlyRoot::kCppHeapExternalMap,
+ StaticReadOnlyRoot::kCppGCManagedBaseMap,
};
} // namespace internal
diff --git a/deps/v8/src/roots/static-roots-intl-wasm.h b/deps/v8/src/roots/static-roots-intl-wasm.h
index 4aa71234ccd..f349dc37a79 100644
--- a/deps/v8/src/roots/static-roots-intl-wasm.h
+++ b/deps/v8/src/roots/static-roots-intl-wasm.h
@@ -205,7 +205,8 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kClassBoilerplateMap = kBytecodeWrapperMap + 40;
static constexpr Tagged_t kClassPositionsMap = kClassBoilerplateMap + 40;
static constexpr Tagged_t kCodeWrapperMap = kClassPositionsMap + 40;
- static constexpr Tagged_t kErrorStackDataMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kDebugScriptScopeInfoMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kErrorStackDataMap = kDebugScriptScopeInfoMap + 40;
static constexpr Tagged_t kFunctionTemplateRareDataMap =
kErrorStackDataMap + 40;
static constexpr Tagged_t kModuleRequestMap =
@@ -1217,7 +1218,7 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kManyClosuresCell = kShadowRealmScopeInfo + 24;
static constexpr Tagged_t kPreallocatedNumberStringTable =
kManyClosuresCell + 16;
- static constexpr Tagged_t kWasmNull = 0xfffd;
+ static constexpr Tagged_t kWasmNull = 0x10001;
static constexpr Tagged_t kTheHoleValue = 0x2fffd;
// -- End of page 0 --
static constexpr Tagged_t kPropertyCellHoleValue = 0x4fffd;
@@ -1239,17 +1240,18 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kJSMessageObjectMap = 0x1a0001;
static constexpr Tagged_t kExternalMap = 0x1a0029;
static constexpr Tagged_t kCppHeapExternalMap = 0x1a0051;
- static constexpr Tagged_t kJSSharedArrayMap = 0x1a0079;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1a00bd;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x1a00e5;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1a010d;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1a0161;
+ 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 = 0x1a0161;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x1a0189;
};
-static constexpr std::array<Tagged_t, 1039> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 1041> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -2244,6 +2246,7 @@ static constexpr std::array<Tagged_t, 1039> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kClassBoilerplateMap,
StaticReadOnlyRoot::kClassPositionsMap,
StaticReadOnlyRoot::kCodeWrapperMap,
+ StaticReadOnlyRoot::kDebugScriptScopeInfoMap,
StaticReadOnlyRoot::kEnumCacheMap,
StaticReadOnlyRoot::kErrorStackDataMap,
StaticReadOnlyRoot::kFunctionTemplateRareDataMap,
@@ -2289,6 +2292,7 @@ static constexpr std::array<Tagged_t, 1039> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kExternalMap,
StaticReadOnlyRoot::kJSMessageObjectMap,
StaticReadOnlyRoot::kCppHeapExternalMap,
+ StaticReadOnlyRoot::kCppGCManagedBaseMap,
};
} // namespace internal
diff --git a/deps/v8/src/roots/static-roots-nointl-nowasm.h b/deps/v8/src/roots/static-roots-nointl-nowasm.h
index 865f91b7b72..97801275472 100644
--- a/deps/v8/src/roots/static-roots-nointl-nowasm.h
+++ b/deps/v8/src/roots/static-roots-nointl-nowasm.h
@@ -205,7 +205,8 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kClassBoilerplateMap = kBytecodeWrapperMap + 40;
static constexpr Tagged_t kClassPositionsMap = kClassBoilerplateMap + 40;
static constexpr Tagged_t kCodeWrapperMap = kClassPositionsMap + 40;
- static constexpr Tagged_t kErrorStackDataMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kDebugScriptScopeInfoMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kErrorStackDataMap = kDebugScriptScopeInfoMap + 40;
static constexpr Tagged_t kFunctionTemplateRareDataMap =
kErrorStackDataMap + 40;
static constexpr Tagged_t kModuleRequestMap =
@@ -1057,17 +1058,18 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kJSMessageObjectMap = 0x180011;
static constexpr Tagged_t kExternalMap = 0x180039;
static constexpr Tagged_t kCppHeapExternalMap = 0x180061;
- static constexpr Tagged_t kJSSharedArrayMap = 0x180089;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1800cd;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x1800f5;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x18011d;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x180171;
+ 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 kFirstAllocatedRoot = 0x11;
- static constexpr Tagged_t kLastAllocatedRoot = 0x180171;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x180199;
};
-static constexpr std::array<Tagged_t, 879> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 881> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -1903,6 +1905,7 @@ static constexpr std::array<Tagged_t, 879> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kClassBoilerplateMap,
StaticReadOnlyRoot::kClassPositionsMap,
StaticReadOnlyRoot::kCodeWrapperMap,
+ StaticReadOnlyRoot::kDebugScriptScopeInfoMap,
StaticReadOnlyRoot::kEnumCacheMap,
StaticReadOnlyRoot::kErrorStackDataMap,
StaticReadOnlyRoot::kFunctionTemplateRareDataMap,
@@ -1947,6 +1950,7 @@ static constexpr std::array<Tagged_t, 879> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kExternalMap,
StaticReadOnlyRoot::kJSMessageObjectMap,
StaticReadOnlyRoot::kCppHeapExternalMap,
+ StaticReadOnlyRoot::kCppGCManagedBaseMap,
};
} // namespace internal
diff --git a/deps/v8/src/roots/static-roots-nointl-wasm.h b/deps/v8/src/roots/static-roots-nointl-wasm.h
index d5d2c565981..a405300d56b 100644
--- a/deps/v8/src/roots/static-roots-nointl-wasm.h
+++ b/deps/v8/src/roots/static-roots-nointl-wasm.h
@@ -205,7 +205,8 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kClassBoilerplateMap = kBytecodeWrapperMap + 40;
static constexpr Tagged_t kClassPositionsMap = kClassBoilerplateMap + 40;
static constexpr Tagged_t kCodeWrapperMap = kClassPositionsMap + 40;
- static constexpr Tagged_t kErrorStackDataMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kDebugScriptScopeInfoMap = kCodeWrapperMap + 40;
+ static constexpr Tagged_t kErrorStackDataMap = kDebugScriptScopeInfoMap + 40;
static constexpr Tagged_t kFunctionTemplateRareDataMap =
kErrorStackDataMap + 40;
static constexpr Tagged_t kModuleRequestMap =
@@ -1061,7 +1062,7 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kManyClosuresCell = kShadowRealmScopeInfo + 24;
static constexpr Tagged_t kPreallocatedNumberStringTable =
kManyClosuresCell + 16;
- static constexpr Tagged_t kWasmNull = 0xfffd;
+ static constexpr Tagged_t kWasmNull = 0x10001;
static constexpr Tagged_t kTheHoleValue = 0x2fffd;
// -- End of page 0 --
static constexpr Tagged_t kPropertyCellHoleValue = 0x4fffd;
@@ -1083,17 +1084,18 @@ struct StaticReadOnlyRoot {
static constexpr Tagged_t kJSMessageObjectMap = 0x1a0001;
static constexpr Tagged_t kExternalMap = 0x1a0029;
static constexpr Tagged_t kCppHeapExternalMap = 0x1a0051;
- static constexpr Tagged_t kJSSharedArrayMap = 0x1a0079;
- static constexpr Tagged_t kJSAtomicsMutexMap = 0x1a00bd;
- static constexpr Tagged_t kJSAtomicsConditionMap = 0x1a00e5;
- static constexpr Tagged_t kNoOpNamedInterceptorInfo = 0x1a010d;
- static constexpr Tagged_t kNoOpIndexedInterceptorInfo = 0x1a0161;
+ 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 = 0x1a0161;
+ static constexpr Tagged_t kLastAllocatedRoot = 0x1a0189;
};
-static constexpr std::array<Tagged_t, 897> StaticReadOnlyRootsPointerTable = {
+static constexpr std::array<Tagged_t, 899> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kUndefinedValue,
StaticReadOnlyRoot::kTheHoleValue,
StaticReadOnlyRoot::kNullValue,
@@ -1946,6 +1948,7 @@ static constexpr std::array<Tagged_t, 897> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kClassBoilerplateMap,
StaticReadOnlyRoot::kClassPositionsMap,
StaticReadOnlyRoot::kCodeWrapperMap,
+ StaticReadOnlyRoot::kDebugScriptScopeInfoMap,
StaticReadOnlyRoot::kEnumCacheMap,
StaticReadOnlyRoot::kErrorStackDataMap,
StaticReadOnlyRoot::kFunctionTemplateRareDataMap,
@@ -1991,6 +1994,7 @@ static constexpr std::array<Tagged_t, 897> StaticReadOnlyRootsPointerTable = {
StaticReadOnlyRoot::kExternalMap,
StaticReadOnlyRoot::kJSMessageObjectMap,
StaticReadOnlyRoot::kCppHeapExternalMap,
+ StaticReadOnlyRoot::kCppGCManagedBaseMap,
};
} // namespace internal
diff --git a/deps/v8/src/runtime/runtime-array.cc b/deps/v8/src/runtime/runtime-array.cc
index 44c4a4638ea..b65cd7ce87e 100644
--- a/deps/v8/src/runtime/runtime-array.cc
+++ b/deps/v8/src/runtime/runtime-array.cc
@@ -10,6 +10,7 @@
#include "src/objects/allocation-site-inl.h"
#include "src/objects/elements.h"
#include "src/objects/js-array-inl.h"
+#include "src/objects/object-conversions-inl.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/src/runtime/runtime-compiler.cc b/deps/v8/src/runtime/runtime-compiler.cc
index d7acc9c7f29..e998c4d59f4 100644
--- a/deps/v8/src/runtime/runtime-compiler.cc
+++ b/deps/v8/src/runtime/runtime-compiler.cc
@@ -122,6 +122,38 @@ Builtin GetTypedBuiltinForBinop(int hint, Builtin current_builtin) noexcept {
#undef TYPED_BINOP_DISPATCH_CASE
}
+Builtin GetTypedBuiltinForUnary(int hint, Builtin current_builtin) noexcept {
+ Builtin target_builtin = Builtin::kNoBuiltinId;
+
+#define TYPED_UNOP_DISPATCH_CASE(hint_value, op_type) \
+ case static_cast<int>(BinaryOperationFeedback::TypeIndex::k##hint_value): \
+ target_builtin = Builtin::k##op_type##_##hint_value##_Baseline; \
+ break;
+
+#define TYPED_UNOP_FAMILY_SWITCH(stub_list, op_type) \
+ if (IsTyped##op_type##Builtin(current_builtin)) { \
+ switch (hint) { \
+ stub_list(TYPED_UNOP_DISPATCH_CASE, op_type) default \
+ : target_builtin = Builtin::k##op_type##_Generic_Baseline; \
+ break; \
+ } \
+ } else /* NOLINT */
+
+#define TYPED_UNOP_DISPATCH_LIST(V) \
+ V(TYPED_UNARY_STUB_LIST, Increment) \
+ V(TYPED_UNARY_STUB_LIST, Decrement) \
+ V(TYPED_NEGATE_STUB_LIST, Negate) \
+ V(TYPED_UNARY_STUB_LIST, BitwiseNot)
+
+ TYPED_UNOP_DISPATCH_LIST(TYPED_UNOP_FAMILY_SWITCH)
+ /* else */ {}
+
+ return target_builtin;
+#undef TYPED_UNOP_DISPATCH_LIST
+#undef TYPED_UNOP_FAMILY_SWITCH
+#undef TYPED_UNOP_DISPATCH_CASE
+}
+
V8_INLINE void UpdateEmbeddedFeedback(Tagged<BytecodeArray> bytecode_array,
int feedback_offset,
int current_feedback) {
@@ -166,6 +198,11 @@ V8_INLINE void TryPatchBinaryOpBaselineCode(Isolate* isolate,
TryPatchBaselineCodeImpl(isolate, current_feedback, GetTypedBuiltinForBinop);
}
+V8_INLINE void TryPatchUnaryOpBaselineCode(Isolate* isolate,
+ int current_feedback) {
+ TryPatchBaselineCodeImpl(isolate, current_feedback, GetTypedBuiltinForUnary);
+}
+
V8_INLINE int UpdateEmbeddedFeedbackAndGetCurrent(RuntimeArguments args) {
int current_feedback = args.smi_value_at(0);
DCHECK_LE(current_feedback, std::numeric_limits<uint8_t>::max());
@@ -339,7 +376,7 @@ RUNTIME_FUNCTION(Runtime_OptimizeTurbofanEager) {
return ReadOnlyRoots(isolate).undefined_value();
}
-RUNTIME_FUNCTION(Runtime_MarkLazyDeoptimized) {
+RUNTIME_FUNCTION(Runtime_MarkLazyDeoptimizedOrFlushed) {
HandleScope scope(isolate);
DCHECK_EQ(2, args.length());
DirectHandle<JSFunction> function = args.at<JSFunction>(0);
@@ -687,7 +724,6 @@ RUNTIME_FUNCTION(Runtime_CompileOptimizedOSR) {
}
namespace {
-
Tagged<Object> CompileOptimizedOSRFromMaglev(Isolate* isolate,
DirectHandle<JSFunction> function,
BytecodeOffset osr_offset) {
@@ -729,7 +765,6 @@ Tagged<Object> CompileOptimizedOSRFromMaglev(Isolate* isolate,
return CompileOptimizedOSR(isolate, function, CodeKind::TURBOFAN_JS,
osr_offset);
}
-
} // namespace
RUNTIME_FUNCTION(Runtime_CompileOptimizedOSRFromMaglev) {
@@ -774,7 +809,7 @@ RUNTIME_FUNCTION(Runtime_CompileOptimizedOSRFromMaglevInlined) {
RUNTIME_FUNCTION(Runtime_LogOrTraceOptimizedOSREntry) {
HandleScope handle_scope(isolate);
DCHECK_EQ(0, args.length());
- CHECK(v8_flags.trace_osr || v8_flags.log_function_events);
+ CHECK(v8_flags.log_or_trace_osr);
BytecodeOffset osr_offset = BytecodeOffset::None();
Handle<JSFunction> function;
@@ -900,6 +935,28 @@ RUNTIME_FUNCTION(Runtime_PatchBinopBaselineCodeAndThrow) {
UpdateEmbeddedFeedbackAndGetCurrent(args));
return isolate->ReThrow(*exception);
}
+
+RUNTIME_FUNCTION(Runtime_PatchUnaryOpBaselineCode) {
+ HandleScope scope(isolate);
+ CHECK(v8_flags.sparkplug_plus);
+ DCHECK_EQ(4, args.length());
+
+ DirectHandle<Object> result = args.at<Object>(1);
+ TryPatchUnaryOpBaselineCode(isolate,
+ UpdateEmbeddedFeedbackAndGetCurrent(args));
+ return *result;
+}
+
+RUNTIME_FUNCTION(Runtime_PatchUnaryOpBaselineCodeAndThrow) {
+ HandleScope scope(isolate);
+ CHECK(v8_flags.sparkplug_plus);
+ DCHECK_EQ(4, args.length());
+
+ DirectHandle<Object> exception = args.at<Object>(1);
+ TryPatchUnaryOpBaselineCode(isolate,
+ UpdateEmbeddedFeedbackAndGetCurrent(args));
+ return isolate->ReThrow(*exception);
+}
#endif // V8_ENABLE_SPARKPLUG_PLUS
} // namespace v8::internal
diff --git a/deps/v8/src/runtime/runtime-debug.cc b/deps/v8/src/runtime/runtime-debug.cc
index 4cd97317b6e..af91478fd5e 100644
--- a/deps/v8/src/runtime/runtime-debug.cc
+++ b/deps/v8/src/runtime/runtime-debug.cc
@@ -8,7 +8,6 @@
#include "src/debug/debug-coverage.h"
#include "src/debug/debug-scopes.h"
#include "src/debug/debug.h"
-#include "src/debug/liveedit.h"
#include "src/execution/frames-inl.h"
#include "src/execution/isolate-inl.h"
#include "src/interpreter/bytecodes.h"
@@ -19,6 +18,7 @@
#include "src/objects/js-promise-inl.h"
#include "src/objects/js-proxy-inl.h"
#include "src/objects/js-weak-refs-inl.h"
+#include "src/objects/module-inl.h"
#include "src/runtime/runtime-utils.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/embedded/embedded-data.h"
@@ -354,6 +354,39 @@ MaybeHandle<JSArray> Runtime::GetInternalProperties(
isolate, result,
isolate->factory()->NewStringFromAsciiChecked("[[WeakRefTarget]]"),
direct_handle(js_weak_ref->target(), isolate));
+ } else if (IsJSDeferredModuleNamespace(*object)) {
+ auto ns = Cast<JSDeferredModuleNamespace>(object);
+
+ const char* status = nullptr;
+ switch (ns->module()->status()) {
+ case Module::kUnlinked:
+ status = "unlinked";
+ break;
+ case Module::kPreLinking:
+ case Module::kLinking:
+ status = "linking";
+ break;
+ case Module::kLinked:
+ status = "linked";
+ break;
+ case Module::kEvaluating:
+ status = "evaluating";
+ break;
+ case Module::kEvaluatingAsync:
+ status = "evaluating-async";
+ break;
+ case Module::kEvaluated:
+ status = "evaluated";
+ break;
+ case Module::kErrored:
+ status = "errored";
+ break;
+ }
+
+ result = ArrayList::Add(
+ isolate, result,
+ isolate->factory()->NewStringFromAsciiChecked("[[ModuleStatus]]"),
+ isolate->factory()->NewStringFromAsciiChecked(status));
} else if (IsJSArrayBuffer(*object)) {
DirectHandle<JSArrayBuffer> js_array_buffer = Cast<JSArrayBuffer>(object);
if (js_array_buffer->was_detached()) {
@@ -858,7 +891,7 @@ RUNTIME_FUNCTION(Runtime_DebugCollectWasmCoverage) {
const CoverageScript& script_data = coverage->at(i);
Handle<Script> script = script_data.script;
DCHECK_EQ(script->type(), Script::Type::kWasm);
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const wasm::WasmModule* module = native_module->module();
@@ -977,40 +1010,6 @@ RUNTIME_FUNCTION(Runtime_DebugPromiseThen) {
return *promise;
}
-RUNTIME_FUNCTION(Runtime_LiveEditPatchScript) {
- HandleScope scope(isolate);
- DCHECK_EQ(2, args.length());
- DirectHandle<JSFunction> script_function = args.at<JSFunction>(0);
- Handle<String> new_source = args.at<String>(1);
-
- Handle<Script> script(Cast<Script>(script_function->shared()->script()),
- isolate);
- v8::debug::LiveEditResult result;
- isolate->debug()->SetScriptSource(script, new_source, /* preview */ false,
- /* allow_top_frame_live_editing */ false,
- &result);
- switch (result.status) {
- case v8::debug::LiveEditResult::COMPILE_ERROR:
- return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
- "LiveEdit failed: COMPILE_ERROR"));
- case v8::debug::LiveEditResult::BLOCKED_BY_RUNNING_GENERATOR:
- return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
- "LiveEdit failed: BLOCKED_BY_RUNNING_GENERATOR"));
- case v8::debug::LiveEditResult::BLOCKED_BY_ACTIVE_FUNCTION:
- return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
- "LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION"));
- case v8::debug::LiveEditResult::BLOCKED_BY_TOP_LEVEL_ES_MODULE_CHANGE:
- return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
- "LiveEdit failed: BLOCKED_BY_TOP_LEVEL_ES_MODULE_CHANGE"));
- case v8::debug::LiveEditResult::FEATURE_DISABLED:
- return isolate->Throw(*isolate->factory()->NewStringFromAsciiChecked(
- "LiveEdit failed: FEATURE_DISABLED"));
- case v8::debug::LiveEditResult::OK:
- return ReadOnlyRoots(isolate).undefined_value();
- }
- return ReadOnlyRoots(isolate).undefined_value();
-}
-
RUNTIME_FUNCTION(Runtime_ProfileCreateSnapshotDataBlob) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
diff --git a/deps/v8/src/runtime/runtime-internal.cc b/deps/v8/src/runtime/runtime-internal.cc
index 09d2e8c6038..d11f4cac191 100644
--- a/deps/v8/src/runtime/runtime-internal.cc
+++ b/deps/v8/src/runtime/runtime-internal.cc
@@ -8,6 +8,7 @@
#include "src/builtins/builtins.h"
#include "src/builtins/superspread.h"
#include "src/common/message-template.h"
+#include "src/compiler-dispatcher/optimizing-compile-dispatcher.h"
#include "src/execution/arguments-inl.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/messages.h"
@@ -460,7 +461,8 @@ Tagged<Object> BytecodeBudgetInterruptWithStackCheck(Isolate* isolate,
Tagged<Object> BytecodeBudgetInterrupt(Isolate* isolate, RuntimeArguments& args,
CodeKind code_kind) {
HandleScope scope(isolate);
- DCHECK_EQ(1, args.length());
+ DCHECK(args.length() == 1 ||
+ (code_kind == CodeKind::MAGLEV && args.length() == 2));
DirectHandle<JSFunction> function = args.at<JSFunction>(0);
function->TraceOptimizationStatus("budget from %s",
CodeKindToString(code_kind));
@@ -491,11 +493,36 @@ RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterrupt_Sparkplug) {
}
RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterrupt_Maglev) {
+ DCHECK_EQ(1, args.length());
return BytecodeBudgetInterrupt(isolate, args, CodeKind::MAGLEV);
}
-RUNTIME_FUNCTION(Runtime_BytecodeBudgetInterruptWithStackCheck_Maglev) {
- return BytecodeBudgetInterruptWithStackCheck(isolate, args, CodeKind::MAGLEV);
+RUNTIME_FUNCTION(Runtime_BytecodeBudgetLoopInterrupt_Maglev) {
+ HandleScope scope(isolate);
+ DCHECK_EQ(2, args.length());
+ DirectHandle<JSFunction> function = args.at<JSFunction>(0);
+ BytecodeOffset osr_offset = BytecodeOffset(args.smi_value_at(1));
+
+ // Check for stack interrupts here so that we can fold the interrupt check
+ // into bytecode budget interrupts.
+ StackLimitCheck check(isolate);
+ if (check.JsHasOverflowed()) {
+ return isolate->StackOverflow();
+ } else if (check.InterruptRequested(
+ StackGuard::InterruptLevel::kNoHeapWrites)) {
+ Tagged<Object> return_value = isolate->stack_guard()->HandleInterrupts(
+ StackGuard::InterruptLevel::kNoHeapWrites);
+ if (!IsUndefined(return_value)) {
+ return return_value;
+ }
+ }
+
+ if (!osr_offset.IsNone() && isolate->concurrent_recompilation_enabled() &&
+ isolate->stack_guard()->CheckInstallCode()) {
+ isolate->optimizing_compile_dispatcher()->InstallOptimizedFunctionsIfReady(
+ function, osr_offset);
+ }
+ return BytecodeBudgetInterrupt(isolate, args, CodeKind::MAGLEV);
}
RUNTIME_FUNCTION(Runtime_AllocateInYoungGeneration) {
diff --git a/deps/v8/src/runtime/runtime-literals.cc b/deps/v8/src/runtime/runtime-literals.cc
index 8c0b8a62631..312f5ddcf90 100644
--- a/deps/v8/src/runtime/runtime-literals.cc
+++ b/deps/v8/src/runtime/runtime-literals.cc
@@ -20,6 +20,7 @@
#include "src/objects/literal-objects-inl.h"
#include "src/objects/lookup.h"
#include "src/objects/map-updater.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects.h"
#include "src/objects/property-descriptor-object.h"
#include "src/objects/property-descriptor.h"
diff --git a/deps/v8/src/runtime/runtime-numbers.cc b/deps/v8/src/runtime/runtime-numbers.cc
index d5d18d0addd..fd21434998e 100644
--- a/deps/v8/src/runtime/runtime-numbers.cc
+++ b/deps/v8/src/runtime/runtime-numbers.cc
@@ -5,6 +5,7 @@
#include "src/common/globals.h"
#include "src/execution/arguments-inl.h"
#include "src/execution/isolate-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/roots/roots-inl.h"
#include "src/runtime/runtime-utils.h"
diff --git a/deps/v8/src/runtime/runtime-object.cc b/deps/v8/src/runtime/runtime-object.cc
index 7d01e1171cf..ec2e3e8cf39 100644
--- a/deps/v8/src/runtime/runtime-object.cc
+++ b/deps/v8/src/runtime/runtime-object.cc
@@ -1738,17 +1738,25 @@ RUNTIME_FUNCTION(Runtime_CheckFastIterableToListPrototype) {
isolate);
DCHECK(map->supports_fast_iterable_to_list());
- // The interceptor's prototype must have [Symbol.iterator] property and
- // "length" property accessor.
- DCHECK(IsJSObject(map->prototype()));
+ // The interceptor's prototype must be JSObject with
+ // [Symbol.iterator] data property and "length" property accessor.
+ if (!IsJSObject(map->prototype())) {
+ return ReadOnlyRoots(isolate).false_value();
+ }
DirectHandle<JSObject> prototype(Cast<JSObject>(map->prototype()), isolate);
- // 1. Check if the prototype has expected [Symbol.iterator] property.
+ // Switch prototype to fast mode in order to ensure that constness tracking
+ // will invalidate the prototype's validity cell in case of modification.
+ JSObject::OptimizeAsPrototype(prototype);
+
+ // 1. Check if the prototype has expected [Symbol.iterator] property (kData
+ // and kConst).
{
DirectHandle<Name> iterator_symbol = isolate->factory()->iterator_symbol();
LookupIterator it_iterator(isolate, prototype, iterator_symbol,
LookupIterator::OWN_SKIP_INTERCEPTOR);
- if (it_iterator.state() != LookupIterator::DATA) {
+ if (it_iterator.state() != LookupIterator::DATA ||
+ it_iterator.constness() != PropertyConstness::kConst) {
return ReadOnlyRoots(isolate).false_value();
}
DirectHandle<Object> iterator_val = it_iterator.GetDataValue();
diff --git a/deps/v8/src/runtime/runtime-regexp.cc b/deps/v8/src/runtime/runtime-regexp.cc
index 36382085238..2a1ba0758cb 100644
--- a/deps/v8/src/runtime/runtime-regexp.cc
+++ b/deps/v8/src/runtime/runtime-regexp.cc
@@ -15,6 +15,7 @@
#include "src/numbers/conversions-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-regexp-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/regexp/regexp-utils.h"
#include "src/regexp/regexp.h"
#include "src/strings/string-builder-inl.h"
@@ -840,8 +841,6 @@ StringReplaceGlobalRegExpWithEmptyString(
// freshly allocated page or on an already swept page. Hence, the sweeper
// thread can not get confused with the filler creation. No synchronization
// needed.
- // TODO(hpayer): We should shrink the large object page if the size
- // of the object changed significantly.
if (!HeapLayout::InAnyLargeSpace(*answer)) {
heap->CreateFillerObjectAt(end_of_string, delta);
}
@@ -1251,7 +1250,6 @@ DirectHandle<JSObject> ConstructNamedCaptureGroupsObject(
LookupIterator it(isolate, groups, capture_name, groups,
LookupIterator::OWN_SKIP_INTERCEPTOR);
if (it.IsFound()) {
- DCHECK(v8_flags.js_regexp_duplicate_named_groups);
if (!IsUndefined(*capture_value)) {
DCHECK(IsUndefined(*it.GetDataValue()));
CHECK(Object::SetDataProperty(&it, capture_value).ToChecked());
@@ -1267,6 +1265,49 @@ DirectHandle<JSObject> ConstructNamedCaptureGroupsObject(
return groups;
}
+// Returns a copy of {matches} that shares nothing mutable with it: the array
+// itself, and with named captures also the per-match argument arrays and the
+// groups objects they hold.
+//
+// Callers must use this on both sides of the results cache: a replace callback
+// can retain and mutate the groups object it is given, and the cache stores
+// entries by reference. Copying on entry keeps the cached arrays unreachable
+// from any callback, which is what lets the exit side be a plain clone.
+DirectHandle<FixedArray> CopyMatches(Isolate* isolate,
+ DirectHandle<FixedArray> matches,
+ bool has_named_captures,
+ int capture_count) {
+ DirectHandle<FixedArray> copy = isolate->factory()->CopyFixedArrayWithMap(
+ matches, isolate->factory()->fixed_array_map());
+ if (!has_named_captures) return copy;
+
+ const uint32_t length = copy->ulength().value();
+ for (uint32_t i = 0; i < length; i++) {
+ // Subject slices are encoded as smis; only matches carry captures.
+ if (!IsJSArray(copy->get(i))) continue;
+ DirectHandle<FixedArray> elements(
+ Cast<FixedArray>(Cast<JSArray>(copy->get(i))->elements()), isolate);
+ DirectHandle<FixedArray> new_elements =
+ isolate->factory()->CopyFixedArrayWithMap(
+ elements, isolate->factory()->fixed_array_map());
+ // The groups object is appended last, after match, captures, index and
+ // subject. GetArgcForReplaceCallable counts the match itself as a capture.
+ DCHECK_EQ(new_elements->ulength().value(),
+ GetArgcForReplaceCallable(capture_count + 1, true));
+ const uint32_t groups_index = new_elements->ulength().value() - 1;
+ DCHECK(IsJSObject(new_elements->get(groups_index)));
+ DirectHandle<JSObject> groups(
+ Cast<JSObject>(new_elements->get(groups_index)), isolate);
+ DirectHandle<JSObject> groups_copy =
+ isolate->factory()->CopyJSObject(groups);
+ new_elements->set(groups_index, *groups_copy);
+ DirectHandle<JSArray> new_match =
+ isolate->factory()->NewJSArrayWithElements(new_elements);
+ copy->set(i, *new_match);
+ }
+ return copy;
+}
+
// Only called from Runtime_RegExpExecMultiple so it doesn't need to maintain
// separate last match info. See comment on that function.
template <bool has_capture>
@@ -1296,6 +1337,10 @@ static Tagged<UnionOf<ExceptionHole, Null, FixedArray>> SearchRegExpMultiple(
int capture_count = regexp_data->capture_count();
int subject_length = subject->length();
+ // has_capture can only be true for IrRegExp.
+ DirectHandle<IrRegExpData> re_data;
+ if (has_capture) re_data = TrustedCast<IrRegExpData>(regexp_data);
+
static const int kMinLengthToCache = 0x1000;
if (subject_length > kMinLengthToCache) {
@@ -1312,10 +1357,12 @@ static Tagged<UnionOf<ExceptionHole, Null, FixedArray>> SearchRegExpMultiple(
}
DirectHandle<FixedArray> cached_fixed_array(
Cast<FixedArray>(cached_answer), isolate);
- // The cache FixedArray is a COW-array and we need to return a copy.
- DirectHandle<FixedArray> copied_fixed_array =
- isolate->factory()->CopyFixedArrayWithMap(
- cached_fixed_array, isolate->factory()->fixed_array_map());
+ // The cache FixedArray is a COW-array and we need to return a copy. A
+ // cache hit implies an earlier run compiled the pattern, so the capture
+ // name map is populated.
+ DirectHandle<FixedArray> copied_fixed_array = CopyMatches(
+ isolate, cached_fixed_array,
+ has_capture && re_data->has_capture_name_map(), capture_count);
RegExp::SetLastMatchInfo(isolate, last_match_array, subject,
capture_count, raw_last_match);
return *copied_fixed_array;
@@ -1336,13 +1383,11 @@ static Tagged<UnionOf<ExceptionHole, Null, FixedArray>> SearchRegExpMultiple(
// Two smis before and after the match, for very long strings.
static const uint32_t kMaxBuilderEntriesPerRegExpMatch = 5;
- DirectHandle<IrRegExpData> re_data;
- bool has_named_captures = false;
- // has_capture can only be true for IrRegExp.
- if (has_capture) {
- re_data = TrustedCast<IrRegExpData>(regexp_data);
- has_named_captures = re_data->has_capture_name_map();
- }
+ // The capture name map is populated lazily, so this must stay below the
+ // GlobalExecRunner constructor, which is what compiles the pattern.
+ const bool has_named_captures =
+ has_capture && re_data->has_capture_name_map();
+
while (true) {
int32_t* current_match = runner.FetchNext();
if (current_match == nullptr) break;
@@ -1368,11 +1413,13 @@ static Tagged<UnionOf<ExceptionHole, Null, FixedArray>> SearchRegExpMultiple(
if (has_capture) {
// Arguments array to replace function is match, captures, index and
- // subject, i.e., 3 + capture count in total. If the RegExp contains
- // named captures, they are also passed as the last argument.
-
- const int argc =
- has_named_captures ? 4 + capture_count : 3 + capture_count;
+ // subject. If the RegExp contains named captures, they are also passed
+ // as the last argument. GetArgcForReplaceCallable counts the match
+ // itself as a capture, and cannot overflow here because kMaxCaptures
+ // is well below Code::kMaxArguments.
+ const uint32_t argc =
+ GetArgcForReplaceCallable(capture_count + 1, has_named_captures);
+ DCHECK_NE(argc, static_cast<uint32_t>(-1));
DirectHandle<FixedArray> elements =
isolate->factory()->NewFixedArray(argc);
@@ -1436,10 +1483,11 @@ static Tagged<UnionOf<ExceptionHole, Null, FixedArray>> SearchRegExpMultiple(
DirectHandle<FixedArray> result_fixed_array =
FixedArray::RightTrimOrEmpty(isolate, builder.array(),
builder.length().value());
- // Cache the result and copy the FixedArray into a COW array.
- DirectHandle<FixedArray> copied_fixed_array =
- isolate->factory()->CopyFixedArrayWithMap(
- result_fixed_array, isolate->factory()->fixed_array_map());
+ // Cache the result and copy the FixedArray into a COW array. The copy
+ // must be deep, or the entry would share its groups objects with the
+ // array returned below.
+ DirectHandle<FixedArray> copied_fixed_array = CopyMatches(
+ isolate, result_fixed_array, has_named_captures, capture_count);
regexp::ResultsCache::Enter(
isolate, subject,
direct_handle(regexp->data(isolate)->wrapper(), isolate),
@@ -1763,6 +1811,10 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) {
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, ctor, Object::SpeciesConstructor(isolate, recv, regexp_fun));
+ if (!ctor.is_identical_to(regexp_fun)) {
+ isolate->CountUsage(v8::Isolate::kRegExpCustomSpecies);
+ }
+
DirectHandle<Object> flags_obj;
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
isolate, flags_obj,
@@ -1800,6 +1852,18 @@ RUNTIME_FUNCTION(Runtime_RegExpSplit) {
Execution::New(isolate, ctor, base::VectorOf(ctor_args)));
splitter = Cast<JSReceiver>(splitter_obj);
+
+ if (IsJSRegExp(*splitter)) {
+ JSRegExp::Flags splitter_flags = Cast<JSRegExp>(*splitter)->flags();
+ bool splitter_sticky = (splitter_flags & JSRegExp::kSticky) != 0;
+ bool splitter_unicode =
+ (splitter_flags & (JSRegExp::kUnicode | JSRegExp::kUnicodeSets)) != 0;
+ if (!splitter_sticky || splitter_unicode != unicode) {
+ isolate->CountUsage(v8::Isolate::kRegExpMatcherFlagsMismatch);
+ }
+ } else {
+ isolate->CountUsage(v8::Isolate::kRegExpMatcherFlagsMismatch);
+ }
}
uint32_t limit;
diff --git a/deps/v8/src/runtime/runtime-scopes.cc b/deps/v8/src/runtime/runtime-scopes.cc
index fe8a3edf528..f1accd94f3e 100644
--- a/deps/v8/src/runtime/runtime-scopes.cc
+++ b/deps/v8/src/runtime/runtime-scopes.cc
@@ -222,10 +222,7 @@ RUNTIME_FUNCTION(Runtime_DeclareGlobals) {
// Compute the property attributes. According to ECMA-262,
// the property must be non-configurable except in eval.
Tagged<Script> script = Cast<Script>(closure->shared()->script());
- PropertyAttributes attr =
- script->compilation_type() == Script::CompilationType::kEval
- ? NONE
- : DONT_DELETE;
+ PropertyAttributes attr = script->is_eval() ? NONE : DONT_DELETE;
// https://tc39.es/ecma262/#sec-globaldeclarationinstantiation 5.d:
// If hasRestrictedGlobal is true, throw a SyntaxError exception.
@@ -554,7 +551,7 @@ DirectHandle<JSObject> NewSloppyArguments(Isolate* isolate,
CHECK(!IsDerivedConstructor(callee->shared()->kind()));
CHECK(callee->shared()->has_simple_parameters());
DirectHandle<JSObject> result =
- isolate->factory()->NewArgumentsObject(callee, argument_count);
+ isolate->factory()->NewSloppyArgumentsObject(callee, argument_count);
// Allocate the elements if needed.
const uint32_t parameter_count =
@@ -573,8 +570,10 @@ DirectHandle<JSObject> NewSloppyArguments(Isolate* isolate,
isolate->factory()->NewSloppyArgumentsElements(
mapped_count, context, arguments, AllocationType::kYoung);
- result->set_map(isolate,
- isolate->native_context()->fast_aliased_arguments_map());
+ Tagged<Map> aliased_map =
+ isolate->native_context()->fast_aliased_arguments_map();
+ CHECK_EQ(aliased_map->instance_size(), result->map()->instance_size());
+ result->set_map(isolate, aliased_map);
result->set_elements(*parameter_map);
// Loop over the actual parameters backwards.
diff --git a/deps/v8/src/runtime/runtime-test-wasm.cc b/deps/v8/src/runtime/runtime-test-wasm.cc
index 7c2fad6d899..1c55008f80d 100644
--- a/deps/v8/src/runtime/runtime-test-wasm.cc
+++ b/deps/v8/src/runtime/runtime-test-wasm.cc
@@ -375,7 +375,7 @@ RUNTIME_FUNCTION(Runtime_IsWasmTrapHandlerEnabled) {
RUNTIME_FUNCTION(Runtime_IsWasmPartialOOBWriteNoop) {
SealHandleScope shs(isolate);
DisallowGarbageCollection no_gc;
- return isolate->heap()->ToBoolean(wasm::kPartialOOBWritesAreNoops);
+ return isolate->heap()->ToBoolean(v8_flags.wasm_partial_oob_writes_are_noops);
}
RUNTIME_FUNCTION(Runtime_GenerateWasmCompilationHints) {
@@ -538,7 +538,9 @@ RUNTIME_FUNCTION(Runtime_GetWasmExceptionValues) {
isolate->factory()->NewFixedArray(values_len);
for (uint32_t i = 0; i < values_len; i++) {
DirectHandle<Object> value(values->get(i), isolate);
- if (!IsSmi(*value)) {
+ if (IsWasmNull(*value)) {
+ value = isolate->factory()->null_value();
+ } else if (!IsSmi(*value)) {
// When fuzzers use this function, don't leak anything that the JS side
// can't handle.
if (IsByteArray(*value) || // Probably a stringview_wtf8.
@@ -797,7 +799,7 @@ static Tagged<Object> CreateWasmObject(Isolate* isolate,
DCHECK(isolate->has_exception());
return ReadOnlyRoots(isolate).exception();
}
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const wasm::WasmModule* module = native_module->module();
wasm::WasmValue value(int64_t{0x7AADF00DBAADF00D});
@@ -807,12 +809,12 @@ static Tagged<Object> CreateWasmObject(Isolate* isolate,
type_index.index));
if (is_struct) {
const wasm::StructType* struct_type = module->struct_type(type_index);
- DCHECK_EQ(struct_type->field_count(), 1);
- DCHECK_EQ(struct_type->field(0), wasm::kWasmI64);
+ SBXCHECK_EQ(struct_type->field_count(), 1);
+ SBXCHECK_EQ(struct_type->field(0), wasm::kWasmI64);
return *isolate->factory()->NewWasmStruct(struct_type, &value,
direct_handle(map, isolate));
} else {
- DCHECK_EQ(module->array_type(type_index)->element_type(), wasm::kWasmI64);
+ SBXCHECK_EQ(module->array_type(type_index)->element_type(), wasm::kWasmI64);
return *isolate->factory()->NewWasmArray(
wasm::kWasmI64, 1, value, direct_handle(map, isolate),
AllocationType::kYoung, SKIP_WRITE_BARRIER);
@@ -1006,10 +1008,9 @@ RUNTIME_FUNCTION(Runtime_WasmTriggerCodeGC) {
}
RUNTIME_FUNCTION(Runtime_EstimateCurrentMemoryConsumption) {
- SealHandleScope shs(isolate);
- DisallowGarbageCollection no_gc;
+ HandleScope shs(isolate);
size_t result = wasm::GetWasmEngine()->EstimateCurrentMemoryConsumption();
- return Smi::FromInt(static_cast<int>(result));
+ return *isolate->factory()->NewNumberFromSize(result);
}
RUNTIME_FUNCTION(Runtime_WasmCompiledExportWrappersCount) {
diff --git a/deps/v8/src/runtime/runtime-test.cc b/deps/v8/src/runtime/runtime-test.cc
index 611ba424608..d0d013c6fed 100644
--- a/deps/v8/src/runtime/runtime-test.cc
+++ b/deps/v8/src/runtime/runtime-test.cc
@@ -37,6 +37,7 @@
#include "src/objects/abstract-code-inl.h"
#include "src/objects/bytecode-array.h"
#include "src/objects/js-collection-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/profiler/heap-profiler.h"
#include "src/sandbox/bytecode-verifier.h"
#include "src/utils/utils.h"
@@ -99,8 +100,7 @@ V8_WARN_UNUSED_RESULT bool CheckMarkedForManualOptimization(
PrintF(
" should be prepared for optimization with "
"%%PrepareFunctionForOptimization before "
- "%%OptimizeFunctionOnNextCall / %%OptimizeMaglevOnNextCall / "
- "%%OptimizeOsr ");
+ "%%OptimizeFunctionOnNextCall / %%OptimizeMaglevOnNextCall");
return false;
}
return true;
@@ -254,7 +254,8 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeFunction) {
}
if (function->HasAttachedOptimizedCode(isolate)) {
- Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting);
+ Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting,
+ function->code(isolate));
}
return ReadOnlyRoots(isolate).undefined_value();
@@ -271,7 +272,8 @@ RUNTIME_FUNCTION(Runtime_DeoptimizeNow) {
CHECK_UNLESS_FUZZING(!function.is_null());
if (function->HasAttachedOptimizedCode(isolate)) {
- Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting);
+ Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting,
+ function->code(isolate));
}
return ReadOnlyRoots(isolate).undefined_value();
@@ -742,10 +744,15 @@ RUNTIME_FUNCTION(Runtime_OptimizeOsr) {
CHECK_UNLESS_FUZZING(!function->shared()->all_optimization_disabled());
- // If we're fuzzing, allow having not marked the function for manual
- // optimization (if the steps below succeed).
- if (!v8_flags.fuzzing) {
- CHECK(CheckMarkedForManualOptimization(isolate, *function));
+ if (!v8_flags.fuzzing &&
+ !ManualOptimizationTable::IsMarkedForManualOptimization(isolate,
+ *function)) {
+ PrintF("Warning: Function ");
+ ShortPrint(*function);
+ PrintF(
+ " might have to be prepared for optimization with "
+ "%%PrepareFunctionForOptimization before "
+ "%%OptimizeOsr");
}
if (function->HasAvailableOptimizedCode(isolate) &&
@@ -911,7 +918,8 @@ RUNTIME_FUNCTION(Runtime_GetOptimizationStatus) {
if (!isolate->use_optimizer()) {
status |= static_cast<int>(OptimizationStatus::kNeverOptimize);
}
- if (v8_flags.deopt_every_n_times) {
+ if (v8_flags.deopt_every_n_times || v8_flags.stress_flush_code ||
+ v8_flags.gc_interval > 0 || v8_flags.random_gc_interval > 0) {
status |= static_cast<int>(OptimizationStatus::kMaybeDeopted);
}
if (v8_flags.optimize_on_next_call_optimizes_to_maglev) {
@@ -1294,7 +1302,7 @@ static void DebugPrintImpl(Tagged<MaybeObject> maybe_object, std::ostream& os) {
os << "DebugPrint: ";
if (weak) os << "[weak] ";
Print(object, os);
- if (IsHeapObject(object)) {
+ if (IsHeapObject(object) && !IsInaccessible(Cast<HeapObject>(object))) {
Print(Cast<HeapObject>(object)->map(), os);
}
#else
@@ -1850,6 +1858,25 @@ RUNTIME_FUNCTION(Runtime_RegexpHasNativeCode) {
return isolate->heap()->ToBoolean(result);
}
+// Returns true iff the regexp cannot match a string starting with |c|,
+// according to the quick-check filters. Lets tests assert that a filter was
+// actually built, which exec results alone cannot show.
+RUNTIME_FUNCTION(Runtime_RegexpQuickCheckRejects) {
+ SealHandleScope shs(isolate);
+ CHECK_UNLESS_FUZZING(args.length() == 2);
+ CHECK_UNLESS_FUZZING(IsJSRegExp(args[0]));
+ CHECK_UNLESS_FUZZING(IsString(args[1]));
+ auto regexp = args.at<JSRegExp>(0);
+ auto string = args.at<String>(1);
+ CHECK_UNLESS_FUZZING(string->length() == 1);
+ if (!regexp->has_data()) return ReadOnlyRoots(isolate).false_value();
+ DisallowGarbageCollection no_gc;
+ String::FlatContent content = string->GetFlatContent(no_gc);
+ if (!content.IsOneByte()) return ReadOnlyRoots(isolate).false_value();
+ return isolate->heap()->ToBoolean(
+ regexp->data(isolate)->QuickCheckRejects(content.ToOneByteVector(), 0));
+}
+
RUNTIME_FUNCTION(Runtime_RegexpTypeTag) {
HandleScope shs(isolate);
CHECK_UNLESS_FUZZING(args.length() == 1);
@@ -2439,6 +2466,12 @@ RUNTIME_FUNCTION(Runtime_GetFeedback) {
feedback_value.slot_kind_ = out.str();
out << ":" << it.GetEmbeddedOperationHint<BinaryOperationFeedback>();
feedback_value.details_ = out.str();
+ } else if (interpreter::Bytecodes::IsUnaryOpWithEmbeddedFeedback(
+ bytecode)) {
+ out << "UnaryOp";
+ feedback_value.slot_kind_ = out.str();
+ out << ":" << it.GetEmbeddedOperationHint<BinaryOperationFeedback>();
+ feedback_value.details_ = out.str();
} else {
UNREACHABLE();
}
@@ -2836,7 +2869,8 @@ RUNTIME_FUNCTION(Runtime_InstallBytecode) {
shared->set_bytecode_array(*new_bytecode);
if (function->HasAttachedOptimizedCode(isolate)) {
- Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting);
+ Deoptimizer::DeoptimizeFunction(*function, LazyDeoptimizeReason::kTesting,
+ function->code(isolate));
}
function->UpdateCode(isolate,
*BUILTIN_CODE(isolate, InterpreterEntryTrampoline));
diff --git a/deps/v8/src/runtime/runtime-wasm.cc b/deps/v8/src/runtime/runtime-wasm.cc
index 77aa9fd7da6..cf497cb2c54 100644
--- a/deps/v8/src/runtime/runtime-wasm.cc
+++ b/deps/v8/src/runtime/runtime-wasm.cc
@@ -22,6 +22,7 @@
#include "src/objects/js-promise-inl.h"
#include "src/objects/lookup-inl.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/object-list-macros.h"
#include "src/objects/objects-inl.h"
#include "src/objects/property-descriptor.h"
@@ -726,7 +727,7 @@ RUNTIME_FUNCTION(Runtime_WasmI32AtomicWait) {
int32_t expected_value = NumberToInt32(args[3]);
Tagged<BigInt> timeout_ns = Cast<BigInt>(args[4]);
- Managed<BackingStore>::Ptr backing_store =
+ CppGCManaged<BackingStore>::Ptr backing_store =
trusted_instance_data->memory_object(memory_index)->backing_store();
// Should have trapped if address was OOB.
DCHECK_LT(offset, backing_store->byte_length());
@@ -752,7 +753,7 @@ RUNTIME_FUNCTION(Runtime_WasmI64AtomicWait) {
Tagged<BigInt> expected_value = Cast<BigInt>(args[3]);
Tagged<BigInt> timeout_ns = Cast<BigInt>(args[4]);
- Managed<BackingStore>::Ptr backing_store =
+ CppGCManaged<BackingStore>::Ptr backing_store =
trusted_instance_data->memory_object(memory_index)->backing_store();
// Should have trapped if address was OOB.
DCHECK_LT(offset, backing_store->byte_length());
@@ -799,6 +800,7 @@ RUNTIME_FUNCTION(Runtime_WasmWaitqueueNew) {
HandleScope scope(isolate);
DCHECK_EQ(0, args.length());
+ // Memory fence is implemented in Managed<>::From.
auto ptr = std::make_shared<FutexManagedObjectWaitList>();
DirectHandle<Managed<FutexManagedObjectWaitList>> managed =
Managed<FutexManagedObjectWaitList>::From(
@@ -1734,8 +1736,7 @@ class PrototypesSetup : public wasm::Decoder {
return {};
}
// TODO(jkummerow): Can we tighten the spec to require non-nullable arrays?
- if (!IsWasmFuncRef(*maybe_func)) {
- DCHECK(IsWasmNull(*maybe_func));
+ if (IsWasmNull(*maybe_func)) {
ThrowWasmError(isolate_, MessageTemplate::kWasmTrapNullFunc);
return {};
}
@@ -2290,16 +2291,11 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf8) {
Tagged<WasmTrustedInstanceData> trusted_instance_data =
TrustedCast<WasmTrustedInstanceData>(args[0]);
uint32_t memory = args.positive_smi_value_at(1);
- uint32_t utf8_variant_value = args.positive_smi_value_at(2);
+ UnicodeConfig config(args.positive_smi_value_at(2));
double offset_double = args.number_value_at(3);
uintptr_t offset = static_cast<uintptr_t>(offset_double);
uint32_t size = NumberToUint32(args[4]);
- DCHECK(utf8_variant_value <=
- static_cast<uint32_t>(unibrow::Utf8Variant::kLastUtf8Variant));
-
- auto utf8_variant = static_cast<unibrow::Utf8Variant>(utf8_variant_value);
-
uint64_t mem_size = trusted_instance_data->memory_size(memory);
if (!base::IsInBounds<uint64_t>(offset, size, mem_size)) {
return ThrowWasmError(isolate, MessageTemplate::kWasmTrapMemOutOfBounds);
@@ -2308,8 +2304,8 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf8) {
const base::Vector<const uint8_t> bytes{
trusted_instance_data->memory_base(memory) + offset, size};
MaybeDirectHandle<v8::internal::String> result_string =
- isolate->factory()->NewStringFromUtf8(bytes, utf8_variant);
- if (utf8_variant == unibrow::Utf8Variant::kUtf8NoTrap) {
+ isolate->factory()->NewStringFromUtf8(bytes, config);
+ if (config.variant() == unibrow::Utf8Variant::kUtf8NoTrap) {
// If the input was invalid, then the decoder has failed silently, and
// the string.new_utf8_try instruction should return null.
if (result_string.is_null() && !isolate->has_exception()) {
@@ -2322,24 +2318,16 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf8) {
}
RUNTIME_FUNCTION(Runtime_WasmStringNewWtf8Array) {
- DCHECK_EQ(5, args.length());
+ DCHECK_EQ(4, args.length());
HandleScope scope(isolate);
- uint32_t utf8_variant_value = args.positive_smi_value_at(0);
+ UnicodeConfig config(args.positive_smi_value_at(0));
DirectHandle<WasmArray> array(Cast<WasmArray>(args[1]), isolate);
uint32_t start = NumberToUint32(args[2]);
uint32_t end = NumberToUint32(args[3]);
- int shared = args.smi_value_at(4);
-
- DCHECK(utf8_variant_value <=
- static_cast<uint32_t>(unibrow::Utf8Variant::kLastUtf8Variant));
- auto utf8_variant = static_cast<unibrow::Utf8Variant>(utf8_variant_value);
MaybeDirectHandle<v8::internal::String> result_string =
- shared ? isolate->factory()->NewSharedStringFromUtf8(array, start, end,
- utf8_variant)
- : isolate->factory()->NewStringFromUtf8(array, start, end,
- utf8_variant);
- if (utf8_variant == unibrow::Utf8Variant::kUtf8NoTrap) {
+ isolate->factory()->NewStringFromUtf8(array, start, end, config);
+ if (config.variant() == unibrow::Utf8Variant::kUtf8NoTrap) {
// If the input was invalid, then the decoder has failed silently, and
// the string.new_utf8_array_try instruction should return null.
if (result_string.is_null() && !isolate->has_exception()) {
@@ -2352,7 +2340,7 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf8Array) {
}
RUNTIME_FUNCTION(Runtime_WasmStringNewWtf16) {
- DCHECK_EQ(4, args.length());
+ DCHECK_EQ(5, args.length());
HandleScope scope(isolate);
Tagged<WasmTrustedInstanceData> trusted_instance_data =
TrustedCast<WasmTrustedInstanceData>(args[0]);
@@ -2360,6 +2348,7 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf16) {
double offset_double = args.number_value_at(2);
uintptr_t offset = static_cast<uintptr_t>(offset_double);
uint32_t size_in_codeunits = NumberToUint32(args[3]);
+ UnicodeConfig config(args.positive_smi_value_at(4));
uint64_t mem_size = trusted_instance_data->memory_size(memory);
if (size_in_codeunits > kMaxUInt32 / 2 ||
@@ -2373,7 +2362,7 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf16) {
const uint8_t* bytes = trusted_instance_data->memory_base(memory) + offset;
const base::uc16* codeunits = reinterpret_cast<const base::uc16*>(bytes);
RETURN_RESULT_OR_TRAP(isolate->factory()->NewStringFromTwoByteLittleEndian(
- {codeunits, size_in_codeunits}));
+ {codeunits, size_in_codeunits}, config));
}
RUNTIME_FUNCTION(Runtime_WasmStringNewWtf16Array) {
@@ -2382,11 +2371,10 @@ RUNTIME_FUNCTION(Runtime_WasmStringNewWtf16Array) {
DirectHandle<WasmArray> array(Cast<WasmArray>(args[0]), isolate);
uint32_t start = NumberToUint32(args[1]);
uint32_t end = NumberToUint32(args[2]);
- int shared = args.number_value_at(3);
+ UnicodeConfig config(args.positive_smi_value_at(3));
RETURN_RESULT_OR_TRAP(
- shared ? isolate->factory()->NewSharedStringFromUtf16(array, start, end)
- : isolate->factory()->NewStringFromUtf16(array, start, end));
+ isolate->factory()->NewStringFromUtf16(array, start, end, config));
}
RUNTIME_FUNCTION(Runtime_WasmSubstring) {
@@ -2680,6 +2668,10 @@ RUNTIME_FUNCTION(Runtime_WasmStringToUtf8Array) {
DirectHandle<String> string(Cast<String>(args[0]), isolate);
int32_t shared = args.smi_value_at(1);
uint32_t length = MeasureWtf8(isolate, string);
+ constexpr int kElemSize = wasm::kWasmI8.value_kind_size();
+ if (length > static_cast<uint32_t>(WasmArray::MaxLength(kElemSize))) {
+ return ThrowWasmError(isolate, MessageTemplate::kWasmTrapArrayTooLarge);
+ }
wasm::WasmValue initial_value(int8_t{0});
Tagged<WeakFixedArray> rtts = isolate->heap()->wasm_canonical_rtts();
// This function can only get called from Wasm code, so we can safely assume
@@ -2974,15 +2966,16 @@ RUNTIME_FUNCTION(Runtime_WasmAllocateContinuation) {
stack->jmpbuf()->pc = wrapper->code()->instruction_start();
trusted_instance_data->native_module()->RegisterStackEntryWrapper(
std::move(wrapper));
- stack->set_func_ref(*func_ref);
stack->set_param_types(sig->parameters());
stack->set_signature_id(sig->index());
- wasm::StackMemory* stack_ptr = stack.get();
- isolate->wasm_stacks().emplace_back(std::move(stack));
DirectHandle<WasmContinuationObject> cont =
isolate->factory()->NewWasmContinuationObject(stack_obj);
- stack_ptr->set_current_continuation(*cont);
- stack_ptr->set_stack_obj(*stack_obj);
+ // Set the references after the heap allocation, so that they are not
+ // immediately stale from a potential GC.
+ stack->set_func_ref(*func_ref);
+ stack->set_current_continuation(*cont);
+ stack->set_stack_obj(*stack_obj);
+ isolate->wasm_stacks().emplace_back(std::move(stack));
return *cont;
}
diff --git a/deps/v8/src/runtime/runtime.h b/deps/v8/src/runtime/runtime.h
index 397d57057bc..9d06fcb2f82 100644
--- a/deps/v8/src/runtime/runtime.h
+++ b/deps/v8/src/runtime/runtime.h
@@ -141,7 +141,9 @@ constexpr bool CanTriggerGC(T... properties) {
IF_SPARKPLUG_PLUS(F, PatchCompareOpBaselineCode, 4, 1) \
IF_SPARKPLUG_PLUS(F, PatchCompareOpBaselineCodeAndThrow, 4, 1) \
IF_SPARKPLUG_PLUS(F, PatchBinopBaselineCode, 4, 1) \
- IF_SPARKPLUG_PLUS(F, PatchBinopBaselineCodeAndThrow, 4, 1)
+ IF_SPARKPLUG_PLUS(F, PatchBinopBaselineCodeAndThrow, 4, 1) \
+ IF_SPARKPLUG_PLUS(F, PatchUnaryOpBaselineCode, 4, 1) \
+ IF_SPARKPLUG_PLUS(F, PatchUnaryOpBaselineCodeAndThrow, 4, 1)
// TODO(olivf): Unify the Maglev/TF variants into one runtime function and pass
// the optimization tier as an argument.
@@ -151,7 +153,7 @@ constexpr bool CanTriggerGC(T... properties) {
F(StartMaglevOptimizeJob, 1, 1) \
F(OptimizeTurbofanEager, 1, 1) \
F(StartTurbofanOptimizeJob, 1, 1) \
- F(MarkLazyDeoptimized, 2, 1)
+ F(MarkLazyDeoptimizedOrFlushed, 2, 1)
#define FOR_EACH_INTRINSIC_COMPILER(F, I) \
FOR_EACH_INTRINSIC_COMPILER_GENERIC(F, I) \
@@ -179,7 +181,6 @@ constexpr bool CanTriggerGC(T... properties) {
F(HandleDebuggerStatement, 0, 1) \
F(IsBreakOnException, 1, 1) \
F(IterableForEach, 2, 1) \
- F(LiveEditPatchScript, 2, 1) \
F(ProfileCreateSnapshotDataBlob, 0, 1) \
F(ScheduleBreak, 0, 1) \
F(ScriptLocationFromLine2, 4, 1) \
@@ -300,7 +301,7 @@ constexpr bool CanTriggerGC(T... properties) {
F(BytecodeBudgetInterrupt_Sparkplug, 1, 1) \
F(BytecodeBudgetInterruptWithStackCheck_Sparkplug, 1, 1) \
F(BytecodeBudgetInterrupt_Maglev, 1, 1) \
- F(BytecodeBudgetInterruptWithStackCheck_Maglev, 1, 1) \
+ F(BytecodeBudgetLoopInterrupt_Maglev, 2, 1) \
F(NotifyContextCellStateWillChange, 1, 1, \
RuntimeCallProperty::kCannotTriggerGC) \
F(NewError, 2, 1) \
@@ -669,6 +670,7 @@ constexpr bool CanTriggerGC(T... properties) {
F(RegexpHasBytecode, 2, 1) \
F(RegexpHasNativeCode, 2, 1) \
F(RegexpIsUnmodified, 1, 1) \
+ F(RegexpQuickCheckRejects, 2, 1) \
F(RegexpTypeTag, 1, 1) \
F(Resume, 1, 1) \
F(RunningInSimulator, 0, 1) \
@@ -763,12 +765,12 @@ constexpr bool CanTriggerGC(T... properties) {
F(WasmSuspended, 2, 1) \
F(WasmAllocateContinuation, 3, 1) \
F(ClearWasmSuspenderResumeField, 1, 1) \
- F(WasmCastToSpecialPrimitiveArray, 2, 1) \
+ F(WasmCastToSpecialPrimitiveArray, 3, 1) \
F(WasmStringAdd_NoMapCheck_Shared, 2, 1) \
F(WasmStringNewSegmentWtf8, 5, 1) \
F(WasmStringNewWtf8, 5, 1) \
- F(WasmStringNewWtf8Array, 5, 1) \
- F(WasmStringNewWtf16, 4, 1) \
+ F(WasmStringNewWtf8Array, 4, 1) \
+ F(WasmStringNewWtf16, 5, 1) \
F(WasmStringNewWtf16Array, 4, 1) \
F(WasmStringConst, 2, 1) \
F(WasmStringMeasureUtf8, 1, 1) \
@@ -776,7 +778,7 @@ constexpr bool CanTriggerGC(T... properties) {
F(WasmStringEncodeWtf8, 5, 1) \
F(WasmStringEncodeWtf16, 6, 1) \
F(WasmStringEncodeWtf8Array, 4, 1) \
- F(WasmStringToUtf8Array, 1, 1) \
+ F(WasmStringToUtf8Array, 2, 1) \
F(WasmStringAsWtf8, 1, 1) \
F(WasmStringViewWtf8Encode, 7, 1) \
F(WasmStringViewWtf8Slice, 3, 1) \
@@ -870,7 +872,7 @@ constexpr bool CanTriggerGC(T... properties) {
F(StoreGlobalIC_Slow, 5, 1) \
F(StoreIC_Miss, 5, 1) \
F(DefineNamedOwnIC_Miss, 5, 1) \
- F(StoreInArrayLiteralIC_Slow, 5, 1) \
+ F(StoreInArrayLiteralIC_Slow, 3, 1) \
F(StorePropertyPastInterceptor, 4, 1) \
F(CloneObjectIC_Slow, 2, 1) \
F(CloneObjectIC_Miss, 4, 1) \
diff --git a/deps/v8/src/sandbox/OWNERS b/deps/v8/src/sandbox/OWNERS
index 35e48ffffb1..1436c7e1eb9 100644
--- a/deps/v8/src/sandbox/OWNERS
+++ b/deps/v8/src/sandbox/OWNERS
@@ -1,5 +1,6 @@
ishell@chromium.org
mlippautz@chromium.org
+omerkatz@chromium.org
saelo@chromium.org
verwaest@chromium.org
sroettger@google.com
diff --git a/deps/v8/src/sandbox/bytecode-verifier.cc b/deps/v8/src/sandbox/bytecode-verifier.cc
index 7b002792ac5..7933722bae5 100644
--- a/deps/v8/src/sandbox/bytecode-verifier.cc
+++ b/deps/v8/src/sandbox/bytecode-verifier.cc
@@ -279,15 +279,28 @@ bool BytecodeVerifier::IsAllowedRuntimeFunction(Runtime::FunctionId id) {
case Runtime::kLoadLookupSlotForCall_Baseline:
case Runtime::kBytecodeBudgetInterruptWithStackCheck_Sparkplug:
case Runtime::kBytecodeBudgetInterrupt_Sparkplug:
- case Runtime::kBytecodeBudgetInterruptWithStackCheck_Maglev:
case Runtime::kBytecodeBudgetInterrupt_Maglev:
+ case Runtime::kBytecodeBudgetLoopInterrupt_Maglev:
case Runtime::kPatchLoadICUninitializedBaseline:
case Runtime::kLoadIC_Miss_FromBaseline:
+ case Runtime::kInstallBaselineCode:
+ case Runtime::kSwissTableAdd:
+ case Runtime::kSwissTableAllocate:
+ case Runtime::kSwissTableDelete:
+ case Runtime::kSwissTableDetailsAt:
+ case Runtime::kSwissTableElementsCount:
+ case Runtime::kSwissTableEquals:
+ case Runtime::kSwissTableFindEntry:
+ case Runtime::kSwissTableUpdate:
+ case Runtime::kSwissTableValueAt:
+ case Runtime::kSwissTableKeyAt:
#if V8_ENABLE_SPARKPLUG_PLUS
case Runtime::kPatchCompareOpBaselineCode:
case Runtime::kPatchCompareOpBaselineCodeAndThrow:
case Runtime::kPatchBinopBaselineCode:
case Runtime::kPatchBinopBaselineCodeAndThrow:
+ case Runtime::kPatchUnaryOpBaselineCode:
+ case Runtime::kPatchUnaryOpBaselineCodeAndThrow:
#endif // V8_ENABLE_SPARKPLUG_PLUS
return false;
#if V8_ENABLE_WEBASSEMBLY
diff --git a/deps/v8/src/sandbox/cppheap-pointer-table-inl.h b/deps/v8/src/sandbox/cppheap-pointer-table-inl.h
index fa7377c083f..d1a445d3d84 100644
--- a/deps/v8/src/sandbox/cppheap-pointer-table-inl.h
+++ b/deps/v8/src/sandbox/cppheap-pointer-table-inl.h
@@ -107,6 +107,11 @@ bool CppHeapPointerTableEntry::HasEvacuationEntry() const {
return payload.ContainsEvacuationEntry();
}
+void CppHeapPointerTableEntry::CopyFrom(const CppHeapPointerTableEntry& other) {
+ auto payload = other.payload_.load(std::memory_order_relaxed);
+ payload_.store(payload, std::memory_order_relaxed);
+}
+
void CppHeapPointerTableEntry::Evacuate(CppHeapPointerTableEntry& dest,
EvacuateMarkMode mode) {
auto payload = payload_.load(std::memory_order_relaxed);
@@ -146,6 +151,17 @@ CppHeapPointerHandle CppHeapPointerTable::AllocateAndInitializeEntry(
return handle;
}
+CppHeapPointerHandle CppHeapPointerTable::DuplicateEntry(
+ Space* space, CppHeapPointerHandle handle) {
+ DCHECK_NE(handle, kNullCppHeapPointerHandle);
+ uint32_t old_index = HandleToIndex(handle);
+ uint32_t new_index = AllocateEntry(space);
+ if (new_index == 0) return kNullCppHeapPointerHandle;
+
+ at(new_index).CopyFrom(at(old_index));
+ return IndexToHandle(new_index);
+}
+
void CppHeapPointerTable::Mark(Space* space, CppHeapPointerHandle handle,
Address handle_location) {
DCHECK(space->BelongsTo(this));
diff --git a/deps/v8/src/sandbox/cppheap-pointer-table.h b/deps/v8/src/sandbox/cppheap-pointer-table.h
index 80c9a9e1867..fda7cea52bc 100644
--- a/deps/v8/src/sandbox/cppheap-pointer-table.h
+++ b/deps/v8/src/sandbox/cppheap-pointer-table.h
@@ -76,6 +76,9 @@ struct CppHeapPointerTableEntry {
// Returns true if this entry contains an evacuation entry.
inline bool HasEvacuationEntry() const;
+ // Copy the content of the provided entry into this entry.
+ inline void CopyFrom(const CppHeapPointerTableEntry& other);
+
// Move the content of this entry into the provided entry, possibly clearing
// the marking bit. Used during table compaction and during promotion.
// Invalidates the source entry.
@@ -192,6 +195,12 @@ class V8_EXPORT_PRIVATE CppHeapPointerTable
Address initial_value,
CppHeapPointerTag tag);
+ // Duplicates an entry, returning a handle to the new entry.
+ //
+ // This method is atomic and can be called from background threads.
+ inline CppHeapPointerHandle DuplicateEntry(Space* space,
+ CppHeapPointerHandle handle);
+
// Marks the specified entry as alive.
//
// If the space to which the entry belongs is currently being compacted, this
diff --git a/deps/v8/src/sandbox/external-entity-table-inl.h b/deps/v8/src/sandbox/external-entity-table-inl.h
index 53e3edbd6b8..c6c04759721 100644
--- a/deps/v8/src/sandbox/external-entity-table-inl.h
+++ b/deps/v8/src/sandbox/external-entity-table-inl.h
@@ -12,8 +12,8 @@
#include "src/base/emulated-virtual-address-subspace.h"
#include "src/base/iterator.h"
#include "src/common/assert-scope.h"
-#include "src/common/segmented-table-inl.h"
#include "src/sandbox/external-pointer-table.h"
+#include "src/sandbox/segmented-table-inl.h"
#include "src/utils/allocation.h"
namespace v8 {
@@ -47,46 +47,13 @@ bool ExternalEntityTable<Entry, size>::Space::Contains(uint32_t index) {
template <typename Entry, size_t size>
void ExternalEntityTable<Entry, size>::Initialize() {
- Base::Initialize();
-
- if (!ExternalEntityTable::kUseContiguousMemory) return;
-
- // Allocate the read-only segments of the table. These segments are always
- // located at offset 0. The first segment contains the null entry (pointing at
- // kNullAddress) at index 0. Initially we allocate these segments with
- // kNoAccess, which is converted to kRead on Extend. It may later be
- // temporarily marked read-write, see UnsealedReadOnlySegmentScope. The first
- // segment is already initialized at kRead such that the null handle can be
- // dereferenced during initialization.
- static_assert(kEndOfReadOnlyIndex * sizeof(Entry) ==
- kSegmentSize * kNumReadOnlySegments);
- Address first_segment = this->vas_->AllocatePages(
- this->vas_->base(), kSegmentSize * kNumReadOnlySegments, Base::kAlignment,
- PagePermissions::kRead);
- if (first_segment != this->vas_->base()) {
- V8::FatalProcessOutOfMemory(
- nullptr,
- "ExternalEntityTable::InitializeTable (r/o segments allocation)");
- }
-
- DCHECK_EQ(first_segment - this->vas_->base(),
- kInternalReadOnlySegmentsOffset);
-
- if constexpr (Base::kUseSegmentPool) {
- Base::FillSegmentsPool(false);
- }
+ Base::Initialize(size, kSegmentSize * kNumReadOnlySegments,
+ Entry::IsWriteProtected);
}
template <typename Entry, size_t size>
void ExternalEntityTable<Entry, size>::TearDown() {
DCHECK(this->is_initialized());
-
- if (ExternalEntityTable::kUseContiguousMemory) {
- // Deallocate the (read-only) first segment.
- this->vas_->FreePages(this->vas_->base(),
- kSegmentSize * kNumReadOnlySegments);
- }
-
Base::TearDown();
}
@@ -131,7 +98,7 @@ void ExternalEntityTable<Entry, size>::AttachSpaceToReadOnlySegments(
// For the internal read-only segment, index 0 is reserved for the `null`
// entry. This call also ensures that the first segment is initialized.
{
- UnsealReadOnlySegmentScope writable(this);
+ SegmentedTableBase::UnsealReadOnlySegmentScope writable(this);
uint32_t null_entry = AllocateEntry(space);
CHECK_EQ(null_entry, kInternalNullEntryIndex);
ZeroInternalNullEntry();
@@ -146,31 +113,12 @@ void ExternalEntityTable<Entry, size>::DetachSpaceFromReadOnlySegments(
// Remove the RO segment from the space's segment list without freeing it.
// The table itself manages the RO segment's lifecycle.
base::MutexGuard guard(&space->mutex_);
- DCHECK_EQ(space->segments_.size(), this->read_only_segments_used_);
- this->read_only_segments_used_ = 0;
+ const uint32_t segments_used = this->ResetReadOnlySegments();
+ DCHECK_EQ(space->segments_.size(), segments_used);
+ USE(segments_used);
space->segments_.clear();
}
-template <typename Entry, size_t size>
-void ExternalEntityTable<Entry, size>::UnsealReadOnlySegments() {
- DCHECK(this->is_initialized());
- if constexpr (!ExternalEntityTable::kUseContiguousMemory) return;
- bool success = this->vas_->SetPagePermissions(
- this->vas_->base(), kSegmentSize * kNumReadOnlySegments,
- PagePermissions::kReadWrite);
- CHECK(success);
-}
-
-template <typename Entry, size_t size>
-void ExternalEntityTable<Entry, size>::SealReadOnlySegments() {
- DCHECK(this->is_initialized());
- if constexpr (!ExternalEntityTable::kUseContiguousMemory) return;
- bool success = this->vas_->SetPagePermissions(
- this->vas_->base(), kSegmentSize * kNumReadOnlySegments,
- PagePermissions::kRead);
- CHECK(success);
-}
-
template <typename Entry, size_t size>
uint32_t ExternalEntityTable<Entry, size>::AllocateEntry(Space* space) {
static constexpr size_t kAllocationTries = 2;
@@ -298,19 +246,13 @@ ExternalEntityTable<Entry, size>::TryExtend(Space* space) {
space->mutex_.AssertHeld();
if (space->is_internal_read_only_space()) {
- // If this check fails during snapshot generation increase
- // kNumReadOnlySegments as needed.
- CHECK_LT(this->read_only_segments_used_, kNumReadOnlySegments);
-
- DCHECK_EQ(space->segments_.size(), this->read_only_segments_used_);
- Segment next_segment =
- Segment::At(kInternalReadOnlySegmentsOffset +
- kSegmentSize * this->read_only_segments_used_);
+ DCHECK_EQ(space->segments_.size(), this->read_only_segments_used());
+ auto next_segment_base = this->AllocateReadOnlySegment();
+ Segment next_segment = Segment::From(next_segment_base);
CHECK_LT(next_segment.last_entry(), kEndOfReadOnlyIndex);
FreelistHead freelist = Base::InitializeFreeList(next_segment);
Extend(space, next_segment, freelist);
DCHECK(!freelist.is_empty());
- this->read_only_segments_used_++;
return freelist;
}
@@ -336,9 +278,6 @@ void ExternalEntityTable<Entry, size>::Extend(Space* space, Segment segment,
segment.number() != 0);
DCHECK_EQ(space->is_internal_read_only_space(),
segment.number() < kNumReadOnlySegments);
- DCHECK_IMPLIES(
- space->is_internal_read_only_space(),
- segment.offset() == this->read_only_segments_used_ * kSegmentSize);
// This must be a release store to prevent reordering of earlier stores to
// the freelist (for example during initialization of the segment) from being
@@ -381,8 +320,8 @@ uint32_t ExternalEntityTable<Entry, size>::GenericSweep(Space* space,
uint32_t previous_freelist_length = current_freelist_length;
// Process every entry in this segment, again going top to bottom.
- for (WriteIterator it = this->iter_at(segment.last_entry());
- it.index() >= segment.first_entry(); --it) {
+ auto write_range = this->GetWritableRange(segment);
+ for (auto it = write_range.rbegin(); it != write_range.rend(); ++it) {
if (!it->IsMarked()) {
it->MakeFreelistEntry(current_freelist_head);
current_freelist_head = it.index();
diff --git a/deps/v8/src/sandbox/external-entity-table.h b/deps/v8/src/sandbox/external-entity-table.h
index 1c06bba63a6..77eb0b2af43 100644
--- a/deps/v8/src/sandbox/external-entity-table.h
+++ b/deps/v8/src/sandbox/external-entity-table.h
@@ -14,7 +14,7 @@
#include "src/base/platform/mutex.h"
#include "src/common/code-memory-access.h"
#include "src/common/globals.h"
-#include "src/common/segmented-table.h"
+#include "src/sandbox/segmented-table.h"
#include "src/utils/utils.h"
namespace v8 {
@@ -57,11 +57,10 @@ class V8_EXPORT_PRIVATE ExternalEntityTable
using Base = SegmentedTable<Entry, size>;
using FreelistHead = Base::FreelistHead;
using Segment = Base::Segment;
- using WriteIterator = Base::WriteIterator;
static constexpr size_t kSegmentSize = Base::kSegmentSize;
static constexpr size_t kEntriesPerSegment = Base::kEntriesPerSegment;
static constexpr size_t kEntrySize = Base::kEntrySize;
- static constexpr size_t kNumReadOnlySegments = Base::kNumReadOnlySegments;
+ static constexpr size_t kNumReadOnlySegments = 64 * KB / kSegmentSize;
// A collection of segments in an external entity table.
//
@@ -254,21 +253,6 @@ class V8_EXPORT_PRIVATE ExternalEntityTable
void DetachSpaceFromReadOnlySegments(Space* space);
void ZeroInternalNullEntry();
- // Use this scope to temporarily unseal the read-only segment (i.e. change
- // permissions to RW).
- class UnsealReadOnlySegmentScope final {
- public:
- explicit UnsealReadOnlySegmentScope(ExternalEntityTable<Entry, size>* table)
- : table_(table) {
- table_->UnsealReadOnlySegments();
- }
-
- ~UnsealReadOnlySegmentScope() { table_->SealReadOnlySegments(); }
-
- private:
- ExternalEntityTable<Entry, size>* const table_;
- };
-
#ifdef OBJECT_PRINT
template <typename EntryCallback>
void Print(Space* space, const char* space_name, uint32_t lower,
@@ -285,11 +269,6 @@ class V8_EXPORT_PRIVATE ExternalEntityTable
// Required for Isolate::CheckIsolateLayout().
friend class Isolate;
- // Helpers to toggle the first segment's permissions between kRead (sealed)
- // and kReadWrite (unsealed).
- void UnsealReadOnlySegments();
- void SealReadOnlySegments();
-
// Extends the given space with the given segment.
void Extend(Space* space, Segment segment, FreelistHead freelist);
};
diff --git a/deps/v8/src/sandbox/external-pointer-inl.h b/deps/v8/src/sandbox/external-pointer-inl.h
index 07913c8bb4b..31b272cb55c 100644
--- a/deps/v8/src/sandbox/external-pointer-inl.h
+++ b/deps/v8/src/sandbox/external-pointer-inl.h
@@ -74,6 +74,15 @@ inline void ExternalPointerMember<kTagRange>::store(IsolateForSandbox isolate,
store_raw(isolate, RedirectValue(isolate, value));
}
+template <ExternalPointerTagRange kTagRange>
+template <ExternalPointerTag tag>
+inline Address ExternalPointerMember<kTagRange>::exchange(
+ IsolateForSandbox isolate, Address value) {
+ static_assert(kTagRange.Contains(tag));
+ return ExchangeExternalPointerField<tag>(reinterpret_cast<Address>(storage_),
+ isolate, value);
+}
+
template <ExternalPointerTagRange kTagRange>
requires TagWithRedirection<kTagRange>
inline Address ExternalPointerMember<kTagRange>::load_raw(
@@ -181,18 +190,26 @@ V8_INLINE void InitExternalPointerField(Address host_address,
#endif // V8_ENABLE_SANDBOX
}
-template <ExternalPointerTagRange tag_range>
-V8_INLINE Address ReadExternalPointerField(Address field_address,
- IsolateForSandbox isolate) {
#ifdef V8_ENABLE_SANDBOX
- // static_assert(tag != kExternalPointerNullTag); // TODO
+V8_INLINE ExternalPointerHandle
+Relaxed_ReadExternalPointerHandle(Address field_address) {
// Handles may be written to objects from other threads so the handle needs
- // to be loaded atomically. We assume that the load from the table cannot
+ // to be loaded atomically. We assume that the access to the table cannot
// be reordered before the load of the handle due to the data dependency
- // between the two loads and therefore use relaxed memory ordering, but
+ // between the two accesses and therefore use relaxed memory ordering, but
// technically we should use memory_order_consume here.
auto location = reinterpret_cast<ExternalPointerHandle*>(field_address);
- ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location);
+ return base::AsAtomic32::Relaxed_Load(location);
+}
+#endif
+
+template <ExternalPointerTagRange tag_range>
+V8_INLINE Address ReadExternalPointerField(Address field_address,
+ IsolateForSandbox isolate) {
+#ifdef V8_ENABLE_SANDBOX
+ static_assert(!tag_range.IsEmpty());
+ ExternalPointerHandle handle =
+ Relaxed_ReadExternalPointerHandle(field_address);
return isolate.GetExternalPointerTableFor(tag_range).Get(handle, tag_range);
#else
return ReadMaybeUnalignedValue<Address>(field_address);
@@ -204,13 +221,8 @@ V8_INLINE Address ReadExternalPointerField(Address field_address,
ExternalPointerTagRange tag_range) {
#ifdef V8_ENABLE_SANDBOX
DCHECK_NE(tag_range.first, kExternalPointerNullTag);
- // Handles may be written to objects from other threads so the handle needs
- // to be loaded atomically. We assume that the load from the table cannot
- // be reordered before the load of the handle due to the data dependency
- // between the two loads and therefore use relaxed memory ordering, but
- // technically we should use memory_order_consume here.
- auto location = reinterpret_cast<ExternalPointerHandle*>(field_address);
- ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location);
+ ExternalPointerHandle handle =
+ Relaxed_ReadExternalPointerHandle(field_address);
return isolate.GetExternalPointerTableFor(tag_range).Get(handle, tag_range);
#else
return ReadMaybeUnalignedValue<Address>(field_address);
@@ -223,9 +235,8 @@ V8_INLINE void WriteExternalPointerField(Address field_address,
Address value) {
#ifdef V8_ENABLE_SANDBOX
static_assert(tag != kExternalPointerNullTag);
- // See comment above for why this is a Relaxed_Load.
- auto location = reinterpret_cast<ExternalPointerHandle*>(field_address);
- ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location);
+ ExternalPointerHandle handle =
+ Relaxed_ReadExternalPointerHandle(field_address);
isolate.GetExternalPointerTableFor(tag).Set(handle, value, tag);
#else
WriteMaybeUnalignedValue<Address>(field_address, value);
@@ -238,15 +249,30 @@ V8_INLINE void WriteExternalPointerField(Address field_address,
Address value) {
#ifdef V8_ENABLE_SANDBOX
DCHECK_NE(tag, kExternalPointerNullTag);
- // See comment above for why this is a Relaxed_Load.
- auto location = reinterpret_cast<ExternalPointerHandle*>(field_address);
- ExternalPointerHandle handle = base::AsAtomic32::Relaxed_Load(location);
+ ExternalPointerHandle handle =
+ Relaxed_ReadExternalPointerHandle(field_address);
isolate.GetExternalPointerTableFor(tag).Set(handle, value, tag);
#else
WriteMaybeUnalignedValue<Address>(field_address, value);
#endif // V8_ENABLE_SANDBOX
}
+template <ExternalPointerTag tag>
+V8_INLINE Address ExchangeExternalPointerField(Address field_address,
+ IsolateForSandbox isolate,
+ Address value) {
+#ifdef V8_ENABLE_SANDBOX
+ static_assert(tag != kExternalPointerNullTag);
+ ExternalPointerHandle handle =
+ Relaxed_ReadExternalPointerHandle(field_address);
+ return isolate.GetExternalPointerTableFor(tag).Exchange(handle, value, tag);
+#else
+ Address old_value = ReadMaybeUnalignedValue<Address>(field_address);
+ WriteMaybeUnalignedValue<Address>(field_address, value);
+ return old_value;
+#endif // V8_ENABLE_SANDBOX
+}
+
V8_INLINE void SetupLazilyInitializedExternalPointerField(
Address field_address) {}
diff --git a/deps/v8/src/sandbox/external-pointer-table-inl.h b/deps/v8/src/sandbox/external-pointer-table-inl.h
index 96fef08f8e0..a6ba845a9a0 100644
--- a/deps/v8/src/sandbox/external-pointer-table-inl.h
+++ b/deps/v8/src/sandbox/external-pointer-table-inl.h
@@ -8,6 +8,7 @@
#include "src/sandbox/external-pointer-table.h"
// Include the non-inl header before the rest of the headers.
+#include "src/sandbox/check.h"
#include "src/sandbox/compactible-external-entity-table-inl.h"
#include "src/sandbox/external-pointer.h"
@@ -62,7 +63,8 @@ void ExternalPointerTableEntry::SetExternalPointer(Address value,
bool ExternalPointerTableEntry::HasExternalPointer(
ExternalPointerTagRange tag_range) const {
auto payload = payload_.load(std::memory_order_relaxed);
- if (!payload.ContainsPointer()) return false;
+ DCHECK(!tag_range.Contains(kExternalPointerFreeEntryTag));
+ DCHECK(!tag_range.Contains(kExternalPointerEvacuationEntryTag));
return payload.IsTaggedWithTagIn(tag_range);
}
@@ -119,10 +121,13 @@ std::optional<uint32_t> ExternalPointerTableEntry::GetNextFreelistEntryIndex()
return payload.ExtractFreelistLink();
}
-bool ExternalPointerTableEntry::Mark() {
+bool ExternalPointerTableEntry::Mark(ExternalPointerTagRange tag_range) {
auto old_payload = payload_.load(std::memory_order_relaxed);
while (true) {
- DCHECK(old_payload.ContainsPointer());
+ // Some entry types (e.g. ArrayBufferExtension) are managed and require that
+ // the EPT mark bit and the speicifc type handling (e.g. marking an
+ // ArrayBufferExtension) stay in sync.
+ SBXCHECK(old_payload.IsTaggedWithTagIn(tag_range));
if (old_payload.HasMarkBitSet()) {
return false;
}
@@ -205,8 +210,9 @@ void ExternalPointerTable::Set(ExternalPointerHandle handle, Address value,
Address ExternalPointerTable::Exchange(ExternalPointerHandle handle,
Address value, ExternalPointerTag tag) {
DCHECK_NE(kNullExternalPointerHandle, handle);
- DCHECK(!IsManagedExternalPointerType(tag));
uint32_t index = HandleToIndex(handle);
+ FreeManagedResourceIfPresent(index);
+ TakeOwnershipOfManagedResourceIfNecessary(value, handle, tag);
return at(index).ExchangeExternalPointer(value, tag);
}
@@ -253,7 +259,8 @@ ExternalPointerHandle ExternalPointerTable::DuplicateEntry(
}
void ExternalPointerTable::Mark(Space* space, ExternalPointerHandle handle,
- Address handle_location) {
+ Address handle_location,
+ ExternalPointerTagRange tag_range) {
DCHECK(space->BelongsTo(this));
// The handle_location must always contain the given handle. Except if the
@@ -274,7 +281,7 @@ void ExternalPointerTable::Mark(Space* space, ExternalPointerHandle handle,
DCHECK(space->Contains(index));
// Bail out in case the entry was already marked.
- if (!at(index).Mark()) {
+ if (!at(index).Mark(tag_range)) {
return;
}
@@ -285,42 +292,63 @@ void ExternalPointerTable::Mark(Space* space, ExternalPointerHandle handle,
MaybeCreateEvacuationEntry(space, index, handle_location);
}
-void ExternalPointerTable::Evacuate(Space* from_space, Space* to_space,
- ExternalPointerHandle handle,
- Address handle_location,
- EvacuateMarkMode mode) {
+ExternalPointerHandle ExternalPointerTable::Evacuate(
+ Space* from_space, Space* to_space, ExternalPointerHandle handle,
+ Address handle_location, EvacuateMarkMode mode,
+ ExternalPointerTagRange tag_range) {
DCHECK(from_space->BelongsTo(this));
DCHECK(to_space->BelongsTo(this));
CHECK(IsValidHandle(handle));
- auto handle_ptr = reinterpret_cast<ExternalPointerHandle*>(handle_location);
-
-#ifdef DEBUG
- // Unlike Mark(), we require that the mutator is stopped, so we can simply
- // verify that the location stores the handle with a non-atomic load.
- DCHECK_EQ(handle, *handle_ptr);
-#endif
-
// If the handle is null, it doesn't have an EPT entry; no evacuation is
// needed.
- if (handle == kNullExternalPointerHandle) return;
+ if (handle == kNullExternalPointerHandle) return kNullExternalPointerHandle;
- uint32_t from_index = HandleToIndex(handle);
- DCHECK(from_space->Contains(from_index));
- uint32_t to_index = AllocateEntry(to_space);
+ const uint32_t from_index = HandleToIndex(handle);
+ // The handle may legitimately already point into old space.
+ if (!from_space->Contains(from_index)) {
+ SBXCHECK(at(from_index).HasExternalPointer(tag_range));
+ return handle;
+ }
- at(from_index).Evacuate(at(to_index), mode);
+ auto old_payload = at(from_index).GetRawPayload();
+ SBXCHECK(old_payload.IsTaggedWithTagIn(tag_range));
+
+ const uint32_t to_index = AllocateEntry(to_space);
ExternalPointerHandle new_handle = IndexToHandle(to_index);
+ ExternalPointerTableEntry::Payload zapped_payload(
+ kNullAddress, kExternalPointerZappedEntryTag);
+ // In legitimate execution, handles and slots are 1:1, so exactly one thread
+ // evacuates this entry. Atomically claim and zap the young entry. If multiple
+ // handles point to the same entry (due to sandbox heap corruption), the CAS
+ // fails and safely traps via SBXCHECK.
+ SBXCHECK(at(from_index)
+ .payload_.compare_exchange_strong(old_payload, zapped_payload,
+ std::memory_order_acq_rel));
+ switch (mode) {
+ case EvacuateMarkMode::kTransferMark:
+ break;
+ case EvacuateMarkMode::kLeaveUnmarked:
+ DCHECK(!old_payload.HasMarkBitSet());
+ break;
+ case EvacuateMarkMode::kClearMark:
+ DCHECK(old_payload.HasMarkBitSet());
+ old_payload.ClearMarkBit();
+ break;
+ }
+ at(to_index).SetRawPayload(old_payload);
+#if defined(LEAK_SANITIZER)
+ at(to_index).raw_pointer_for_lsan_ = at(from_index).raw_pointer_for_lsan_;
+#endif
if (Address addr = at(to_index).ExtractManagedResourceOrNull()) {
ManagedResource* resource = reinterpret_cast<ManagedResource*>(addr);
- DCHECK_EQ(resource->ept_entry_, handle);
resource->ept_entry_ = new_handle;
}
-
- // Update slot to point to new handle.
- base::AsAtomic32::Relaxed_Store(handle_ptr, new_handle);
+ base::AsAtomic32::Relaxed_Store(
+ reinterpret_cast<ExternalPointerHandle*>(handle_location), new_handle);
+ return new_handle;
}
// static
diff --git a/deps/v8/src/sandbox/external-pointer-table.h b/deps/v8/src/sandbox/external-pointer-table.h
index 6d5ef06948c..d7be4291137 100644
--- a/deps/v8/src/sandbox/external-pointer-table.h
+++ b/deps/v8/src/sandbox/external-pointer-table.h
@@ -101,7 +101,7 @@ struct ExternalPointerTableEntry {
// Mark this entry as alive during table garbage collection. Returns true if
// the entry transitioned from un-marked to marked, and false otherwise.
- inline bool Mark();
+ inline bool Mark(ExternalPointerTagRange tag_range);
static constexpr bool IsWriteProtected = false;
@@ -343,16 +343,15 @@ class V8_EXPORT_PRIVATE ExternalPointerTable
//
// This method is atomic and can be called from background threads.
inline void Mark(Space* space, ExternalPointerHandle handle,
- Address handle_location);
+ Address handle_location, ExternalPointerTagRange tag_range);
// Evacuate the specified entry from one space to another, updating the handle
- // location in place.
- //
- // This method is not atomic and can be called only when the mutator is
- // paused.
- inline void Evacuate(Space* from_space, Space* to_space,
- ExternalPointerHandle handle, Address handle_location,
- EvacuateMarkMode mode);
+ // location in place and returning the valid evacuated handle.
+ inline ExternalPointerHandle Evacuate(Space* from_space, Space* to_space,
+ ExternalPointerHandle handle,
+ Address handle_location,
+ EvacuateMarkMode mode,
+ ExternalPointerTagRange tag_range);
// Evacuate all segments from from_space to to_space, leaving from_space empty
// with an empty free list. Then free unmarked entries, finishing compaction
diff --git a/deps/v8/src/sandbox/external-pointer.h b/deps/v8/src/sandbox/external-pointer.h
index 83c7cb111ee..3240816823c 100644
--- a/deps/v8/src/sandbox/external-pointer.h
+++ b/deps/v8/src/sandbox/external-pointer.h
@@ -55,6 +55,14 @@ class ExternalPointerMember {
store<kTagRange.first>(isolate, value);
}
+ template <ExternalPointerTag tag>
+ inline Address exchange(IsolateForSandbox isolate, Address value);
+ inline Address exchange(IsolateForSandbox isolate, Address value)
+ requires(kTagRange.Size() == 1)
+ {
+ return exchange<kTagRange.first>(isolate, value);
+ }
+
inline ExternalPointer_t load_encoded() const;
inline void store_encoded(ExternalPointer_t value);
@@ -168,6 +176,11 @@ V8_INLINE void WriteExternalPointerField(Address field_address,
IsolateForSandbox isolate,
ExternalPointerTag tag, Address value);
+template <ExternalPointerTag tag>
+V8_INLINE Address ExchangeExternalPointerField(Address field_address,
+ IsolateForSandbox isolate,
+ Address value);
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/src/sandbox/generated-code-validator-arm64.cc b/deps/v8/src/sandbox/generated-code-validator-arm64.cc
index fb0a6c275c6..9a5ed461a80 100644
--- a/deps/v8/src/sandbox/generated-code-validator-arm64.cc
+++ b/deps/v8/src/sandbox/generated-code-validator-arm64.cc
@@ -6,7 +6,10 @@
#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
+#include "src/base/logging.h"
+#include "src/builtins/builtins.h"
#include "src/codegen/arm64/instructions-arm64.h"
+#include "src/codegen/arm64/register-arm64.h"
#include "src/objects/code-inl.h"
#ifdef __clang__
@@ -20,26 +23,458 @@
namespace v8::internal {
-void GeneratedCodeValidator::ValidateImpl(IsolateForSandbox isolate,
- Tagged<Code> code) {
+namespace {
+
+struct Da64InstFormatter {
+ static std::string Format(const Da64Inst& instr) {
+ char formatted_instruction[128] = {'\0'};
+ da64_format(&instr, formatted_instruction);
+ return formatted_instruction;
+ }
+};
+
+static bool Da64OpEquals(const Da64Op& op1, const Da64Op& op2) {
+ if (op1.type != op2.type) {
+ return false;
+ }
+
+ switch (op1.type) {
+ case DA_OP_NONE:
+ return true;
+ case DA_OP_IMMLARGE:
+ case DA_OP_RELADDR:
+ case DA_OP_IMMFLOAT:
+ // These operand types keep their values in the Da64Inst struct. Comparing
+ // such operand should not use this method.
+ UNREACHABLE();
+ case DA_OP_REGGP:
+ case DA_OP_REGGPINC:
+ case DA_OP_REGSP:
+ return op1.reg == op2.reg && op1.reggp.sf == op2.reggp.sf;
+ case DA_OP_REGGPEXT:
+ return op1.reg == op2.reg && op1.reggpext.sf == op2.reggpext.sf &&
+ op1.reggpext.ext == op2.reggpext.ext &&
+ op1.reggpext.shift == op2.reggpext.shift;
+ case DA_OP_REGFP:
+ return op1.reg == op2.reg && op1.regfp.size == op2.regfp.size;
+ case DA_OP_REGVEC:
+ return op1.reg == op2.reg && op1.regvec.va == op2.regvec.va;
+ case DA_OP_REGVTBL:
+ return op1.reg == op2.reg && op1.regvtbl.va == op2.regvtbl.va &&
+ op1.regvtbl.cnt == op2.regvtbl.cnt;
+ case DA_OP_REGVIDX:
+ return op1.reg == op2.reg && op1.regvidx.esize == op2.regvidx.esize &&
+ op1.regvidx.elem == op2.regvidx.elem;
+ case DA_OP_REGVTBLIDX:
+ return op1.reg == op2.reg &&
+ op1.regvtblidx.esize == op2.regvtblidx.esize &&
+ op1.regvtblidx.elem == op2.regvtblidx.elem &&
+ op1.regvtblidx.cnt == op2.regvtblidx.cnt;
+ case DA_OP_MEMUOFF:
+ return op1.reg == op2.reg && op1.uimm16 == op2.uimm16;
+ case DA_OP_MEMSOFF:
+ case DA_OP_MEMSOFFPRE:
+ case DA_OP_MEMSOFFPOST:
+ return op1.reg == op2.reg && op1.simm16 == op2.simm16;
+ case DA_OP_MEMREG:
+ case DA_OP_MEMREGPOST:
+ return op1.reg == op2.reg && op1.memreg.sc == op2.memreg.sc &&
+ op1.memreg.ext == op2.memreg.ext &&
+ op1.memreg.shift == op2.memreg.shift &&
+ op1.memreg.offreg == op2.memreg.offreg;
+ case DA_OP_MEMINC:
+ return op1.reg == op2.reg;
+ case DA_OP_COND:
+ return op1.cond == op2.cond;
+ case DA_OP_PRFOP:
+ return op1.prfop == op2.prfop;
+ case DA_OP_SYSREG:
+ return op1.sysreg == op2.sysreg;
+ case DA_OP_IMMSMALL:
+ case DA_OP_UIMM:
+ return op1.uimm16 == op2.uimm16;
+ case DA_OP_SIMM:
+ return op1.simm16 == op2.simm16;
+ case DA_OP_UIMMSHIFT:
+ return op1.uimm16 == op2.uimm16 &&
+ op1.immshift.mask == op2.immshift.mask &&
+ op1.immshift.shift == op2.immshift.shift;
+ }
+
+ UNREACHABLE();
+}
+
+} // namespace
+
+#define VALIDATOR_CHECK(condition, message) \
+ do { \
+ if (V8_UNLIKELY(!(condition))) { \
+ violations_reporter_.ReportViolationWithInstruction( \
+ pc, Da64InstFormatter::Format(instr), (message)); \
+ } \
+ } while (false)
+
+class InstructionChecker {
+ static_assert(kPtrComprCageBaseRegister != no_reg);
+ static constexpr int cage_base_register = kPtrComprCageBaseRegister.code();
+ static_assert(kRootRegister != no_reg);
+ static constexpr int root_register = kRootRegister.code();
+ static constexpr int kMaxOperands = 5;
+
+ using ViolationsReporter = GeneratedCodeValidator::ViolationsReporter;
+ using Utils = GeneratedCodeValidator::Utils;
+ using State = GeneratedCodeValidator::State;
+
+ public:
+ InstructionChecker(Isolate* isolate, Tagged<Code> code,
+ ViolationsReporter& violations_reporter)
+ : isolate_(isolate),
+ code_(code),
+ violations_reporter_(violations_reporter),
+ state_(code_),
+ root_reg_init_state_(isolate_) {}
+
+ void Check(const uint8_t* pc, const Da64Inst& instr) {
+ static_assert(kMaxOperands == (sizeof(instr.ops) / sizeof(Da64Op)));
+ // REGEXP code doesn't follow the V8 ABI and instead uses standard C ABI.
+ if (code_->kind() != CodeKind::REGEXP) {
+ CheckNoWritesToCageBaseRegister(pc, instr);
+ CheckNoWritesToRootRegister(pc, instr);
+ }
+ CheckNoSystemRegisterWrites(pc, instr);
+ }
+
+ private:
+ // Verifies whether the instruction accesses the pointer compression cage base
+ // register (x28) directly or modifies it via writeback. The cage base
+ // register must remain read-only across all generated code to preserve
+ // sandbox integrity and prevent pointer corruption. This will not block using
+ // the cage base register as a base address for a memory operand without
+ // writeback.
+ void CheckNoWritesToCageBaseRegister(const uint8_t* pc,
+ const Da64Inst& instr) {
+ switch (instr.mnem) {
+ // Subs is used as a comparison to assert that a register holds a heap
+ // object in the main cage.
+ case DA64I_SUBS_SHIFT:
+ // Add and sub instructions are used for decompressing and compressing
+ // sandboxed pointers.
+ case DA64I_ADD_SHIFT:
+ case DA64I_SUB_SHIFT:
+ // Or and Add instructions are used for decompressing tagged pointers.
+ case DA64I_ADD_IMM:
+ case DA64I_ORR_IMM:
+ case DA64I_ORR_SHIFT:
+ // Add extended register is used for decompressing tagged pointers with
+ // zero-extension: add xd, x28, ws, uxtw #0.
+ case DA64I_ADD_EXT:
+ // Check that the target is not the cage base register.
+ if (!IsCageBaseReg(instr.ops[0])) {
+ // Arithmetic and logical instructions do not support writeback
+ // operands.
+ return;
+ }
+ break;
+ // Stp is used by entry and deopt builtins to save the cage base
+ // register's value in C++ code.
+ case DA64I_STPX:
+ case DA64I_STPX_PRE:
+ case DA64I_STPX_POST:
+ // Stp isn't updating any registers.
+ DCHECK_IMPLIES(
+ IsCageBaseReg(instr.ops[0]) || IsCageBaseReg(instr.ops[1]),
+ Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_));
+ if (!IsCageBaseWritebackReg(instr.ops[2])) {
+ return;
+ }
+ break;
+ // Ldp is used by entry and deopt builtins to restore the cage base
+ // register's value in C++ code.
+ case DA64I_LDPX:
+ case DA64I_LDPX_PRE:
+ case DA64I_LDPX_POST:
+ // TODO(523128533): verify the popped value is the same as the
+ // previously pushed value. E.g. track changes to stack register and
+ // check that push and pop operate on the same offset (assuming calls
+ // don't violate it).
+ // TODO(523128533): Deopt builtins save and restore the cage base
+ // register so that the deoptimizer can update register values as
+ // needed. Since the cage base register is callee saved and should not
+ // change, can we avoid saving and restoring it?
+ if (Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_)) {
+ if ((IsCageBaseReg(instr.ops[0]) || IsCageBaseReg(instr.ops[1]))) {
+ state_.is_cage_base_reg_valid_ = false;
+ }
+ if (!IsCageBaseWritebackReg(instr.ops[2])) {
+ return;
+ }
+ }
+ break;
+ // Ldur is used by entry builtins to initialize the cage base register.
+ case DA64I_LDURX:
+ if (!IsCageBaseReg(instr.ops[0])) {
+ return;
+ }
+ VALIDATOR_CHECK(!state_.is_cage_base_reg_valid_,
+ "Instruction overwrites a valid cage base register");
+ if (Utils::IsEntryCode(code_) &&
+ IsExpectedOperand(instr.ops[1],
+ {.type = DA_OP_MEMSOFF,
+ .reg = root_register,
+ .simm16 = IsolateData::cage_base_offset()})) {
+ VALIDATOR_CHECK(
+ state_.is_root_reg_valid_,
+ "Cage base register initialization uses invalid root register");
+ state_.is_cage_base_reg_valid_ = true;
+ return;
+ }
+ break;
+ default:
+ // All other cases are not expected to accesses the cage base register
+ // directly and fall through to the generic handling below.
+ break;
+ }
+
+ // Check that no operand is the cage base register.
+ for (int i = 0; i < kMaxOperands; i++) {
+ VALIDATOR_CHECK(
+ !IsCageBaseReg(instr.ops[i]) && !IsCageBaseWritebackReg(instr.ops[i]),
+ std::format("Instruction accesses cage bage register at operand {0}",
+ i));
+ }
+ }
+
+ // Verifies whether the instruction accesses the root register (x26) directly
+ // or modifies it via writeback. The root register must remain read-only
+ // across all generated code to preserve sandbox integrity and prevent pointer
+ // corruption. This will not block using the root register as a base address
+ // for a memory operand without writeback.
+ void CheckNoWritesToRootRegister(const uint8_t* pc, const Da64Inst& instr) {
+ const bool expecting_init = root_reg_init_state_.in_progress;
+ bool was_init = false;
+ // Flag to skip the generic validation at the end of this method. Used to
+ // prevent accidentally skipping the `expecting_init && !was_init` check
+ // below.
+ bool is_validated = false;
+ switch (instr.mnem) {
+ // Add and sub are also used for root relative indexing and accessing
+ // isolate fields (or the isolate itself) via the root register.
+ case DA64I_ADD_SHIFT:
+ case DA64I_ADD_IMM:
+ case DA64I_ADD_EXT:
+ case DA64I_SUB_IMM:
+ // Orr is used for copying the root register value and by entry builtins
+ // to initialize the root register.
+ case DA64I_ORR_SHIFT:
+ // Check that the target is not the cage base register or root register.
+ if (!IsRootReg(instr.ops[0])) {
+ // Arithmetic and logical instructions do not support writeback
+ // operands.
+ is_validated = true;
+ break;
+ }
+ VALIDATOR_CHECK(!state_.is_root_reg_valid_,
+ "Instruction overwrites a valid root register");
+ if (Utils::IsEntryCode(code_) && IsValidRootRegInitialization(instr)) {
+ is_validated = true;
+ }
+ break;
+ // Stp is used by entry and deopt builtins to save the root register's
+ // value in C++ code.
+ case DA64I_STPX:
+ case DA64I_STPX_PRE:
+ case DA64I_STPX_POST:
+ // Stp isn't updating any registers.
+ DCHECK_IMPLIES(IsRootReg(instr.ops[0]) || IsRootReg(instr.ops[1]),
+ Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_));
+ if (!IsRootWritebackReg(instr.ops[2])) {
+ is_validated = true;
+ }
+ break;
+ // Ldp is used by entry and deopt builtins to restore the root registers'
+ // value in C++ code.
+ case DA64I_LDPX:
+ case DA64I_LDPX_PRE:
+ case DA64I_LDPX_POST:
+ // TODO(523128533): verify the popped value is the same as the
+ // previously pushed value. E.g. track changes to stack register and
+ // check that push and pop operate on the same offset (assuming calls
+ // don't violate it).
+ // TODO(523128533): Deopt builtins save and restore the root
+ // register so that the deoptimizer can update register values as
+ // needed. Since the root register is callee saved and should not
+ // change, can we avoid saving and restoring it?
+ if (Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_)) {
+ if ((IsRootReg(instr.ops[0]) || IsRootReg(instr.ops[1]))) {
+ state_.is_root_reg_valid_ = false;
+ }
+ if (!IsRootWritebackReg(instr.ops[2])) {
+ is_validated = true;
+ }
+ }
+ break;
+ // Mov is used by entry builtins to initialize the root register.
+ case DA64I_MOVZ:
+ case DA64I_MOVK:
+ if (!IsRootReg(instr.ops[0])) {
+ is_validated = true;
+ break;
+ }
+ VALIDATOR_CHECK(!state_.is_root_reg_valid_,
+ "Instruction overwrites a valid root register");
+ was_init = true;
+ if (Utils::IsEntryCode(code_) && IsValidRootRegInitialization(instr)) {
+ is_validated = true;
+ }
+ break;
+ default:
+ // All other cases are not expected to accesses the cage base register
+ // or root register directly and fall through to the generic handling
+ // below.
+ break;
+ }
+
+ VALIDATOR_CHECK(!(expecting_init && !was_init),
+ "Root register initialization interrupted");
+
+ if (is_validated) {
+ return;
+ }
+
+ // Check that no operand is the cage base register or the root register.
+ for (int i = 0; i < kMaxOperands; i++) {
+ VALIDATOR_CHECK(
+ !IsRootReg(instr.ops[i]) && !IsRootWritebackReg(instr.ops[i]),
+ std::format("Instruction accesses root register at operand {0}", i));
+ }
+ }
+
+ // Verifies that system register instruction MSR is never used. 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,
+ "Instruction writes to prohibited system registers");
+ }
+
+ static bool IsExpectedReg(const Da64Op& op, int expected_reg) {
+ return ((op.type == DA_OP_REGGP) || (op.type == DA_OP_REGGPEXT) ||
+ (op.type == DA_OP_REGGPINC)) &&
+ (op.reg == expected_reg);
+ }
+
+ static bool IsCageBaseReg(const Da64Op& op) {
+ return IsExpectedReg(op, cage_base_register);
+ }
+
+ static bool IsRootReg(const Da64Op& op) {
+ return IsExpectedReg(op, root_register);
+ }
+
+ static bool IsExpectedWritebackReg(const Da64Op& op, int expected_reg) {
+ return ((op.type == DA_OP_MEMSOFFPRE) || (op.type == DA_OP_MEMSOFFPOST) ||
+ (op.type == DA_OP_MEMREGPOST) || (op.type == DA_OP_MEMINC)) &&
+ (op.reg == expected_reg);
+ }
+
+ static bool IsCageBaseWritebackReg(const Da64Op& op) {
+ return IsExpectedWritebackReg(op, cage_base_register);
+ }
+
+ static bool IsRootWritebackReg(const Da64Op& op) {
+ return IsExpectedWritebackReg(op, root_register);
+ }
+
+ static bool IsExpectedOperand(const Da64Op& op, const Da64Op& expected) {
+ return Da64OpEquals(op, expected);
+ }
+
+ bool IsValidRootRegInitialization(const Da64Inst& instr) {
+ DCHECK(IsRootReg(instr.ops[0]));
+ switch (instr.mnem) {
+ case DA64I_MOVZ:
+ // Movz is the first in a sequence of movs to initialize the root
+ // register.
+ DCHECK_EQ(root_reg_init_state_.current_value, kNullAddress);
+ DCHECK(!root_reg_init_state_.in_progress);
+ [[fallthrough]];
+ case DA64I_MOVK: {
+ // Movk and Movz are used to construct the expected root register value.
+ const Da64Op& op = instr.ops[1];
+ DCHECK_EQ(DA_OP_UIMMSHIFT, op.type);
+ DCHECK_EQ(0, op.immshift.mask);
+ const Address previous_value = root_reg_init_state_.current_value;
+ root_reg_init_state_.current_value |=
+ (static_cast<uint64_t>(op.uimm16) << op.immshift.shift);
+ state_.is_root_reg_valid_ = root_reg_init_state_.current_value ==
+ root_reg_init_state_.expected_value_;
+ root_reg_init_state_.in_progress = !state_.is_root_reg_valid_;
+ // This is a valid initialization as long as it's making progress
+ // towards the expected value.
+ return (previous_value != root_reg_init_state_.current_value) &&
+ ((root_reg_init_state_.current_value &
+ root_reg_init_state_.expected_value_) ==
+ root_reg_init_state_.current_value);
+ }
+ case DA64I_ORR_SHIFT:
+ DCHECK(!root_reg_init_state_.in_progress);
+ // Assumes builtins receive the correct value as their first
+ // argument.
+ state_.is_root_reg_valid_ = (code_->kind() == CodeKind::BUILTIN) &&
+ IsExpectedReg(instr.ops[2], x0.code()) &&
+ IsExpectedReg(instr.ops[1], xzr.code());
+ break;
+ default:
+ break;
+ }
+ return state_.is_root_reg_valid_;
+ }
+
+ Isolate* const isolate_;
+ const Tagged<Code> code_;
+ ViolationsReporter& violations_reporter_;
+ State state_;
+ struct RootRegisterInitializationState {
+ explicit RootRegisterInitializationState(Isolate* isolate)
+ : expected_value_(ExternalReference::isolate_root(isolate).raw()) {
+ CHECK_NE(expected_value_, kNullAddress);
+ }
+
+ const Address expected_value_;
+ Address current_value = kNullAddress;
+ bool in_progress = false;
+ } root_reg_init_state_;
+};
+
+void GeneratedCodeValidator::ValidateImpl(Isolate* isolate, Tagged<Code> code) {
+ DCHECK_EQ(code->instruction_size() % kInstrSize, 0);
+
+ ViolationsReporter reporter(code);
+
+ InstructionChecker instruction_checker(isolate, code, reporter);
+
InstructionIteratorSkippingData it(code);
while (!it.IsDone()) {
const uint8_t* pc = it.GetCurrent();
- // `instr` is currently unused but will be used soon for the actual
- // validation.
- struct Da64Inst instr;
+ Da64Inst instr;
da64_decode(*reinterpret_cast<const uint32_t*>(pc), &instr);
if (instr.mnem == DA64I_UNKNOWN) {
- FATAL(
- "Generated code validator failed: invalid instruction at offset %td",
- pc - reinterpret_cast<const uint8_t*>(code->instruction_start()));
+ reporter.ReportDisassemblyFailed(pc, kInstrSize);
+ return;
+ }
+ if (v8_flags.validate_generated_code_include_code) {
+ reporter.RecordDisassembledInstruction(pc, kInstrSize,
+ Da64InstFormatter::Format(instr));
}
+ instruction_checker.Check(pc, instr);
it.Advance(kInstrSize);
}
}
} // namespace v8::internal
+#undef VALIDATOR_CHECK
+
#endif // V8_ENABLE_GENERATED_CODE_VALIDATOR
diff --git a/deps/v8/src/sandbox/generated-code-validator-x64.cc b/deps/v8/src/sandbox/generated-code-validator-x64.cc
index e5928a10dcf..ef22f718d15 100644
--- a/deps/v8/src/sandbox/generated-code-validator-x64.cc
+++ b/deps/v8/src/sandbox/generated-code-validator-x64.cc
@@ -6,34 +6,309 @@
#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
+#include "src/base/logging.h"
+#include "src/builtins/builtins.h"
+#include "src/codegen/x64/register-x64.h"
#include "src/objects/code-inl.h"
#include "third_party/fadec/src/fadec.h"
namespace v8::internal {
-void GeneratedCodeValidator::ValidateImpl(IsolateForSandbox isolate,
- Tagged<Code> code) {
+namespace {
+
+struct FdInstrFormatter {
+ static std::string Format(const FdInstr& instr) {
+ char formatted_instruction[128] = {'\0'};
+ fd_format(&instr, formatted_instruction, 128);
+ return formatted_instruction;
+ }
+
+ static size_t GetInstructionSize(const FdInstr& instr) {
+ return FD_SIZE(&instr);
+ }
+};
+
+} // namespace
+
+#define VALIDATOR_CHECK(condition, message) \
+ do { \
+ if (V8_UNLIKELY(!(condition))) { \
+ violations_reporter_.ReportViolationWithInstruction( \
+ pc, FdInstrFormatter::Format(instr), (message)); \
+ } \
+ } while (false)
+
+class InstructionChecker {
+ static_assert(kPtrComprCageBaseRegister != no_reg);
+ static constexpr int cage_base_register = kPtrComprCageBaseRegister.code();
+ static_assert(kRootRegister != no_reg);
+ static constexpr int root_register = kRootRegister.code();
+ static constexpr int kMaxOperands = 4;
+
+ using ViolationsReporter = GeneratedCodeValidator::ViolationsReporter;
+ using Utils = GeneratedCodeValidator::Utils;
+ using State = GeneratedCodeValidator::State;
+
+ public:
+ InstructionChecker(Isolate* isolate, Tagged<Code> code,
+ ViolationsReporter& violations_reproter)
+ : isolate_(isolate),
+ code_(code),
+ violations_reporter_(violations_reproter),
+ state_(code_) {}
+
+ void Check(const uint8_t* pc, const FdInstr& instr) {
+ static_assert(kMaxOperands == (sizeof(instr.operands) / sizeof(FdOp)));
+ // REGEXP code doesn't follow the V8 ABI and instead uses standard C ABI.
+ if (code_->kind() != CodeKind::REGEXP) {
+ CheckNoWritesToCageBaseRegister(pc, instr);
+ CheckNoWritesToRootRegister(pc, instr);
+ }
+ CheckNoSegmentRegisters(pc, instr);
+ }
+
+ private:
+ // Verifies whether the instruction accesses the pointer compression cage base
+ // register (r14) directly. The cage base register must remain read-only
+ // across all generated code to preserve sandbox integrity and prevent pointer
+ // corruption. This will not block using the case base register as a
+ // base address for a memory operand.
+ void CheckNoWritesToCageBaseRegister(const uint8_t* pc,
+ const FdInstr& instr) {
+ switch (FD_TYPE(&instr)) {
+ // Cmp is used to assert that a register holds a heap object in the main
+ // cage.
+ case FDI_CMP:
+ // Add and sub instructions are used for decompressing and compressing
+ // sandboxed pointers.
+ case FDI_ADD:
+ case FDI_SUB:
+ // Or and Add instructions are used for decompressing tagged pointers.
+ case FDI_OR:
+ // Check that the target is not the cage base register.
+ if (!IsCageBaseReg(instr, 0)) {
+ return;
+ }
+ break;
+ // Push is used by entry and deopt builtins to save the cage
+ // base register's value in C++ code.
+ case FDI_PUSH:
+ // Push isn't updating any registers.
+ DCHECK_IMPLIES(IsCageBaseReg(instr, 0),
+ Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_));
+ return;
+ // Push is used by entry and deopt builtins to restore the cage
+ // base register's value in C++ code.
+ case FDI_POP:
+ if (IsCageBaseReg(instr, 0) &&
+ (Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_))) {
+ // TODO(523128533): verify the popped value is the same as the
+ // previously pushed value. E.g. track changes to stack register and
+ // check that push and pop operate on the same offset (assuming calls
+ // don't violate it).
+ // TODO(523128533): Deopt builtins save and restore the cage base
+ // register so that the deoptimizer can update register values as
+ // needed. Since the cage base register is callee saved and should not
+ // change, can we avoid saving and restoring it?
+ state_.is_cage_base_reg_valid_ = false;
+ return;
+ }
+ break;
+ // Mov is used by entry builtins to initialize the cage base register.
+ // This instructions should only appear once per entry builtin.
+ case FDI_MOV:
+ if (!IsCageBaseReg(instr, 0)) {
+ return;
+ }
+ VALIDATOR_CHECK(!state_.is_cage_base_reg_valid_,
+ "Instruction overwrites a valid cage base register");
+ if (Utils::IsEntryCode(code_) &&
+ IsExpectedMemoryOperand(instr, 1, root_register, FD_REG_NONE, 0,
+ IsolateData::cage_base_offset())) {
+ VALIDATOR_CHECK(
+ state_.is_root_reg_valid_,
+ "Cage base register initialization uses invalid root register");
+ state_.is_cage_base_reg_valid_ = true;
+ return;
+ }
+ break;
+ default:
+ // All other cases are not expected to accesses the cage base register
+ // directly and fall through to the generic handling below.
+ break;
+ }
+
+ // Check that no operand is the cage base register.
+ for (int i = 0; i < kMaxOperands; i++) {
+ VALIDATOR_CHECK(
+ !IsCageBaseReg(instr, i),
+ std::format("Instruction accesses cage bage register at operand {0}",
+ i));
+ }
+ }
+
+ // Verifies whether the instruction writes to the root register (r13)
+ // directly. The root register must remain read-only across all generated code
+ // to preserve sandbox integrity and prevent pointer corruption. This will not
+ // block using the root register as a base address for a memory operand.
+ void CheckNoWritesToRootRegister(const uint8_t* pc, const FdInstr& instr) {
+ switch (FD_TYPE(&instr)) {
+ // Push is used by entry and deopt builtins to save the root register's
+ // value in C++ code.
+ case FDI_PUSH:
+ // Push isn't updating any registers.
+ DCHECK_IMPLIES(IsRootReg(instr, 0),
+ Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_));
+ return;
+ // Pop is used by entry and deopt builtins to restore the root register's
+ // value in C++ code.
+ case FDI_POP:
+ // TODO(523128533): verify the popped value is the same as the
+ // previously pushed value. E.g. track changes to stack register and
+ // check that push and pop operate on the same offset (assuming calls
+ // don't violate it).
+ // TODO(523128533): Deopt builtins save and restore the root
+ // register so that the deoptimizer can update register values as
+ // needed. Since the root register is callee saved and should not
+ // change, can we avoid saving and restoring it?
+ if (IsRootReg(instr, 0) &&
+ (Utils::IsEntryCode(code_) || Utils::IsDeoptCode(code_))) {
+ state_.is_root_reg_valid_ = false;
+ return;
+ }
+ break;
+ // Mov is used by entry builtins to initialize the root register.
+ case FDI_MOV:
+ case FDI_MOVABS:
+ if (!IsRootReg(instr, 0)) {
+ return;
+ }
+ VALIDATOR_CHECK(!state_.is_root_reg_valid_,
+ "Instruction overwrites a valid root register");
+ if (Utils::IsEntryCode(code_) && IsValidRootRegInitialization(instr)) {
+ return;
+ }
+ break;
+ default:
+ // All other cases are not expected to accesses the root register
+ // directly and fall through to the generic handling below.
+ break;
+ }
+
+ // Check that no operand is the cage base register or the root register.
+ for (int i = 0; i < kMaxOperands; i++) {
+ VALIDATOR_CHECK(
+ !IsRootReg(instr, i),
+ std::format("Instruction accesses root register at operand {0}", i));
+ }
+ }
+
+ // Verifies that the instruction does not use segment override prefixes or
+ // segment register operands. V8 executes in a flat 64-bit address space where
+ // segmentation is unused; manipulating segment registers is either privileged
+ // or reserved for OS/runtime thread-local storage (TLS) and can be used to
+ // escape the sandbox.
+ void CheckNoSegmentRegisters(const uint8_t* pc, const FdInstr& instr) {
+ VALIDATOR_CHECK(FD_SEGMENT(&instr) == FD_REG_NONE,
+ "Instruction uses a segment register");
+ for (int i = 0; i < kMaxOperands; ++i) {
+ VALIDATOR_CHECK(
+ !(FD_OP_TYPE(&instr, i) == FD_OT_REG &&
+ FD_OP_REG_TYPE(&instr, i) == FD_RT_SEG),
+ std::format("Instruction uses a segment register at operand {0}", i));
+ }
+ }
+
+ static bool IsExpectedReg(const FdInstr& instr, int op_idx,
+ int expected_reg) {
+ return FD_OP_TYPE(&instr, op_idx) == FD_OT_REG &&
+ (FD_OP_REG_TYPE(&instr, op_idx) == FD_RT_GPL ||
+ FD_OP_REG_TYPE(&instr, op_idx) == FD_RT_GPH) &&
+ FD_OP_REG(&instr, op_idx) == expected_reg;
+ }
+
+ static bool IsRootReg(const FdInstr& instr, int op_idx) {
+ return IsExpectedReg(instr, op_idx, root_register);
+ }
+
+ static bool IsCageBaseReg(const FdInstr& instr, int op_idx) {
+ return IsExpectedReg(instr, op_idx, cage_base_register);
+ }
+
+ static bool IsExpectedMemoryOperand(const FdInstr& instr, int op_idx,
+ int base, int index, int scale,
+ int displacement) {
+ return (FD_OP_TYPE(&instr, op_idx) == FD_OT_MEM) &&
+ (FD_OP_BASE(&instr, op_idx) == base) &&
+ (FD_OP_INDEX(&instr, op_idx) == index) &&
+ (FD_OP_SCALE(&instr, op_idx) == scale) &&
+ (FD_OP_DISP(&instr, op_idx) == displacement);
+ }
+
+ bool IsValidRootRegInitialization(const FdInstr& instr) {
+ DCHECK(IsRootReg(instr, 0));
+ switch (FD_TYPE(&instr)) {
+ case FDI_MOVABS: {
+ DCHECK_EQ(FD_OT_IMM, FD_OP_TYPE(&instr, 1));
+ const int64_t imm_value = FD_OP_IMM(&instr, 1);
+ state_.is_root_reg_valid_ =
+ static_cast<const uint64_t>(imm_value) ==
+ ExternalReference::isolate_root(isolate_).raw();
+ break;
+ }
+ case FDI_MOV:
+ // Assumes builtins receive the correct value as their first
+ // argument.
+ state_.is_root_reg_valid_ =
+ (code_->kind() == CodeKind::BUILTIN) &&
+ IsExpectedReg(instr, 1, kCArgRegs[0].code());
+ break;
+ default:
+ UNREACHABLE();
+ }
+ return state_.is_root_reg_valid_;
+ }
+
+ Isolate* const isolate_;
+ const Tagged<Code> code_;
+ ViolationsReporter& violations_reporter_;
+ State state_;
+};
+
+void GeneratedCodeValidator::ValidateImpl(Isolate* isolate, Tagged<Code> code) {
const uint8_t* const code_start =
reinterpret_cast<const uint8_t*>(code->instruction_start());
const uint8_t* const code_end = code_start + code->instruction_size();
+ ViolationsReporter reporter(code);
+
+ InstructionChecker instruction_checker(isolate, code, reporter);
+
InstructionIteratorSkippingData it(code);
while (!it.IsDone()) {
const uint8_t* pc = it.GetCurrent();
- // `instr` is currently unused but will be used soon for the actual
- // validation.
FdInstr instr;
- int res = fd_decode(pc, code_end - pc, 64, 0, &instr);
+ size_t remaining_length = code_end - pc;
+ int res = fd_decode(pc, remaining_length, 64, 0, &instr);
if (res < 0) {
- FATAL(
- "Generated code validator failed: invalid instruction at offset %td",
- pc - code_start);
+ static constexpr size_t kMaxInstructionSize = 15;
+ reporter.ReportDisassemblyFailed(
+ pc, std::min(remaining_length, kMaxInstructionSize));
+ return;
}
+ DCHECK_LE(res, remaining_length);
+ if (v8_flags.validate_generated_code_include_code) {
+ reporter.RecordDisassembledInstruction(pc, res,
+ FdInstrFormatter::Format(instr));
+ }
+ instruction_checker.Check(pc, instr);
it.Advance(res);
}
}
} // namespace v8::internal
+#undef VALIDATOR_CHECK
+
#endif // V8_ENABLE_GENERATED_CODE_VALIDATOR
diff --git a/deps/v8/src/sandbox/generated-code-validator.cc b/deps/v8/src/sandbox/generated-code-validator.cc
index 1dede9f9803..536ffd7a021 100644
--- a/deps/v8/src/sandbox/generated-code-validator.cc
+++ b/deps/v8/src/sandbox/generated-code-validator.cc
@@ -6,7 +6,10 @@
#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
+#include <algorithm>
+
#include "src/objects/code-inl.h"
+#include "src/objects/code-kind.h"
#include "src/sandbox/isolate-inl.h"
namespace v8::internal {
@@ -18,8 +21,7 @@ bool ShouldValidateCode(Tagged<Code> code) {
} // namespace
// static
-void GeneratedCodeValidator::Validate(IsolateForSandbox isolate,
- Tagged<Code> code) {
+void GeneratedCodeValidator::Validate(Isolate* isolate, Tagged<Code> code) {
if (!ShouldValidateCode(code)) {
return;
}
@@ -112,6 +114,152 @@ void GeneratedCodeValidator::InstructionIteratorSkippingData::SkipCheck() {
}
}
+GeneratedCodeValidator::ViolationsReporter::ViolationsReporter(
+ Tagged<Code> code)
+ : code_(code),
+ code_start_(reinterpret_cast<const uint8_t*>(code->instruction_start())) {
+}
+
+GeneratedCodeValidator::ViolationsReporter::~ViolationsReporter() {
+ PrintEpilogueIfNeeded();
+}
+
+void GeneratedCodeValidator::ViolationsReporter::ReportDisassemblyFailed(
+ const uint8_t* pc, size_t max_instruction_size) {
+ if (v8_flags.validate_generated_code_include_code) {
+ RecordDisassembledInstruction(pc, max_instruction_size, "???");
+ }
+ ReportViolation(pc, "Failed to disassemble invalid instruction.");
+}
+
+void GeneratedCodeValidator::ViolationsReporter::ReportViolationWithInstruction(
+ const uint8_t* pc, std::string instr, std::string error) {
+ ReportViolation(pc, error + ": " + instr);
+}
+
+void GeneratedCodeValidator::ViolationsReporter::RecordDisassembledInstruction(
+ const uint8_t* pc, size_t instruction_size, std::string instr) {
+ DCHECK(v8_flags.validate_generated_code_include_code);
+ DCHECK_GT(instruction_size, 0);
+ // Print offset in the instruction stream.
+ disassembled_instructions_ << "\t" << AsHex(pc - code_start_, 8, true)
+ << "\t";
+ // Print raw bytes (with padding if needed).
+ for (size_t i = 0; i < instruction_size; ++i) {
+ disassembled_instructions_ << AsHex(pc[i], 2, false);
+ }
+ static constexpr size_t kMaxInstructionSizeForPadding = 8;
+ static constexpr char kInstructionPadding[] =
+ " "; // 14 whitespaces
+ if (kMaxInstructionSizeForPadding > instruction_size) {
+ disassembled_instructions_.write(
+ kInstructionPadding,
+ (kMaxInstructionSizeForPadding - instruction_size) * 2);
+ }
+ // Print disassembled instruction.
+ disassembled_instructions_ << "\t" << instr << "\n";
+}
+
+namespace {
+
+static constexpr char kGeneratedCodeValidatorTag[] =
+ "[Generated code validator]";
+
+std::string GetCodeName(Tagged<Code> code) {
+ if (code->is_builtin()) {
+ return Builtins::name(code->builtin_id());
+ }
+ if (code->uses_deoptimization_data()) {
+ Tagged<DeoptimizationData> data = code->deoptimization_data();
+ if (data->length().value() > 0) {
+ std::unique_ptr<char[]> debug_name =
+ data->GetSharedFunctionInfo()->DebugNameCStr();
+ std::string name(debug_name.get());
+ for (char& c : name) {
+ if (!std::isalnum(static_cast<unsigned char>(c)) && c != '_') {
+ c = '_';
+ }
+ }
+ return name;
+ }
+ }
+ return "unknown method";
+}
+
+} // namespace
+
+void GeneratedCodeValidator::ViolationsReporter::ReportViolation(
+ const uint8_t* pc, std::string error) {
+ PrintPrologueIfNeeded();
+ v8::base::OS::PrintError("%s Offset %.8zx: %s\n", kGeneratedCodeValidatorTag,
+ pc - code_start_, error.c_str());
+}
+
+void GeneratedCodeValidator::ViolationsReporter::PrintPrologueIfNeeded() {
+ if (violations_found_) {
+ // Prologue have already been printed.
+ return;
+ }
+ v8::base::OS::PrintError("%s Violations found for %s compiled at tier %s:\n",
+ kGeneratedCodeValidatorTag,
+ GetCodeName(code_).c_str(),
+ CodeKindToString(code_->kind()));
+ violations_found_ = true;
+}
+
+void GeneratedCodeValidator::ViolationsReporter::PrintEpilogueIfNeeded() {
+ if (!violations_found_) {
+ return;
+ }
+
+ DCHECK_IMPLIES(!v8_flags.validate_generated_code_include_code,
+ disassembled_instructions_.str().empty());
+ if (v8_flags.validate_generated_code_include_code) {
+ v8::base::OS::PrintError("%s Disassembled code is:\n%s",
+ kGeneratedCodeValidatorTag,
+ disassembled_instructions_.str().c_str());
+ }
+
+ if (v8_flags.validate_generated_code_non_fatal) {
+ return;
+ }
+ FATAL("Generated code validation failed. See stderr output for violations.");
+}
+
+// static
+bool GeneratedCodeValidator::Utils::IsEntryCode(const Tagged<Code> code) {
+ switch (code->kind()) {
+#if V8_ENABLE_WEBASSEMBLY
+ case CodeKind::C_WASM_ENTRY:
+#endif // V8_ENABLE_WEBASSEMBLY
+ case CodeKind::FOR_TESTING:
+ return true;
+ case CodeKind::BUILTIN:
+ DCHECK(code->is_builtin());
+ static constexpr Builtin entry_builtins[] = {
+ Builtin::kJSEntry, Builtin::kJSConstructEntry,
+ Builtin::kJSRunMicrotasksEntry};
+ return std::find(std::begin(entry_builtins), std::end(entry_builtins),
+ code->builtin_id()) != std::end(entry_builtins);
+ default:
+ return false;
+ }
+}
+
+// static
+bool GeneratedCodeValidator::Utils::IsDeoptCode(const Tagged<Code> code) {
+ static constexpr Builtin entry_builtins[] = {
+ Builtin::kDeoptimizationEntry_Eager, Builtin::kDeoptimizationEntry_Lazy,
+ Builtin::kDeoptimizationEntry_LazyAfterFastCall};
+ return code->is_builtin() &&
+ std::find(std::begin(entry_builtins), std::end(entry_builtins),
+ code->builtin_id()) != std::end(entry_builtins);
+}
+
+GeneratedCodeValidator::State::State(const Tagged<Code> code)
+ : is_root_reg_valid_(!Utils::IsEntryCode(code)),
+ is_cage_base_reg_valid_(!Utils::IsEntryCode(code)) {}
+
} // namespace v8::internal
#endif // V8_ENABLE_GENERATED_CODE_VALIDATOR
diff --git a/deps/v8/src/sandbox/generated-code-validator.h b/deps/v8/src/sandbox/generated-code-validator.h
index 111ee28614b..23143b41eab 100644
--- a/deps/v8/src/sandbox/generated-code-validator.h
+++ b/deps/v8/src/sandbox/generated-code-validator.h
@@ -16,10 +16,11 @@
namespace v8::internal {
+class InstructionChecker;
+
class GeneratedCodeValidator {
public:
- static V8_EXPORT_PRIVATE void Validate(IsolateForSandbox isolate,
- Tagged<Code> code);
+ static V8_EXPORT_PRIVATE void Validate(Isolate* isolate, Tagged<Code> code);
static V8_EXPORT_PRIVATE bool IsValidated(Tagged<Code> code);
private:
@@ -55,7 +56,48 @@ class GeneratedCodeValidator {
disasm::Disassembler disasm_;
};
- static void ValidateImpl(IsolateForSandbox isolate, Tagged<Code> code);
+ class ViolationsReporter {
+ public:
+ explicit ViolationsReporter(Tagged<Code> code);
+ ~ViolationsReporter();
+
+ void ReportDisassemblyFailed(const uint8_t* pc,
+ size_t max_instruction_size);
+ void ReportViolationWithInstruction(const uint8_t* pc, std::string instr,
+ std::string error);
+ void RecordDisassembledInstruction(const uint8_t* pc,
+ size_t instruction_size,
+ std::string instr);
+
+ private:
+ void ReportViolation(const uint8_t* pc, std::string error);
+ void PrintPrologueIfNeeded();
+ void PrintEpilogueIfNeeded();
+
+ const Tagged<Code> code_;
+ const uint8_t* const code_start_;
+ std::stringstream disassembled_instructions_;
+ bool violations_found_ = false;
+ };
+
+ class Utils {
+ public:
+ static bool IsEntryCode(const Tagged<Code> code);
+ static bool IsDeoptCode(const Tagged<Code> code);
+ };
+
+ // TODO(523128533): Propagate `State` between instructions based on data flow.
+ struct State {
+ explicit State(const Tagged<Code> code);
+
+ bool is_root_reg_valid_;
+ // TODO(523128533): Check this field when checking memory writes to sandbox.
+ bool is_cage_base_reg_valid_;
+ };
+
+ static void ValidateImpl(Isolate* isolate, Tagged<Code> code);
+
+ friend class InstructionChecker;
};
} // namespace v8::internal
diff --git a/deps/v8/src/sandbox/isolate.h b/deps/v8/src/sandbox/isolate.h
index c6d343ef3d0..835998d023b 100644
--- a/deps/v8/src/sandbox/isolate.h
+++ b/deps/v8/src/sandbox/isolate.h
@@ -46,7 +46,10 @@ class V8_EXPORT_PRIVATE IsolateForSandbox final {
// are the same.
inline bool SharesPointerTablesWith(IsolateForSandbox other) const;
+ inline Isolate* GetIsolate() const { return isolate_; }
+
private:
+ friend class IsolateForPointerCompression;
Isolate* const isolate_;
};
@@ -72,6 +75,15 @@ class V8_EXPORT_PRIVATE IsolateForPointerCompression final {
template <typename IsolateT>
IsolateForPointerCompression(IsolateT* isolate) // NOLINT(runtime/explicit)
: isolate_(isolate->ForSandbox()) {}
+#ifdef V8_ENABLE_SANDBOX
+ IsolateForPointerCompression(
+ IsolateForSandbox isolate) // NOLINT(runtime/explicit)
+ : isolate_(isolate.isolate_) {}
+#else
+ constexpr IsolateForPointerCompression(
+ IsolateForSandbox) // NOLINT(runtime/explicit)
+ : isolate_(nullptr) {}
+#endif
inline ExternalPointerTable& GetExternalPointerTableFor(
ExternalPointerTagRange tag_range);
@@ -81,6 +93,8 @@ class V8_EXPORT_PRIVATE IsolateForPointerCompression final {
inline CppHeapPointerTable& GetCppHeapPointerTable();
inline CppHeapPointerTable::Space* GetCppHeapPointerTableSpace();
+ inline Isolate* GetIsolate() const { return isolate_; }
+
private:
Isolate* const isolate_;
};
@@ -90,6 +104,9 @@ class V8_EXPORT_PRIVATE IsolateForPointerCompression final {
template <typename IsolateT>
constexpr IsolateForPointerCompression(IsolateT*) // NOLINT(runtime/explicit)
{}
+ constexpr IsolateForPointerCompression(
+ IsolateForSandbox) // NOLINT(runtime/explicit)
+ {}
};
#endif // V8_COMPRESS_POINTERS
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/segmented-table-inl.h b/deps/v8/src/sandbox/segmented-table-inl.h
new file mode 100644
index 00000000000..9890b5e4051
--- /dev/null
+++ b/deps/v8/src/sandbox/segmented-table-inl.h
@@ -0,0 +1,88 @@
+// Copyright 2024 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_SEGMENTED_TABLE_INL_H_
+#define V8_SANDBOX_SEGMENTED_TABLE_INL_H_
+
+#include "src/sandbox/segmented-table.h"
+// Include the non-inl header before the rest of the headers.
+
+#include "src/base/emulated-virtual-address-subspace.h"
+#include "src/common/assert-scope.h"
+#include "src/sandbox/testing.h"
+#include "src/utils/allocation.h"
+
+namespace v8::internal {
+
+template <typename Entry, size_t size>
+typename SegmentedTable<Entry, size>::Segment
+SegmentedTable<Entry, size>::Segment::At(uint32_t offset) {
+ DCHECK(IsAligned(offset, kSegmentSize));
+ return Segment(SegmentBase::At(offset));
+}
+
+template <typename Entry, size_t size>
+typename SegmentedTable<Entry, size>::Segment
+SegmentedTable<Entry, size>::Segment::Containing(uint32_t entry_index) {
+ uint32_t number = entry_index / kEntriesPerSegment;
+ return Segment(number);
+}
+
+template <typename Entry, size_t size>
+Entry& SegmentedTable<Entry, size>::at(uint32_t index) {
+ return reinterpret_cast<Entry*>(this->base())[index];
+}
+
+template <typename Entry, size_t size>
+const Entry& SegmentedTable<Entry, size>::at(uint32_t index) const {
+ return reinterpret_cast<Entry*>(this->base())[index];
+}
+
+template <typename Entry, size_t size>
+typename SegmentedTable<Entry, size>::WritableRange
+SegmentedTable<Entry, size>::GetWritableRange(Segment segment) {
+ return WritableRange(reinterpret_cast<Entry*>(this->base()), segment);
+}
+
+template <typename Entry, size_t size>
+typename SegmentedTable<Entry, size>::FreelistHead
+SegmentedTable<Entry, size>::InitializeFreeList(Segment segment) {
+ uint32_t num_entries = kEntriesPerSegment;
+ uint32_t first = segment.first_entry();
+ uint32_t last = segment.last_entry();
+ {
+ auto write_range = GetWritableRange(segment);
+ for (auto it = write_range.begin(); it != write_range.end(); ++it) {
+ it->MakeFreelistEntry(it.index() == last ? 0 : it.index() + 1);
+ }
+ }
+
+ return FreelistHead(first, num_entries);
+}
+
+template <typename Entry, size_t size>
+std::pair<typename SegmentedTable<Entry, size>::Segment,
+ typename SegmentedTable<Entry, size>::FreelistHead>
+SegmentedTable<Entry, size>::AllocateAndInitializeSegment() {
+ if (auto res = TryAllocateAndInitializeSegment()) {
+ return *res;
+ }
+ V8::FatalProcessOutOfMemory(nullptr,
+ "SegmentedTable::AllocateAndInitializeSegment");
+}
+
+template <typename Entry, size_t size>
+std::optional<std::pair<typename SegmentedTable<Entry, size>::Segment,
+ typename SegmentedTable<Entry, size>::FreelistHead>>
+SegmentedTable<Entry, size>::TryAllocateAndInitializeSegment() {
+ auto segment_base = TryAllocateSegment();
+ if (!segment_base) return {};
+ auto segment = Segment::From(*segment_base);
+ FreelistHead freelist = InitializeFreeList(segment);
+ return {{segment, freelist}};
+}
+
+} // namespace v8::internal
+
+#endif // V8_SANDBOX_SEGMENTED_TABLE_INL_H_
diff --git a/deps/v8/src/sandbox/segmented-table.cc b/deps/v8/src/sandbox/segmented-table.cc
new file mode 100644
index 00000000000..8d31f5bb993
--- /dev/null
+++ b/deps/v8/src/sandbox/segmented-table.cc
@@ -0,0 +1,169 @@
+// 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/sandbox/segmented-table.h"
+
+#include "src/base/emulated-virtual-address-subspace.h"
+#include "src/utils/allocation.h"
+
+#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
+#include "src/sandbox/testing.h"
+#endif // V8_ENABLE_MEMORY_CORRUPTION_API
+
+namespace v8::internal {
+
+void SegmentedTableBase::Initialize(size_t reservation_size,
+ size_t read_only_reservation_size,
+ bool wants_write_protection) {
+ CHECK_NULL(vas_);
+ CHECK_NULL(base_);
+
+ VirtualAddressSpace* root_space = GetPlatformVirtualAddressSpace();
+
+#ifdef V8_TARGET_ARCH_64_BIT
+ static_assert(kUseContiguousMemory);
+ CHECK(IsAligned(reservation_size, root_space->allocation_granularity()));
+ CHECK(IsAligned(read_only_reservation_size,
+ root_space->allocation_granularity()));
+
+ std::optional<VirtualAddressSpace::MemoryProtectionKeyId> pkey;
+ if (kUseContiguousMemory && wants_write_protection &&
+ ThreadIsolation::Enabled()) {
+#if V8_HAS_PKU_JIT_WRITE_PROTECT
+ pkey = ThreadIsolation::pkey();
+#else
+ UNREACHABLE();
+#endif // V8_HAS_PKU_JIT_WRITE_PROTECT
+ }
+
+ if (root_space->CanAllocateSubspaces()) [[likely]] {
+ auto subspace = root_space->AllocateSubspace(
+ VirtualAddressSpace::kNoHint, reservation_size, kAlignment,
+ PagePermissions::kReadWrite, pkey);
+ vas_ = subspace.release();
+ } else {
+ // This may be required on old Windows versions that don't support
+ // VirtualAlloc2, which is required for subspaces. In that case, just
+ // use a fully-backed emulated subspace.
+ CHECK(!pkey);
+ Address reservation_base = root_space->AllocatePages(
+ VirtualAddressSpace::kNoHint, reservation_size, kAlignment,
+ PagePermissions::kNoAccess);
+ if (reservation_base) {
+ vas_ = new base::EmulatedVirtualAddressSubspace(
+ root_space, reservation_base, reservation_size, reservation_size);
+ }
+ }
+ if (!vas_) [[unlikely]] {
+ V8::FatalProcessOutOfMemory(
+ nullptr, "SegmentedTable::InitializeTable (subspace allocation)");
+ }
+ vas_->SetName(kPointerTableAddressSpaceName);
+#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
+ // In-sandbox corruption of handles can lead to out-of-bounds accesses into
+ // our tables, but these will stay inside the table's reserved region and hit
+ // PROT_NONE mappings, so they are safe. They can be both read- and write
+ // accesses though as we also write new pointers into existing table entries.
+ // Writing is fine as long as the value is not attacker controlled. It's only
+ // when we write attacker-controlled data that we (likely) have a security
+ // problem (but then it doesn't matter whether it's out-of-bounds or not).
+ SandboxTesting::RegisterSafeMemoryRegion(
+ vas_->base(), vas_->size(), SandboxTesting::kReadAndWriteAccessIsSafe);
+#endif // V8_ENABLE_MEMORY_CORRUPTION_API
+#else
+ static_assert(!kUseContiguousMemory);
+ vas_ = root_space;
+#endif // V8_TARGET_ARCH_64_BIT
+ base_ = reinterpret_cast<void*>(vas_->base());
+
+ if constexpr (kUseContiguousMemory) {
+ if (read_only_reservation_size) {
+ read_only_reservation_size_ = read_only_reservation_size;
+ CHECK_LE(read_only_reservation_size, reservation_size);
+ CHECK_EQ(0, read_only_reservation_size % kSegmentSize);
+
+ const Address first_segment =
+ vas_->AllocatePages(this->vas_->base(), read_only_reservation_size,
+ kAlignment, PagePermissions::kRead);
+ if (first_segment != vas_->base()) [[unlikely]] {
+ V8::FatalProcessOutOfMemory(
+ nullptr,
+ "SegmentedTableBase::Initialize (r/o segments allocation)");
+ }
+ CHECK_EQ(first_segment - vas_->base(), kInternalReadOnlySegmentsOffset);
+ }
+ }
+}
+
+void SegmentedTableBase::TearDown() {
+ CHECK(is_initialized());
+
+#ifdef V8_ENABLE_MEMORY_CORRUPTION_API
+ SandboxTesting::UnregisterSafeMemoryRegion(vas_->base());
+#endif
+
+ if (read_only_reservation_size_) {
+ // Deallocate all read only segments.
+ vas_->FreePages(vas_->base(), read_only_reservation_size_);
+ }
+
+ base_ = nullptr;
+#ifdef V8_TARGET_ARCH_64_BIT
+ delete vas_;
+#endif
+ vas_ = nullptr;
+}
+
+void SegmentedTableBase::FreeTableSegment(SegmentBase segment) {
+ const Address segment_start = vas_->base() + segment.offset();
+ vas_->FreePages(segment_start, kSegmentSize);
+}
+
+std::optional<SegmentedTableBase::SegmentBase>
+SegmentedTableBase::TryAllocateSegment() {
+ const Address start =
+ vas_->AllocatePages(VirtualAddressSpace::kNoHint, kSegmentSize,
+ kSegmentSize, PagePermissions::kReadWrite);
+ if (!start) [[unlikely]] {
+ return {};
+ }
+ const uint32_t offset = static_cast<uint32_t>(start - vas_->base());
+ auto segment = SegmentBase::At(offset);
+ DCHECK_IMPLIES(
+ kUseContiguousMemory && read_only_reservation_size_,
+ segment.number() >= read_only_reservation_size_ / kSegmentSize);
+ return segment;
+}
+
+SegmentedTableBase::SegmentBase SegmentedTableBase::AllocateReadOnlySegment() {
+ // If this check fails during snapshot generation increase the read-only
+ // reservation part of the table.
+ CHECK_LT(read_only_segments_used_ * kSegmentSize,
+ read_only_reservation_size_);
+ return SegmentBase::At(kInternalReadOnlySegmentsOffset +
+ kSegmentSize * read_only_segments_used_++);
+}
+
+uint32_t SegmentedTableBase::ResetReadOnlySegments() {
+ return std::exchange(read_only_segments_used_, 0);
+}
+
+void SegmentedTableBase::UnsealReadOnlySegments() {
+ CHECK(is_initialized());
+ if (read_only_reservation_size_ == 0) return;
+ const bool success = this->vas_->SetPagePermissions(
+ this->vas_->base(), read_only_reservation_size_,
+ PagePermissions::kReadWrite);
+ CHECK(success);
+}
+
+void SegmentedTableBase::SealReadOnlySegments() {
+ CHECK(is_initialized());
+ if (read_only_reservation_size_ == 0) return;
+ const bool success = this->vas_->SetPagePermissions(
+ this->vas_->base(), read_only_reservation_size_, PagePermissions::kRead);
+ CHECK(success);
+}
+
+} // namespace v8::internal
diff --git a/deps/v8/src/sandbox/segmented-table.h b/deps/v8/src/sandbox/segmented-table.h
new file mode 100644
index 00000000000..c4e813fc0b2
--- /dev/null
+++ b/deps/v8/src/sandbox/segmented-table.h
@@ -0,0 +1,417 @@
+// Copyright 2024 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_SEGMENTED_TABLE_H_
+#define V8_SANDBOX_SEGMENTED_TABLE_H_
+
+#include "include/v8-internal.h"
+#include "src/base/logging.h"
+#include "src/base/macros.h"
+#include "src/common/code-memory-access.h"
+
+namespace v8::internal {
+
+/**
+ * A table with a fixed maximum size split into segments.
+ *
+ * The table provides thread-safe methods to allocate and free segments. It is
+ * completely agnostic to entries stored on the Segments. See specific
+ * subclasses on how these tables are managed on Entry-level.
+ *
+ * The table also provides low-level allocation of read-only segments. Read-only
+ * segment handling is assumed to run single-threaded.
+ */
+class V8_EXPORT_PRIVATE SegmentedTableBase {
+ public:
+ // Use this scope to temporarily unseal the read-only segment (i.e. change
+ // permissions to RW).
+ class UnsealReadOnlySegmentScope;
+
+ static constexpr size_t BaseOffset();
+
+ protected:
+ // Base class for all segments that is agnostic to entry types.
+ class SegmentBase;
+
+#ifdef V8_TARGET_ARCH_64_BIT
+ // On 64 bit, we use a large address space reservation for the table memory.
+ static constexpr bool kUseContiguousMemory = true;
+ static constexpr size_t kSegmentSize = 64 * KB;
+#else
+ // On 32 bit, segments are individually mapped.
+ static constexpr bool kUseContiguousMemory = false;
+#ifdef V8_TARGET_OS_WIN
+ // On windows the allocation granularity is 64KB.
+ static constexpr size_t kSegmentSize = 64 * KB;
+#else
+ static constexpr size_t kSegmentSize = 16 * KB;
+#endif
+#endif // V8_TARGET_ARCH_64_BIT
+
+ static constexpr uint32_t kInternalReadOnlySegmentsOffset = 0;
+ static constexpr size_t kAlignment = kSegmentSize;
+
+ // The sandbox relies on not being able to access any SegmentedTable out of
+ // bounds.
+ static_assert(kUseContiguousMemory || !V8_ENABLE_SANDBOX_BOOL);
+
+ SegmentedTableBase() = default;
+ SegmentedTableBase(const SegmentedTableBase&) = delete;
+ SegmentedTableBase& operator=(const SegmentedTableBase&) = delete;
+
+ // Initializes the table by reserving the backing memory.
+ void Initialize(size_t reservation_size, size_t read_only_reservation_size,
+ bool wants_write_protection);
+
+ // Deallocates all memory associated with this table.
+ void TearDown();
+
+ // Returns true if this table has been initialized.
+ bool is_initialized() const {
+ DCHECK_IMPLIES(base_, reinterpret_cast<Address>(base_) == vas_->base());
+ return vas_ != nullptr;
+ }
+
+ // Returns the base address of this table.
+ Address base() const {
+ DCHECK(is_initialized());
+ return reinterpret_cast<Address>(base_);
+ }
+
+ // Tries to allocate a segment from the table.
+ std::optional<SegmentBase> TryAllocateSegment();
+
+ // Free the specified segment of this table.
+ //
+ // The memory of this segment will afterwards be inaccessible which is a
+ // requirement for sandbox security.
+ void FreeTableSegment(SegmentBase segment);
+
+ // Allocates a read-only segment.
+ SegmentBase AllocateReadOnlySegment();
+
+ // Resets the read-only segments. Doesn't actually free any of the pages.
+ // Returns the number of segments that were used.
+ uint32_t ResetReadOnlySegments();
+
+ // Returns the number of read-only segments allocated and in-use.
+ uint32_t read_only_segments_used() const { return read_only_segments_used_; }
+
+ private:
+ // Helpers to toggle the first segment's permissions between kRead (sealed)
+ // and kReadWrite (unsealed).
+ void SealReadOnlySegments();
+ void UnsealReadOnlySegments();
+
+ // The pointer to the base of the virtual address space backing this table.
+ // All entry accesses happen through this pointer. It is equivalent to
+ // `vas_->base()` and is effectively const after initialization since the
+ // backing memory is never reallocated.
+ void* base_ = nullptr;
+ // The virtual address space backing this table. This is used to manage the
+ // underlying OS pages, in particular to allocate and free the segments that
+ // make up the table.
+ VirtualAddressSpace* vas_ = nullptr;
+ // Used to keep track of actually used RO segments.
+ uint32_t read_only_segments_used_ = 0;
+ // RO reservation size.
+ size_t read_only_reservation_size_ = 0;
+};
+
+// static
+constexpr size_t SegmentedTableBase::BaseOffset() {
+ return offsetof(SegmentedTableBase, base_);
+}
+
+class SegmentedTableBase::SegmentBase {
+ public:
+ // Returns the segment starting at the specified offset from the base of the
+ // table.
+ static SegmentBase At(uint32_t offset) {
+ DCHECK(IsAligned(offset, kSegmentSize));
+ const uint32_t number = offset / kSegmentSize;
+ return SegmentBase(number);
+ }
+
+ // The segments of a table are numbered sequentially. This method returns
+ // the number of this segment.
+ constexpr uint32_t number() const { return number_; }
+
+ // Returns the offset of this segment from the table base.
+ constexpr uint32_t offset() const {
+ return number_ * SegmentedTableBase::kSegmentSize;
+ }
+
+ // Segments are ordered by their `number()`.
+ constexpr bool operator<(const SegmentBase& other) const {
+ return number_ < other.number_;
+ }
+ constexpr bool operator==(const SegmentBase& other) const {
+ return number_ == other.number_;
+ }
+ constexpr bool operator!=(const SegmentBase& other) const {
+ return number_ != other.number_;
+ }
+
+ protected:
+ // Initialize a segment given its number.
+ constexpr explicit SegmentBase(uint32_t number) : number_(number) {}
+
+ // A segment is identified by its number, which is its offset from the base
+ // of the table divided by the segment size.
+ const uint32_t number_;
+};
+
+class SegmentedTableBase::UnsealReadOnlySegmentScope final {
+ public:
+ explicit UnsealReadOnlySegmentScope(SegmentedTableBase* table)
+ : table_(table) {
+ table_->UnsealReadOnlySegments();
+ }
+
+ ~UnsealReadOnlySegmentScope() { table_->SealReadOnlySegments(); }
+
+ private:
+ SegmentedTableBase* const table_;
+};
+
+/**
+ * A thread-safe table with a fixed maximum size split into segments.
+ *
+ * The table provides thread-safe methods to allocate and free of segments and
+ * an inline freelist implementation. Allocation and Freeing of entries is
+ * implemented in subclasses since it depends on if the table is manually
+ * managed or GCed.
+ *
+ * For the purpose of memory management, the table is partitioned into Segments
+ * (for example 64kb memory chunks) that are grouped together in "Spaces". All
+ * segments in a space share a freelist, and so entry allocation and garbage
+ * collection happen on the level of spaces.
+ *
+ * The Entry type defines how the freelist is represented. For that, it must
+ * implement the following methods:
+ * - void MakeFreelistEntry(uint32_t next_entry_index)
+ * - uint32_t GetNextFreelistEntry()
+ */
+template <typename Entry, size_t size>
+class V8_EXPORT_PRIVATE SegmentedTable : public SegmentedTableBase {
+ protected:
+ // The table is organized into segments where a segment that holds entries.
+ struct Segment;
+
+ // Head of the freelist.
+ //
+ // A segmented table uses simple, singly-linked lists to manage free entries.
+ // Each entry on the freelist contains the 32-bit index of the next entry. The
+ // last entry points to zero.
+ struct FreelistHead;
+ // We expect the FreelistHead struct to fit into a single atomic word.
+ // Otherwise, access to it would be slow.
+ static_assert(std::atomic<FreelistHead>::is_always_lock_free);
+
+ class WriteIterator;
+ class ReverseWriteIterator;
+ // Iterator range that acts as a scope object to temporarily lift any
+ // write-protection that may be otherwise enforced when kIsWriteProtected is
+ // true.
+ class WritableRange;
+
+ static constexpr bool kIsWriteProtected = Entry::IsWriteProtected;
+ static constexpr int kEntrySize = sizeof(Entry);
+ static constexpr size_t kEntriesPerSegment = kSegmentSize / kEntrySize;
+
+#ifdef V8_TARGET_ARCH_64_BIT
+ static constexpr size_t kReservationSize = size;
+ static constexpr size_t kMaxCapacity = kReservationSize / kEntrySize;
+#endif // V8_TARGET_ARCH_64_BIT
+
+ SegmentedTable() = default;
+ SegmentedTable(const SegmentedTable&) = delete;
+ SegmentedTable& operator=(const SegmentedTable&) = delete;
+
+ // Access the entry at the specified index.
+ Entry& at(uint32_t index);
+ const Entry& at(uint32_t index) const;
+
+ // Returns a range that can be used to perform multiple write operations
+ // on the given segment without switching write-protections continuously (if
+ // kIsWriteProtected is true).
+ WritableRange GetWritableRange(Segment segment);
+
+ // Allocate a new segment in this table.
+ //
+ // The segment is initialized with freelist entries.
+ std::pair<Segment, FreelistHead> AllocateAndInitializeSegment();
+ // Same as above but fails if there is no space left.
+ std::optional<std::pair<Segment, FreelistHead>>
+ TryAllocateAndInitializeSegment();
+
+ // Initialize a table segment with a freelist.
+ //
+ // Note that you don't need to call this function on segments allocated with
+ // `AllocateAndInitializeSegment()` since those already get initialized.
+ FreelistHead InitializeFreeList(Segment segment);
+};
+
+template <typename Entry, size_t size>
+struct SegmentedTable<Entry, size>::Segment
+ : public SegmentedTableBase::SegmentBase {
+ public:
+ // Returns the segment starting at the specified offset from the base of the
+ // table.
+ static Segment At(uint32_t offset);
+
+ // Returns the segment containing the entry at the given index.
+ static Segment Containing(uint32_t entry_index);
+
+ // Returns the segment from the base class.
+ static Segment From(SegmentBase base) { return Segment(base); }
+
+ // Returns the index of the first entry in this segment.
+ constexpr uint32_t first_entry() const {
+ return number_ * SegmentedTable::kEntriesPerSegment;
+ }
+
+ // Return the index of the last entry in this segment.
+ constexpr uint32_t last_entry() const {
+ return first_entry() + SegmentedTable::kEntriesPerSegment - 1;
+ }
+
+ private:
+ // Initialize a segment given its number.
+ constexpr explicit Segment(uint32_t number) : SegmentBase(number) {}
+ // Create from untyped base class.
+ constexpr explicit Segment(SegmentBase base) : SegmentBase(base.number()) {}
+};
+
+template <typename Entry, size_t size>
+struct SegmentedTable<Entry, size>::FreelistHead {
+ constexpr FreelistHead() = default;
+ constexpr FreelistHead(uint32_t next, uint32_t length)
+ : next_(next), length_(length) {}
+
+ // Returns the index of the next entry on the freelist. Returns zero for an
+ // empty freelist.
+ uint32_t next() const { return next_; }
+
+ // Returns the total length of the freelist.
+ uint32_t length() const { return length_; }
+
+ // Returns whether the freelist is empty, i.e., it's length is zero.
+ bool is_empty() const { return length_ == 0; }
+
+ private:
+ uint32_t next_ = 0;
+ uint32_t length_ = 0;
+};
+
+template <typename Entry, size_t size>
+class SegmentedTable<Entry, size>::WriteIterator {
+ public:
+ using iterator_category = std::bidirectional_iterator_tag;
+ using value_type = Entry;
+ using difference_type = std::ptrdiff_t;
+ using pointer = Entry*;
+ using reference = Entry&;
+
+ WriteIterator(Entry* base, Segment segment, uint32_t index)
+ : base_(base), segment_(segment), index_(index) {
+ DCHECK_GE(index_, segment_.first_entry());
+ DCHECK_LE(index_, segment_.last_entry() + 1);
+ }
+
+ uint32_t index() const { return index_; }
+
+ Entry* operator->() const {
+ DCHECK_GE(index_, segment_.first_entry());
+ DCHECK_LE(index_, segment_.last_entry());
+ return &base_[index_];
+ }
+ Entry& operator*() const {
+ DCHECK_GE(index_, segment_.first_entry());
+ DCHECK_LE(index_, segment_.last_entry());
+ return base_[index_];
+ }
+
+ WriteIterator& operator++() {
+ DCHECK_LE(index_, segment_.last_entry());
+ index_++;
+ return *this;
+ }
+ WriteIterator operator++(int) {
+ WriteIterator tmp = *this;
+ ++(*this);
+ return tmp;
+ }
+ WriteIterator& operator--() {
+ DCHECK_GT(index_, segment_.first_entry());
+ index_--;
+ return *this;
+ }
+ WriteIterator operator--(int) {
+ WriteIterator tmp = *this;
+ --(*this);
+ return tmp;
+ }
+
+ bool operator==(const WriteIterator& other) const {
+ DCHECK_EQ(segment_, other.segment_);
+ return index_ == other.index_;
+ }
+ bool operator!=(const WriteIterator& other) const {
+ DCHECK_EQ(segment_, other.segment_);
+ return index_ != other.index_;
+ }
+
+ private:
+ Entry* base_;
+ Segment segment_;
+ uint32_t index_;
+};
+
+template <typename Entry, size_t size>
+class SegmentedTable<Entry, size>::ReverseWriteIterator
+ : public std::reverse_iterator<WriteIterator> {
+ public:
+ using Base = std::reverse_iterator<WriteIterator>;
+ using Base::Base;
+
+ uint32_t index() const { return std::prev(this->base()).index(); }
+};
+
+template <typename Entry, size_t size>
+class SegmentedTable<Entry, size>::WritableRange {
+ public:
+ using iterator = WriteIterator;
+ using const_iterator = WriteIterator;
+ using reverse_iterator = ReverseWriteIterator;
+ using const_reverse_iterator = ReverseWriteIterator;
+
+ WritableRange(Entry* base, Segment segment)
+ : base_(base), segment_(segment), write_scope_("pointer table write") {}
+
+ WritableRange(const WritableRange&) = delete;
+ WritableRange& operator=(const WritableRange&) = delete;
+
+ iterator begin() const {
+ return WriteIterator(base_, segment_, segment_.first_entry());
+ }
+ iterator end() const {
+ return WriteIterator(base_, segment_, segment_.last_entry() + 1);
+ }
+
+ reverse_iterator rbegin() const { return ReverseWriteIterator(end()); }
+ reverse_iterator rend() const { return ReverseWriteIterator(begin()); }
+
+ private:
+ Entry* base_;
+ Segment segment_;
+ std::conditional_t<kIsWriteProtected, CFIMetadataWriteScope,
+ NopRwxMemoryWriteScope>
+ write_scope_;
+};
+
+} // namespace v8::internal
+
+#endif // V8_SANDBOX_SEGMENTED_TABLE_H_
diff --git a/deps/v8/src/sandbox/testing.cc b/deps/v8/src/sandbox/testing.cc
index 94d46e76dc9..5dc89dd48d2 100644
--- a/deps/v8/src/sandbox/testing.cc
+++ b/deps/v8/src/sandbox/testing.cc
@@ -23,7 +23,9 @@
#include "src/objects/feedback-vector.h"
#include "src/objects/fixed-array.h"
#include "src/objects/fixed-primitive-array-inl.h"
+#include "src/objects/foreign.h"
#include "src/objects/instance-type.h"
+#include "src/objects/js-array-buffer.h"
#include "src/objects/js-objects.h"
#include "src/objects/tagged-field-inl.h"
#include "src/objects/templates.h"
@@ -1481,6 +1483,7 @@ SandboxTesting::InstanceTypeMap& SandboxTesting::GetInstanceTypeMap() {
types["JS_BOUND_FUNCTION_TYPE"] = JS_BOUND_FUNCTION_TYPE;
types["JS_ARRAY_TYPE"] = JS_ARRAY_TYPE;
types["JS_ARRAY_BUFFER_TYPE"] = JS_ARRAY_BUFFER_TYPE;
+ types["FOREIGN_TYPE"] = FOREIGN_TYPE;
types["JS_REG_EXP_TYPE"] = JS_REG_EXP_TYPE;
types["JS_TYPED_ARRAY_TYPE"] = JS_TYPED_ARRAY_TYPE;
types["SEQ_ONE_BYTE_STRING_TYPE"] = SEQ_ONE_BYTE_STRING_TYPE;
@@ -1539,6 +1542,10 @@ SandboxTesting::FieldOffsetMap& SandboxTesting::GetFieldOffsetMap() {
offsetof(JSBoundFunction, bound_arguments_);
fields[JS_ARRAY_TYPE]["elements"] = offsetof(JSObject, elements_);
fields[JS_ARRAY_TYPE]["length"] = offsetof(JSArray, length_);
+ fields[JS_ARRAY_BUFFER_TYPE]["extension"] =
+ offsetof(JSArrayBuffer, extension_);
+ fields[FOREIGN_TYPE]["foreign_address"] =
+ offsetof(Foreign, foreign_address_);
fields[JS_REG_EXP_TYPE]["data"] = offsetof(JSRegExp, data_);
fields[JS_TYPED_ARRAY_TYPE]["byte_length"] =
offsetof(JSArrayBufferView, raw_byte_length_);
@@ -1553,6 +1560,11 @@ SandboxTesting::FieldOffsetMap& SandboxTesting::GetFieldOffsetMap() {
InstanceType instance_type = static_cast<InstanceType>(string_type);
fields[instance_type]["length"] = offsetof(String, length_);
fields[instance_type]["hash"] = offsetof(String, raw_hash_field_);
+ if (InstanceTypeChecker::IsExternalString(instance_type)) {
+ fields[instance_type]["resource"] = offsetof(ExternalString, resource_);
+ fields[instance_type]["resource_data"] =
+ offsetof(ExternalString, resource_data_);
+ }
}
fields[SLICED_ONE_BYTE_STRING_TYPE]["parent"] =
offsetof(SlicedString, parent_);
@@ -1576,6 +1588,8 @@ SandboxTesting::FieldOffsetMap& SandboxTesting::GetFieldOffsetMap() {
offsetof(JSPromise, reactions_or_result_);
fields[PROMISE_REACTION_TYPE]["fulfill_handler"] =
offsetof(PromiseReaction, fulfill_handler_);
+ fields[PROMISE_REACTION_TYPE]["reject_handler"] =
+ offsetof(PromiseReaction, reject_handler_);
fields[FEEDBACK_CELL_TYPE]["value"] = offsetof(FeedbackCell, value_);
fields[FEEDBACK_VECTOR_TYPE]["length"] = offsetof(FeedbackVector, length_);
fields[FEEDBACK_VECTOR_TYPE]["data"] =
diff --git a/deps/v8/src/snapshot/code-serializer.cc b/deps/v8/src/snapshot/code-serializer.cc
index 755402ad4d2..034ef5f52ea 100644
--- a/deps/v8/src/snapshot/code-serializer.cc
+++ b/deps/v8/src/snapshot/code-serializer.cc
@@ -137,7 +137,7 @@ void CodeSerializer::SerializeObjectImpl(Handle<HeapObject> obj,
{
DisallowGarbageCollection no_gc;
Tagged<Script> script_obj = Cast<Script>(*obj);
- DCHECK_NE(script_obj->compilation_type(), Script::CompilationType::kEval);
+ DCHECK(!script_obj->has_eval_origin());
// We want to differentiate between undefined and uninitialized_symbol for
// context_data for now. It is hack to allow debugging for scripts that
// are included as a part of custom snapshot. (see
diff --git a/deps/v8/src/snapshot/context-deserializer.cc b/deps/v8/src/snapshot/context-deserializer.cc
index a3c5197fe94..ab6afe5ff82 100644
--- a/deps/v8/src/snapshot/context-deserializer.cc
+++ b/deps/v8/src/snapshot/context-deserializer.cc
@@ -66,6 +66,7 @@ MaybeDirectHandle<Object> ContextDeserializer::Deserialize(
embedder_fields_deserializer);
DeserializeApiWrapperFields(
embedder_fields_deserializer.api_wrapper_callback);
+ PostProcessExposedTrustedObjects();
LogNewMapEvents();
}
diff --git a/deps/v8/src/snapshot/deserializer.cc b/deps/v8/src/snapshot/deserializer.cc
index c91280b71fc..9db502d38a2 100644
--- a/deps/v8/src/snapshot/deserializer.cc
+++ b/deps/v8/src/snapshot/deserializer.cc
@@ -21,6 +21,7 @@
#include "src/logging/local-logger.h"
#include "src/logging/log.h"
#include "src/objects/backing-store.h"
+#include "src/objects/bytecode-array-inl.h"
#include "src/objects/heap-object-field-inl.h"
#include "src/objects/heap-object-set-map-inl.h"
#include "src/objects/js-array-buffer-inl.h"
@@ -29,7 +30,9 @@
#include "src/objects/objects.h"
#include "src/objects/slots.h"
#include "src/objects/string.h"
+#include "src/objects/trusted-object-inl.h"
#include "src/roots/roots.h"
+#include "src/sandbox/bytecode-verifier.h"
#include "src/sandbox/js-dispatch-table-inl.h"
#include "src/snapshot/embedded/embedded-data-inl.h"
#include "src/snapshot/references.h"
@@ -37,6 +40,7 @@
#include "src/snapshot/shared-heap-serializer.h"
#include "src/snapshot/snapshot-data.h"
#include "src/utils/memcopy.h"
+#include "src/zone/zone.h"
// Has to be the last include (doesn't have include guards)
#include "src/objects/object-macros.h"
@@ -334,6 +338,7 @@ Deserializer<IsolateT>::Deserializer(IsolateT* isolate,
interceptor_infos_(isolate),
function_template_infos_(isolate),
new_scripts_(isolate),
+ new_exposed_trusted_objects_(isolate),
deserializing_user_code_(deserializing_user_code),
should_rehash_((v8_flags.rehash_snapshot && can_rehash) ||
deserializing_user_code),
@@ -438,6 +443,22 @@ void Deserializer<IsolateT>::LogScriptEvents(Tagged<Script> script) {
LOG(isolate(), ScriptDetails(script));
}
+template <typename IsolateT>
+void Deserializer<IsolateT>::PostProcessExposedTrustedObjects() {
+#ifdef V8_ENABLE_SANDBOX
+ Zone zone(isolate()->allocator(), ZONE_NAME);
+ for (DirectHandle<ExposedTrustedObject> obj : new_exposed_trusted_objects()) {
+ if (Is<BytecodeArray>(*obj)) {
+ DirectHandle<BytecodeArray> bytecode = TrustedCast<BytecodeArray>(obj);
+ BytecodeVerifier::Verify(isolate(), indirect_handle(bytecode, isolate()),
+ &zone);
+ } else {
+ obj->Publish(isolate());
+ }
+ }
+#endif
+}
+
namespace {
template <typename IsolateT>
uint32_t ComputeRawHashField(IsolateT* isolate, Tagged<String> string) {
@@ -1494,7 +1515,9 @@ int Deserializer<IsolateT>::ReadInitializeSelfIndirectPointer(
Tagged<ExposedTrustedObject> host =
TrustedCast<ExposedTrustedObject>(*slot_accessor.object());
- host->InitAndPublish(isolate());
+ host->InitDontPublish(isolate());
+ new_exposed_trusted_objects_.push_back(
+ TrustedCast<ExposedTrustedObject>(slot_accessor.object()));
return 1;
#else
diff --git a/deps/v8/src/snapshot/deserializer.h b/deps/v8/src/snapshot/deserializer.h
index e42a00dfd9e..12c74d5e9e8 100644
--- a/deps/v8/src/snapshot/deserializer.h
+++ b/deps/v8/src/snapshot/deserializer.h
@@ -28,6 +28,7 @@ namespace internal {
class HeapObject;
class Object;
+class ExposedTrustedObject;
// Used for platforms with embedded constant pools to trigger deserialization
// of objects found in code.
@@ -60,6 +61,8 @@ class Deserializer : public SerializerDeserializer {
void LogScriptEvents(Tagged<Script> script);
void LogNewMapEvents();
+ void PostProcessExposedTrustedObjects();
+
// This returns the address of an object that has been described in the
// snapshot by object vector index.
Handle<HeapObject> GetBackReferencedObject();
@@ -102,6 +105,11 @@ class Deserializer : public SerializerDeserializer {
base::Vector<const DirectHandle<Script>> new_scripts() const {
return {new_scripts_.data(), new_scripts_.size()};
}
+ base::Vector<const DirectHandle<ExposedTrustedObject>>
+ new_exposed_trusted_objects() const {
+ return {new_exposed_trusted_objects_.data(),
+ new_exposed_trusted_objects_.size()};
+ }
std::shared_ptr<BackingStore> backing_store(size_t i) {
DCHECK_LT(i, backing_stores_.size());
@@ -290,6 +298,7 @@ class Deserializer : public SerializerDeserializer {
DirectHandleVector<InterceptorInfo> interceptor_infos_;
DirectHandleVector<FunctionTemplateInfo> function_template_infos_;
DirectHandleVector<Script> new_scripts_;
+ DirectHandleVector<ExposedTrustedObject> new_exposed_trusted_objects_;
std::vector<std::shared_ptr<BackingStore>> backing_stores_;
// Vector of allocated objects that can be accessed by a backref, by index.
diff --git a/deps/v8/src/snapshot/object-deserializer.cc b/deps/v8/src/snapshot/object-deserializer.cc
index 00f4da9bea1..6411f966431 100644
--- a/deps/v8/src/snapshot/object-deserializer.cc
+++ b/deps/v8/src/snapshot/object-deserializer.cc
@@ -9,8 +9,12 @@
#include "src/heap/local-factory-inl.h"
#include "src/objects/allocation-site-inl.h"
#include "src/objects/allocation-site.h"
+#include "src/objects/bytecode-array-inl.h"
#include "src/objects/objects.h"
+#include "src/objects/trusted-object-inl.h"
+#include "src/sandbox/bytecode-verifier.h"
#include "src/snapshot/code-serializer.h"
+#include "src/zone/zone.h"
namespace v8 {
namespace internal {
@@ -62,6 +66,7 @@ void ObjectDeserializer::CommitPostProcessedObjects() {
MaybeObjectDirectHandle::Weak(script));
isolate()->heap()->SetRootScriptList(*list);
}
+ PostProcessExposedTrustedObjects();
}
void ObjectDeserializer::LinkAllocationSites() {
@@ -122,7 +127,12 @@ MaybeDirectHandle<HeapObject> OffThreadObjectDeserializer::Deserialize(
}
Rehash();
+ CommitPostProcessedObjects(deserialized_scripts);
+ return scope.CloseAndEscape(result);
+}
+void OffThreadObjectDeserializer::CommitPostProcessedObjects(
+ std::vector<IndirectHandle<Script>>* deserialized_scripts) {
// TODO(leszeks): Figure out a better way of dealing with scripts.
CHECK_EQ(new_scripts().size(), 1);
for (DirectHandle<Script> script : new_scripts()) {
@@ -132,8 +142,7 @@ MaybeDirectHandle<HeapObject> OffThreadObjectDeserializer::Deserialize(
deserialized_scripts->push_back(
isolate()->heap()->NewPersistentHandle(script));
}
-
- return scope.CloseAndEscape(result);
+ PostProcessExposedTrustedObjects();
}
} // namespace internal
diff --git a/deps/v8/src/snapshot/object-deserializer.h b/deps/v8/src/snapshot/object-deserializer.h
index 61b25cdf24a..bb045714b1f 100644
--- a/deps/v8/src/snapshot/object-deserializer.h
+++ b/deps/v8/src/snapshot/object-deserializer.h
@@ -44,6 +44,9 @@ class OffThreadObjectDeserializer final : public Deserializer<LocalIsolate> {
// Deserialize an object graph. Fail gracefully.
MaybeDirectHandle<HeapObject> Deserialize(
std::vector<IndirectHandle<Script>>* deserialized_scripts);
+
+ void CommitPostProcessedObjects(
+ std::vector<IndirectHandle<Script>>* deserialized_scripts);
};
} // namespace internal
diff --git a/deps/v8/src/snapshot/read-only-deserializer.cc b/deps/v8/src/snapshot/read-only-deserializer.cc
index 10b47bb5067..ed0b1d90021 100644
--- a/deps/v8/src/snapshot/read-only-deserializer.cc
+++ b/deps/v8/src/snapshot/read-only-deserializer.cc
@@ -440,6 +440,7 @@ void ReadOnlyDeserializer::PostProcessNewObjects() {
trusted_pointer_entries;
#endif // V8_ENABLE_SANDBOX
for (Tagged<HeapObject> o = it.Next(); !o.is_null(); o = it.Next()) {
+ if (IsInaccessible(o)) continue;
const InstanceType instance_type = o->map()->instance_type();
if (should_rehash()) {
if (InstanceTypeChecker::IsString(instance_type)) {
diff --git a/deps/v8/src/snapshot/read-only-serializer.cc b/deps/v8/src/snapshot/read-only-serializer.cc
index 222ebb9723d..027e181673d 100644
--- a/deps/v8/src/snapshot/read-only-serializer.cc
+++ b/deps/v8/src/snapshot/read-only-serializer.cc
@@ -431,6 +431,14 @@ class ReadOnlyHeapImageSerializer {
int size;
};
static std::optional<UnmappedBody> GetUnmappedBody(Tagged<HeapObject> obj) {
+#if V8_ENABLE_WEBASSEMBLY && \
+ (V8_STATIC_ROOTS_BOOL || V8_STATIC_ROOTS_GENERATION_BOOL)
+ // We must check for WasmNull before any of the other TryCast<...> below
+ // attempt to load obj's instance type.
+ if (Tagged<WasmNull> wasm_null; TryCast<WasmNull>(obj, &wasm_null)) {
+ return {{wasm_null.address(), WasmNull::kSize}};
+ }
+#endif // V8_ENABLE_WEBASSEMBLY && ...
if (Tagged<FreeSpace> free_space; TryCast<FreeSpace>(obj, &free_space)) {
return {{free_space.address() + sizeof(FreeSpace),
free_space->Size() - static_cast<int>(sizeof(FreeSpace))}};
@@ -439,12 +447,6 @@ class ReadOnlyHeapImageSerializer {
return {{hole.address() + sizeof(HeapObject),
sizeof(Hole) - sizeof(HeapObject)}};
}
-#ifdef V8_ENABLE_WEBASSEMBLY
- if (Tagged<WasmNull> wasm_null; TryCast<WasmNull>(obj, &wasm_null)) {
- return {{wasm_null.address() + WasmNull::kHeaderSize,
- WasmNull::kSize - WasmNull::kHeaderSize}};
- }
-#endif
return {};
}
@@ -495,10 +497,11 @@ class ReadOnlyHeapImageSerializer {
// Serialize a segment from the current pos, up to the start of the
// unmapped body.
ptrdiff_t segment_size = unmapped_body->start - pos;
- CHECK_GT(segment_size, 0);
- ReadOnlySegmentForSerialization segment(isolate_, page, pos, segment_size,
- &pre_processor_);
- EmitSegment(&segment);
+ if (segment_size > 0) {
+ ReadOnlySegmentForSerialization segment(isolate_, page, pos,
+ segment_size, &pre_processor_);
+ EmitSegment(&segment);
+ }
if (v8_flags.trace_serializer) {
PrintF(
@@ -570,6 +573,7 @@ void ReadOnlySerializer::Serialize() {
ReadOnlyHeapObjectIterator it(isolate()->read_only_heap());
for (Tagged<HeapObject> o = it.Next(); !o.is_null(); o = it.Next()) {
+ if (IsInaccessible(o)) continue;
CheckRehashability(o);
if (v8_flags.serialization_statistics) {
CountAllocation(o->map(), o->Size(), SnapshotSpace::kReadOnlyHeap);
diff --git a/deps/v8/src/snapshot/serializer.cc b/deps/v8/src/snapshot/serializer.cc
index 7673cbcb5de..9c5161c76e8 100644
--- a/deps/v8/src/snapshot/serializer.cc
+++ b/deps/v8/src/snapshot/serializer.cc
@@ -24,6 +24,7 @@
#include "src/objects/slots-inl.h"
#include "src/objects/slots.h"
#include "src/objects/smi.h"
+#include "src/sandbox/check.h"
#include "src/sandbox/js-dispatch-table-inl.h"
#include "src/snapshot/embedded/embedded-data.h"
#include "src/snapshot/serializer-deserializer.h"
@@ -536,6 +537,7 @@ void Serializer::ObjectSerializer::SerializePrologue(SnapshotSpace space,
// initialized before the pending reference is resolved. Otherwise, the
// object cannot be referenced.
if (V8_ENABLE_SANDBOX_BOOL && IsExposedTrustedObject(*object_)) {
+ SBXCHECK_EQ(space, SnapshotSpace::kTrusted);
sink_->Put(kInitializeSelfIndirectPointer,
"InitializeSelfIndirectPointer");
}
@@ -712,17 +714,11 @@ void Serializer::ObjectSerializer::SerializeExternalString() {
if (serializer_->external_reference_encoder_.TryEncode(resource).To(
&reference)) {
DCHECK(reference.is_from_api());
-#ifdef V8_ENABLE_SANDBOX
- uint32_t external_pointer_entry =
- string->GetResourceRefForDeserialization();
-#endif
- string->SetResourceRefForSerialization(reference.index());
+ // 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();
-#ifdef V8_ENABLE_SANDBOX
- string->SetResourceRefForSerialization(external_pointer_entry);
-#else
- string->set_address_as_resource(isolate(), resource);
-#endif
+ string->RestoreResourceRefs(isolate(), refs);
} else {
SerializeExternalStringAsSequentialString();
}
@@ -1141,12 +1137,14 @@ void Serializer::ObjectSerializer::VisitCppHeapPointer(
PtrComprCageBase cage_base(isolate());
// Currently there's only very limited support for CppHeapPointerSlot
- // serialization as it's only used for API wrappers.
+ // serialization.
//
// We serialize the slot as initialized-but-unused slot. The actual API
// wrapper serialization is implemented in
// `ContextSerializer::SerializeApiWrapperFields()`.
- DCHECK(IsJSApiWrapperObjectMap(object_->map()) || IsNativeContext(*object_));
+ DCHECK(IsJSApiWrapperObjectMap(object_->map()) || IsNativeContext(*object_) ||
+ IsCppGCManagedBase(*object_) ||
+ IsEmbedderDataArray(*object_));
static_assert(kCppHeapPointerSlotSize % kTaggedSize == 0);
sink_->Put(
FixedRawDataWithSize::Encode(kCppHeapPointerSlotSize >> kTaggedSizeLog2),
@@ -1166,39 +1164,27 @@ void Serializer::ObjectSerializer::VisitExternalPointer(
InstanceTypeChecker::IsFunctionTemplateInfo(instance_type)) {
// If necessary, output any raw data preceding this slot.
OutputRawData(slot.address());
- Address value = slot.load(isolate());
#ifdef V8_ENABLE_SANDBOX
+ ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
+ const ExternalPointerTable& table =
+ IsolateForSandbox(isolate()).GetExternalPointerTableFor(
+ slot.tag_range());
+ Address value = table.Get(handle, slot.tag_range());
// We need to load the actual tag from the table here since the slot may
// use a generic tag (e.g. kAnyExternalPointerTag) if the concrete tag is
// unknown by the visitor (for example the case for Foreigns).
- ExternalPointerHandle handle = slot.Relaxed_LoadHandle();
- ExternalPointerTag tag = isolate()->external_pointer_table().GetTag(handle);
+ ExternalPointerTag tag = table.GetTag(handle);
#else
+ Address value = slot.load(isolate());
ExternalPointerTag tag = kExternalPointerNullTag;
#endif // V8_ENABLE_SANDBOX
const bool sandboxify = V8_ENABLE_SANDBOX_BOOL;
OutputExternalReference(value, kSystemPointerSize, sandboxify, tag);
bytes_processed_so_far_ += kExternalPointerSlotSize;
-
-#ifndef V8_CPPGC_MICROTASK_QUEUE
- } else if (InstanceTypeChecker::IsNativeContext(instance_type)) {
- // If necessary, output any raw data preceding this slot.
- OutputRawData(slot.address());
- // Serialize MicrotaskQueue* value as nullptr (it'll be set to correct
- // value during deserialization anyway).
- const bool sandboxify = V8_ENABLE_SANDBOX_BOOL;
- OutputExternalReference(kNullAddress, kSystemPointerSize, sandboxify,
- kNativeContextMicrotaskQueueTag);
- bytes_processed_so_far_ += kExternalPointerSlotSize;
-#endif // V8_CPPGC_MICROTASK_QUEUE
-
} else {
// Serialization of external references in other objects is handled
// elsewhere or not supported.
DCHECK(
- // Serialization of external pointers stored in EmbedderDataArray
- // is not supported yet, mostly because it's not used.
- InstanceTypeChecker::IsEmbedderDataArray(instance_type) ||
// See ObjectSerializer::SerializeJSTypedArray().
InstanceTypeChecker::IsJSTypedArray(instance_type) ||
// See ObjectSerializer::SerializeJSArrayBuffer().
@@ -1346,7 +1332,6 @@ void Serializer::ObjectSerializer::VisitJSDispatchTableEntry(
sink_->Put(kJSDispatchEntry, "JSDispatchEntry");
sink_->PutUint30(it->second, "EntryID");
}
-
}
namespace {
@@ -1419,8 +1404,10 @@ void Serializer::ObjectSerializer::OutputRawData(Address up_to) {
// make the snapshot content deterministic.
SeqString::DataAndPaddingSizes sizes =
Cast<SeqString>(*object_)->GetDataAndPaddingSizes();
- DCHECK_EQ(bytes_to_output, sizes.data_size - base + sizes.padding_size);
+ SBXCHECK_EQ(bytes_to_output, sizes.data_size - base + sizes.padding_size);
int data_bytes_to_output = sizes.data_size - base;
+ SBXCHECK_GE(data_bytes_to_output, 0);
+ SBXCHECK_GE(sizes.padding_size, 0);
sink_->PutRaw(reinterpret_cast<uint8_t*>(object_start + base),
data_bytes_to_output, "SeqStringData");
sink_->PutN(sizes.padding_size, 0, "SeqStringPadding");
diff --git a/deps/v8/src/snapshot/shared-heap-deserializer.cc b/deps/v8/src/snapshot/shared-heap-deserializer.cc
index 0c8d63187ac..bc302869d69 100644
--- a/deps/v8/src/snapshot/shared-heap-deserializer.cc
+++ b/deps/v8/src/snapshot/shared-heap-deserializer.cc
@@ -26,6 +26,7 @@ void SharedHeapDeserializer::DeserializeIntoIsolate() {
IterateSharedHeapObjectCache(isolate(), this);
DeserializeStringTable();
DeserializeDeferredObjects();
+ PostProcessExposedTrustedObjects();
if (should_rehash()) {
// The hash seed has already been initialized in ReadOnlyDeserializer, thus
diff --git a/deps/v8/src/snapshot/startup-deserializer.cc b/deps/v8/src/snapshot/startup-deserializer.cc
index 500644df1f1..c2c1e0adbd1 100644
--- a/deps/v8/src/snapshot/startup-deserializer.cc
+++ b/deps/v8/src/snapshot/startup-deserializer.cc
@@ -50,6 +50,7 @@ void StartupDeserializer::DeserializeIntoIsolate() {
isolate()->heap()->IterateWeakRoots(
this, base::EnumSet<SkipRoot>{SkipRoot::kUnserializable});
DeserializeDeferredObjects();
+ PostProcessExposedTrustedObjects();
if (USE_SIMULATOR_BOOL) {
for (DirectHandle<AccessorInfo> info : accessor_infos()) {
info->RestoreCallbackRedirectionAfterDeserialization(isolate());
diff --git a/deps/v8/src/strings/string-stream.cc b/deps/v8/src/strings/string-stream.cc
index 2be47011bb0..669e1e19118 100644
--- a/deps/v8/src/strings/string-stream.cc
+++ b/deps/v8/src/strings/string-stream.cc
@@ -11,6 +11,7 @@
#include "src/logging/log.h"
#include "src/objects/heap-object.h"
#include "src/objects/js-array-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/prototype.h"
diff --git a/deps/v8/src/strings/unicode.h b/deps/v8/src/strings/unicode.h
index 79252be161e..8fec602bf95 100644
--- a/deps/v8/src/strings/unicode.h
+++ b/deps/v8/src/strings/unicode.h
@@ -317,4 +317,64 @@ struct V8_EXPORT_PRIVATE CanonicalizationRange {
} // namespace unibrow
+namespace v8::internal {
+
+class UnicodeConfig {
+ public:
+ constexpr explicit UnicodeConfig(unibrow::Utf8Variant variant)
+ : UnicodeConfig(variant, SharedFlag{false}, SharedFlag{false}) {}
+
+ constexpr UnicodeConfig(unibrow::Utf8Variant variant,
+ SharedFlag source_shared, SharedFlag dest_shared)
+ : flags_(VariantField::encode(variant) |
+ SourceSharedField::encode(source_shared.value()) |
+ DestSharedField::encode(dest_shared.value())) {}
+
+ constexpr UnicodeConfig(SharedFlag source_shared, SharedFlag dest_shared)
+ : flags_(SourceSharedField::encode(source_shared.value()) |
+ DestSharedField::encode(dest_shared.value())) {}
+
+ explicit constexpr UnicodeConfig(uint32_t raw_flags) : flags_(raw_flags) {}
+
+ // Predefined convenience constants.
+ static constexpr UnicodeConfig kLossyUtf8Unshared() {
+ return UnicodeConfig(unibrow::Utf8Variant::kLossyUtf8, SharedFlag{false},
+ SharedFlag{false});
+ }
+ static constexpr UnicodeConfig kLossyUtf8Shared() {
+ return UnicodeConfig(unibrow::Utf8Variant::kLossyUtf8, SharedFlag{true},
+ SharedFlag{true});
+ }
+ static constexpr UnicodeConfig kWtf16Unshared() {
+ return UnicodeConfig(SharedFlag{false}, SharedFlag{false});
+ }
+ static constexpr UnicodeConfig kWtf16Shared() {
+ return UnicodeConfig(SharedFlag{true}, SharedFlag{true});
+ }
+
+ constexpr unibrow::Utf8Variant variant() const {
+ return VariantField::decode(flags_);
+ }
+ constexpr bool source_shared() const {
+ return SourceSharedField::decode(flags_);
+ }
+ constexpr bool dest_shared() const { return DestSharedField::decode(flags_); }
+ constexpr int32_t raw_as_int() const { return static_cast<int32_t>(flags_); }
+
+ private:
+ // When used for WTF16 operations, this field is unused/ignored.
+ using VariantField = base::BitField<unibrow::Utf8Variant, 0, 3>;
+ // "source shared" indicates whether the source data/array can be concurrently
+ // modified and should hence be copied before multiple passes over it can
+ // rely on seeing the same bits.
+ using SourceSharedField = VariantField::Next<bool, 1>;
+ // "dest shared" controls whether the result of the operation should be
+ // allocated in shared space.
+ using DestSharedField = SourceSharedField::Next<bool, 1>;
+
+ uint32_t flags_ = 0;
+};
+
+} // namespace v8::internal
+
#endif // V8_STRINGS_UNICODE_H_
diff --git a/deps/v8/src/torque/constants.h b/deps/v8/src/torque/constants.h
index b0d1720e65f..b057b9f2111 100644
--- a/deps/v8/src/torque/constants.h
+++ b/deps/v8/src/torque/constants.h
@@ -95,6 +95,8 @@ static const char* const ANNOTATION_HAS_SAME_INSTANCE_TYPE_AS_PARENT =
"@hasSameInstanceTypeAsParent";
static const char* const ANNOTATION_DO_NOT_GENERATE_CPP_CLASS =
"@doNotGenerateCppClass";
+static const char* const ANNOTATION_DO_NOT_GENERATE_INSTANCE_TYPE_CHECK =
+ "@doNotGenerateInstanceTypeCheck";
static const char* const ANNOTATION_CUSTOM_MAP = "@customMap";
static const char* const ANNOTATION_CUSTOM_CPP_CLASS = "@customCppClass";
static const char* const ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT =
@@ -173,9 +175,10 @@ enum class ClassFlag {
kHighestInstanceTypeWithinParent = 1 << 6,
kLowestInstanceTypeWithinParent = 1 << 7,
kUndefinedLayout = 1 << 8,
- kExport = 1 << 10,
- kDoNotGenerateCast = 1 << 11,
- kCppObjectLayoutDefinition = 1 << 14,
+ kExport = 1 << 9,
+ kDoNotGenerateCast = 1 << 10,
+ kDoNotGenerateInstanceTypeCheck = 1 << 11,
+ kCppObjectLayoutDefinition = 1 << 12,
};
using ClassFlags = base::Flags<ClassFlag>;
diff --git a/deps/v8/src/torque/implementation-visitor.cc b/deps/v8/src/torque/implementation-visitor.cc
index 4ddcd25d3ee..eec2a04006d 100644
--- a/deps/v8/src/torque/implementation-visitor.cc
+++ b/deps/v8/src/torque/implementation-visitor.cc
@@ -2728,15 +2728,21 @@ std::pair<std::string, std::string> GetClassInstanceTypeRange(
const ClassType* class_type) {
std::pair<std::string, std::string> result;
if (class_type->InstanceTypeRange()) {
- auto instance_type_range = *class_type->InstanceTypeRange();
- std::string instance_type_string_first =
- "static_cast<InstanceType>(" +
- std::to_string(instance_type_range.first) + ")";
- std::string instance_type_string_second =
- "static_cast<InstanceType>(" +
- std::to_string(instance_type_range.second) + ")";
+ // Emit the named FIRST_/LAST_ range markers rather than the integer
+ // literals Torque computed at codegen time. After the metagen cutover
+ // the IT values come from tools/metagen/, not from Torque, so any
+ // literal here would be stale. Always use the range form, never the
+ // bare _TYPE symbol: whether a class covers one instance type or a
+ // range is also metagen's call (its C++-derived hierarchy can have
+ // subclasses Torque doesn't know about), and DownCastForTorqueClass
+ // decides equality-check vs range-check from these constants at C++
+ // compile time. Both generators emit FIRST_/LAST_ markers for every
+ // class, aliasing the sole value for single-instance-type classes.
+ const std::string type_name =
+ CapifyStringWithUnderscores(class_type->name()) + "_TYPE";
result =
- std::make_pair(instance_type_string_first, instance_type_string_second);
+ std::make_pair("static_cast<InstanceType>(FIRST_" + type_name + ")",
+ "static_cast<InstanceType>(LAST_" + type_name + ")");
} else {
ReportError(
"%Min/MaxInstanceType must take a class type that is either a string "
@@ -4023,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 + ")";
}
@@ -4116,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/instance-type-generator.cc b/deps/v8/src/torque/instance-type-generator.cc
index 5d9d84cfcc7..376984a4a39 100644
--- a/deps/v8/src/torque/instance-type-generator.cc
+++ b/deps/v8/src/torque/instance-type-generator.cc
@@ -284,46 +284,54 @@ std::unique_ptr<InstanceTypeTree> AssignInstanceTypes() {
}
// Prints items in macro lists for the given type and its descendants.
-// - definitions: This list is pairs of instance type name and assigned value,
-// such as V(ODDBALL_TYPE, 67). It includes FIRST_* and LAST_* items for each
-// type that has more than one associated InstanceType. Items within those
-// ranges are indented for readability.
-// - values: This list is just instance type names, like V(ODDBALL_TYPE). It
-// does not include any FIRST_* and LAST_* range markers.
-// - fully_defined_single_instance_types: This list is pairs of class name and
-// instance type, for classes which have defined layouts and a single
-// corresponding instance type.
-// - fully_defined_multiple_instance_types: This list is pairs of class name and
-// instance type, for classes which have defined layouts and subclasses.
-// - only_declared_single_instance_types: This list is pairs of class name and
-// instance type, for classes which have a single corresponding instance type
-// and do not have layout definitions in Torque.
-// - only_declared_multiple_instance_types: This list is pairs of class name and
-// instance type, for classes which have subclasses but also have a single
-// corresponding instance type, and do not have layout definitions in Torque.
-// - fully_defined_range_instance_types: This list is triples of class name,
-// first instance type, and last instance type, for classes which have defined
-// layouts and multiple corresponding instance types.
-// - only_declared_range_instance_types: This list is triples of class name,
-// first instance type, and last instance type, for classes which have
-// multiple corresponding instance types and do not have layout definitions in
-// Torque.
+// - definitions: pairs of instance type name and assigned value, such as
+// V(ODDBALL_TYPE, 67). Includes FIRST_*/LAST_* items for each type that has
+// more than one associated InstanceType, with items within those ranges
+// indented for readability.
+// - values: just instance type names, like V(ODDBALL_TYPE). Does not include
+// any FIRST_*/LAST_* range markers.
+// - debug_reader_classes_single: pairs of (ClassName, INSTANCE_TYPE) for
+// classes that have a Torque body (`extern class X extends Y { ... }`) and
+// a single corresponding instance type. Drives consumers that need to map
+// IT -> TqClass debug reader (debug_helper, gen-postmortem-metadata).
+// - debug_reader_classes_multiple: same, for classes with a body and
+// subclasses sharing the IT.
+// - debug_reader_classes_range: triples of (ClassName, FIRST_TYPE, LAST_TYPE)
+// for classes with a body spanning a contiguous IT range.
+// Body-less Torque declarations (`extern class X extends Y;`) get no entry
+// in the debug-reader lists -- Torque emits no TqClass for them.
+// The `it_list_*` streams below reproduce metagen's
+// INSTANCE_TYPE_LIST_{SINGLE,MULTIPLE,RANGE} buckets (instance_types.py)
+// so the torque path (V8_USE_METAGEN_INSTANCE_TYPES=0) can drive the same
+// instance-type-checker.h / instance-type-inl.h consumers as metagen.
+// Unlike the debug-reader lists, these include body-less declarations
+// (HasUndefinedLayout()), because the checkers map IT -> class for every
+// IT-bearing class, not just those Torque has a layout for.
+// TODO(jgruber): remove together with the V8_USE_METAGEN_INSTANCE_TYPES switch
+// once metagen is the sole instance-type generator.
void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
std::ostream& values,
- std::ostream& fully_defined_single_instance_types,
- std::ostream& fully_defined_multiple_instance_types,
- std::ostream& only_declared_single_instance_types,
- std::ostream& only_declared_multiple_instance_types,
- std::ostream& fully_defined_range_instance_types,
- std::ostream& only_declared_range_instance_types,
+ std::ostream& debug_reader_classes_single,
+ std::ostream& debug_reader_classes_multiple,
+ std::ostream& debug_reader_classes_range,
+ std::ostream& it_list_single,
+ std::ostream& it_list_multiple,
+ std::ostream& it_list_range,
const std::string& indent) {
std::string type_name =
CapifyStringWithUnderscores(root->type->name()) + "_TYPE";
std::string inner_indent = indent;
+ // Every type gets FIRST_/LAST_ range markers, aliasing the sole value for
+ // single-instance-type classes. Generated CSA references the range markers
+ // unconditionally (see GetClassInstanceTypeRange), so the single-vs-range
+ // decision in DownCastForTorqueClass is made against the values in the
+ // active instance-types.h (which may be metagen's, whose class hierarchy
+ // can diverge from Torque's) instead of being baked in at Torque codegen
+ // time.
+ definitions << indent << "V(FIRST_" << type_name << ", " << root->start
+ << ") \\\n";
if (root->num_values > 1) {
- definitions << indent << "V(FIRST_" << type_name << ", " << root->start
- << ") \\\n";
inner_indent += " ";
}
if (root->num_own_values == 1) {
@@ -331,41 +339,46 @@ void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
<< ") /* " << root->type->GetPosition() << " */\\\n";
values << " V(" << type_name << ") /* " << root->type->GetPosition()
<< " */\\\n";
- std::ostream& type_checker_list =
- root->type->HasUndefinedLayout()
- ? (root->num_values == 1 ? only_declared_single_instance_types
- : only_declared_multiple_instance_types)
- : (root->num_values == 1 ? fully_defined_single_instance_types
- : fully_defined_multiple_instance_types);
- type_checker_list << " V(" << root->type->name() << ", " << type_name
- << ") /* " << root->type->GetPosition() << " */ \\\n";
+ if (!root->type->DoNotGenerateInstanceTypeCheck()) {
+ if (!root->type->HasUndefinedLayout()) {
+ std::ostream& sink = root->num_values == 1
+ ? debug_reader_classes_single
+ : debug_reader_classes_multiple;
+ sink << " V(" << root->type->name() << ", " << type_name << ") /* "
+ << root->type->GetPosition() << " */ \\\n";
+ }
+ std::ostream& it_sink =
+ root->num_values == 1 ? it_list_single : it_list_multiple;
+ it_sink << " V(" << root->type->name() << ", " << type_name << ") /* "
+ << root->type->GetPosition() << " */ \\\n";
+ }
}
for (auto& child : root->children) {
- PrintInstanceTypes(child.get(), definitions, values,
- fully_defined_single_instance_types,
- fully_defined_multiple_instance_types,
- only_declared_single_instance_types,
- only_declared_multiple_instance_types,
- fully_defined_range_instance_types,
- only_declared_range_instance_types, inner_indent);
+ PrintInstanceTypes(
+ child.get(), definitions, values, debug_reader_classes_single,
+ debug_reader_classes_multiple, debug_reader_classes_range,
+ it_list_single, it_list_multiple, it_list_range, inner_indent);
+ }
+ // We can't emit LAST_STRING_TYPE because it's not a valid flags
+ // combination. So if the class type has multiple own values, which only
+ // happens when using ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, then omit
+ // the end marker.
+ if (root->num_own_values <= 1) {
+ definitions << indent << "V(LAST_" << type_name << ", " << root->end
+ << ") \\\n";
}
- if (root->num_values > 1) {
- // We can't emit LAST_STRING_TYPE because it's not a valid flags
- // combination. So if the class type has multiple own values, which only
- // happens when using ANNOTATION_RESERVE_BITS_IN_INSTANCE_TYPE, then omit
- // the end marker.
- if (root->num_own_values <= 1) {
- definitions << indent << "V(LAST_" << type_name << ", " << root->end
- << ") \\\n";
- }
+ if (root->num_values > 1) {
// Only output the instance type range for things other than the root type.
- if (root->type->GetSuperClass() != nullptr) {
- std::ostream& range_instance_types =
- root->type->HasUndefinedLayout() ? only_declared_range_instance_types
- : fully_defined_range_instance_types;
- range_instance_types << " V(" << root->type->name() << ", FIRST_"
- << type_name << ", LAST_" << type_name << ") \\\n";
+ if (root->type->GetSuperClass() != nullptr &&
+ !root->type->DoNotGenerateInstanceTypeCheck()) {
+ if (!root->type->HasUndefinedLayout()) {
+ debug_reader_classes_range << " V(" << root->type->name() << ", FIRST_"
+ << type_name << ", LAST_" << type_name
+ << ") \\\n";
+ }
+ it_list_range << " V(" << root->type->name() << ", FIRST_" << type_name
+ << ", LAST_" << type_name << ") \\\n";
}
}
}
@@ -374,31 +387,35 @@ void PrintInstanceTypes(InstanceTypeTree* root, std::ostream& definitions,
void ImplementationVisitor::GenerateInstanceTypes(
const std::string& output_directory) {
+ std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes();
+ std::stringstream assigned_instance_types;
+ std::stringstream values_list;
+ std::stringstream debug_reader_classes_single;
+ std::stringstream debug_reader_classes_multiple;
+ std::stringstream debug_reader_classes_range;
+ std::stringstream it_list_single;
+ std::stringstream it_list_multiple;
+ std::stringstream it_list_range;
+ if (instance_types != nullptr) {
+ PrintInstanceTypes(instance_types.get(), assigned_instance_types,
+ values_list, debug_reader_classes_single,
+ debug_reader_classes_multiple,
+ debug_reader_classes_range, it_list_single,
+ it_list_multiple, it_list_range, " ");
+ }
+
+ // Emit `torque-generated/instance-types.h`: IT enum + IT-name list. Pure
+ // IT concern; consumed via src/objects/instance-types-gen.h's forwarder
+ // when V8_USE_METAGEN_INSTANCE_TYPES is 0.
std::stringstream header;
- std::string file_name = "instance-types.h";
+ const std::string file_name = "instance-types.h";
{
IncludeGuardScope guard(header, file_name);
header << "// Instance types for all classes except for those that use "
"InstanceType as flags.\n";
header << "#define TORQUE_ASSIGNED_INSTANCE_TYPES(V) \\\n";
- std::unique_ptr<InstanceTypeTree> instance_types = AssignInstanceTypes();
- std::stringstream values_list;
- std::stringstream fully_defined_single_instance_types;
- std::stringstream fully_defined_multiple_instance_types;
- std::stringstream only_declared_single_instance_types;
- std::stringstream only_declared_multiple_instance_types;
- std::stringstream fully_defined_range_instance_types;
- std::stringstream only_declared_range_instance_types;
- if (instance_types != nullptr) {
- PrintInstanceTypes(instance_types.get(), header, values_list,
- fully_defined_single_instance_types,
- fully_defined_multiple_instance_types,
- only_declared_single_instance_types,
- only_declared_multiple_instance_types,
- fully_defined_range_instance_types,
- only_declared_range_instance_types, " ");
- }
+ header << assigned_instance_types.str();
header << "\n";
header << "// Instance types for all classes except for those that use\n";
@@ -406,52 +423,84 @@ void ImplementationVisitor::GenerateInstanceTypes(
header << "#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V) \\\n";
header << values_list.str();
header << "\n";
-
- header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have\n";
- header << "// full Torque definitions.\n";
- header << "#define TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(V) \\\n";
- header << fully_defined_single_instance_types.str();
- header << "\n";
-
- header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have\n";
- header << "// full Torque definitions and subclasses.\n";
- header << "#define TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(V) \\\n";
- header << fully_defined_multiple_instance_types.str();
- header << "\n";
-
- header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n";
- header << "// declared but not defined in Torque. These classes may\n";
- header << "// correspond with actual C++ classes, but they are not\n";
- header << "// guaranteed to.\n";
- header << "#define TORQUE_INSTANCE_CHECKERS_SINGLE_ONLY_DECLARED(V) \\\n";
- header << only_declared_single_instance_types.str();
- header << "\n";
-
- header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that are\n";
- header << "// declared but not defined in Torque, and have subclasses.\n";
- header << "// These classes may correspond with actual C++ classes, but\n";
- header << "// they are not guaranteed to.\n";
- header << "#define TORQUE_INSTANCE_CHECKERS_MULTIPLE_ONLY_DECLARED(V) \\\n";
- header << only_declared_multiple_instance_types.str();
- header << "\n";
-
- header << "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes\n";
- header << "// that have full Torque definitions.\n";
- header << "#define TORQUE_INSTANCE_CHECKERS_RANGE_FULLY_DEFINED(V) \\\n";
- header << fully_defined_range_instance_types.str();
- header << "\n";
-
- header << "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes\n";
- header << "// that are declared but not defined in Torque. These classes\n";
- header << "// may correspond with actual C++ classes, but they are not\n";
- header << "// guaranteed to.\n";
- header << "#define TORQUE_INSTANCE_CHECKERS_RANGE_ONLY_DECLARED(V) \\\n";
- header << only_declared_range_instance_types.str();
- header << "\n";
-
}
- std::string output_header_path = output_directory + "/" + file_name;
- WriteFile(output_header_path, header.str());
+ WriteFile(output_directory + "/" + file_name, header.str());
+
+ // Emit `torque-generated/debug-reader-classes-list.h`: layout-availability
+ // concern (which classes Torque has a body for, and therefore emits a
+ // TqClass debug reader for). Consumed by tools/debug_helper and
+ // tools/gen-postmortem-metadata.py. Separate file (and separate include
+ // guard) from instance-types.h so consumers can include it independently
+ // of the IT enum, which they get from metagen via the forwarder.
+ std::stringstream debug_classes_header;
+ const std::string debug_classes_file = "debug-reader-classes-list.h";
+ {
+ IncludeGuardScope debug_classes_guard(debug_classes_header,
+ debug_classes_file);
+ debug_classes_header
+ << "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have a\n"
+ "// Torque body and a single corresponding instance type. The\n"
+ "// INSTANCE_TYPE symbols resolve via the IT enum provided by\n"
+ "// instance-types-gen.h (which forwards to metagen's emission\n"
+ "// by default).\n";
+ debug_classes_header
+ << "#define TORQUE_DEBUG_READER_CLASSES_SINGLE(V) \\\n";
+ debug_classes_header << debug_reader_classes_single.str();
+ debug_classes_header << "\n";
+
+ debug_classes_header
+ << "// Same, for classes whose IT is also held by subclasses.\n";
+ debug_classes_header
+ << "#define TORQUE_DEBUG_READER_CLASSES_MULTIPLE(V) \\\n";
+ debug_classes_header << debug_reader_classes_multiple.str();
+ debug_classes_header << "\n";
+
+ debug_classes_header
+ << "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes with\n"
+ "// a Torque body that span a contiguous IT range.\n";
+ debug_classes_header << "#define TORQUE_DEBUG_READER_CLASSES_RANGE(V) \\\n";
+ debug_classes_header << debug_reader_classes_range.str();
+ debug_classes_header << "\n";
+ }
+ WriteFile(output_directory + "/" + debug_classes_file,
+ debug_classes_header.str());
+
+ // Emit `torque-generated/instance-type-checker-lists.h`: the
+ // INSTANCE_TYPE_LIST_{SINGLE,MULTIPLE,RANGE} buckets that metagen emits
+ // into metagen/instance-types.h. Provided here so the torque path
+ // (V8_USE_METAGEN_INSTANCE_TYPES=0) can satisfy the same consumers. It is
+ // included only from src/objects/instance-types-gen.h's #else (torque)
+ // branch and is additionally guarded below, so the metagen path never
+ // sees it. Remove this file (and the #else include) once metagen is the
+ // sole instance-type generator.
+ std::stringstream it_lists_header;
+ const std::string it_lists_file = "instance-type-checker-lists.h";
+ {
+ IncludeGuardScope it_lists_guard(it_lists_header, it_lists_file);
+ it_lists_header << "#if !V8_USE_METAGEN_INSTANCE_TYPES\n";
+ it_lists_header
+ << "// Pairs of (ClassName, INSTANCE_TYPE) for classes whose instance\n"
+ "// type is unique to them (no subclasses share it).\n";
+ it_lists_header << "#define INSTANCE_TYPE_LIST_SINGLE(V) \\\n";
+ it_lists_header << it_list_single.str();
+ it_lists_header << "\n";
+
+ it_lists_header << "// Pairs of (ClassName, INSTANCE_TYPE) for classes "
+ "that have their\n"
+ "// own instance type and whose subclasses share it.\n";
+ it_lists_header << "#define INSTANCE_TYPE_LIST_MULTIPLE(V) \\\n";
+ it_lists_header << it_list_multiple.str();
+ it_lists_header << "\n";
+
+ it_lists_header
+ << "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes that\n"
+ "// span a contiguous range of instance types.\n";
+ it_lists_header << "#define INSTANCE_TYPE_LIST_RANGE(V) \\\n";
+ it_lists_header << it_list_range.str();
+ it_lists_header << "\n";
+ it_lists_header << "#endif // !V8_USE_METAGEN_INSTANCE_TYPES\n";
+ }
+ WriteFile(output_directory + "/" + it_lists_file, it_lists_header.str());
GlobalContext::SetInstanceTypesInitialized();
}
diff --git a/deps/v8/src/torque/torque-parser.cc b/deps/v8/src/torque/torque-parser.cc
index 5a06255c7bf..3511bec33fd 100644
--- a/deps/v8/src/torque/torque-parser.cc
+++ b/deps/v8/src/torque/torque-parser.cc
@@ -1039,6 +1039,7 @@ std::optional<ParseResult> MakeClassDeclaration(
ANNOTATION_DO_NOT_GENERATE_CPP_CLASS, ANNOTATION_CUSTOM_CPP_CLASS,
ANNOTATION_CUSTOM_MAP, ANNOTATION_EXPORT,
ANNOTATION_DO_NOT_GENERATE_CAST,
+ ANNOTATION_DO_NOT_GENERATE_INSTANCE_TYPE_CHECK,
ANNOTATION_HIGHEST_INSTANCE_TYPE_WITHIN_PARENT,
ANNOTATION_LOWEST_INSTANCE_TYPE_WITHIN_PARENT,
ANNOTATION_CPP_OBJECT_LAYOUT_DEFINITION},
@@ -1068,6 +1069,9 @@ std::optional<ParseResult> MakeClassDeclaration(
if (annotations.Contains(ANNOTATION_DO_NOT_GENERATE_CAST)) {
flags |= ClassFlag::kDoNotGenerateCast;
}
+ if (annotations.Contains(ANNOTATION_DO_NOT_GENERATE_INSTANCE_TYPE_CHECK)) {
+ flags |= ClassFlag::kDoNotGenerateInstanceTypeCheck;
+ }
if (annotations.Contains(ANNOTATION_EXPORT)) {
flags |= ClassFlag::kExport;
}
diff --git a/deps/v8/src/torque/types.h b/deps/v8/src/torque/types.h
index 7ede14edbec..33a569bd9d7 100644
--- a/deps/v8/src/torque/types.h
+++ b/deps/v8/src/torque/types.h
@@ -683,6 +683,9 @@ class ClassType final : public AggregateType {
bool DoNotGenerateCast() const {
return flags_ & ClassFlag::kDoNotGenerateCast;
}
+ bool DoNotGenerateInstanceTypeCheck() const {
+ return flags_ & ClassFlag::kDoNotGenerateInstanceTypeCheck;
+ }
bool IsTransient() const override { return flags_ & ClassFlag::kTransient; }
bool IsAbstract() const { return flags_ & ClassFlag::kAbstract; }
bool IsLayoutDefinedInCpp() const {
diff --git a/deps/v8/src/tracing/code-data-source.cc b/deps/v8/src/tracing/code-data-source.cc
index 38b735888b2..eb13ccb3ff1 100644
--- a/deps/v8/src/tracing/code-data-source.cc
+++ b/deps/v8/src/tracing/code-data-source.cc
@@ -34,12 +34,11 @@ using ::perfetto::protos::pbzero::TracePacket;
using ::protozero::ConstChars;
InternedV8JsScript::Type GetJsScriptType(Tagged<Script> script) {
- if (script->compilation_type() == Script::CompilationType::kEval) {
+ if (script->has_eval_origin()) {
return InternedV8JsScript::TYPE_EVAL;
}
- // TODO(carlscab): Camillo to extend the Script::Type enum. compilation_type
- // will no longer be needed.
+ // TODO(carlscab): Camillo to extend the Script::Type enum.
switch (script->type()) {
case Script::Type::kNative:
diff --git a/deps/v8/src/utils/address-map.cc b/deps/v8/src/utils/address-map.cc
index a2faf89d4b6..3521f24ce78 100644
--- a/deps/v8/src/utils/address-map.cc
+++ b/deps/v8/src/utils/address-map.cc
@@ -16,13 +16,13 @@ RootIndexMap::RootIndexMap(Isolate* isolate) {
map_ = new HeapObjectToIndexHashMap();
for (RootIndex root_index = RootIndex::kFirstStrongOrReadOnlyRoot;
root_index <= RootIndex::kLastStrongOrReadOnlyRoot; ++root_index) {
- Tagged<Object> root = isolate->root(root_index);
- if (!IsHeapObject(root)) continue;
// Omit root entries that can be written after initialization. They must
// not be referenced through the root list in the snapshot.
// Since we map the raw address of an root item to its root list index, the
// raw address must be constant, i.e. the object must be immovable.
if (RootsTable::IsImmortalImmovable(root_index)) {
+ Tagged<Object> root = isolate->root(root_index);
+ DCHECK(IsHeapObject(root));
Tagged<HeapObject> heap_object = Cast<HeapObject>(root);
Maybe<uint32_t> maybe_index = map_->Get(heap_object);
uint32_t index = static_cast<uint32_t>(root_index);
diff --git a/deps/v8/src/utils/boxed-float.h b/deps/v8/src/utils/boxed-float.h
index f6d95d71386..ae0a9670382 100644
--- a/deps/v8/src/utils/boxed-float.h
+++ b/deps/v8/src/utils/boxed-float.h
@@ -171,13 +171,6 @@ class Float64 {
#endif
is_hole_nan();
}
- bool has_undefined_or_hole_nan_high_bits() const {
- return
-#ifdef V8_ENABLE_UNDEFINED_DOUBLE
- ((get_bits() >> 32) == kUndefinedNanUpper32) ||
-#endif
- ((get_bits() >> 32) == kHoleNanUpper32);
- }
bool is_nan() const {
// Even though {get_scalar()} might set the quiet NaN bit, it's ok here,
@@ -191,6 +184,8 @@ class Float64 {
return is_nan() && (bit_pattern_ & (uint64_t{1} << 51));
}
+ bool is_signalling_nan() const { return is_nan() && !is_quiet_nan(); }
+
V8_WARN_UNUSED_RESULT Float64 to_quiet_nan() const {
DCHECK(is_nan());
Float64 quiet_nan{bit_pattern_ | (uint64_t{1} << 51)};
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 31c0782acbc..72a0c15e7b6 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
@@ -1298,7 +1298,7 @@ void LiftoffAssembler::AtomicExchangeTaggedPointer(
if (trapping_load_pc) *trapping_load_pc = pc_offset();
if constexpr (COMPRESS_POINTERS_BOOL) {
swpal(value.gp().W(), result.gp().W(), MemOperand(actual_addr));
- add(result.gp().X(), result.gp().X(), kPtrComprCageBaseRegister);
+ orr(result.gp().X(), result.gp().X(), kPtrComprCageBaseRegister);
} else {
swpal(value.gp(), result.gp(), MemOperand(actual_addr));
}
@@ -1318,7 +1318,7 @@ void LiftoffAssembler::AtomicExchangeTaggedPointer(
}
Cbnz(store_result.W(), &retry);
if constexpr (COMPRESS_POINTERS_BOOL) {
- add(result.gp().X(), result.gp().X(), kPtrComprCageBaseRegister);
+ orr(result.gp().X(), result.gp().X(), kPtrComprCageBaseRegister);
}
}
}
@@ -1495,7 +1495,7 @@ void LiftoffAssembler::AtomicCompareExchangeTaggedPointer(
Bind(&done);
if constexpr (COMPRESS_POINTERS_BOOL) {
- add(result.gp().X(), result.gp().X(), kPtrComprCageBaseRegister);
+ orr(result.gp().X(), result.gp().X(), kPtrComprCageBaseRegister);
}
}
diff --git a/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32-inl.h b/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32-inl.h
index 7e57a4be319..edcbbd074f7 100644
--- a/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32-inl.h
+++ b/deps/v8/src/wasm/baseline/ia32/liftoff-assembler-ia32-inl.h
@@ -7,6 +7,7 @@
#include <optional>
+#include "src/base/overflowing-math.h"
#include "src/codegen/assembler.h"
#include "src/codegen/interface-descriptors-inl.h"
#include "src/compiler/backend/simd-shuffle.h"
@@ -1647,9 +1648,7 @@ void LiftoffAssembler::emit_i32_sub(Register dst, Register lhs, Register rhs) {
void LiftoffAssembler::emit_i32_subi(Register dst, Register lhs, int32_t imm) {
if (dst != lhs) {
- // We'll have to implement an UB-safe version if we need this corner case.
- DCHECK_NE(imm, kMinInt);
- lea(dst, Operand(lhs, -imm));
+ lea(dst, Operand(lhs, base::NegateWithWraparound(imm)));
} else {
sub(dst, Immediate(imm));
}
@@ -3340,7 +3339,7 @@ void LiftoffAssembler::emit_i8x16_popcnt(LiftoffRegister dst,
Register scratch = GetUnusedRegister(RegClass::kGpReg, {}).gp();
XMMRegister tmp =
GetUnusedRegister(RegClass::kFpReg, LiftoffRegList{dst, src}).fp();
- I8x16Popcnt(dst.fp(), src.fp(), liftoff::kScratchDoubleReg, tmp, scratch);
+ I8x16Popcnt(dst.fp(), src.fp(), scratch, liftoff::kScratchDoubleReg, tmp);
}
void LiftoffAssembler::emit_i8x16_splat(LiftoffRegister dst,
@@ -4049,12 +4048,9 @@ void LiftoffAssembler::emit_i16x8_q15mulr_sat_s(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_relaxed_q15mulr_s(LiftoffRegister dst,
LiftoffRegister src1,
LiftoffRegister src2) {
- if (CpuFeatures::IsSupported(AVX) || dst == src1) {
- Pmulhrsw(dst.fp(), src1.fp(), src2.fp());
- } else {
- movdqa(dst.fp(), src1.fp());
- pmulhrsw(dst.fp(), src2.fp());
- }
+ liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmulhrsw,
+ &Assembler::pmulhrsw>(this, dst, src1, src2,
+ SSSE3);
}
void LiftoffAssembler::emit_i16x8_dot_i8x16_i7x16_s(LiftoffRegister dst,
diff --git a/deps/v8/src/wasm/baseline/liftoff-assembler.h b/deps/v8/src/wasm/baseline/liftoff-assembler.h
index f210dc7389b..c4e8c349880 100644
--- a/deps/v8/src/wasm/baseline/liftoff-assembler.h
+++ b/deps/v8/src/wasm/baseline/liftoff-assembler.h
@@ -107,6 +107,14 @@ class LiftoffAssembler : public MacroAssembler {
// A tagged value known to be a Smi can be treated like a ptr-sized int.
static constexpr ValueKind kSmiKind = kTaggedSize == kInt32Size ? kI32 : kI64;
+ // Whether {StoreConst} is implemented, i.e. whether integer constants can be
+ // stored to memory as immediates.
+#if V8_TARGET_ARCH_X64
+ static constexpr bool kSupportsStoreConst = true;
+#else
+ static constexpr bool kSupportsStoreConst = false;
+#endif
+
using ValueKindSig = Signature<ValueKind>;
using VarState = LiftoffVarState;
@@ -769,6 +777,20 @@ class LiftoffAssembler : public MacroAssembler {
LiftoffRegList pinned,
uint32_t* trapping_store_pc = nullptr,
bool is_store_mem = false, bool i64_offset = false);
+ // Store the integer constant {value} (sign-extended for i64 stores) as an
+ // immediate. Only implemented on architectures with an immediate store form;
+ // see {kSupportsStoreConst}.
+#if V8_TARGET_ARCH_X64
+ inline void StoreConst(Register dst_addr, Register offset_reg,
+ uintptr_t offset_imm, int32_t value, StoreType type,
+ uint32_t* trapping_store_pc, bool i64_offset);
+#else
+ inline void StoreConst(Register dst_addr, Register offset_reg,
+ uintptr_t offset_imm, int32_t value, StoreType type,
+ uint32_t* trapping_store_pc, bool i64_offset) {
+ UNREACHABLE();
+ }
+#endif
inline void AtomicLoad(LiftoffRegister dst, Register src_addr,
Register offset_reg, uintptr_t offset_imm,
LoadType type, uint32_t* trapping_load_pc,
diff --git a/deps/v8/src/wasm/baseline/liftoff-compiler.cc b/deps/v8/src/wasm/baseline/liftoff-compiler.cc
index 7d2411761a5..324a3570b97 100644
--- a/deps/v8/src/wasm/baseline/liftoff-compiler.cc
+++ b/deps/v8/src/wasm/baseline/liftoff-compiler.cc
@@ -22,6 +22,7 @@
#include "src/objects/contexts.h"
#include "src/objects/smi.h"
#include "src/roots/roots.h"
+#include "src/strings/unicode.h"
#include "src/tracing/trace-event.h"
#include "src/utils/ostreams.h"
#include "src/utils/utils.h"
@@ -131,6 +132,13 @@ struct assert_field_size {
// from exceeding backend limits (like register allocation timeouts).
constexpr int GetOpcodeCost(WasmOpcode opcode) {
switch (opcode) {
+ // Opcodes that trigger memory growth and external memory reallocation.
+ // Memory allocation, zeroing, and external memory GC accounting have high
+ // overhead, so we charge a higher static cost to prevent GC thrashing in
+ // loops.
+ case kExprMemoryGrow:
+ return 10000;
+
// Opcodes that trigger runtime calls and process bulk data.
// These can have execution times significantly higher than a single
// instruction and often involve complex backend lowering.
@@ -138,7 +146,6 @@ constexpr int GetOpcodeCost(WasmOpcode opcode) {
case kExprMemoryFill:
case kExprMemoryInit:
case kExprDataDrop:
- case kExprMemoryGrow:
case kExprTableCopy:
case kExprTableFill:
case kExprTableInit:
@@ -450,7 +457,8 @@ void CheckBailoutAllowed(LiftoffBailoutReason reason, const char* detail,
#define LIST_FEATURE(name, ...) WasmEnabledFeature::name,
constexpr WasmEnabledFeatures kExperimentalFeatures{
- FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(LIST_FEATURE)};
+ FOREACH_EXPERIMENTAL_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, LIST_FEATURE,
+ IGNORE_NON_WASM_FEATURE)};
#undef LIST_FEATURE
// Bailout is allowed if any experimental feature is enabled.
@@ -2224,21 +2232,40 @@ class LiftoffCompiler {
void ContNew(FullDecoder* decoder, const ContIndexImmediate& imm,
const Value& func_ref, Value* result) {
- unsupported(decoder, kWasmfx,
- "unimplemented Liftoff instruction: cont.new");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: cont.new");
+ }
}
void ContBind(FullDecoder* decoder, const ContIndexImmediate& orig_imm,
Value input_cont, const Value args[],
const ContIndexImmediate& new_imm, Value* result) {
- unsupported(decoder, kWasmfx,
- "unimplemented Liftoff instruction: cont.bind");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: cont.bind");
+ }
}
void Resume(FullDecoder* decoder, const ContIndexImmediate& imm,
base::Vector<HandlerCase> handlers, const Value& cont_ref,
const Value args[], const Value returns[]) {
- unsupported(decoder, kWasmfx, "unimplemented Liftoff instruction: resume");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: resume");
+ }
}
void ResumeHandler(FullDecoder* decoder, const HandlerCase& handler,
@@ -2252,8 +2279,14 @@ class LiftoffCompiler {
const TagIndexImmediate& exc_imm,
base::Vector<wasm::HandlerCase> handlers, const Value& cont,
const Value args[], const Value returns[]) {
- unsupported(decoder, kWasmfx,
- "unimplemented Liftoff instruction: resume_throw");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: resume_throw");
+ }
}
void ResumeThrowRef(FullDecoder* decoder,
@@ -2261,14 +2294,27 @@ class LiftoffCompiler {
base::Vector<wasm::HandlerCase> handlers,
const Value& cont, const Value& exn,
const Value returns[]) {
- unsupported(decoder, kWasmfx,
- "unimplemented Liftoff instruction: resume_throw_ref");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: resume_throw_ref");
+ }
}
void Switch(FullDecoder* decoder, const TagIndexImmediate& tag_imm,
const ContIndexImmediate& con_imm, const Value& cont_ref,
const Value args[], Value returns[]) {
- unsupported(decoder, kWasmfx, "unimplemented Liftoff instruction: switch");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: switch");
+ }
}
void BeginEffectHandlers(FullDecoder* decoder) { UNREACHABLE(); }
@@ -2277,7 +2323,14 @@ class LiftoffCompiler {
void Suspend(FullDecoder* decoder, const TagIndexImmediate& imm,
const Value args[], const Value returns[]) {
- unsupported(decoder, kWasmfx, "unimplemented Liftoff instruction: suspend");
+ // Use UNIMPLEMENTED under --liftoff-only to avoid spurious fuzzer reports.
+ // Otherwise, bail out to Turboshaft.
+ if (v8_flags.liftoff_only) {
+ UNIMPLEMENTED();
+ } else {
+ unsupported(decoder, kWasmfx,
+ "unimplemented Liftoff instruction: suspend");
+ }
}
// Before emitting the conditional branch, {will_freeze} will be initialized
@@ -2928,7 +2981,8 @@ class LiftoffCompiler {
return EmitBinOpImm<kI32, kI32>(&LiftoffAssembler::emit_i32_add,
&LiftoffAssembler::emit_i32_addi);
case kExprI32Sub:
- return EmitBinOp<kI32, kI32>(&LiftoffAssembler::emit_i32_sub);
+ return EmitBinOpImm<kI32, kI32>(&LiftoffAssembler::emit_i32_sub,
+ &LiftoffAssembler::emit_i32_subi);
case kExprI32Mul:
return EmitBinOp<kI32, kI32>(&LiftoffAssembler::emit_i32_mul);
case kExprI32And:
@@ -4620,18 +4674,28 @@ class LiftoffCompiler {
if (!CheckSupportedType(decoder, kind, "store")) return;
LiftoffRegList pinned;
- LiftoffRegister value = pinned.set(__ PopToRegister());
+ // Where the architecture has an immediate store form, store an integer
+ // constant directly instead of materializing it in a register first. Only
+ // i32 and i64 values are ever constant in the cache state, and Liftoff
+ // keeps i64 constants as sign-extended 32-bit values.
+ VarState value = __ PopVarState();
+ if (!LiftoffAssembler::kSupportsStoreConst || !value.is_const()) {
+ LiftoffRegister reg = pinned.set(__ LoadToRegister(value, pinned));
+ value.MakeRegister(reg);
+ }
if (type.value() == StoreType::kF32StoreF16 &&
!asm_.supports_f16_mem_access()) {
type = StoreType::kI32Store16;
- // {value} is always a float, so can't alias with {i16}.
+ // {value} is always a float, so it is never a constant and cannot
+ // alias with {i16}.
DCHECK_EQ(kF32, kind);
+ DCHECK(value.is_reg());
LiftoffRegister i16 = pinned.set(__ GetUnusedRegister(kGpReg, {}));
auto conv_ref = ExternalReference::wasm_float32_to_float16();
GenerateCCallWithStackBuffer(&i16, kVoid, kI16,
- {VarState{kF32, value, 0}}, conv_ref);
- value = i16;
+ {VarState{kF32, value.reg(), 0}}, conv_ref);
+ value.MakeRegister(i16);
}
uintptr_t offset = imm.offset;
@@ -4645,13 +4709,19 @@ class LiftoffCompiler {
__ cache_state()->stack_state.pop_back();
SCOPED_CODE_COMMENT("store to memory (constant offset)");
Register mem = pinned.set(GetMemoryStart(imm.mem_index, pinned));
- __ Store(mem, no_reg, offset, value, type, pinned, nullptr, true,
- i64_offset);
+ if (value.is_const()) {
+ __ StoreConst(mem, no_reg, offset, value.i32_const(), type, nullptr,
+ i64_offset);
+ } else {
+ __ Store(mem, no_reg, offset, value.reg(), type, pinned, nullptr, true,
+ i64_offset);
+ }
} else {
LiftoffRegister full_index = __ PopToRegister(pinned);
- ForceCheck force_check = (kPartialOOBWritesAreNoops || type.size() == 1)
- ? kDontForceCheck
- : kDoForceCheck;
+ ForceCheck force_check =
+ (v8_flags.wasm_partial_oob_writes_are_noops || type.size() == 1)
+ ? kDontForceCheck
+ : kDoForceCheck;
index =
BoundsCheckMem(decoder, imm.memory, type.size(), imm.offset,
full_index, pinned, force_check, kDontCheckAlignment);
@@ -4664,8 +4734,13 @@ class LiftoffCompiler {
Register mem = pinned.set(GetMemoryStart(imm.mem_index, pinned));
LiftoffRegList outer_pinned;
if (V8_UNLIKELY(v8_flags.trace_wasm_memory)) outer_pinned.set(index);
- __ Store(mem, index, offset, value, type, outer_pinned,
- &trapping_store_pc, true, i64_offset);
+ if (value.is_const()) {
+ __ StoreConst(mem, index, offset, value.i32_const(), type,
+ &trapping_store_pc, i64_offset);
+ } else {
+ __ Store(mem, index, offset, value.reg(), type, outer_pinned,
+ &trapping_store_pc, true, i64_offset);
+ }
if (imm.memory->bounds_checks == kTrapHandler) {
RegisterTrappingInstruction(decoder, trapping_store_pc);
}
@@ -4684,9 +4759,10 @@ class LiftoffCompiler {
LiftoffRegList pinned;
LiftoffRegister value = pinned.set(__ PopToRegister());
LiftoffRegister full_index = __ PopToRegister(pinned);
- ForceCheck force_check = (kPartialOOBWritesAreNoops || type.size() == 1)
- ? kDontForceCheck
- : kDoForceCheck;
+ ForceCheck force_check =
+ (v8_flags.wasm_partial_oob_writes_are_noops || type.size() == 1)
+ ? kDontForceCheck
+ : kDoForceCheck;
Register index =
BoundsCheckMem(decoder, imm.memory, type.size(), imm.offset, full_index,
pinned, force_check, kDontCheckAlignment);
@@ -6848,6 +6924,11 @@ class LiftoffCompiler {
__ AtomicFence(imm.order);
}
+ void Publish(FullDecoder* decoder, const Value& ref) {
+ // Overapproximate a release fence with an acquire-release fence.
+ __ AtomicFence(AtomicMemoryOrder::kAcqRel);
+ }
+
void Pause(FullDecoder* decoder) { __ Pause(); }
void StructAtomicRMW(FullDecoder* decoder, WasmOpcode opcode,
@@ -6861,9 +6942,8 @@ class LiftoffCompiler {
LiftoffRegister value = pinned.set(__ PopToRegister(pinned));
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
- const bool requires_aligned_access = field_kind == ValueKind::kI64;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- struct_object.type, field.field_imm.index, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(struct_object.type, field.field_imm.index);
if (explicit_check) {
MaybeEmitNullCheck(decoder, obj.gp(), pinned, struct_object.type);
}
@@ -6992,9 +7072,8 @@ class LiftoffCompiler {
const StructType* struct_type = field.struct_imm.struct_type;
ValueKind field_kind = struct_type->field(field.field_imm.index).kind();
int offset = StructFieldOffset(struct_type, field.field_imm.index);
- const bool requires_aligned_access = field_kind == ValueKind::kI64;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- struct_object.type, field.field_imm.index, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(struct_object.type, field.field_imm.index);
#if V8_TARGET_ARCH_IA32
DCHECK(!implicit_check); // No trap handler on 32-bit.
@@ -7895,9 +7974,8 @@ class LiftoffCompiler {
const Value& descriptor_value) {
LiftoffRegList pinned;
LiftoffRegister descriptor = pinned.set(__ PopToRegister({}));
- const bool requires_aligned_access = false;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- descriptor_value.type, 0, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(descriptor_value.type, 0);
if (explicit_check) {
MaybeEmitNullCheck(decoder, descriptor.gp(), pinned,
descriptor_value.type);
@@ -7993,7 +8071,7 @@ class LiftoffCompiler {
pinned.clear(value);
}
- if (type.is_shared) __ AtomicFence(AtomicMemoryOrder::kSeqCst);
+ if (type.is_shared) __ AtomicFence(AtomicMemoryOrder::kAcqRel);
// If this assert fails then initialization of padding field might be
// necessary.
@@ -8022,9 +8100,8 @@ class LiftoffCompiler {
LiftoffRegList pinned;
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
- const bool requires_aligned_access = false;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- struct_obj.type, field.field_imm.index, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(struct_obj.type, field.field_imm.index);
if (explicit_check) {
MaybeEmitNullCheck(decoder, obj.gp(), pinned, struct_obj.type);
@@ -8045,9 +8122,8 @@ class LiftoffCompiler {
LiftoffRegList pinned;
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
- const bool requires_aligned_access = field_kind == ValueKind::kI64;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- struct_obj.type, field.field_imm.index, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(struct_obj.type, field.field_imm.index);
if (explicit_check) {
MaybeEmitNullCheck(decoder, obj.gp(), pinned, struct_obj.type);
@@ -8068,9 +8144,8 @@ class LiftoffCompiler {
LiftoffRegister value = pinned.set(__ PopToRegister(pinned));
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
- const bool requires_aligned_access = false;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- struct_obj.type, field.field_imm.index, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(struct_obj.type, field.field_imm.index);
if (explicit_check) {
MaybeEmitNullCheck(decoder, obj.gp(), pinned, struct_obj.type);
@@ -8092,9 +8167,8 @@ class LiftoffCompiler {
LiftoffRegister value = pinned.set(__ PopToRegister(pinned));
LiftoffRegister obj = pinned.set(__ PopToRegister(pinned));
- const bool requires_aligned_access = field_kind == ValueKind::kI64;
- auto [explicit_check, implicit_check] = null_checks_for_struct_op(
- struct_obj.type, field.field_imm.index, requires_aligned_access);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(struct_obj.type, field.field_imm.index);
if (explicit_check) {
MaybeEmitNullCheck(decoder, obj.gp(), pinned, struct_obj.type);
}
@@ -8162,7 +8236,7 @@ class LiftoffCompiler {
? compiler::kFullWriteBarrier
: compiler::kNoWriteBarrier);
- if (is_shared) __ AtomicFence(AtomicMemoryOrder::kSeqCst);
+ if (is_shared) __ AtomicFence(AtomicMemoryOrder::kAcqRel);
__ PushRegister(kRef, obj);
}
@@ -8409,7 +8483,7 @@ class LiftoffCompiler {
element, false, pinned, elem_kind, write_barrier);
}
- if (is_shared) __ AtomicFence(AtomicMemoryOrder::kSeqCst);
+ if (is_shared) __ AtomicFence(AtomicMemoryOrder::kAcqRel);
// Push the array onto the stack.
__ PushRegister(kRef, array);
@@ -8648,11 +8722,21 @@ class LiftoffCompiler {
LiftoffRegList pinned;
LiftoffRegister ref = pinned.set(__ PopToRegister());
- // Implicit null checks don't cover the map load.
- MaybeEmitNullCheck(decoder, ref.gp(), pinned, ref_val.type);
+ auto [explicit_check, implicit_check] =
+ null_checks_for_struct_op(ref_val.type, 0);
+
+ if (explicit_check) {
+ MaybeEmitNullCheck(decoder, ref.gp(), pinned, ref_val.type);
+ }
LiftoffRegister value = __ GetUnusedRegister(kGpReg, pinned);
+ // Can't use {LoadObjectField} because it's not designed for negative
+ // offsets.
+ uint32_t protected_load_pc = __ pc_offset();
__ LoadMap(value.gp(), ref.gp());
+ if (implicit_check) {
+ RegisterTrappingInstruction(decoder, protected_load_pc);
+ }
LoadObjectField(decoder, value, value.gp(), no_reg,
offsetof(Map, instance_descriptors_) - kHeapObjectTag, kRef,
false, false, pinned);
@@ -8685,10 +8769,7 @@ class LiftoffCompiler {
Label match;
bool is_cast_from_any = obj_type.is_reference_to(GenericKind::kAny);
- // Skip the null check if casting from any and not {null_succeeds}.
- // In that case the instance type check will identify null as not being a
- // wasm object and fail.
- if (obj_type.is_nullable() && (!is_cast_from_any || null_succeeds)) {
+ if (obj_type.is_nullable()) {
__ emit_cond_jump(kEqual, null_succeeds ? &match : no_match,
obj_type.kind(), obj_reg, scratch_null, frozen);
}
@@ -9484,10 +9565,12 @@ class LiftoffCompiler {
VarState memory_var{kI32, static_cast<int>(imm.index), 0};
- LiftoffRegister variant_reg =
+ LiftoffRegister config_reg =
pinned.set(__ GetUnusedRegister(kGpReg, pinned));
- LoadSmi(variant_reg, static_cast<int32_t>(variant));
- VarState variant_var(kSmiKind, variant_reg, 0);
+ UnicodeConfig config(variant, imm.memory->is_shared,
+ result->type.is_shared());
+ LoadSmi(config_reg, config.raw_as_int());
+ VarState config_var(kSmiKind, config_reg, 0);
VarState& size_var = __ cache_state()->stack_state.end()[-1];
@@ -9497,7 +9580,7 @@ class LiftoffCompiler {
CallBuiltin(
Builtin::kWasmStringNewWtf8,
MakeSig::Returns(kRefNull).Params(kIntPtrKind, kI32, kI32, kSmiKind),
- {address, size_var, memory_var, variant_var}, decoder->position());
+ {address, size_var, memory_var, config_var}, decoder->position());
__ DropValues(2);
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
@@ -9517,19 +9600,19 @@ class LiftoffCompiler {
MaybeEmitNullCheck(decoder, array_reg.gp(), pinned, array.type);
VarState array_var(kRef, array_reg, 0);
- LiftoffRegister variant_reg =
+ LiftoffRegister config_reg =
pinned.set(__ GetUnusedRegister(kGpReg, pinned));
- LoadSmi(variant_reg, static_cast<int32_t>(variant));
- VarState variant_var(kSmiKind, variant_reg, 0);
- VarState shared_var(kSmiKind, 0, 0);
-
- CallBuiltin(
- Builtin::kWasmStringNewWtf8Array,
- MakeSig::Returns(kRefNull).Params(kI32, kI32, kRef, kSmiKind, kSmiKind),
- {__ cache_state()->stack_state.end()[-2], // start
- __ cache_state()->stack_state.end()[-1], // end
- array_var, variant_var, shared_var},
- decoder->position());
+ UnicodeConfig config(variant, array.type.is_shared(),
+ result->type.is_shared());
+ LoadSmi(config_reg, config.raw_as_int());
+ VarState config_var(kSmiKind, config_reg, 0);
+
+ CallBuiltin(Builtin::kWasmStringNewWtf8Array,
+ MakeSig::Returns(kRefNull).Params(kI32, kI32, kRef, kSmiKind),
+ {__ cache_state()->stack_state.end()[-2], // start
+ __ cache_state()->stack_state.end()[-1], // end
+ array_var, config_var},
+ decoder->position());
__ cache_state()->stack_state.pop_back(3);
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
@@ -9540,17 +9623,25 @@ class LiftoffCompiler {
void StringNewWtf16(FullDecoder* decoder, const MemoryIndexImmediate& imm,
const Value& offset, const Value& size, Value* result) {
FuzzerChargeSteps(decoder, 0);
+ LiftoffRegList pinned;
+
VarState memory_var{kI32, static_cast<int32_t>(imm.index), 0};
+ LiftoffRegister config_reg =
+ pinned.set(__ GetUnusedRegister(kGpReg, pinned));
+ UnicodeConfig config(imm.memory->is_shared, result->type.is_shared());
+ LoadSmi(config_reg, config.raw_as_int());
+ VarState config_var(kSmiKind, config_reg, 0);
+
VarState& size_var = __ cache_state()->stack_state.end()[-1];
- LiftoffRegList pinned;
DCHECK(MatchingMemType(imm.memory, 1));
VarState address = IndexToVarStateSaturating(1, &pinned);
- CallBuiltin(Builtin::kWasmStringNewWtf16,
- MakeSig::Returns(kRef).Params(kI32, kIntPtrKind, kI32),
- {memory_var, address, size_var}, decoder->position());
+ CallBuiltin(
+ Builtin::kWasmStringNewWtf16,
+ MakeSig::Returns(kRef).Params(kI32, kIntPtrKind, kI32, kSmiKind),
+ {memory_var, address, size_var, config_var}, decoder->position());
__ DropValues(2);
RegisterDebugSideTableEntry(decoder, DebugSideTableBuilder::kDidSpill);
@@ -9569,12 +9660,19 @@ class LiftoffCompiler {
MaybeEmitNullCheck(decoder, array_reg.gp(), pinned, array.type);
VarState array_var(kRef, array_reg, 0);
+ LiftoffRegister config_reg =
+ pinned.set(__ GetUnusedRegister(kGpReg, pinned));
+ UnicodeConfig config(array.type.is_shared(), result->type.is_shared());
+ LoadSmi(config_reg, config.raw_as_int());
+ VarState config_var(kSmiKind, config_reg, 0);
+
CallBuiltin(Builtin::kWasmStringNewWtf16Array,
- MakeSig::Returns(kRef).Params(kRef, kI32, kI32),
+ MakeSig::Returns(kRef).Params(kRef, kI32, kI32, kSmiKind),
{
array_var,
__ cache_state()->stack_state.end()[-2], // start
__ cache_state()->stack_state.end()[-1], // end
+ config_var,
},
decoder->position());
__ cache_state()->stack_state.pop_back(3);
@@ -10926,13 +11024,12 @@ class LiftoffCompiler {
kHeapObjectTag;
}
- std::pair<bool, bool> null_checks_for_struct_op(
- ValueType struct_type, int field_index, bool requires_aligned_access) {
+ std::pair<bool, bool> null_checks_for_struct_op(ValueType struct_type,
+ int field_index) {
bool explicit_null_check =
struct_type.is_nullable() &&
(null_check_strategy_ == compiler::NullCheckStrategy::kExplicit ||
- field_index > wasm::kMaxStructFieldIndexForImplicitNullCheck ||
- requires_aligned_access);
+ field_index > wasm::kMaxStructFieldIndexForImplicitNullCheck);
bool implicit_null_check =
struct_type.is_nullable() && !explicit_null_check;
return {explicit_null_check, implicit_null_check};
@@ -11486,6 +11583,15 @@ std::unique_ptr<DebugSideTable> GenerateLiftoffDebugSideTable(
code->for_debugging() == kForStepping
? base::ArrayVector(kSteppingBreakpoints)
: base::Vector<const int>{};
+ WasmFunctionCoverageData* coverage_data = nullptr;
+ if (V8_UNLIKELY(v8_flags.wasm_code_coverage)) {
+ DCHECK_NOT_NULL(env.module_coverage_data);
+ int declared_function_index =
+ code->index() - native_module->module()->num_imported_functions;
+ coverage_data = env.module_coverage_data->GetFunctionCoverageData(
+ declared_function_index);
+ DCHECK_NOT_NULL(coverage_data);
+ }
WasmFullDecoder<Decoder::NoValidationTag, LiftoffCompiler> decoder(
&zone, native_module->module(), env.enabled_features, &detected,
func_body, call_descriptor, &env, &zone,
@@ -11494,7 +11600,7 @@ std::unique_ptr<DebugSideTable> GenerateLiftoffDebugSideTable(
LiftoffOptions{.func_index = code->index(),
.for_debugging = code->for_debugging(),
.breakpoints = breakpoints},
- nullptr);
+ coverage_data);
decoder.Decode();
DCHECK(decoder.ok());
DCHECK(!decoder.interface().did_bailout());
diff --git a/deps/v8/src/wasm/baseline/loong64/liftoff-assembler-loong64-inl.h b/deps/v8/src/wasm/baseline/loong64/liftoff-assembler-loong64-inl.h
index 0ee85128d3c..a83a6fd9182 100644
--- a/deps/v8/src/wasm/baseline/loong64/liftoff-assembler-loong64-inl.h
+++ b/deps/v8/src/wasm/baseline/loong64/liftoff-assembler-loong64-inl.h
@@ -271,7 +271,9 @@ void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
}
// Set the new stack and frame pointer.
- addi_d(sp, fp, -stack_param_delta * 8);
+ // WebAssembly allows functions to have up to 1000 parameters
+ // (see kV8MaxWasmFunctionParams).
+ Add_d(sp, fp, Operand(-stack_param_delta * 8));
Pop(ra, fp);
}
@@ -1146,7 +1148,7 @@ void LiftoffAssembler::AtomicExchangeTaggedPointer(
if constexpr (COMPRESS_POINTERS_BOOL) {
amswap_db_w(result.gp(), value.gp(), actual_addr);
Bstrpick_d(result.gp(), result.gp(), 31, 0);
- add_d(result.gp(), result.gp(), kPtrComprCageBaseRegister);
+ Or(result.gp(), result.gp(), kPtrComprCageBaseRegister);
} else {
amswap_db_d(result.gp(), value.gp(), actual_addr);
}
@@ -2301,9 +2303,18 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
} else {
if (kind == kI64) {
MacroAssembler::Branch(label, cond, lhs, Operand(rhs));
- } else {
- DCHECK((kind == kI32) || (kind == kRef) || (kind == kRefNull));
+ } else if ((kind == kRef) || (kind == kRefNull) || (cond == eq) ||
+ (cond == ne)) {
+ DCHECK(cond == eq || cond == ne);
MacroAssembler::CompareTaggedAndBranch(label, cond, lhs, Operand(rhs));
+ } else {
+ DCHECK(kind == kI32);
+ UseScratchRegisterScope temps(this);
+ Register scratch1 = temps.Acquire();
+ Register scratch2 = temps.Acquire();
+ slli_w(scratch1, lhs, 0);
+ slli_w(scratch2, rhs, 0);
+ MacroAssembler::Branch(label, cond, scratch1, Operand(scratch2));
}
}
}
@@ -2311,7 +2322,10 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
void LiftoffAssembler::emit_i32_cond_jumpi(Condition cond, Label* label,
Register lhs, int32_t imm,
const FreezeCacheState& frozen) {
- MacroAssembler::CompareTaggedAndBranch(label, cond, lhs, Operand(imm));
+ UseScratchRegisterScope temps(this);
+ Register scratch1 = temps.Acquire();
+ slli_w(scratch1, lhs, 0);
+ MacroAssembler::Branch(label, cond, scratch1, Operand(imm));
}
void LiftoffAssembler::emit_ptrsize_cond_jumpi(Condition cond, Label* label,
diff --git a/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64-inl.h b/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64-inl.h
index 1e730cbcd77..0e68f6caf04 100644
--- a/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64-inl.h
+++ b/deps/v8/src/wasm/baseline/mips64/liftoff-assembler-mips64-inl.h
@@ -335,7 +335,9 @@ void LiftoffAssembler::PrepareTailCall(int num_callee_stack_params,
}
// Set the new stack and frame pointer.
- daddiu(sp, fp, -stack_param_delta * 8);
+ // WebAssembly allows functions to have up to 1000 parameters
+ // (see kV8MaxWasmFunctionParams).
+ Daddu(sp, fp, Operand(-stack_param_delta * 8));
Pop(ra, fp);
}
diff --git a/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc-inl.h b/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc-inl.h
index a8967aad9bf..5f69e048524 100644
--- a/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc-inl.h
+++ b/deps/v8/src/wasm/baseline/ppc/liftoff-assembler-ppc-inl.h
@@ -2838,7 +2838,7 @@ void LiftoffAssembler::LoadTransform(LiftoffRegister dst, Register src_addr,
void LiftoffAssembler::emit_smi_check(Register obj, Label* target,
SmiCheckMode mode,
const FreezeCacheState& frozen) {
- TestIfSmi(obj, r0);
+ TestIfSmi(obj);
Condition condition = mode == kJumpOnSmi ? eq : ne;
b(condition, target, cr0); // branch if SMI
}
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 8247a334224..ec8bff5ec2c 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
@@ -1160,8 +1160,8 @@ void LiftoffAssembler::emit_i8x16_bitmask(LiftoffRegister dst,
void LiftoffAssembler::emit_i8x16_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E8);
- andi(rhs.gp(), rhs.gp(), 8 - 1);
- vsll_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 8 - 1);
+ vsll_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i8x16_shli(LiftoffRegister dst, LiftoffRegister lhs,
@@ -1174,8 +1174,8 @@ void LiftoffAssembler::emit_i8x16_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E8);
- andi(rhs.gp(), rhs.gp(), 8 - 1);
- vsra_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 8 - 1);
+ vsra_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i8x16_shri_s(LiftoffRegister dst,
@@ -1188,8 +1188,8 @@ void LiftoffAssembler::emit_i8x16_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E8);
- andi(rhs.gp(), rhs.gp(), 8 - 1);
- vsrl_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 8 - 1);
+ vsrl_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i8x16_shri_u(LiftoffRegister dst,
@@ -1296,8 +1296,8 @@ void LiftoffAssembler::emit_i16x8_bitmask(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E16);
- andi(rhs.gp(), rhs.gp(), 16 - 1);
- vsll_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 16 - 1);
+ vsll_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i16x8_shli(LiftoffRegister dst, LiftoffRegister lhs,
@@ -1310,8 +1310,8 @@ void LiftoffAssembler::emit_i16x8_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E16);
- andi(rhs.gp(), rhs.gp(), 16 - 1);
- vsra_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 16 - 1);
+ vsra_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i16x8_shri_s(LiftoffRegister dst,
@@ -1324,8 +1324,8 @@ void LiftoffAssembler::emit_i16x8_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E16);
- andi(rhs.gp(), rhs.gp(), 16 - 1);
- vsrl_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 16 - 1);
+ vsrl_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i16x8_shri_u(LiftoffRegister dst,
@@ -1438,8 +1438,8 @@ void LiftoffAssembler::emit_i32x4_bitmask(LiftoffRegister dst,
void LiftoffAssembler::emit_i32x4_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E32);
- andi(rhs.gp(), rhs.gp(), 32 - 1);
- vsll_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 32 - 1);
+ vsll_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i32x4_shli(LiftoffRegister dst, LiftoffRegister lhs,
@@ -1456,8 +1456,8 @@ void LiftoffAssembler::emit_i32x4_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E32);
- andi(rhs.gp(), rhs.gp(), 32 - 1);
- vsra_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 32 - 1);
+ vsra_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i32x4_shri_s(LiftoffRegister dst,
@@ -1475,8 +1475,8 @@ void LiftoffAssembler::emit_i32x4_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E32);
- andi(rhs.gp(), rhs.gp(), 32 - 1);
- vsrl_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 32 - 1);
+ vsrl_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i32x4_shri_u(LiftoffRegister dst,
@@ -1682,8 +1682,8 @@ void LiftoffAssembler::emit_i64x2_alltrue(LiftoffRegister dst,
void LiftoffAssembler::emit_i64x2_shl(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E64);
- andi(rhs.gp(), rhs.gp(), 64 - 1);
- vsll_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 64 - 1);
+ vsll_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i64x2_shli(LiftoffRegister dst, LiftoffRegister lhs,
@@ -1701,8 +1701,8 @@ void LiftoffAssembler::emit_i64x2_shr_s(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E64);
- andi(rhs.gp(), rhs.gp(), 64 - 1);
- vsra_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 64 - 1);
+ vsra_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i64x2_shri_s(LiftoffRegister dst,
@@ -1720,8 +1720,8 @@ void LiftoffAssembler::emit_i64x2_shr_u(LiftoffRegister dst,
LiftoffRegister lhs,
LiftoffRegister rhs) {
VU.SetSimd128(E64);
- andi(rhs.gp(), rhs.gp(), 64 - 1);
- vsrl_vx(dst.simd128(), lhs.simd128(), rhs.gp());
+ andi(kScratchReg, rhs.gp(), 64 - 1);
+ vsrl_vx(dst.simd128(), lhs.simd128(), kScratchReg);
}
void LiftoffAssembler::emit_i64x2_shri_u(LiftoffRegister dst,
diff --git a/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv64-inl.h b/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv64-inl.h
index 1a37e281196..f0711e49a55 100644
--- a/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv64-inl.h
+++ b/deps/v8/src/wasm/baseline/riscv/liftoff-assembler-riscv64-inl.h
@@ -179,7 +179,16 @@ inline void StoreToMemory(LiftoffAssembler* assm, MemOperand dst,
src_reg = temps.Acquire();
assm->li(src_reg, src.i32_const());
}
- assm->StoreWord(src_reg, dst);
+ switch (src.kind()) {
+ case kI32:
+ assm->Sw(src_reg, dst);
+ break;
+ case kI64:
+ assm->StoreWord(src_reg, dst);
+ break;
+ default:
+ UNREACHABLE();
+ }
} else if (src.is_reg()) {
switch (src.kind()) {
case kI16:
@@ -499,13 +508,36 @@ inline void AtomicBinop(LiftoffAssembler* lasm, Register dst_addr,
Register result_reg = result.gp();
if (result_reg == value.gp() || result_reg == dst_addr ||
result_reg == offset_reg) {
- result_reg = __ GetUnusedRegister(kGpReg, pinned).gp();
+ result_reg = pinned.set(__ GetUnusedRegister(kGpReg, pinned)).gp();
}
UseScratchRegisterScope temps(lasm);
Register actual_addr = liftoff::CalculateActualAddress(
lasm, temps, dst_addr, offset_reg, offset_imm);
+ bool is_subword = type.value() == StoreType::kI64Store8 ||
+ type.value() == StoreType::kI32Store8 ||
+ type.value() == StoreType::kI64Store16 ||
+ type.value() == StoreType::kI32Store16;
+ Register word = no_reg;
+ Register shift = no_reg;
+ if (is_subword) {
+ // TODO(riscv): use Zabha instruction if enabled
+ word = pinned.set(lasm->GetUnusedRegister(kGpReg, pinned)).gp();
+ shift = pinned.set(lasm->GetUnusedRegister(kGpReg, pinned)).gp();
+ Register addr = pinned.set(lasm->GetUnusedRegister(kGpReg, pinned)).gp();
+ __ mv(addr, actual_addr);
+ if (offset_reg != no_reg || offset_imm != 0) {
+ temps.Include(actual_addr);
+ }
+ actual_addr = addr;
+ bool is_doubleword = type.value() == StoreType::kI64Store8 ||
+ type.value() == StoreType::kI64Store16;
+ __ andi(shift, actual_addr, is_doubleword ? 0x7 : 0x3);
+ __ Sub64(actual_addr, actual_addr, Operand(shift));
+ __ Sll32(shift, shift, 3);
+ }
+
Label retry;
__ bind(&retry);
if (type.value() == StoreType::kI32Store ||
@@ -603,22 +635,22 @@ inline void AtomicBinop(LiftoffAssembler* lasm, Register dst_addr,
break;
}
} else {
- // Allocate an additional {temp} register to hold the result that should be
- // stored to memory. Note that {temp} and {store_result} are not allowed to
- // be the same register.
- Register temp = temps.Acquire();
+ Register temp =
+ is_subword ? pinned.set(lasm->GetUnusedRegister(kGpReg, pinned)).gp()
+ : temps.Acquire();
if (trapping_load_pc) *trapping_load_pc = lasm->pc_offset();
- // TODO(riscv): use Zabha instruction if enabled
switch (type.value()) {
case StoreType::kI64Store8:
- case StoreType::kI32Store8:
- __ lbu(result_reg, actual_addr, 0);
- __ sync();
- break;
case StoreType::kI64Store16:
+ __ lr_d(true, false, word, actual_addr);
+ __ ExtractBits(result_reg, word, shift,
+ type.value() == StoreType::kI64Store8 ? 8 : 16, false);
+ break;
+ case StoreType::kI32Store8:
case StoreType::kI32Store16:
- __ lhu(result_reg, actual_addr, 0);
- __ sync();
+ __ lr_w(true, false, word, actual_addr);
+ __ ExtractBits(result_reg, word, shift,
+ type.value() == StoreType::kI32Store8 ? 8 : 16, false);
break;
case StoreType::kI64Store32:
__ lr_w(true, false, result_reg, actual_addr);
@@ -656,18 +688,16 @@ inline void AtomicBinop(LiftoffAssembler* lasm, Register dst_addr,
}
switch (type.value()) {
case StoreType::kI64Store8:
- case StoreType::kI32Store8:
- __ sync();
- __ sb(temp, actual_addr, 0);
- __ sync();
- __ mv(store_result, zero_reg);
- break;
case StoreType::kI64Store16:
+ __ InsertBits(word, temp, shift,
+ type.value() == StoreType::kI64Store8 ? 8 : 16);
+ __ sc_d(false, true, store_result, actual_addr, word);
+ break;
+ case StoreType::kI32Store8:
case StoreType::kI32Store16:
- __ sync();
- __ sh(temp, actual_addr, 0);
- __ sync();
- __ mv(store_result, zero_reg);
+ __ InsertBits(word, temp, shift,
+ type.value() == StoreType::kI32Store8 ? 8 : 16);
+ __ sc_w(false, true, store_result, actual_addr, word);
break;
case StoreType::kI64Store32:
case StoreType::kI32Store:
@@ -844,7 +874,7 @@ void LiftoffAssembler::AtomicLoadTaggedPointer(Register dst, Register src_addr,
void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, uint32_t* trapping_store_pc,
- AtomicMemoryOrder /* memory_order */,
+ AtomicMemoryOrder memory_order,
LiftoffRegList /* pinned */,
bool /* i64_offset */,
Endianness /* endianness */) {
@@ -872,6 +902,7 @@ void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
default:
UNREACHABLE();
}
+ if (memory_order == AtomicMemoryOrder::kSeqCst) sync();
DCHECK_IMPLIES(trapping_store_pc != nullptr,
InstructionAt(*trapping_store_pc)->IsStore());
}
@@ -887,12 +918,13 @@ void LiftoffAssembler::AtomicStoreTaggedPointer(
if (trapping_store_pc) *trapping_store_pc = static_cast<uint32_t>(offset);
};
+ sync();
if (COMPRESS_POINTERS_BOOL) {
Sw(src, MemOperand(dst_reg, 0), trapper);
} else {
Sd(src, MemOperand(dst_reg, 0), trapper);
}
- sync();
+ if (memory_order == AtomicMemoryOrder::kSeqCst) sync();
if (v8_flags.disable_write_barriers) return;
// The write barrier.
Label exit;
@@ -989,7 +1021,8 @@ void LiftoffAssembler::AtomicExchangeTaggedPointer(
if (trapping_load_pc) *trapping_load_pc = pc_offset();
if constexpr (COMPRESS_POINTERS_BOOL) {
amoswap_w(true, true, result.gp(), actual_addr, value.gp());
- AddWord(result.gp(), result.gp(), kPtrComprCageBaseRegister);
+ ZeroExtendWord(result.gp(), result.gp());
+ Or(result.gp(), result.gp(), kPtrComprCageBaseRegister);
} else {
amoswap_d(true, true, result.gp(), actual_addr, value.gp());
}
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 900ef8fc592..326e73790d2 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
@@ -7,6 +7,7 @@
#include <optional>
+#include "src/base/overflowing-math.h"
#include "src/codegen/assembler.h"
#include "src/codegen/atomic-memory-order.h"
#include "src/codegen/cpu-features.h"
@@ -705,6 +706,36 @@ void LiftoffAssembler::Store(Register dst_addr, Register offset_reg,
}
}
+void LiftoffAssembler::StoreConst(Register dst_addr, Register offset_reg,
+ uintptr_t offset_imm, int32_t value,
+ StoreType type, uint32_t* trapping_store_pc,
+ bool i64_offset) {
+ if (offset_reg != no_reg && !i64_offset) AssertZeroExtended(offset_reg);
+ Operand dst_op = liftoff::GetMemOp(this, dst_addr, offset_reg, offset_imm);
+ if (trapping_store_pc) *trapping_store_pc = pc_offset();
+ switch (type.value()) {
+ case StoreType::kI32Store8:
+ case StoreType::kI64Store8:
+ movb(dst_op, Immediate(value));
+ break;
+ case StoreType::kI32Store16:
+ case StoreType::kI64Store16:
+ movw(dst_op, Immediate(value));
+ break;
+ case StoreType::kI32Store:
+ case StoreType::kI64Store32:
+ movl(dst_op, Immediate(value));
+ break;
+ case StoreType::kI64Store:
+ // The 32-bit immediate is sign-extended, matching how Liftoff keeps i64
+ // constants.
+ movq(dst_op, Immediate(value));
+ break;
+ default:
+ UNREACHABLE();
+ }
+}
+
void LiftoffAssembler::AtomicStore(Register dst_addr, Register offset_reg,
uintptr_t offset_imm, LiftoffRegister src,
StoreType type, uint32_t* trapping_store_pc,
@@ -1024,7 +1055,7 @@ void LiftoffAssembler::AtomicExchangeTaggedPointer(
if (trapping_load_pc) *trapping_load_pc = pc_offset();
if constexpr (COMPRESS_POINTERS_BOOL) {
xchgl(result.gp(), dst_op);
- addq(result.gp(), kPtrComprCageBaseRegister);
+ orq(result.gp(), kPtrComprCageBaseRegister);
} else {
xchgq(result.gp(), dst_op);
}
@@ -1373,9 +1404,7 @@ void LiftoffAssembler::emit_i32_sub(Register dst, Register lhs, Register rhs) {
void LiftoffAssembler::emit_i32_subi(Register dst, Register lhs, int32_t imm) {
if (dst != lhs) {
- // We'll have to implement an UB-safe version if we need this corner case.
- DCHECK_NE(imm, kMinInt);
- leal(dst, Operand(lhs, -imm));
+ leal(dst, Operand(lhs, base::NegateWithWraparound(imm)));
} else {
subl(dst, Immediate(imm));
}
@@ -2664,14 +2693,14 @@ void LiftoffAssembler::emit_cond_jump(Condition cond, Label* label,
void LiftoffAssembler::emit_i32_cond_jumpi(Condition cond, Label* label,
Register lhs, int imm,
const FreezeCacheState& frozen) {
- cmpl(lhs, Immediate(imm));
+ Cmp(lhs, imm);
j(cond, label);
}
void LiftoffAssembler::emit_ptrsize_cond_jumpi(Condition cond, Label* label,
Register lhs, int32_t imm,
const FreezeCacheState& frozen) {
- cmpq(lhs, Immediate(imm));
+ Cmpq(lhs, imm);
j(cond, label);
}
@@ -3098,8 +3127,8 @@ void LiftoffAssembler::emit_s128_relaxed_laneselect(LiftoffRegister dst,
void LiftoffAssembler::emit_i8x16_popcnt(LiftoffRegister dst,
LiftoffRegister src) {
- I8x16Popcnt(dst.fp(), src.fp(), kScratchDoubleReg,
- liftoff::kScratchDoubleReg2, kScratchRegister);
+ I8x16Popcnt(dst.fp(), src.fp(), kScratchRegister, kScratchDoubleReg,
+ liftoff::kScratchDoubleReg2);
}
void LiftoffAssembler::emit_i8x16_splat(LiftoffRegister dst,
@@ -3458,8 +3487,9 @@ void LiftoffAssembler::emit_s128_select(LiftoffRegister dst,
// Ensure that we don't overwrite any inputs with the movaps below.
DCHECK_NE(dst, src1);
DCHECK_NE(dst, src2);
- if (!CpuFeatures::IsSupported(AVX) && dst != mask) {
- movaps(dst.fp(), mask.fp());
+ // AVX10 vpternlogd and non-AVX fallback require dst == mask.
+ if ((UseAvx10_1() || !CpuFeatures::IsSupported(AVX)) && dst != mask) {
+ Movaps(dst.fp(), mask.fp());
S128Select(dst.fp(), dst.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
} else {
S128Select(dst.fp(), mask.fp(), src1.fp(), src2.fp(), kScratchDoubleReg);
@@ -3779,12 +3809,9 @@ void LiftoffAssembler::emit_i16x8_q15mulr_sat_s(LiftoffRegister dst,
void LiftoffAssembler::emit_i16x8_relaxed_q15mulr_s(LiftoffRegister dst,
LiftoffRegister src1,
LiftoffRegister src2) {
- if (CpuFeatures::IsSupported(AVX) || dst == src1) {
- Pmulhrsw(dst.fp(), src1.fp(), src2.fp());
- } else {
- movdqa(dst.fp(), src1.fp());
- pmulhrsw(dst.fp(), src2.fp());
- }
+ liftoff::EmitSimdCommutativeBinOp<&Assembler::vpmulhrsw,
+ &Assembler::pmulhrsw>(this, dst, src1, src2,
+ SSSE3);
}
void LiftoffAssembler::emit_i16x8_dot_i8x16_i7x16_s(LiftoffRegister dst,
@@ -4052,12 +4079,16 @@ void LiftoffAssembler::emit_i64x2_sub(LiftoffRegister dst, LiftoffRegister lhs,
void LiftoffAssembler::emit_i64x2_mul(LiftoffRegister dst, LiftoffRegister lhs,
LiftoffRegister rhs) {
- static constexpr RegClass tmp_rc = reg_class_for(kS128);
- LiftoffRegister tmp1 =
- GetUnusedRegister(tmp_rc, LiftoffRegList{dst, lhs, rhs});
- LiftoffRegister tmp2 =
- GetUnusedRegister(tmp_rc, LiftoffRegList{dst, lhs, rhs, tmp1});
- I64x2Mul(dst.fp(), lhs.fp(), rhs.fp(), tmp1.fp(), tmp2.fp());
+ if (UseAvx10_1()) {
+ I64x2Mul(dst.fp(), lhs.fp(), rhs.fp());
+ } else {
+ static constexpr RegClass tmp_rc = reg_class_for(kS128);
+ LiftoffRegister tmp1 =
+ GetUnusedRegister(tmp_rc, LiftoffRegList{dst, lhs, rhs});
+ LiftoffRegister tmp2 =
+ GetUnusedRegister(tmp_rc, LiftoffRegList{dst, lhs, rhs, tmp1});
+ I64x2Mul(dst.fp(), lhs.fp(), rhs.fp(), tmp1.fp(), tmp2.fp());
+ }
}
void LiftoffAssembler::emit_i64x2_extmul_low_i32x4_s(LiftoffRegister dst,
diff --git a/deps/v8/src/wasm/c-api.cc b/deps/v8/src/wasm/c-api.cc
index d697c550d69..badd152eaa5 100644
--- a/deps/v8/src/wasm/c-api.cc
+++ b/deps/v8/src/wasm/c-api.cc
@@ -491,7 +491,8 @@ StoreImpl::~StoreImpl() {
}
struct ManagedData {
- static constexpr i::ExternalPointerTag kManagedTag = i::kWasmManagedDataTag;
+ static constexpr i::ManagedTypeId kTypeID =
+ i::ManagedTypeId::kWasmManagedData;
ManagedData(void* info, void (*finalizer)(void*))
: info(info), finalizer(finalizer) {}
@@ -512,7 +513,7 @@ void StoreImpl::SetHostInfo(i::DirectHandle<i::Object> object, void* info,
// but all we get from the embedder is a {void*}, so our best estimate
// is the size of the metadata.
size_t estimated_size = sizeof(ManagedData);
- i::DirectHandle<i::Object> wrapper = i::Managed<ManagedData>::From(
+ i::DirectHandle<i::Object> wrapper = i::CppGCManaged<ManagedData>::Create(
i_isolate(), estimated_size,
std::make_shared<ManagedData>(info, finalizer));
int32_t hash = i::Object::GetOrCreateHash(*object, i_isolate()).value();
@@ -526,7 +527,7 @@ void* StoreImpl::GetHostInfo(i::DirectHandle<i::Object> key,
i::Tagged<i::Object> raw =
i::Cast<i::EphemeronHashTable>(host_info_map_->table())->Lookup(key);
if (IsTheHole(raw)) return nullptr;
- return i::Cast<i::Managed<ManagedData>>(raw)->raw(no_gc)->info;
+ return i::Cast<i::CppGCManaged<ManagedData>>(raw)->raw(no_gc)->info;
}
template <>
@@ -1270,7 +1271,7 @@ WASM_EXPORT auto Module::make(Store* store_abs, const vec<byte_t>& binary)
}
WASM_EXPORT auto Module::imports() const -> ownvec<ImportType> {
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
impl(this)->v8_object()->native_module();
const i::wasm::WasmModule* module = native_module->module();
const v8::base::Vector<const uint8_t> wire_bytes =
@@ -1291,7 +1292,7 @@ WASM_EXPORT auto Module::imports() const -> ownvec<ImportType> {
ownvec<ExportType> ExportsImpl(
i::DirectHandle<i::WasmModuleObject> module_obj) {
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
module_obj->native_module();
const i::wasm::WasmModule* module = native_module->module();
const v8::base::Vector<const uint8_t> wire_bytes =
@@ -1322,7 +1323,7 @@ WASM_EXPORT auto Module::serialize() const -> vec<byte_t> {
i::Isolate* isolate = impl(this)->isolate();
PtrComprCageAccessScope ptr_compr_cage_access_scope(isolate);
v8::Isolate::Scope isolate_scope(reinterpret_cast<v8::Isolate*>(isolate));
- i::Managed<i::wasm::NativeModule>::Ptr native_module =
+ i::CppGCManaged<i::wasm::NativeModule>::Ptr native_module =
impl(this)->v8_object()->native_module();
native_module->compilation_state()->TierUpAllFunctions();
v8::base::Vector<const uint8_t> wire_bytes = native_module->wire_bytes();
@@ -1506,7 +1507,7 @@ WASM_EXPORT void Func::destroy() { delete impl(this); }
WASM_EXPORT auto Func::copy() const -> own<Func> { return impl(this)->copy(); }
struct FuncData {
- static constexpr i::ExternalPointerTag kManagedTag = i::kWasmFuncDataTag;
+ static constexpr i::ManagedTypeId kTypeID = i::ManagedTypeId::kWasmFuncData;
Store* store;
own<FuncType> type;
@@ -1600,8 +1601,8 @@ auto make_func(Store* store_abs, std::shared_ptr<FuncData> data) -> own<Func> {
v8::Isolate::Scope isolate_scope(store->isolate());
i::HandleScope handle_scope(isolate);
CheckAndHandleInterrupts(isolate);
- i::DirectHandle<i::Managed<FuncData>> embedder_data =
- i::Managed<FuncData>::From(isolate, sizeof(FuncData), data);
+ i::DirectHandle<i::CppGCManaged<FuncData>> embedder_data =
+ i::CppGCManaged<FuncData>::Create(isolate, sizeof(FuncData), data);
i::wasm::CanonicalTypeIndex sig_index =
SignatureHelper::Canonicalize(data->type.get());
const i::wasm::CanonicalSig* sig =
@@ -1795,8 +1796,8 @@ void PopArgs(const i::wasm::CanonicalSig* sig, vec<Val>& results,
own<Trap> CallWasmCapiFunction(i::Tagged<i::WasmCapiFunctionData> data,
const vec<Val>& args, vec<Val>& results) {
- i::Managed<FuncData>::Ptr func_data =
- i::Cast<i::Managed<FuncData>>(data->embedder_data())->ptr();
+ i::CppGCManaged<FuncData>::Ptr func_data =
+ i::Cast<i::CppGCManaged<FuncData>>(data->embedder_data())->ptr();
if (func_data->kind == FuncData::kCallback) {
return (func_data->callback)(args, results);
}
@@ -1910,8 +1911,9 @@ WASM_EXPORT auto Func::call(const vec<Val>& args, vec<Val>& results) const
i::Address FuncData::v8_callback(i::Address host_data_foreign,
i::Address argv) {
- i::Managed<FuncData>::Ptr self =
- i::Cast<i::Managed<FuncData>>(i::Tagged<i::Object>(host_data_foreign))
+ i::CppGCManaged<FuncData>::Ptr self =
+ i::Cast<i::CppGCManaged<FuncData>>(
+ i::Tagged<i::Object>(host_data_foreign))
->ptr();
StoreImpl* store = impl(self->store);
i::Isolate* isolate = store->i_isolate();
@@ -2070,14 +2072,13 @@ WASM_EXPORT auto Global::get() const -> Val {
StoreImpl* store = impl(this)->store();
i::HandleScope scope(store->i_isolate());
i::DirectHandle<i::Object> result = v8_global->GetRef();
- if (IsWasmFuncRef(*result)) {
+ if (IsWasmNull(*result)) {
+ result = i::Isolate::Current()->factory()->null_value();
+ } else if (IsWasmFuncRef(*result)) {
result = i::WasmInternalFunction::GetOrCreateExternal(i::direct_handle(
i::Cast<i::WasmFuncRef>(*result)->internal(store->i_isolate()),
store->i_isolate()));
}
- if (IsWasmNull(*result)) {
- result = i::Isolate::Current()->factory()->null_value();
- }
return Val(V8RefValueToWasm(store, result));
}
case i::wasm::kS128:
@@ -2222,12 +2223,11 @@ WASM_EXPORT auto Table::get(size_t index) const -> own<Ref> {
i::HandleScope handle_scope(isolate);
i::DirectHandle<i::Object> result =
i::WasmTableObject::Get(isolate, table, static_cast<uint32_t>(index));
- if (IsWasmFuncRef(*result)) {
- result = i::WasmInternalFunction::GetOrCreateExternal(i::direct_handle(
- i::Cast<i::WasmFuncRef>(*result)->internal(isolate), isolate));
- }
if (IsWasmNull(*result)) {
result = isolate->factory()->null_value();
+ } else if (IsWasmFuncRef(*result)) {
+ result = i::WasmInternalFunction::GetOrCreateExternal(i::direct_handle(
+ i::Cast<i::WasmFuncRef>(*result)->internal(isolate), isolate));
}
DCHECK(IsNull(*result) || IsJSReceiver(*result));
return V8RefValueToWasm(impl(this)->store(), result);
diff --git a/deps/v8/src/wasm/canonical-types.cc b/deps/v8/src/wasm/canonical-types.cc
index 126c50f1ebd..dd57b62de6d 100644
--- a/deps/v8/src/wasm/canonical-types.cc
+++ b/deps/v8/src/wasm/canonical-types.cc
@@ -9,6 +9,7 @@
#include "src/execution/isolate.h"
#include "src/handles/handles-inl.h"
#include "src/heap/heap-inl.h"
+#include "src/heap/parked-scope-inl.h"
#include "src/init/v8.h"
#include "src/roots/roots-inl.h"
#include "src/utils/utils.h"
@@ -539,22 +540,21 @@ size_t TypeCanonicalizer::GetCurrentNumberOfTypes() const {
return canonical_supertypes_.size();
}
-// static
-void TypeCanonicalizer::PrepareForCanonicalTypeId(Isolate* isolate,
- CanonicalTypeIndex id) {
- if (!id.valid()) return;
- Heap* heap = isolate->heap();
+namespace {
+MaybeDirectHandle<WeakFixedArray> MaybeGrowRtts(
+ Isolate* isolate, Tagged<WeakFixedArray> old_rtts_raw,
+ CanonicalTypeIndex id, AllocationType allocation) {
+ // The fast path is non-handlified.
+
// This invocation's {id} may be the next invocation's {old_length}, and
// the {old_length * 3} computation below must not overflow.
static_assert(kMaxCanonicalTypes <= kMaxInt / 3 - 1);
// Canonical types are zero-indexed.
const uint32_t length = id.index + 1;
- // The fast path is non-handlified.
- Tagged<WeakFixedArray> old_rtts_raw = heap->wasm_canonical_rtts();
// Fast path: length is sufficient.
uint32_t old_length = old_rtts_raw->ulength().value();
- if (old_length >= length) return;
+ if (old_length >= length) return {};
// Allocate a bigger WeakFixedArray, growing exponentially.
const uint32_t new_length = std::max(old_length * 3 / 2, length);
@@ -568,11 +568,44 @@ void TypeCanonicalizer::PrepareForCanonicalTypeId(Isolate* isolate,
// pass the cleared value in a handle (see https://crbug.com/364591622). We
// overwrite the new entries via {MemsetTagged} afterwards.
DirectHandle<WeakFixedArray> new_rtts =
- WeakFixedArray::New(isolate, new_length, AllocationType::kOld);
+ WeakFixedArray::New(isolate, new_length, allocation);
WeakFixedArray::CopyElements(isolate, *new_rtts, 0, *old_rtts, 0, old_length);
MemsetTagged(new_rtts->RawFieldOfFirstElement() + old_length, ClearedValue(),
new_length - old_length);
- heap->SetWasmCanonicalRtts(*new_rtts);
+ return new_rtts;
+}
+
+} // namespace
+
+// static
+void TypeCanonicalizer::PrepareForCanonicalTypeId(Isolate* isolate,
+ CanonicalTypeIndex id,
+ SharedFlag shared) {
+ DirectHandle<WeakFixedArray> new_rtts;
+ if (MaybeGrowRtts(isolate, isolate->heap()->wasm_canonical_rtts(), id,
+ AllocationType::kOld)
+ .ToHandle(&new_rtts)) {
+ isolate->heap()->SetWasmCanonicalRtts(*new_rtts);
+ }
+
+ if (shared) {
+ // Another thread may cause shared GC while holding this mutex. We have to
+ // use a safepoint-aware MutexGuard here, otherwise the GC might wait
+ // forever on this blocked thread.
+ ParkedMutexGuard mutex_guard(
+ isolate->main_thread_local_isolate(),
+ isolate->shared_space_isolate()->wasm_shared_canonical_types_mutex());
+ DirectHandle<WeakFixedArray> new_shared_rtts;
+ if (MaybeGrowRtts(isolate,
+ isolate->shared_space_isolate()
+ ->heap()
+ ->wasm_shared_canonical_rtts(),
+ id, AllocationType::kSharedOld)
+ .ToHandle(&new_shared_rtts)) {
+ isolate->shared_space_isolate()->heap()->SetWasmSharedCanonicalRtts(
+ *new_shared_rtts);
+ }
+ }
}
// static
@@ -585,7 +618,6 @@ void TypeCanonicalizer::ClearWasmCanonicalTypesForTesting(Isolate* isolate) {
SharedFlag TypeCanonicalizer::IsShared(CanonicalTypeIndex index) const {
return canonical_types_[index]->is_shared;
}
-// Currently only used for heap verification.
bool TypeCanonicalizer::has_descriptor(CanonicalTypeIndex index) const {
return canonical_types_[index]->descriptor.valid();
}
diff --git a/deps/v8/src/wasm/canonical-types.h b/deps/v8/src/wasm/canonical-types.h
index 8ad410f7af9..503e037befd 100644
--- a/deps/v8/src/wasm/canonical-types.h
+++ b/deps/v8/src/wasm/canonical-types.h
@@ -132,9 +132,12 @@ class TypeCanonicalizer {
V8_EXPORT_PRIVATE size_t GetCurrentNumberOfTypes() const;
// Prepares wasm for the provided canonical type index. This reserves enough
- // space in the canonical rtts and the JSToWasm wrappers on the isolate roots.
- V8_EXPORT_PRIVATE static void PrepareForCanonicalTypeId(
- Isolate* isolate, CanonicalTypeIndex id);
+ // space in the canonical rtts on the isolate roots. If {shared}, it also
+ // reserves enough space in the shared canonical rtts of the shared space
+ // isolate.
+ V8_EXPORT_PRIVATE static void PrepareForCanonicalTypeId(Isolate* isolate,
+ CanonicalTypeIndex id,
+ SharedFlag shared);
// Reset the canonical rtts and JSToWasm wrappers on the isolate roots for
// testing purposes (in production cases canonical type ids are never freed).
V8_EXPORT_PRIVATE static void ClearWasmCanonicalTypesForTesting(
@@ -143,7 +146,8 @@ class TypeCanonicalizer {
SharedFlag IsShared(CanonicalTypeIndex index) const;
bool has_descriptor(CanonicalTypeIndex index) const;
- // Currently only used for heap verification.
+ // TODO(manoskouk): Implement a fast version of this if we have evidence that
+ // it is needed.
uint8_t GetSubtypingDepth_Slow(CanonicalTypeIndex index) const {
uint8_t depth = 0;
const CanonicalType* type = canonical_types_[index];
diff --git a/deps/v8/src/wasm/compilation-environment.h b/deps/v8/src/wasm/compilation-environment.h
index 28c73da4b48..611df0d2dc6 100644
--- a/deps/v8/src/wasm/compilation-environment.h
+++ b/deps/v8/src/wasm/compilation-environment.h
@@ -29,18 +29,6 @@ class WasmCode;
struct FastApiData;
class WasmModuleCoverageData;
-// The Arm architecture does not specify the results in memory of
-// partially-in-bound writes, which does not align with the wasm spec. This
-// affects when trap handlers can be used for OOB detection; however, Mac
-// systems with Apple silicon currently do provide trapping behaviour for
-// partially-out-of-bound writes, so we assume we can rely on that on MacOS,
-// since doing so provides better performance for writes.
-#if V8_TARGET_ARCH_RISCV64 || (V8_TARGET_ARCH_ARM64 && !V8_OS_MACOS)
-constexpr bool kPartialOOBWritesAreNoops = false;
-#else
-constexpr bool kPartialOOBWritesAreNoops = true;
-#endif
-
// The {CompilationEnv} encapsulates the module data that is used during
// compilation. CompilationEnvs are shareable across multiple compilations.
struct CompilationEnv {
diff --git a/deps/v8/src/wasm/constant-expression-interface.cc b/deps/v8/src/wasm/constant-expression-interface.cc
index 2badee69ecc..4451c93795c 100644
--- a/deps/v8/src/wasm/constant-expression-interface.cc
+++ b/deps/v8/src/wasm/constant-expression-interface.cc
@@ -171,11 +171,11 @@ DirectHandle<Map> ConstantExpressionInterface::GetRtt(
DCHECK(type.has_descriptor());
WasmValue desc = descriptor.runtime_value;
DirectHandle<Object> maybe_obj = desc.to_ref();
- if (!IsWasmStruct(*maybe_obj)) {
- DCHECK(IsWasmNull(*maybe_obj));
+ if (IsWasmNull(*maybe_obj)) {
error_ = MessageTemplate::kWasmTrapNullDereference;
return {};
}
+ DCHECK(IsWasmStruct(*maybe_obj));
DCHECK_EQ(desc.type().ref_index(),
module_->canonical_type_id(type.descriptor));
return direct_handle(Cast<WasmStruct>(*maybe_obj)->described_rtt(), isolate_);
@@ -192,7 +192,9 @@ void ConstantExpressionInterface::StructNew(FullDecoder* decoder,
ends_with_struct_new_ = decoder->lookahead(offset_to_next_instr, kExprEnd);
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);
@@ -299,7 +301,9 @@ void ConstantExpressionInterface::StructNewDefault(
ends_with_struct_new_ = decoder->lookahead(offset_to_next_instr, kExprEnd);
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);
@@ -372,6 +376,7 @@ 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)),
@@ -395,6 +400,7 @@ 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)),
@@ -423,6 +429,7 @@ 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)),
@@ -511,6 +518,7 @@ void ConstantExpressionInterface::WaitqueueNew(FullDecoder* decoder,
Value* result) {
if (!generate_value()) return;
+ // Memory fence is implemented in Managed<>::From.
auto ptr = std::make_shared<FutexManagedObjectWaitList>();
DirectHandle<Managed<FutexManagedObjectWaitList>> managed =
Managed<FutexManagedObjectWaitList>::From(
diff --git a/deps/v8/src/wasm/effect-handler.h b/deps/v8/src/wasm/effect-handler.h
index 35cbcaf9ad8..6c69ecedcee 100644
--- a/deps/v8/src/wasm/effect-handler.h
+++ b/deps/v8/src/wasm/effect-handler.h
@@ -13,13 +13,13 @@ namespace wasm {
struct __attribute__((packed)) EffectHandlerTagIndex {
using IsSwitchField = base::BitField<bool, 0, 1>;
- using IndexField = base::BitField<int, 1, 20>;
+ using IndexField = IsSwitchField::Next<uint32_t, 31>;
uint32_t tag_and_kind;
bool is_switch() const { return IsSwitchField::decode(tag_and_kind); }
- int index() const { return IndexField::decode(tag_and_kind); }
+ uint32_t index() const { return IndexField::decode(tag_and_kind); }
- void encode(bool is_switch, int tag_index) {
+ void encode(bool is_switch, uint32_t tag_index) {
tag_and_kind =
IsSwitchField::encode(is_switch) | IndexField::encode(tag_index);
}
diff --git a/deps/v8/src/wasm/function-body-decoder-impl.h b/deps/v8/src/wasm/function-body-decoder-impl.h
index 6178fc4a1f5..284bed29c55 100644
--- a/deps/v8/src/wasm/function-body-decoder-impl.h
+++ b/deps/v8/src/wasm/function-body-decoder-impl.h
@@ -1566,6 +1566,7 @@ struct ControlBase : public PcForErrors<ValidationTag::validate> {
F(AtomicOp, WasmOpcode opcode, const Value args[], const size_t argc, \
const MemoryAccessImmediate& imm, Value* result) \
F(AtomicFence, const MemoryOrderImmediate& imm) \
+ F(Publish, const Value& value) \
F(Pause) \
F(MemoryInit, const MemoryInitImmediate& imm, const Value& dst, \
const Value& src, const Value& size) \
@@ -2816,6 +2817,7 @@ class WasmDecoder : public Decoder {
(ios.MemoryOrder(memory_order), ...);
return length + memory_order.length;
}
+ case kExprPublish:
case kExprPause:
case kExprWaitqueueNew:
case kExprWaitqueueNotify:
@@ -5811,6 +5813,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
switch (opcode) {
case kExprStructNew:
case kExprStructNewDesc: {
+ this->detected_->add_gc_allocation();
StructIndexImmediate imm(this, this->pc_ + opcode_length, validate);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
Value descriptor =
@@ -5824,6 +5827,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
}
case kExprStructNewDefault:
case kExprStructNewDefaultDesc: {
+ this->detected_->add_gc_allocation();
StructIndexImmediate imm(this, this->pc_ + opcode_length, validate);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
if (ValidationTag::validate) {
@@ -5907,6 +5911,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
return opcode_length + field.length;
}
case kExprArrayNew: {
+ this->detected_->add_gc_allocation();
ArrayIndexImmediate imm(this, this->pc_ + opcode_length, validate);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
auto [initial_value, length] =
@@ -5918,6 +5923,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
return opcode_length + imm.length;
}
case kExprArrayNewDefault: {
+ this->detected_->add_gc_allocation();
ArrayIndexImmediate imm(this, this->pc_ + opcode_length, validate);
if (!this->Validate(this->pc_ + opcode_length, imm)) return 0;
if (!VALIDATE(imm.array_type->element_type().is_defaultable())) {
@@ -5936,6 +5942,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
case kExprArrayNewData: {
// TODO(14616): Add check that array sharedness == segment sharedness?
NON_CONST_ONLY
+ this->detected_->add_gc_allocation();
ArrayIndexImmediate array_imm(this, this->pc_ + opcode_length,
validate);
if (!this->Validate(this->pc_ + opcode_length, array_imm)) return 0;
@@ -5964,6 +5971,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
case kExprArrayNewElem: {
// TODO(14616): Add check that array sharedness == segment sharedness?
NON_CONST_ONLY
+ this->detected_->add_gc_allocation();
ArrayIndexImmediate array_imm(this, this->pc_ + opcode_length,
validate);
if (!this->Validate(this->pc_ + opcode_length, array_imm)) return 0;
@@ -6196,6 +6204,7 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
return opcode_length + array_imm.length;
}
case kExprArrayNewFixed: {
+ this->detected_->add_gc_allocation();
ArrayIndexImmediate array_imm(this, this->pc_ + opcode_length,
validate);
if (!this->Validate(this->pc_ + opcode_length, array_imm)) return 0;
@@ -7443,6 +7452,27 @@ class WasmFullDecoder : public WasmDecoder<ValidationTag, decoding_mode> {
CALL_INTERFACE_IF_OK_AND_REACHABLE(WaitqueueNew, result);
return opcode_length;
}
+ case kExprPublish: {
+ CHECK_PROTOTYPE_OPCODE(shared);
+ NON_CONST_ONLY
+ Value value = Peek();
+ if (!VALIDATE(value.type.is_ref() || value.type == kWasmBottom)) {
+ PopTypeError(0, value, "reference type");
+ return 0;
+ }
+ // No-op for unshared types.
+ if (!value.type.is_shared()) {
+ return opcode_length;
+ }
+ // No-op for references to anything that cannot be a struct or array.
+ RefTypeKind kind = value.type.ref_type_kind();
+ if (kind == RefTypeKind::kStruct || kind == RefTypeKind::kArray ||
+ value.type.is_reference_to(GenericKind::kEq) ||
+ value.type.is_reference_to(GenericKind::kAny)) {
+ CALL_INTERFACE_IF_OK_AND_REACHABLE(Publish, value);
+ }
+ return opcode_length;
+ }
case kExprArrayAtomicGet: {
CHECK_PROTOTYPE_OPCODE(shared);
NON_CONST_ONLY
diff --git a/deps/v8/src/wasm/fuzzing/random-module-generation.cc b/deps/v8/src/wasm/fuzzing/random-module-generation.cc
index 895948cc53a..10af875989f 100644
--- a/deps/v8/src/wasm/fuzzing/random-module-generation.cc
+++ b/deps/v8/src/wasm/fuzzing/random-module-generation.cc
@@ -4479,17 +4479,6 @@ class ModuleGen {
uint8_t num_fields = (config >> 4) & 3; // Bits 4-5
uint8_t maybe_supertype = (config >> 6) & 3; // Bits 6-7
ModuleTypeIndex supertype = kNoSuperType;
-
- // Can't have a descriptor if this is the last type in the recgroup or
- // the last struct type.
- bool can_have_descriptor =
- v8_flags.wasm_custom_descriptors &&
- current_type_index != current_rec_group_end &&
- current_type_index < last_struct_type_index - 1;
- if (have_descriptor && !can_have_descriptor) {
- have_descriptor = false;
- }
-
uint32_t existing_struct_types =
static_cast<uint32_t>(struct_types.size());
if (is_descriptor) {
@@ -4502,11 +4491,8 @@ class ModuleGen {
// or the pre-selected number of structs would need to be allowed to
// be exceeded.
have_descriptor = false;
- // If the described type isn't final, we won't make the descriptor
- // final either -- any subtypes wouldn't know how to deal with that.
- if (!builder_->GetType_Unsafe(is_descriptor_for).is_final) {
- is_final = false;
- }
+ // Described and descriptor types must have matching finality.
+ is_final = builder_->GetType_Unsafe(is_descriptor_for).is_final;
} else if (existing_struct_types > 0 && have_supertype) {
supertype = ModuleTypeIndex{
struct_types[maybe_supertype % existing_struct_types]};
@@ -4520,16 +4506,26 @@ class ModuleGen {
supertype = ModuleTypeIndex{
struct_types[maybe_supertype % existing_struct_types]};
}
+ // If the chosen supertype is final, it can't be a supertype.
+ if (builder_->GetType_Unsafe(supertype).is_final) {
+ supertype = kNoSuperType;
+ }
}
+
+ // Can't have a descriptor if this is the last type in the recgroup or
+ // the last struct type, or if the chosen supertype has no descriptor.
+ bool can_have_descriptor =
+ v8_flags.wasm_custom_descriptors &&
+ current_type_index != current_rec_group_end &&
+ current_type_index < last_struct_type_index - 1 &&
+ (supertype == kNoSuperType ||
+ builder_->GetType_Unsafe(supertype).has_descriptor());
+ have_descriptor = have_descriptor && can_have_descriptor;
+
do {
if (supertype == kNoSuperType) break;
const TypeDefinition& supertype_def =
builder_->GetType_Unsafe(supertype);
- // If the chosen supertype is final, it can't be a supertype.
- if (supertype_def.is_final) {
- supertype = kNoSuperType;
- break;
- }
// If the chosen supertype has a descriptor, this type must have one
// too, otherwise that can't be the supertype.
if (supertype_def.has_descriptor()) {
diff --git a/deps/v8/src/wasm/interpreter/riscv/interpreter-builtins-riscv.cc b/deps/v8/src/wasm/interpreter/riscv/interpreter-builtins-riscv.cc
index 02032219d18..f5f3b0248f5 100644
--- a/deps/v8/src/wasm/interpreter/riscv/interpreter-builtins-riscv.cc
+++ b/deps/v8/src/wasm/interpreter/riscv/interpreter-builtins-riscv.cc
@@ -190,15 +190,13 @@ void LoadWasmInstanceFromFunctionData(MacroAssembler* masm,
#if V8_ENABLE_SANDBOX
__ DecompressProtected(
trusted_instance_data,
- MemOperand(function_data,
- offsetof(WasmExportedFunctionData, protected_instance_data_) -
- kHeapObjectTag));
+ FieldMemOperand(function_data, offsetof(WasmExportedFunctionData,
+ protected_instance_data_)));
#else
__ LoadTaggedField(
trusted_instance_data,
- MemOperand(function_data,
- offsetof(WasmExportedFunctionData, protected_instance_data_) -
- kHeapObjectTag));
+ FieldMemOperand(function_data, offsetof(WasmExportedFunctionData,
+ protected_instance_data_)));
#endif
__ LoadTaggedField(
wasm_instance,
@@ -345,6 +343,15 @@ void Builtins::Generate_JSToWasmInterpreterWrapperAsm(MacroAssembler* masm) {
// from the wrapper buffer into a3, which WasmInterpreterEntry will
// forward to Runtime_WasmRunInterpreter.
DEFINE_PINNED(ref_params_array, a3);
+ __ LoadWord(
+ ref_params_array,
+ MemOperand(
+ wrapper_buffer,
+ WasmInterpreterWrapperConstants::kWrapperBufferRefParamsArray));
+ // Load the FixedArray of converted reference parameters (or Undefined)
+ // from the wrapper buffer into a3, which WasmInterpreterEntry will
+ // forward to Runtime_WasmRunInterpreter.
+ DEFINE_PINNED(ref_params_array, a3);
__ LoadWord(
ref_params_array,
MemOperand(
diff --git a/deps/v8/src/wasm/interpreter/wasm-interpreter-runtime.cc b/deps/v8/src/wasm/interpreter/wasm-interpreter-runtime.cc
index 88fde908240..25766aa55ad 100644
--- a/deps/v8/src/wasm/interpreter/wasm-interpreter-runtime.cc
+++ b/deps/v8/src/wasm/interpreter/wasm-interpreter-runtime.cc
@@ -995,18 +995,21 @@ void WasmInterpreterRuntime::BeginExecution(
const FunctionSig* sig = module_->functions[func_index].sig;
size_t args_count = 0;
uint32_t rets_slots_size = 0;
+ uint32_t args_slots_size = 0;
uint32_t ref_rets_count = 0;
uint32_t ref_args_count = 0;
WasmBytecode* target_function = GetFunctionBytecode(func_index);
if (target_function) {
args_count = target_function->args_count();
rets_slots_size = target_function->rets_slots_size();
+ args_slots_size = target_function->args_slots_size();
ref_rets_count = target_function->ref_rets_count();
ref_args_count = target_function->ref_args_count();
} else {
// We begin execution by calling an imported function.
args_count = sig->parameter_count();
rets_slots_size = WasmBytecode::RetsSizeInSlots(sig);
+ args_slots_size = WasmBytecode::ArgsSizeInSlots(sig);
ref_rets_count = WasmBytecode::RefRetsCount(sig);
ref_args_count = WasmBytecode::RefArgsCount(sig);
}
@@ -1023,19 +1026,43 @@ void WasmInterpreterRuntime::BeginExecution(
uint8_t* p = interpreter_fp + rets_slots_size * kSlotSize;
- // Check stack overflow.
+ // The interpreter stack frame holds slots for return values, arguments,
+ // locals, constants and the result of each instruction (the SSA-like
+ // registers). For an imported function we don't enter a new interpreter
+ // frame, so only the args+rets we write here need to fit.
+ size_t required_frame_size =
+ target_function ? target_function->frame_size()
+ : (rets_slots_size + args_slots_size) * kSlotSize;
const uint8_t* stack_limit = thread->StackLimitAddress();
- if (V8_UNLIKELY(p + (ref_rets_count + ref_args_count) * sizeof(WasmRef) >=
- stack_limit)) {
+ if (V8_UNLIKELY(stack_limit <= interpreter_fp ||
+ static_cast<size_t>(stack_limit - interpreter_fp) <
+ required_frame_size)) {
size_t additional_required_size =
- p + (ref_rets_count + ref_args_count) * sizeof(WasmRef) - stack_limit;
+ required_frame_size - (stack_limit - interpreter_fp);
if (!thread->ExpandStack(additional_required_size)) {
// TODO(paolosev@microsoft.com) - Calculate initial function offset.
- SealHandleScope shs(isolate_);
- isolate_->StackOverflow();
+ {
+ // Raising the stack-overflow RangeError allocates. Both entries into
+ // the interpreter hold a DisallowHeapAllocation across this call:
+ // Runtime_WasmRunInterpreter, to protect the raw arg buffer, and
+ // CallExternalWasmFunction, to protect the raw ref args that
+ // StoreRefArgsIntoStackSlots just wrote into the callee's (unscanned)
+ // interpreter stack slots. Re-enabling allocation is safe here only
+ // because this branch returns without reading either raw buffer again:
+ // the JS entry has already boxed its ref arguments into handles, and
+ // the cross-instance entry abandons the callee frame it just filled.
+ // Keep the allowance as narrow as possible so the invariant stays in
+ // force for the rest of the function. Handles created below belong to
+ // the HandleScope opened above.
+ AllowHeapAllocation allow_allocation;
+ isolate_->StackOverflow();
+ }
const pc_t trap_pc = 0;
SetTrap(MessageTemplate::kWasmTrapUnreachable, trap_pc);
thread->FinishActivation();
+ // Restore the caller's frame state.
+ const FrameState* frame_state = thread->GetCurrentActivationFor(this);
+ current_frame_ = frame_state ? *frame_state : FrameState();
return;
}
}
@@ -2221,10 +2248,9 @@ void WasmInterpreterRuntime::ExecuteCallRef(
// Use the callee's declared canonical signature for JS return-value
// validation, matching compiled code's per-import wrapper behavior.
- // {actual_sig_index} (computed above) is the actual callee's canonical
- // signature index.
const CanonicalSig* callee_canonical_sig =
- GetTypeCanonicalizer()->LookupFunctionSignature(actual_sig_index);
+ GetTypeCanonicalizer()->LookupFunctionSignature(
+ internal->sig()->index());
ExternalCallResult result = CallExternalJSFunction(
current_code, module_, func_ref, signature,
@@ -2507,7 +2533,7 @@ ExternalCallResult WasmInterpreterRuntime::CallExternalJSFunction(
{
// Packing the raw refs must not allocate; the only allocation in this
// block is the JS call below, which re-enables GC via its own nested
- // {AllowGarbageCollection} scope.
+ // {AllowHeapAllocation} scope.
DisallowGarbageCollection no_gc_packing;
size_t ref_idx = 0;
uint32_t* p = sp + WasmBytecode::RetsSizeInSlots(callsite_sig);
@@ -2547,6 +2573,13 @@ ExternalCallResult WasmInterpreterRuntime::CallExternalJSFunction(
DCHECK_NOT_NULL(current_thread_);
current_thread_->StopExecutionTimer();
{
+ // The enclosing {no_gc_packing} scope is a DisallowGarbageCollection,
+ // which disables both heap allocation AND safepoints. Calling into JS
+ // runs arbitrary code that must be allowed to allocate and to safepoint
+ // (GC). AllowHeapAllocation only re-enables allocation, leaving
+ // safepoints disallowed, so an allocation inside the JS callee trips
+ // DCHECK(AllowSafepoints::IsAllowed()) in LocalHeap::Safepoint. Use
+ // AllowGarbageCollection to re-enable both for the duration of the call.
AllowGarbageCollection allow_gc;
CallWasmToJSBuiltin(isolate_, object_ref, packer.argv(), callsite_sig);
}
@@ -2623,7 +2656,6 @@ ExternalCallResult WasmInterpreterRuntime::CallExternalJSFunction(
continue;
}
DirectHandle<Object>& ref = ref_returns[ref_idx++];
-
// Normalize JS null -> wasm_null for funcref returns (funcref uses
// wasm_null, not JS null).
bool is_funcref =
@@ -2643,7 +2675,6 @@ ExternalCallResult WasmInterpreterRuntime::CallExternalJSFunction(
} else {
ref = JSToWasmObject(ref, callsite_sig->GetReturn(i));
}
-
if (isolate_->has_exception()) {
return ExternalCallResult::EXTERNAL_EXCEPTION;
}
@@ -2786,9 +2817,10 @@ ExternalCallResult WasmInterpreterRuntime::CallExternalWasmFunction(
DirectHandle<Map> WasmInterpreterRuntime::RttCanon(uint32_t type_index) const {
// {managed_object_maps} holds the canonical RTTs for all (shared and
// non-shared) types on the single trusted instance data.
- DirectHandle<WasmTrustedInstanceData> data = wasm_trusted_instance_data();
DirectHandle<Map> rtt{
- TrustedCast<Map>(data->managed_object_maps()->get(type_index)), isolate_};
+ TrustedCast<Map>(
+ wasm_trusted_instance_data()->managed_object_maps()->get(type_index)),
+ isolate_};
return rtt;
}
@@ -2989,6 +3021,9 @@ WasmRef WasmInterpreterRuntime::JSToWasmObject(WasmRef extern_ref,
}
WasmRef WasmInterpreterRuntime::WasmToJSObject(WasmRef value) const {
+ if (IsWasmNull(*value) || i::IsNull(*value)) {
+ return direct_handle(ReadOnlyRoots(isolate_).null_value(), isolate_);
+ }
if (Is<WasmFuncRef>(*value)) {
Tagged<WasmFuncRef> wasm_func_ref = Cast<WasmFuncRef>(*value);
value = direct_handle(wasm_func_ref->internal(isolate_), isolate_);
@@ -3000,9 +3035,6 @@ WasmRef WasmInterpreterRuntime::WasmToJSObject(WasmRef value) const {
direct_handle(wasm_internal_function, isolate_);
return WasmInternalFunction::GetOrCreateExternal(internal);
}
- if (IsWasmNull(*value)) {
- return direct_handle(ReadOnlyRoots(isolate_).null_value(), isolate_);
- }
return value;
}
@@ -3042,7 +3074,7 @@ bool WasmInterpreterRuntime::SubtypeCheck(const WasmRef obj,
// Skip the null check if casting from any and not {null_succeeds}.
// In that case the instance type check will identify null as not being a
// wasm object and fail.
- if (obj_type.is_nullable() && (!is_cast_from_any || null_succeeds)) {
+ if (obj_type.is_nullable()) {
if (obj_type == kWasmExternRef || obj_type == kWasmNullExternRef) {
if (i::IsNull(*obj)) return null_succeeds;
} else {
@@ -3091,9 +3123,8 @@ using TypeChecker = bool (*)(const WasmRef obj);
template <TypeChecker type_checker>
bool AbstractTypeCast(Isolate* isolate, const WasmRef obj,
const ValueType obj_type, bool null_succeeds) {
- if (null_succeeds && obj_type.is_nullable() &&
- WasmInterpreterRuntime::IsNull(isolate, obj, obj_type)) {
- return true;
+ if (WasmInterpreterRuntime::IsNull(isolate, obj, obj_type)) {
+ return null_succeeds;
}
return type_checker(obj);
}
@@ -3104,6 +3135,7 @@ static bool EqCheck(const WasmRef obj) {
}
Tagged<HeapObject> heap_obj;
if (!TryCast(*obj, &heap_obj)) return false;
+ if (i::IsWasmNull(heap_obj)) return false;
InstanceType instance_type = heap_obj->map()->instance_type();
return instance_type >= FIRST_WASM_OBJECT_TYPE &&
instance_type <= LAST_WASM_OBJECT_TYPE;
@@ -3127,6 +3159,7 @@ static bool StructCheck(const WasmRef obj) {
}
Tagged<HeapObject> heap_obj;
if (!TryCast(*obj, &heap_obj)) return false;
+ if (i::IsWasmNull(heap_obj)) return false;
InstanceType instance_type = heap_obj->map()->instance_type();
return instance_type == WASM_STRUCT_TYPE;
}
@@ -3142,6 +3175,7 @@ static bool ArrayCheck(const WasmRef obj) {
}
Tagged<HeapObject> heap_obj;
if (!TryCast(*obj, &heap_obj)) return false;
+ if (i::IsWasmNull(heap_obj)) return false;
InstanceType instance_type = heap_obj->map()->instance_type();
return instance_type == WASM_ARRAY_TYPE;
}
@@ -3157,6 +3191,7 @@ static bool StringCheck(const WasmRef obj) {
}
Tagged<HeapObject> heap_obj;
if (!TryCast(*obj, &heap_obj)) return false;
+ if (i::IsWasmNull(heap_obj)) return false;
InstanceType instance_type = heap_obj->map()->instance_type();
return instance_type < FIRST_NONSTRING_TYPE;
}
diff --git a/deps/v8/src/wasm/interpreter/wasm-interpreter-simd.cc b/deps/v8/src/wasm/interpreter/wasm-interpreter-simd.cc
index 3c7eb5195f3..3e120ed8182 100644
--- a/deps/v8/src/wasm/interpreter/wasm-interpreter-simd.cc
+++ b/deps/v8/src/wasm/interpreter/wasm-interpreter-simd.cc
@@ -283,8 +283,8 @@ bool WasmBytecodeGenerator::DecodeSimdOp(WasmOpcode opcode,
opcode == kExprS128Load32Zero || opcode == kExprS128Load64Zero) {
bool is_rmw = WasmOpcodes::IsAtomicRmwOpcode(opcode);
MemoryAccessImmediate imm(decoder, code->at(pc + *len), 64, false,
- is_rmw ? MemoryAccessImmediate::kAtomicRMW
- : MemoryAccessImmediate::kNonAtomic,
+ is_rmw ? MemoryAccessImmediate::Kind::kAtomicRMW
+ : MemoryAccessImmediate::Kind::kNonAtomic,
Decoder::kNoValidation);
optional->memory_access.offset = imm.offset;
optional->memory_access.memory_index = imm.mem_index;
diff --git a/deps/v8/src/wasm/interpreter/wasm-interpreter.cc b/deps/v8/src/wasm/interpreter/wasm-interpreter.cc
index 58bd42f9bb1..18319e21875 100644
--- a/deps/v8/src/wasm/interpreter/wasm-interpreter.cc
+++ b/deps/v8/src/wasm/interpreter/wasm-interpreter.cc
@@ -261,14 +261,18 @@ WasmInterpreterThreadMap* WasmInterpreterThread::thread_interpreter_map_s =
WasmInterpreterThread* WasmInterpreterThreadMap::GetCurrentInterpreterThread(
Isolate* isolate) {
const int current_thread_id = ThreadId::Current().ToInteger();
+ // Key by both the OS thread id and the isolate: the same OS thread can run
+ // wasm for different isolates over time (v8::Locker multiplexing), and each
+ // isolate needs its own WasmInterpreterThread so that isolate_,
+ // reference_stack_ and stack_mem_ are never reused across isolates.
+ const std::pair<int, Isolate*> key(current_thread_id, isolate);
{
base::MutexGuard guard(&mutex_);
- auto it = map_.find(current_thread_id);
+ auto it = map_.find(key);
if (it == map_.end()) {
- map_[current_thread_id] =
- std::make_unique<WasmInterpreterThread>(isolate);
- it = map_.find(current_thread_id);
+ map_[key] = std::make_unique<WasmInterpreterThread>(isolate);
+ it = map_.find(key);
}
return it->second.get();
}
@@ -537,7 +541,12 @@ WasmInterpreterThread::WasmInterpreterThread(Isolate* isolate)
current_ref_stack_size_(0),
execution_timer_(isolate, true) {
PageAllocator* page_allocator = GetPlatformPageAllocator();
- stack_mem_ = AllocatePages(page_allocator, kMaxStackSize,
+ // Reserve kMaxStackSize bytes of growable stack plus a permanently
+ // inaccessible guard region of kInterpreterStackGuardSize bytes at the top.
+ // The guard region is never committed, so any OOB write past kMaxStackSize
+ // faults deterministically instead of touching memory belonging to another
+ // allocation.
+ stack_mem_ = AllocatePages(page_allocator, kInterpreterStackReservationSize,
page_allocator->AllocatePageSize(),
PageAllocator::kNoAccess);
if (!stack_mem_ ||
@@ -552,7 +561,8 @@ WasmInterpreterThread::WasmInterpreterThread(Isolate* isolate)
WasmInterpreterThread::~WasmInterpreterThread() {
GlobalHandles::Destroy(reference_stack_.location());
- FreePages(GetPlatformPageAllocator(), stack_mem_, kMaxStackSize);
+ FreePages(GetPlatformPageAllocator(), stack_mem_,
+ kInterpreterStackReservationSize);
}
void WasmInterpreterThread::EnsureRefStackSpace(size_t new_size) {
@@ -4896,9 +4906,13 @@ class Handlers : public HandlersBase {
UNOP_CASE(F32x4NearestInt, f32x4, float32x4, 4, nearbyintf(a))
UNOP_CASE(I64x2Neg, i64x2, int64x2, 2, base::NegateWithWraparound(a))
UNOP_CASE(I32x4Neg, i32x4, int32x4, 4, base::NegateWithWraparound(a))
- // Use llabs which will work correctly on both 64-bit and 32-bit.
- UNOP_CASE(I64x2Abs, i64x2, int64x2, 2, std::llabs(a))
- UNOP_CASE(I32x4Abs, i32x4, int32x4, 4, std::abs(a))
+ // abs(INT_MIN) wraps to INT_MIN per the Wasm SIMD spec. Using std::abs /
+ // std::llabs on INT_MIN is undefined behavior, so route the negative case
+ // through NegateWithWraparound.
+ UNOP_CASE(I64x2Abs, i64x2, int64x2, 2,
+ a < 0 ? base::NegateWithWraparound(a) : a)
+ UNOP_CASE(I32x4Abs, i32x4, int32x4, 4,
+ a < 0 ? base::NegateWithWraparound(a) : a)
UNOP_CASE(S128Not, i32x4, int32x4, 4, ~a)
UNOP_CASE(I16x8Neg, i16x8, int16x8, 8, base::NegateWithWraparound(a))
UNOP_CASE(I16x8Abs, i16x8, int16x8, 8, std::abs(a))
@@ -8308,18 +8322,18 @@ WasmInstruction WasmBytecodeGenerator::DecodeInstruction(pc_t pc,
break;
}
-#define LOAD_CASE(name, ctype, mtype, rep, type, opcode) \
- case kExpr##name: { \
- bool is_rmw = WasmOpcodes::IsAtomicRmwOpcode(opcode); \
- MemoryAccessImmediate imm(&decoder, wasm_code_->at(pc + 1), sizeof(ctype), \
- false, \
- is_rmw ? MemoryAccessImmediate::kAtomicRMW \
- : MemoryAccessImmediate::kNonAtomic, \
- Decoder::kNoValidation); \
- len = 1 + imm.length; \
- optional.memory_access.offset = imm.offset; \
- optional.memory_access.memory_index = imm.mem_index; \
- break; \
+#define LOAD_CASE(name, ctype, mtype, rep, type, opcode) \
+ case kExpr##name: { \
+ bool is_rmw = WasmOpcodes::IsAtomicRmwOpcode(opcode); \
+ MemoryAccessImmediate imm( \
+ &decoder, wasm_code_->at(pc + 1), sizeof(ctype), false, \
+ is_rmw ? MemoryAccessImmediate::Kind::kAtomicRMW \
+ : MemoryAccessImmediate::Kind::kNonAtomic, \
+ Decoder::kNoValidation); \
+ len = 1 + imm.length; \
+ optional.memory_access.offset = imm.offset; \
+ optional.memory_access.memory_index = imm.mem_index; \
+ break; \
}
LOAD_CASE(I32LoadMem8S, int32_t, int8_t, kWord8, I32, opcode);
LOAD_CASE(I32LoadMem8U, int32_t, uint8_t, kWord8, I32, opcode);
@@ -8337,18 +8351,18 @@ WasmInstruction WasmBytecodeGenerator::DecodeInstruction(pc_t pc,
LOAD_CASE(F64LoadMem, Float64, uint64_t, kFloat64, F64, opcode);
#undef LOAD_CASE
-#define STORE_CASE(name, ctype, mtype, rep, type, opcode) \
- case kExpr##name: { \
- bool is_rmw = WasmOpcodes::IsAtomicRmwOpcode(opcode); \
- MemoryAccessImmediate imm(&decoder, wasm_code_->at(pc + 1), sizeof(ctype), \
- false, \
- is_rmw ? MemoryAccessImmediate::kAtomicRMW \
- : MemoryAccessImmediate::kNonAtomic, \
- Decoder::kNoValidation); \
- len = 1 + imm.length; \
- optional.memory_access.offset = imm.offset; \
- optional.memory_access.memory_index = imm.mem_index; \
- break; \
+#define STORE_CASE(name, ctype, mtype, rep, type, opcode) \
+ case kExpr##name: { \
+ bool is_rmw = WasmOpcodes::IsAtomicRmwOpcode(opcode); \
+ MemoryAccessImmediate imm( \
+ &decoder, wasm_code_->at(pc + 1), sizeof(ctype), false, \
+ is_rmw ? MemoryAccessImmediate::Kind::kAtomicRMW \
+ : MemoryAccessImmediate::Kind::kNonAtomic, \
+ Decoder::kNoValidation); \
+ len = 1 + imm.length; \
+ optional.memory_access.offset = imm.offset; \
+ optional.memory_access.memory_index = imm.mem_index; \
+ break; \
}
STORE_CASE(I32StoreMem8, int32_t, int8_t, kWord8, I32, opcode);
STORE_CASE(I32StoreMem16, int32_t, int16_t, kWord16, I32, opcode);
@@ -8777,12 +8791,12 @@ void WasmBytecodeGenerator::DecodeAtomicOp(WasmOpcode opcode,
case kExpr##name: { \
MachineType memtype = MachineType::Type(); \
bool is_rmw = WasmOpcodes::IsAtomicRmwOpcode(opcode); \
- MemoryAccessImmediate imm(decoder, code->at(pc + *len), \
- ElementSizeLog2Of(memtype.representation()), \
- false, \
- is_rmw ? MemoryAccessImmediate::kAtomicRMW \
- : MemoryAccessImmediate::kNonAtomic, \
- Decoder::kNoValidation); \
+ MemoryAccessImmediate imm( \
+ decoder, code->at(pc + *len), \
+ ElementSizeLog2Of(memtype.representation()), false, \
+ is_rmw ? MemoryAccessImmediate::Kind::kAtomicRMW \
+ : MemoryAccessImmediate::Kind::kNonAtomic, \
+ Decoder::kNoValidation); \
optional->memory_access.offset = imm.offset; \
optional->memory_access.memory_index = imm.mem_index; \
*len += imm.length; \
@@ -9969,6 +9983,7 @@ RegMode WasmBytecodeGenerator::DoEncodeInstruction(const WasmInstruction& instr,
} else {
EMIT_INSTR_HANDLER(s2s_Branch);
EmitBranchOffset(br_on_cast_data.label_depth());
+ SetUnreachableMode();
}
} else if (V8_LIKELY(!TypeCheckAlwaysFails(
obj_type, target_type.heap_type(), null_succeeds))) {
@@ -10017,6 +10032,7 @@ RegMode WasmBytecodeGenerator::DoEncodeInstruction(const WasmInstruction& instr,
StoreBlockParamsAndResultsIntoSlots(target_branch_index, kExprBrOnCast);
EMIT_INSTR_HANDLER(s2s_Branch);
EmitBranchOffset(br_on_cast_data.label_depth());
+ SetUnreachableMode();
} else if (V8_UNLIKELY(TypeCheckAlwaysSucceeds(
obj_type, target_type.heap_type()))) {
// The branch can still be taken on null.
@@ -11429,7 +11445,7 @@ RegMode WasmBytecodeGenerator::DoEncodeInstruction(const WasmInstruction& instr,
case kExprRefAsNonNull: {
EMIT_INSTR_HANDLER_WITH_PC(s2s_RefAsNonNull, instr.pc);
ValueType value_type = RefPop();
- RefPush(value_type);
+ RefPush(value_type.AsNonNull());
break;
}
@@ -12040,7 +12056,9 @@ RegMode WasmBytecodeGenerator::DoEncodeInstruction(const WasmInstruction& instr,
RefPush(resulting_value_type);
} else {
// In this case we just trap.
+ RefPop(false);
EMIT_INSTR_HANDLER_WITH_PC(s2s_TrapIllegalCast, instr.pc);
+ SetUnreachableMode();
}
} else {
if (instr.opcode == kExprRefCast) {
@@ -12520,9 +12538,10 @@ RegMode WasmBytecodeGenerator::DoEncodeInstruction(const WasmInstruction& instr,
(AixFpOpWorkaround<float, &nearbyintf>(a)))
UNOP_CASE(I64x2Neg, i64x2, int64x2, 2, base::NegateWithWraparound(a))
UNOP_CASE(I32x4Neg, i32x4, int32x4, 4, base::NegateWithWraparound(a))
- // Use llabs which will work correctly on both 64-bit and 32-bit.
- UNOP_CASE(I64x2Abs, i64x2, int64x2, 2, std::llabs(a))
- UNOP_CASE(I32x4Abs, i32x4, int32x4, 4, std::abs(a))
+ UNOP_CASE(I64x2Abs, i64x2, int64x2, 2,
+ a < 0 ? base::NegateWithWraparound(a) : a)
+ UNOP_CASE(I32x4Abs, i32x4, int32x4, 4,
+ a < 0 ? base::NegateWithWraparound(a) : a)
UNOP_CASE(S128Not, i32x4, int32x4, 4, ~a)
UNOP_CASE(I16x8Neg, i16x8, int16x8, 8, base::NegateWithWraparound(a))
UNOP_CASE(I16x8Abs, i16x8, int16x8, 8, std::abs(a))
diff --git a/deps/v8/src/wasm/interpreter/wasm-interpreter.h b/deps/v8/src/wasm/interpreter/wasm-interpreter.h
index dd7d507ffb3..f2a8cf63036 100644
--- a/deps/v8/src/wasm/interpreter/wasm-interpreter.h
+++ b/deps/v8/src/wasm/interpreter/wasm-interpreter.h
@@ -11,6 +11,7 @@
#include <atomic>
#include <memory>
+#include <utility>
#include <vector>
#include "absl/container/flat_hash_map.h"
@@ -398,7 +399,12 @@ class V8_EXPORT_PRIVATE WasmInterpreterThreadMap {
void NotifyIsolateDisposal(Isolate* isolate);
private:
- typedef absl::flat_hash_map<int, std::unique_ptr<WasmInterpreterThread>>
+ // The map is process-global and shared by all isolates. A single OS thread
+ // can be time-shared by multiple isolates (e.g. an embedder that multiplexes
+ // isolates on one thread via v8::Locker), so entries must be keyed by both
+ // the OS thread id and the isolate.
+ typedef absl::flat_hash_map<std::pair<int, Isolate*>,
+ std::unique_ptr<WasmInterpreterThread>>
ThreadInterpreterMap;
ThreadInterpreterMap map_;
base::Mutex mutex_;
@@ -606,6 +612,48 @@ class V8_EXPORT_PRIVATE WasmInterpreterThread {
#endif // V8_ENABLE_DRUMBRAKE_TRACING
};
+ // The interpreter dedicates a per-thread stack to Wasm frames, distinct from
+ // the C++ stack. Its memory layout is:
+ //
+ // stack_mem_ -> +------------------------------+
+ // | committed region | grows in
+ // | ([0, current_stack_size_)) | kStackSizeIncrement
+ // | readable/writable | chunks via
+ // | | ExpandStack(), up to
+ // | | kMaxStackSize.
+ // +------------------------------+
+ // | reserved-but-uncommitted | permanently kNoAccess;
+ // | growth region | the ExpandStack path
+ // | ([current_stack_size_, | commits pages out of
+ // | kMaxStackSize)) | this region on demand.
+ // +------------------------------+
+ // | guard region | permanently kNoAccess.
+ // | ([kMaxStackSize, | Defense in depth: see
+ // | kInterpreterStackReservationSize)) the comment on
+ // | | kInterpreterStackGuardSize
+ // | | below.
+ // +------------------------------+
+ static constexpr uint32_t kInitialStackSize = 1 * MB;
+ static constexpr uint32_t kStackSizeIncrement = 1 * MB;
+ static constexpr uint32_t kMaxStackSize = 32 * MB;
+
+ // Tail guard region appended to the reservation, kept permanently kNoAccess.
+ //
+ // Defense in depth against bugs where the stack-overflow check undercounts
+ // the callee frame: if such a check ever lets a frame execute when it doesn't
+ // fit in the committed region, the callee's frame writes (args copy, slot
+ // initialization, etc.) progress sequentially from low to high addresses,
+ // so the very first byte that crosses into kNoAccess memory raises an access
+ // violation. The remaining bytes of the would-be write never happen. A single
+ // page is therefore sufficient; we use kStackSizeIncrement for a generous
+ // margin (still essentially free on 64-bit, since the tail is reserved-only
+ // and never committed).
+ static constexpr uint32_t kInterpreterStackGuardSize = kStackSizeIncrement;
+ static constexpr uint32_t kInterpreterStackReservationSize =
+ kMaxStackSize + kInterpreterStackGuardSize;
+ static_assert(kInterpreterStackReservationSize > kMaxStackSize,
+ "Reservation must leave a non-empty guard region.");
+
explicit WasmInterpreterThread(Isolate* isolate);
~WasmInterpreterThread();
@@ -779,9 +827,6 @@ class V8_EXPORT_PRIVATE WasmInterpreterThread {
// used to access the stack.
Address fuzzer_entry_frame_pointer_;
- static constexpr uint32_t kInitialStackSize = 1 * MB;
- static constexpr uint32_t kStackSizeIncrement = 1 * MB;
- static constexpr uint32_t kMaxStackSize = 32 * MB;
uint32_t current_stack_size_;
void* stack_mem_;
diff --git a/deps/v8/src/wasm/jump-table-assembler.cc b/deps/v8/src/wasm/jump-table-assembler.cc
index dfebd423c7c..2c911498f82 100644
--- a/deps/v8/src/wasm/jump-table-assembler.cc
+++ b/deps/v8/src/wasm/jump-table-assembler.cc
@@ -687,15 +687,20 @@ void JumpTableAssembler::SkipUntil(int offset) {
#elif V8_TARGET_ARCH_RISCV64
void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index,
Address lazy_compile_target) {
- static_assert(kLazyCompileTableSlotSize == 3 * kInstrSize);
+ static_assert(kLazyCompileTableSlotSize == 4 * kInstrSize);
int64_t high_20 = (func_index + 0x800) >> 12;
int64_t low_12 = int64_t(func_index) << 52 >> 52;
+ // The lazy compile target (a slot in the far jump table) can be farther away
+ // than the range of a single JAL for large modules. Use a checked AUIPC/JALR
+ // pair instead, so an out-of-range displacement cannot be silently truncated
+ // in release builds.
int64_t target_offset = MacroAssembler::CalculateTargetOffset(
lazy_compile_target, RelocInfo::NO_INFO,
reinterpret_cast<uint8_t*>(pc_ + 2 * kInstrSize));
- DCHECK(is_int21(target_offset));
- DCHECK_EQ(target_offset & 0x1, 0);
+ CHECK(is_int32(target_offset));
+ int32_t hi20 = (static_cast<int32_t>(target_offset) + 0x800) >> 12;
+ int32_t lo12 = static_cast<int32_t>(target_offset) << 20 >> 20;
const uint32_t inst[kLazyCompileTableSlotSize / 4] = {
(RO_LUI | (kWasmCompileLazyFuncIndexRegister.code() << kRdShift) |
@@ -703,16 +708,16 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index,
(RO_ADDI | (kWasmCompileLazyFuncIndexRegister.code() << kRdShift) |
(kWasmCompileLazyFuncIndexRegister.code() << kRs1Shift) |
int32_t(low_12 << kImm12Shift)), // addi t0, t0, low_12
- (RO_JAL | (zero_reg.code() << kRdShift) |
- uint32_t(target_offset & 0xff000) | // bits 19-12
- uint32_t((target_offset & 0x800) << 9) | // bit 11
- uint32_t((target_offset & 0x7fe) << 20) | // bits 10-1
- uint32_t((target_offset & 0x100000) << 11)), // bit 20 ), // jal
+ (RO_AUIPC | (t6.code() << kRdShift) |
+ (uint32_t(hi20) << kImm20Shift)), // auipc t6, hi20
+ (RO_JALR | (zero_reg.code() << kRdShift) | (t6.code() << kRs1Shift) |
+ (uint32_t(lo12) << kImm12Shift)), // jalr x0, t6, lo12
};
emit<uint32_t>(inst[0]);
emit<uint32_t>(inst[1]);
emit<uint32_t>(inst[2]);
+ emit<uint32_t>(inst[3]);
}
bool JumpTableAssembler::EmitJumpSlot(Address target) {
@@ -802,15 +807,19 @@ void JumpTableAssembler::SkipUntil(int offset) {
#elif V8_TARGET_ARCH_RISCV32
void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index,
Address lazy_compile_target) {
- static_assert(kLazyCompileTableSlotSize == 3 * kInstrSize);
+ static_assert(kLazyCompileTableSlotSize == 4 * kInstrSize);
int64_t high_20 = (func_index + 0x800) >> 12;
int64_t low_12 = int64_t(func_index) << 52 >> 52;
+ // See the RISC-V64 implementation: use a checked AUIPC/JALR pair instead of
+ // a range-limited JAL so an out-of-range displacement cannot be silently
+ // truncated in release builds.
int64_t target_offset = MacroAssembler::CalculateTargetOffset(
lazy_compile_target, RelocInfo::NO_INFO,
reinterpret_cast<uint8_t*>(pc_ + 2 * kInstrSize));
- DCHECK(is_int21(target_offset));
- DCHECK_EQ(target_offset & 0x1, 0);
+ CHECK(is_int32(target_offset));
+ int32_t hi20 = (static_cast<int32_t>(target_offset) + 0x800) >> 12;
+ int32_t lo12 = static_cast<int32_t>(target_offset) << 20 >> 20;
const uint32_t inst[kLazyCompileTableSlotSize / 4] = {
(RO_LUI | (kWasmCompileLazyFuncIndexRegister.code() << kRdShift) |
@@ -818,16 +827,16 @@ void JumpTableAssembler::EmitLazyCompileJumpSlot(uint32_t func_index,
(RO_ADDI | (kWasmCompileLazyFuncIndexRegister.code() << kRdShift) |
(kWasmCompileLazyFuncIndexRegister.code() << kRs1Shift) |
int32_t(low_12 << kImm12Shift)), // addi t0, t0, low_12
- (RO_JAL | (zero_reg.code() << kRdShift) |
- uint32_t(target_offset & 0xff000) | // bits 19-12
- uint32_t((target_offset & 0x800) << 9) | // bit 11
- uint32_t((target_offset & 0x7fe) << 20) | // bits 10-1
- uint32_t((target_offset & 0x100000) << 11)), // bit 20 ), // jal
+ (RO_AUIPC | (t6.code() << kRdShift) |
+ (uint32_t(hi20) << kImm20Shift)), // auipc t6, hi20
+ (RO_JALR | (zero_reg.code() << kRdShift) | (t6.code() << kRs1Shift) |
+ (uint32_t(lo12) << kImm12Shift)), // jalr x0, t6, lo12
};
emit<uint32_t>(inst[0], kRelaxedStore);
emit<uint32_t>(inst[1], kRelaxedStore);
emit<uint32_t>(inst[2], kRelaxedStore);
+ emit<uint32_t>(inst[3], kRelaxedStore);
}
bool JumpTableAssembler::EmitJumpSlot(Address target) {
uint32_t high_20 = (int64_t(3 * kInstrSize + 0x800) >> 12);
diff --git a/deps/v8/src/wasm/jump-table-assembler.h b/deps/v8/src/wasm/jump-table-assembler.h
index 91252dc6e67..d863b51ef61 100644
--- a/deps/v8/src/wasm/jump-table-assembler.h
+++ b/deps/v8/src/wasm/jump-table-assembler.h
@@ -231,12 +231,12 @@ class V8_EXPORT_PRIVATE JumpTableAssembler {
static constexpr int kJumpTableSlotSize = 6 * kInstrSize;
static constexpr int kJumpTableLineSize = kJumpTableSlotSize;
static constexpr int kFarJumpTableSlotSize = 6 * kInstrSize;
- static constexpr int kLazyCompileTableSlotSize = 3 * kInstrSize;
+ static constexpr int kLazyCompileTableSlotSize = 4 * kInstrSize;
#elif V8_TARGET_ARCH_RISCV32
static constexpr int kJumpTableSlotSize = 4 * kInstrSize;
static constexpr int kJumpTableLineSize = kJumpTableSlotSize;
static constexpr int kFarJumpTableSlotSize = kJumpTableSlotSize;
- static constexpr int kLazyCompileTableSlotSize = 3 * kInstrSize;
+ static constexpr int kLazyCompileTableSlotSize = 4 * kInstrSize;
#elif V8_TARGET_ARCH_LOONG64
static constexpr int kJumpTableLineSize = 1 * kInstrSize;
static constexpr int kJumpTableSlotSize = 1 * kInstrSize;
diff --git a/deps/v8/src/wasm/module-compiler.cc b/deps/v8/src/wasm/module-compiler.cc
index 65e42c8c9fb..2de1e3f956b 100644
--- a/deps/v8/src/wasm/module-compiler.cc
+++ b/deps/v8/src/wasm/module-compiler.cc
@@ -33,7 +33,7 @@
#include "src/wasm/wasm-code-manager.h"
#include "src/wasm/wasm-code-pointer-table-inl.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
+#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-import-wrapper-cache.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-limits.h"
@@ -1593,6 +1593,7 @@ void PublishDetectedFeatures(WasmDetectedFeatures detected_features,
{WasmDetectedFeature::memory64, Feature::kWasmMemory64},
{WasmDetectedFeature::multi_memory, Feature::kWasmMultiMemory},
{WasmDetectedFeature::gc, Feature::kWasmGC},
+ {WasmDetectedFeature::gc_allocation, Feature::kWasmGCAllocation},
{WasmDetectedFeature::imported_strings, Feature::kWasmImportedStrings},
{WasmDetectedFeature::imported_strings_utf8,
Feature::kWasmImportedStringsUtf8},
@@ -1636,8 +1637,10 @@ void PublishDetectedFeatures(WasmDetectedFeatures detected_features,
};
#define CHECK_USE_COUNTER(feat, ...) \
static_assert(check_use_counter(WasmDetectedFeature::feat));
- FOREACH_WASM_STAGING_FEATURE_FLAG(CHECK_USE_COUNTER)
- FOREACH_WASM_SHIPPED_FEATURE_FLAG(CHECK_USE_COUNTER)
+ FOREACH_STAGED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, CHECK_USE_COUNTER,
+ IGNORE_NON_WASM_FEATURE)
+ FOREACH_SHIPPED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, CHECK_USE_COUNTER,
+ IGNORE_NON_WASM_FEATURE)
FOREACH_WASM_NON_FLAG_FEATURE(CHECK_USE_COUNTER)
#undef CHECK_USE_COUNTER
@@ -3371,7 +3374,7 @@ bool AsyncStreamingProcessor::Deserialize(
}
DCHECK_NULL(job_->new_native_module_);
- Managed<NativeModule>::Ptr deserialized_native_module =
+ CppGCManaged<NativeModule>::Ptr deserialized_native_module =
module_object->native_module();
job_->wire_bytes_ = ModuleWireBytes(deserialized_native_module->wire_bytes());
// Calling {FinishCompile} deletes the {AsyncCompileJob} and {this}.
@@ -3958,7 +3961,11 @@ void CompilationStateImpl::TriggerOutstandingCallbacks() {
// For dynamic tiering, trigger "compilation chunk finished" after a new chunk
// of size {v8_flags.wasm_caching_threshold}.
- if (v8_flags.wasm_dynamic_tiering &&
+ // Only emit the kFinishedCompilationChunk event after
+ // kFinishedBaselineCompilation, and only when a non-zero amount of code has
+ // been generated (the threshold flag could be set to zero).
+ if (v8_flags.wasm_dynamic_tiering && outstanding_baseline_units_ == 0 &&
+ bytes_since_last_chunk_ > 0 &&
static_cast<size_t>(v8_flags.wasm_caching_threshold) <=
bytes_since_last_chunk_) {
// Trigger caching immediately if
diff --git a/deps/v8/src/wasm/module-decoder-impl.h b/deps/v8/src/wasm/module-decoder-impl.h
index 82be903662b..21a99c62009 100644
--- a/deps/v8/src/wasm/module-decoder-impl.h
+++ b/deps/v8/src/wasm/module-decoder-impl.h
@@ -853,6 +853,12 @@ class ModuleDecoderImpl : public Decoder {
i, type_def.descriptor.index);
return;
}
+ if (V8_UNLIKELY(descriptor.is_final != type_def.is_final)) {
+ errorf(pc_,
+ "Type %u and its descriptor %u must have same finality", i,
+ type_def.descriptor.index);
+ return;
+ }
}
if (type_def.describes.valid()) {
if (V8_UNLIKELY(module->type(type_def.describes).descriptor.index !=
diff --git a/deps/v8/src/wasm/module-instantiate.cc b/deps/v8/src/wasm/module-instantiate.cc
index 1bcaccf2bc7..2ce07a3477a 100644
--- a/deps/v8/src/wasm/module-instantiate.cc
+++ b/deps/v8/src/wasm/module-instantiate.cc
@@ -13,12 +13,14 @@
#include "src/compiler/fast-api-calls.h"
#include "src/compiler/wasm-compiler.h"
#include "src/handles/handle-scope-implementer-inl.h"
+#include "src/heap/parked-scope-inl.h"
#include "src/logging/counters-scopes.h"
#include "src/logging/metrics.h"
#include "src/numbers/conversions-inl.h"
#include "src/objects/descriptor-array-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/managed.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/property-descriptor.h"
#include "src/sandbox/trusted-pointer-scope.h"
#include "src/tracing/trace-event.h"
@@ -68,6 +70,31 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module,
}
const TypeDefinition type = module->type(type_index);
+
+ Isolate* shared_space_isolate;
+ // Another thread may cause shared GC while holding this mutex. We have to use
+ // a safepoint-aware MutexGuard here, otherwise the GC might wait forever on
+ // this blocked thread.
+ std::optional<ParkedMutexGuard> lock;
+ if (type.is_shared) {
+ shared_space_isolate = isolate->shared_space_isolate();
+ lock.emplace(isolate->main_thread_local_isolate(),
+ shared_space_isolate->wasm_shared_canonical_types_mutex());
+ DirectHandle<WeakFixedArray> shared_canonical_rtts(
+ shared_space_isolate->heap()->wasm_shared_canonical_rtts(), isolate);
+ DCHECK_GT(shared_canonical_rtts->ulength().value(),
+ canonical_type_index.index);
+ Tagged<MaybeObject> maybe_shared_canonical_map =
+ shared_canonical_rtts->get(canonical_type_index.index);
+ if (!maybe_shared_canonical_map.IsCleared()) {
+ canonical_rtts->set(canonical_type_index.index,
+ maybe_shared_canonical_map);
+ maps->set(type_index.index,
+ maybe_shared_canonical_map.GetHeapObjectAssumeWeak());
+ return;
+ }
+ }
+
int num_supertypes = type.subtyping_depth;
DirectHandle<Map> rtt_parent;
ModuleTypeIndex supertype = module->supertype(type_index);
@@ -76,9 +103,10 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module,
// create maps in order, so the supertype map must exist already.
DCHECK_LT(supertype.index, type_index.index);
DCHECK(IsMap(maps->get(supertype.index)));
- DCHECK(num_supertypes == module->type(supertype).subtyping_depth + 1);
+ DCHECK_EQ(num_supertypes, module->type(supertype).subtyping_depth + 1);
rtt_parent = direct_handle(Cast<Map>(maps->get(supertype.index)), isolate);
}
+
DirectHandle<Map> map;
switch (type.kind) {
case TypeDefinition::kStruct: {
@@ -101,6 +129,10 @@ void CreateMapForType(Isolate* isolate, const WasmModule* module,
}
canonical_rtts->set(canonical_type_index.index, MakeWeak(*map));
maps->set(type_index.index, *map);
+ if (type.is_shared) {
+ shared_space_isolate->heap()->wasm_shared_canonical_rtts()->set(
+ canonical_type_index.index, MakeWeak(*map));
+ }
}
namespace {
@@ -322,11 +354,17 @@ bool ResolveBoundJSFastApiFunction(const wasm::CanonicalSig* expected_sig,
}
bool IsStringRef(wasm::CanonicalValueType type) {
- return type.is_abstract_ref() && type.generic_kind() == GenericKind::kString;
+ // We could use {type == kWasmStringRef} for simplicity, but that would
+ // reject non-nullable types.
+ return type.is_abstract_ref() && !type.is_shared() &&
+ type.generic_kind() == GenericKind::kString;
}
bool IsExternRef(wasm::CanonicalValueType type) {
- return type.is_abstract_ref() && type.generic_kind() == GenericKind::kExtern;
+ // We could use {type == kWasmExternRef} for simplicity, but that would
+ // reject non-nullable types.
+ return type.is_abstract_ref() && !type.is_shared() &&
+ type.generic_kind() == GenericKind::kExtern;
}
bool IsStringOrExternRef(wasm::CanonicalValueType type) {
@@ -978,7 +1016,8 @@ MaybeDirectHandle<WasmInstanceObject> InstantiateToInstanceObject(
InstanceBuilder builder(isolate, context_id, thrower, module_object, imports);
MaybeDirectHandle<WasmInstanceObject> instance_object = builder.Build();
if (!instance_object.is_null()) {
- Managed<NativeModule>::Ptr native_module = module_object->native_module();
+ CppGCManaged<NativeModule>::Ptr native_module =
+ module_object->native_module();
if (v8_flags.wasm_pgo_to_file && native_module->ShouldPgoDataBeWritten() &&
native_module->module()->num_declared_functions > 0) {
WriteOutPGOTask::Schedule(std::move(native_module).as_shared_ptr());
@@ -1182,7 +1221,8 @@ Maybe<bool> InstanceBuilder::Build_Phase1(
// Make sure all canonical indices have been set.
DCHECK(module_->MaxCanonicalTypeIndex().valid());
TypeCanonicalizer::PrepareForCanonicalTypeId(
- isolate_, module_->MaxCanonicalTypeIndex());
+ isolate_, module_->MaxCanonicalTypeIndex(),
+ SharedFlag{module_->has_shared_part});
}
DirectHandle<FixedArray> managed_object_maps =
isolate_->factory()->NewFixedArray(
@@ -1203,7 +1243,12 @@ Maybe<bool> InstanceBuilder::Build_Phase1(
} else if (module_->has_array(index)) {
DCHECK_EQ(map->instance_type(), WASM_ARRAY_TYPE);
} else if (module_->has_struct(index)) {
- DCHECK_EQ(map->instance_type(), WASM_STRUCT_TYPE);
+ if (module_->types[i].is_descriptor() &&
+ v8_flags.wasm_merged_descriptors) {
+ DCHECK_EQ(map->instance_type(), WASM_CUSTOM_MAP_TYPE);
+ } else {
+ DCHECK_EQ(map->instance_type(), WASM_STRUCT_TYPE);
+ }
}
}
#endif
@@ -2093,7 +2138,8 @@ bool InstanceBuilder::ProcessImportedMemories(
uint32_t memory_index = import.index;
auto memory_object = Cast<WasmMemoryObject>(value);
- Managed<BackingStore>::Ptr backing_store = memory_object->backing_store();
+ CppGCManaged<BackingStore>::Ptr backing_store =
+ memory_object->backing_store();
#ifdef DEBUG
if (Tagged<JSArrayBuffer> buffer;
TryCast(memory_object->array_buffer(), &buffer)) {
diff --git a/deps/v8/src/wasm/stacks.cc b/deps/v8/src/wasm/stacks.cc
index 5235fb80115..964564fdd6b 100644
--- a/deps/v8/src/wasm/stacks.cc
+++ b/deps/v8/src/wasm/stacks.cc
@@ -7,10 +7,54 @@
#include "src/base/platform/platform.h"
#include "src/execution/frames.h"
#include "src/execution/simulator.h"
+#include "src/heap/heap-inl.h"
+#include "src/heap/heap-layout-inl.h"
+#include "src/objects/code-inl.h"
+#include "src/objects/slots-inl.h"
#include "src/wasm/wasm-objects.h"
namespace v8::internal::wasm {
+namespace {
+
+class YoungPointerTrackingVisitor : public RootVisitor {
+ public:
+ void VisitRootPointers(Root root, const char* description,
+ FullObjectSlot start, FullObjectSlot end) override {
+ if (found_young_) return;
+ for (FullObjectSlot slot = start; slot < end; ++slot) {
+ Tagged<Object> obj = *slot;
+ // Stack slots only hold strong references or Smis; weak references
+ // cannot appear on the execution stack.
+ if (HAS_STRONG_HEAP_OBJECT_TAG(obj.ptr()) &&
+ HeapLayout::InYoungGeneration(obj)) {
+ found_young_ = true;
+ return;
+ }
+ }
+ }
+
+ bool found_young() const { return found_young_; }
+
+ private:
+ bool found_young_ = false;
+};
+
+#ifdef DEBUG
+class VerifyNoYoungPointersVisitor : public RootVisitor {
+ public:
+ void VisitRootPointers(Root root, const char* description,
+ FullObjectSlot start, FullObjectSlot end) override {
+ for (FullObjectSlot slot = start; slot < end; ++slot) {
+ Tagged<Object> obj = *slot;
+ DCHECK(!HeapLayout::InYoungGeneration(obj));
+ }
+ }
+};
+#endif // DEBUG
+
+} // namespace
+
// static
StackMemory* StackMemory::GetCentralStackView(Isolate* isolate) {
base::Vector<uint8_t> view = SimulatorStack::GetCentralStackView(isolate);
@@ -111,31 +155,73 @@ StackMemory::StackSegment::~StackSegment() {
}
}
+void StackMemory::IterateWasmFXRoots(v8::internal::RootVisitor* v) {
+ if (!v8_flags.wasm_wasmfx) return;
+ v->VisitRootPointer(
+ Root::kStackRoots, nullptr,
+ FullObjectSlot(reinterpret_cast<Address>(¤t_cont_)));
+ v->VisitRootPointer(Root::kStackRoots, nullptr,
+ FullObjectSlot(reinterpret_cast<Address>(&func_ref_)));
+ v->VisitRootPointer(Root::kStackRoots, nullptr,
+ FullObjectSlot(reinterpret_cast<Address>(&stack_obj_)));
+ IterateWasmFXArgBuffer(param_types_, [this, v](size_t index, int offset) {
+ if (static_cast<int>(index) < num_bound_args_ &&
+ param_types_[index].is_ref()) {
+ v->VisitRootPointer(Root::kStackRoots, "wasm cont ref bound argument",
+ FullObjectSlot(reinterpret_cast<Address>(
+ this->arg_buffer_ + offset)));
+ }
+ });
+}
+
void StackMemory::Iterate(v8::internal::RootVisitor* v, Isolate* isolate,
ThreadLocalTop* thread) {
- StackFrameIterator it =
- IsActive() ? StackFrameIterator(isolate, thread,
- StackFrameIterator::FirstStackOnly{})
- : StackFrameIterator(isolate, this);
- for (; !it.done(); it.Advance()) {
- it.frame()->Iterate(v);
- }
- if (v8_flags.wasm_wasmfx) {
- v->VisitRootPointer(
- Root::kStackRoots, nullptr,
- FullObjectSlot(reinterpret_cast<Address>(¤t_cont_)));
- v->VisitRootPointer(Root::kStackRoots, nullptr,
- FullObjectSlot(reinterpret_cast<Address>(&func_ref_)));
- v->VisitRootPointer(Root::kStackRoots, nullptr,
- FullObjectSlot(reinterpret_cast<Address>(&stack_obj_)));
- IterateWasmFXArgBuffer(param_types_, [this, v](size_t index, int offset) {
- if (static_cast<int>(index) < num_bound_args_ &&
- param_types_[index].is_ref()) {
- v->VisitRootPointer(Root::kStackRoots, "wasm cont ref bound argument",
- FullObjectSlot(reinterpret_cast<Address>(
- this->arg_buffer_ + offset)));
+ if (IsActive()) {
+ StackFrameIterator it(isolate, thread,
+ StackFrameIterator::FirstStackOnly{});
+ for (; !it.done(); it.Advance()) {
+ it.frame()->Iterate(v);
+ }
+ IterateWasmFXRoots(v);
+ } else {
+ if (Heap::IsYoungGenerationCollector(v->collector())) {
+ if (contains_only_old_pointers_) {
+#ifdef DEBUG
+ VerifyNoYoungPointersVisitor verifier;
+ StackFrameIterator it(isolate, this);
+ for (; !it.done(); it.Advance()) {
+ it.frame()->Iterate(&verifier);
+ }
+ IterateWasmFXRoots(&verifier);
+#endif
+ return;
+ }
+
+ YoungPointerTrackingVisitor tracking_visitor;
+ StackFrameIterator it(isolate, this);
+ for (; !it.done(); it.Advance()) {
+ it.frame()->Iterate(v);
+ it.frame()->Iterate(&tracking_visitor);
+ }
+ IterateWasmFXRoots(v);
+ IterateWasmFXRoots(&tracking_visitor);
+
+ contains_only_old_pointers_ = !tracking_visitor.found_young();
+ } else {
+ StackFrameIterator it(isolate, this);
+ for (; !it.done(); it.Advance()) {
+ it.frame()->Iterate(v);
}
- });
+ IterateWasmFXRoots(v);
+
+ // Non-GC passes (e.g. Heap::Verify under --verify-heap) also use
+ // non-young-generation visitors. Only set contains_only_old_pointers_ to
+ // true during an actual Major GC (Mark-Compact), after which the young
+ // generation is guaranteed to be empty.
+ if (isolate->heap()->gc_state() == Heap::MARK_COMPACT) {
+ contains_only_old_pointers_ = true;
+ }
+ }
}
}
@@ -234,6 +320,7 @@ void StackMemory::Reset() {
param_types_ = {};
signature_id_ = CanonicalTypeIndex{kInvalidCanonicalIndex};
wasm_code_ = nullptr;
+ contains_only_old_pointers_ = false;
}
bool StackMemory::IsValidContinuation(Tagged<WasmContinuationObject> cont) {
@@ -241,7 +328,9 @@ bool StackMemory::IsValidContinuation(Tagged<WasmContinuationObject> cont) {
}
std::unique_ptr<StackMemory> StackPool::GetOrAllocate() {
- while (size_ > kMaxSize) {
+ while (v8_flags.wasm_stack_pool_capacity_mb >= 0 &&
+ size_ >
+ static_cast<size_t>(v8_flags.wasm_stack_pool_capacity_mb) * MB) {
size_ -= freelist_.back()->allocated_size();
freelist_.pop_back();
}
diff --git a/deps/v8/src/wasm/stacks.h b/deps/v8/src/wasm/stacks.h
index e0af4b55908..7cd25c52e8d 100644
--- a/deps/v8/src/wasm/stacks.h
+++ b/deps/v8/src/wasm/stacks.h
@@ -92,6 +92,7 @@ class StackMemory {
}
void set_current_continuation(Tagged<WasmContinuationObject> cont) {
current_cont_ = cont;
+ contains_only_old_pointers_ = false;
}
void set_stack_obj(Tagged<WasmStackObject> stack) { stack_obj_ = stack; }
Tagged<WasmStackObject> stack_obj() { return stack_obj_; }
@@ -138,6 +139,13 @@ class StackMemory {
bool Grow(Address current_fp, size_t min_size);
Address Shrink();
void ShrinkTo(Address stack_address);
+ bool contains_only_old_pointers() const {
+ return contains_only_old_pointers_;
+ }
+ void set_contains_only_old_pointers(bool value) {
+ contains_only_old_pointers_ = value;
+ }
+
void Reset();
class StackSegment {
@@ -258,6 +266,8 @@ class StackMemory {
// Overload to represent a view of the libc stack.
StackMemory(uint8_t* limit, size_t size);
+ void IterateWasmFXRoots(v8::internal::RootVisitor* v);
+
uint8_t* limit_;
size_t size_;
bool owned_;
@@ -298,6 +308,10 @@ class StackMemory {
// The pointer is cleared when we return/suspend back to this stack to avoid
// keeping a dangling pointer if the frame is popped.
WasmCode* wasm_code_ = nullptr;
+
+ // Generational state for optimizing minor GC root iteration on suspended
+ // stacks.
+ bool contains_only_old_pointers_ = false;
// When adding fields here, also check if it needs to be cleared in
// StackMemory::Reset() when the stack is moved to the stack pool after
// retiring.
@@ -331,9 +345,6 @@ class StackPool {
private:
std::vector<std::unique_ptr<StackMemory>> freelist_;
size_t size_ = 0;
- // If the next finished stack would move the total size above this limit, the
- // stack is freed instead of being added to the free list.
- static constexpr int kMaxSize = 4 * MB;
};
using WasmFXArgBufferCallback =
diff --git a/deps/v8/src/wasm/streaming-decoder.h b/deps/v8/src/wasm/streaming-decoder.h
index 2f5094af04a..d6b5b5a34e8 100644
--- a/deps/v8/src/wasm/streaming-decoder.h
+++ b/deps/v8/src/wasm/streaming-decoder.h
@@ -125,7 +125,16 @@ class V8_EXPORT_PRIVATE StreamingDecoder {
std::shared_ptr<const std::string> shared_url() const { return url_; }
void SetUrl(base::Vector<const char> url) {
+ // We shouldn't modify {url_} while it is being read. The API contract
+ // hence states that {SetUrl()} must be called early.
+ // Enforcing this with a CHECK is possibly racy when an attacker with an
+ // in-sandbox corruption primitive performs a swapping attack. If that
+ // becomes a problem, we can add a lock. As an attack mitigation, a CHECK
+ // that fails most of the time is probably good enough.
+ SBXCHECK_EQ(stream_state_, kReceivingBytes);
url_->assign(url.begin(), url.size());
+ // Safely crash if a race did happen:
+ SBXCHECK_EQ(stream_state_, kReceivingBytes);
}
static std::unique_ptr<StreamingDecoder> Create(
diff --git a/deps/v8/src/wasm/turboshaft-graph-interface.cc b/deps/v8/src/wasm/turboshaft-graph-interface.cc
index cb4fb458f45..a186831fcbc 100644
--- a/deps/v8/src/wasm/turboshaft-graph-interface.cc
+++ b/deps/v8/src/wasm/turboshaft-graph-interface.cc
@@ -22,8 +22,10 @@
#include "src/compiler/turboshaft/select-lowering-reducer.h"
#include "src/compiler/turboshaft/variable-reducer.h"
#include "src/compiler/wasm-compiler-definitions.h"
+#include "src/execution/frame-constants.h"
#include "src/flags/flags.h"
#include "src/objects/object-list-macros.h"
+#include "src/strings/unicode.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/canonical-types.h"
#include "src/wasm/compilation-environment.h"
@@ -1523,7 +1525,7 @@ class TurboshaftGraphBuildingInterface
MemoryRepresentation::FromMachineRepresentation(type.mem_rep());
compiler::EnforceBoundsCheck enforce_bounds_check =
- (wasm::kPartialOOBWritesAreNoops || type.size() == 1)
+ (v8_flags.wasm_partial_oob_writes_are_noops || type.size() == 1)
? compiler::kCanOmitBoundsCheck
: compiler::kNeedsBoundsCheck;
@@ -1574,7 +1576,7 @@ class TurboshaftGraphBuildingInterface
MemoryRepresentation::FromMachineRepresentation(type.mem_rep());
compiler::EnforceBoundsCheck enforce_bounds_check =
- (wasm::kPartialOOBWritesAreNoops || type.size() == 1)
+ (v8_flags.wasm_partial_oob_writes_are_noops || type.size() == 1)
? compiler::kCanOmitBoundsCheck
: compiler::kNeedsBoundsCheck;
@@ -2155,6 +2157,7 @@ class TurboshaftGraphBuildingInterface
OpIndex ret_val = __ Call(target_address, OpIndex::Invalid(),
base::VectorOf(inputs), ts_call_descriptor);
BuildSwitchBackFromCentralStack(old_sp, old_limit);
+ instance_cache_.ReloadCachedMemory();
#if DEBUG
// Reset the context again after the call, to make sure nobody is using the
@@ -2339,18 +2342,20 @@ class TurboshaftGraphBuildingInterface
break;
}
case WKI::kStringFromWtf16Array: {
+ constexpr int config = UnicodeConfig::kWtf16Unshared().raw_as_int();
V<String> result_value = CallBuiltinThroughJumptable<
BuiltinCallDescriptor::WasmStringNewWtf16Array>(
- decoder,
- {V<WasmArray>::Cast(NullCheck(args[0])), args[1].op, args[2].op});
+ decoder, {V<WasmArray>::Cast(NullCheck(args[0])), args[1].op,
+ args[2].op, __ SmiConstant(Smi::FromInt(config))});
result = __ AnnotateWasmType(result_value, kWasmRefExternString);
break;
}
case WKI::kStringFromWtf16ArrayShared: {
+ constexpr int config = UnicodeConfig::kWtf16Shared().raw_as_int();
V<String> result_value = CallBuiltinThroughJumptable<
- BuiltinCallDescriptor::WasmStringNewWtf16ArrayShared>(
- decoder,
- {V<WasmArray>::Cast(NullCheck(args[0])), args[1].op, args[2].op});
+ BuiltinCallDescriptor::WasmStringNewWtf16Array>(
+ decoder, {V<WasmArray>::Cast(NullCheck(args[0])), args[1].op,
+ args[2].op, __ SmiConstant(Smi::FromInt(config))});
result = __ AnnotateWasmType(result_value, kWasmRefSharedExternString);
break;
}
@@ -2361,14 +2366,13 @@ class TurboshaftGraphBuildingInterface
break;
case WKI::kStringFromUtf8ArrayShared: {
// TODO(448741522): If needed, special-case the array being an
- // array.new_data, like StringNewWtf8ArrayImpl
+ // array.new_data, like StringNewWtf8ArrayImpl.
+ constexpr int config = UnicodeConfig::kLossyUtf8Shared().raw_as_int();
V<Object> builtin_result = CallBuiltinThroughJumptable<
BuiltinCallDescriptor::WasmStringNewWtf8Array>(
decoder,
{args[1].op, args[2].op, V<WasmArray>::Cast(NullCheck(args[0])),
- __ SmiConstant(Smi::FromInt(
- static_cast<int32_t>(unibrow::Utf8Variant::kLossyUtf8))),
- __ SmiConstant(Smi::FromInt(1)) /* shared */});
+ __ SmiConstant(Smi::FromInt(config))});
result =
__ AnnotateWasmType(builtin_result, kWasmRefSharedExternString);
break;
@@ -4216,8 +4220,7 @@ class TurboshaftGraphBuildingInterface
-> AllocateVector<compiler::turboshaft::EffectHandler>(
handlers.size());
for (size_t i = 0; i < handlers.size(); ++i) {
- DCHECK(handlers[i].tag.index >= 0 &&
- handlers[i].tag.index < kV8MaxWasmTags);
+ DCHECK_LT(handlers[i].tag.index, decoder->module_->tags.size());
asm_handlers[i].tag_and_kind.encode(
handlers[i].kind == wasm::SwitchKind::kSwitch, handlers[i].tag.index);
asm_handlers[i].block = __ NewBlock();
@@ -4788,6 +4791,14 @@ class TurboshaftGraphBuildingInterface
__ MemoryBarrier(imm.order);
}
+ void Publish(FullDecoder* decoder, const Value& value) {
+ // Overapproximate a release fence with an acquire-release fence.
+ // TODO(b/556394003): Model this as a separate operation so it can be
+ // optimized out when there are no intervening writes between object
+ // allocation and publication.
+ __ MemoryBarrier(AtomicMemoryOrder::kAcqRel);
+ }
+
void Pause(FullDecoder* decoder) { __ Pause(); }
void MemoryInit(FullDecoder* decoder, const MemoryInitImmediate& imm,
@@ -5114,9 +5125,12 @@ class TurboshaftGraphBuildingInterface
// initialize the function table entry.
Label<Object> resolved(&asm_);
Label<> call_runtime(&asm_);
- // The entry is a WasmFuncRef, WasmNull, or Tuple2. Hence
- // it is safe to cast it to HeapObject.
+ // The entry is a WasmFuncRef, WasmNull, or Tuple2. We can cast it
+ // to HeapObject after checking for WasmNull.
+ GOTO_IF(UNLIKELY(__ IsNull(entry, kWasmFuncRef)), resolved, entry);
V<Map> entry_map = __ LoadMapField(V<HeapObject>::Cast(entry));
+ // TODO(jkummerow): Instead of loading the instance type, compare
+ // the Tuple2Map by pointer identity.
V<Word32> instance_type = __ LoadInstanceTypeField(entry_map);
GOTO_IF(
UNLIKELY(__ Word32Equal(instance_type, InstanceType::TUPLE2_TYPE)),
@@ -5799,7 +5813,7 @@ class TurboshaftGraphBuildingInterface
__ ArraySet(array, __ Word32Constant(i), elements[i].op, element_type, {},
write_barrier, ArraySetOp::Kind::kInitialize);
}
- if (shared) __ MemoryBarrier(AtomicMemoryOrder::kSeqCst);
+ if (shared) __ MemoryBarrier(AtomicMemoryOrder::kAcqRel);
result->op = array;
}
@@ -6046,13 +6060,14 @@ class TurboshaftGraphBuildingInterface
const unibrow::Utf8Variant variant, const Value& offset,
const Value& size, Value* result) {
V<Word32> memory = __ Word32Constant(imm.index);
- V<Smi> variant_smi =
- __ SmiConstant(Smi::FromInt(static_cast<int>(variant)));
+ UnicodeConfig config(variant, imm.memory->is_shared,
+ result->type.is_shared());
+ V<Smi> config_smi = __ SmiConstant(Smi::FromInt(config.raw_as_int()));
V<WordPtr> index = MemoryAddressToUintPtrOrOOBTrap(imm.memory->address_type,
offset.get<Word>());
V<WasmStringRefNullable> result_value =
CallBuiltinThroughJumptable<BuiltinCallDescriptor::WasmStringNewWtf8>(
- decoder, {index, size.op, memory, variant_smi});
+ decoder, {index, size.op, memory, config_smi});
result->op = __ AnnotateWasmType(result_value, result->type);
}
@@ -6092,7 +6107,10 @@ class TurboshaftGraphBuildingInterface
// Special case: shortcut a sequence "array from data segment" + "string
// from wtf8 array" to directly create a string from the segment.
V<internal::UnionOf<String, WasmNull, Null>> call;
- if (const CallOp* array_new = IsArrayNewSegment(array.get<Object>())) {
+ const CallOp* array_new = result_type.is_shared().value()
+ ? nullptr
+ : IsArrayNewSegment(array.get<Object>());
+ if (array_new != nullptr) {
// We can only pass 3 untagged parameters to the builtin (on 32-bit
// platforms). The segment index is easy to tag: if it validated, it must
// be in Smi range.
@@ -6116,12 +6134,13 @@ class TurboshaftGraphBuildingInterface
offset_smi, variant_smi});
} else {
// Regular path if the shortcut wasn't taken.
+ UnicodeConfig config(variant, array.type.is_shared(),
+ result_type.is_shared());
call = CallBuiltinThroughJumptable<
BuiltinCallDescriptor::WasmStringNewWtf8Array>(
decoder,
{start.op, end.get<Word32>(), V<WasmArray>::Cast(NullCheck(array)),
- __ SmiConstant(Smi::FromInt(static_cast<int32_t>(variant))),
- __ SmiConstant(Smi::FromInt(0)) /* shared */});
+ __ SmiConstant(Smi::FromInt(config.raw_as_int()))});
}
DCHECK_IMPLIES(variant == unibrow::Utf8Variant::kUtf8NoTrap,
result_type.is_nullable());
@@ -6143,19 +6162,23 @@ class TurboshaftGraphBuildingInterface
const Value& offset, const Value& size, Value* result) {
V<WordPtr> index = MemoryAddressToUintPtrOrOOBTrap(imm.memory->address_type,
offset.get<Word>());
+ UnicodeConfig config(imm.memory->is_shared, result->type.is_shared());
V<String> result_value =
CallBuiltinThroughJumptable<BuiltinCallDescriptor::WasmStringNewWtf16>(
- decoder, {__ Word32Constant(imm.index), index, size.op});
+ decoder, {__ Word32Constant(imm.index), index, size.op,
+ __ SmiConstant(Smi::FromInt(config.raw_as_int()))});
result->op = __ AnnotateWasmType(result_value, result->type);
}
void StringNewWtf16Array(FullDecoder* decoder, const Value& array,
const Value& start, const Value& end,
Value* result) {
+ UnicodeConfig config(array.type.is_shared(), result->type.is_shared());
V<String> result_value = CallBuiltinThroughJumptable<
BuiltinCallDescriptor::WasmStringNewWtf16Array>(
- decoder, {V<WasmArray>::Cast(NullCheck(array)), start.get<Word32>(),
- end.get<Word32>()});
+ decoder,
+ {V<WasmArray>::Cast(NullCheck(array)), start.get<Word32>(),
+ end.get<Word32>(), __ SmiConstant(Smi::FromInt(config.raw_as_int()))});
result->op = __ AnnotateWasmType(result_value, result->type);
}
@@ -7160,6 +7183,18 @@ class TurboshaftGraphBuildingInterface
// stack check.
CHECK_NE(liftoff_frame_size_,
FunctionTypeFeedback::kUninitializedLiftoffFrameSize);
+
+ int parameter_stack_slots = 0;
+ class DummyResultCollector {
+ public:
+ void AddParamAt(size_t index, LinkageLocation location) {}
+ void AddReturnAt(size_t index, LinkageLocation location) {}
+ } result_collector;
+ wasm::IterateSignatureImpl(decoder->sig_, false, result_collector, nullptr,
+ ¶meter_stack_slots, nullptr, nullptr);
+
+ liftoff_frame_size_ += parameter_stack_slots * kSystemPointerSize +
+ CommonFrameConstants::kFixedFrameSizeAboveFp;
return liftoff_frame_size_;
}
@@ -9023,7 +9058,7 @@ class TurboshaftGraphBuildingInterface
// Initialize the elements.
ArrayFillImpl(array, __ Word32Constant(0), initial_value, length,
array_type, write_barrier, ArraySetOp::Kind::kInitialize);
- if (shared) __ MemoryBarrier(AtomicMemoryOrder::kSeqCst);
+ if (shared) __ MemoryBarrier(AtomicMemoryOrder::kAcqRel);
return array;
}
@@ -9098,7 +9133,7 @@ class TurboshaftGraphBuildingInterface
static_assert(Heap::kMinObjectSizeInTaggedWords == 2 &&
WasmStruct::kHeaderSize == 2 * kTaggedSize,
"empty struct might require initialization of padding field");
- if (type.is_shared) __ MemoryBarrier(AtomicMemoryOrder::kSeqCst);
+ if (type.is_shared) __ MemoryBarrier(AtomicMemoryOrder::kAcqRel);
return struct_value;
}
diff --git a/deps/v8/src/wasm/wasm-builtin-list.h b/deps/v8/src/wasm/wasm-builtin-list.h
index 80e4f4dbdaa..620e7ddac1b 100644
--- a/deps/v8/src/wasm/wasm-builtin-list.h
+++ b/deps/v8/src/wasm/wasm-builtin-list.h
@@ -137,7 +137,6 @@ namespace v8::internal::wasm {
V(WasmStringSliceShared) \
V(WasmStringNewWtf8Array) \
V(WasmStringNewWtf16Array) \
- V(WasmStringNewWtf16ArrayShared) \
V(WasmStringEncodeWtf8Array) \
V(WasmStringToUtf8Array) \
V(WasmStringEncodeWtf16Array) \
diff --git a/deps/v8/src/wasm/wasm-code-manager.cc b/deps/v8/src/wasm/wasm-code-manager.cc
index cc10f58f428..dbfcfa9ef3b 100644
--- a/deps/v8/src/wasm/wasm-code-manager.cc
+++ b/deps/v8/src/wasm/wasm-code-manager.cc
@@ -1038,10 +1038,10 @@ NativeModule::NativeModule(WasmEnabledFeatures enabled_features,
std::shared_ptr<NativeModule>* shared_this)
: engine_scope_(
GetWasmEngine()->GetBarrierForBackgroundCompile()->TryLock()),
- code_allocator_(&counter_updates_),
enabled_features_(enabled_features),
compile_imports_(std::move(compile_imports)),
module_(std::move(module)),
+ code_allocator_(&counter_updates_),
// We don't use `std::make_shared` here because of problems with UBsan,
// see http://b/478120402.
fast_api_data_(new FastApiData[module_->num_imported_functions]) {
@@ -2171,6 +2171,14 @@ WasmCodePointer NativeModule::GetCodePointerHandle(int index) const {
NativeModule::~NativeModule() {
TRACE_HEAP("Deleting native module: %p\n", this);
+
+ // Ensure that {code_allocator_} is declared after {owned_code_} so that C++
+ // destroys {code_allocator_} (and removes the memory ranges from
+ // {WasmCodeManager::lookup_map_}) BEFORE {owned_code_} is destroyed.
+ static_assert(offsetof(NativeModule, code_allocator_) >
+ offsetof(NativeModule, owned_code_),
+ "code_allocator_ must be declared after owned_code_");
+
// Cancel all background compilation before resetting any field of the
// NativeModule or freeing anything.
compilation_state_->CancelCompilation();
@@ -2986,10 +2994,13 @@ size_t NativeModule::EstimateCurrentMemoryConsumption() const {
result += counter_updates_.EstimateCurrentMemoryConsumption() -
sizeof(counter_updates_);
- result += ContentSize(stack_entry_wrappers_);
- for (const std::shared_ptr<WasmWrapperHandle>& wrapper :
- stack_entry_wrappers_) {
- result += wrapper->code()->EstimateCurrentMemoryConsumption();
+ {
+ base::MutexGuard lock(&stack_wrapper_mutex_);
+ result += ContentSize(stack_entry_wrappers_);
+ for (const std::shared_ptr<WasmWrapperHandle>& wrapper :
+ stack_entry_wrappers_) {
+ result += wrapper->code()->EstimateCurrentMemoryConsumption();
+ }
}
// We cannot hold the `allocation_mutex_` while calling
diff --git a/deps/v8/src/wasm/wasm-code-manager.h b/deps/v8/src/wasm/wasm-code-manager.h
index 748400474e4..bab5eca796f 100644
--- a/deps/v8/src/wasm/wasm-code-manager.h
+++ b/deps/v8/src/wasm/wasm-code-manager.h
@@ -641,7 +641,7 @@ class WasmCodeAllocator {
class V8_EXPORT_PRIVATE NativeModule final {
public:
- static constexpr ExternalPointerTag kManagedTag = kWasmNativeModuleTag;
+ static constexpr ManagedTypeId kTypeID = ManagedTypeId::kWasmNativeModule;
#if V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_S390X || V8_TARGET_ARCH_ARM64 || \
V8_TARGET_ARCH_PPC64 || V8_TARGET_ARCH_LOONG64 || \
@@ -1038,10 +1038,6 @@ class V8_EXPORT_PRIVATE NativeModule final {
// last.
OperationsBarrier::Token engine_scope_;
- // {WasmCodeAllocator} manages all code reservations and allocations for this
- // {NativeModule}.
- WasmCodeAllocator code_allocator_;
-
// Features enabled for this module. We keep a copy of the features that
// were enabled at the time of the creation of this native module,
// to be consistent across asynchronous compilations later.
@@ -1133,6 +1129,12 @@ class V8_EXPORT_PRIVATE NativeModule final {
std::unique_ptr<NamesProvider> names_provider_;
+ // {WasmCodeAllocator} manages all code reservations and allocations for this
+ // {NativeModule}. It must be declared after {owned_code_} so that its
+ // destructor runs before {owned_code_}, removing memory ranges from the
+ // global {WasmCodeManager::lookup_map_} before code objects are freed.
+ WasmCodeAllocator code_allocator_;
+
DebugState debug_state_ = kNotDebugging;
// End of fields protected by {allocation_mutex_}.
@@ -1164,7 +1166,7 @@ class V8_EXPORT_PRIVATE NativeModule final {
// The stack wrappers are compiled lazily and shared across modules, but the
// cache itself only holds weak pointers. Keep strong pointers in the module
// to keep them alive.
- base::Mutex stack_wrapper_mutex_;
+ mutable base::Mutex stack_wrapper_mutex_;
std::unordered_set<std::shared_ptr<WasmWrapperHandle>> stack_entry_wrappers_;
};
diff --git a/deps/v8/src/wasm/wasm-code-pointer-table-inl.h b/deps/v8/src/wasm/wasm-code-pointer-table-inl.h
index d87b59173f9..d305c69ea0f 100644
--- a/deps/v8/src/wasm/wasm-code-pointer-table-inl.h
+++ b/deps/v8/src/wasm/wasm-code-pointer-table-inl.h
@@ -9,7 +9,7 @@
// Include the non-inl header before the rest of the headers.
#include "src/common/code-memory-access-inl.h"
-#include "src/common/segmented-table-inl.h"
+#include "src/sandbox/segmented-table-inl.h"
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
diff --git a/deps/v8/src/wasm/wasm-code-pointer-table.cc b/deps/v8/src/wasm/wasm-code-pointer-table.cc
index 51a20ad8d94..7d63f59a62d 100644
--- a/deps/v8/src/wasm/wasm-code-pointer-table.cc
+++ b/deps/v8/src/wasm/wasm-code-pointer-table.cc
@@ -9,7 +9,11 @@
namespace v8::internal::wasm {
-void WasmCodePointerTable::Initialize() { Base::Initialize(); }
+void WasmCodePointerTable::Initialize() {
+ Base::Initialize(kWasmCodePointerTableReservationSize,
+ 0 /* no read only size*/,
+ WasmCodePointerTableEntry::IsWriteProtected);
+}
void WasmCodePointerTable::TearDown() {
FreeNativeFunctionHandles();
diff --git a/deps/v8/src/wasm/wasm-code-pointer-table.h b/deps/v8/src/wasm/wasm-code-pointer-table.h
index 4ae673134e2..c80a5645434 100644
--- a/deps/v8/src/wasm/wasm-code-pointer-table.h
+++ b/deps/v8/src/wasm/wasm-code-pointer-table.h
@@ -6,7 +6,7 @@
#define V8_WASM_WASM_CODE_POINTER_TABLE_H_
#include "include/v8-internal.h"
-#include "src/common/segmented-table.h"
+#include "src/sandbox/segmented-table.h"
#if !V8_ENABLE_WEBASSEMBLY
#error This header should only be included if WebAssembly is enabled.
diff --git a/deps/v8/src/wasm/wasm-constants.h b/deps/v8/src/wasm/wasm-constants.h
index e3497ef0456..cca252d2862 100644
--- a/deps/v8/src/wasm/wasm-constants.h
+++ b/deps/v8/src/wasm/wasm-constants.h
@@ -260,6 +260,10 @@ constexpr int kOptimizationPriorityExecutedOnceSentinel = 127;
// priority was not specified.
constexpr int kOptimizationPriorityNotSpecifiedSentinel = -1;
+// Numeric limits for i31ref.
+constexpr int32_t kInt31MaxValue = 0x3fffffff;
+constexpr int32_t kInt31MinValue = -kInt31MaxValue - 1;
+
#if V8_TARGET_ARCH_X64
constexpr int32_t kOSRTargetOffset = 4 * kSystemPointerSize;
#endif
diff --git a/deps/v8/src/wasm/wasm-debug.cc b/deps/v8/src/wasm/wasm-debug.cc
index 8a897981f12..2a45a67074f 100644
--- a/deps/v8/src/wasm/wasm-debug.cc
+++ b/deps/v8/src/wasm/wasm-debug.cc
@@ -1032,7 +1032,8 @@ bool WasmScript::SetBreakPoint(DirectHandle<Script> script, int* position,
if (*position < 0) return false;
// Find the function for this breakpoint.
- Managed<wasm::NativeModule>::Ptr native_module = script->wasm_native_module();
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
+ script->wasm_native_module();
const wasm::WasmModule* module = native_module->module();
int func_index = GetContainingWasmFunction(module, *position);
if (func_index < 0) return false;
@@ -1065,7 +1066,8 @@ bool WasmScript::SetBreakPointOnFirstBreakableForFunction(
if (func_index < 0) return false;
int offset_in_func = 0;
- Managed<wasm::NativeModule>::Ptr native_module = script->wasm_native_module();
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
+ script->wasm_native_module();
int breakable_offset = FindNextBreakablePosition(native_module.raw(),
func_index, offset_in_func);
if (breakable_offset == 0) return false;
@@ -1083,7 +1085,8 @@ bool WasmScript::SetBreakPointForFunction(
DCHECK_NE(0, offset);
// Find the function for this breakpoint.
- Managed<wasm::NativeModule>::Ptr native_module = script->wasm_native_module();
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
+ script->wasm_native_module();
const wasm::WasmModule* module = native_module->module();
const wasm::WasmFunction& func = module->functions[func_index];
@@ -1171,7 +1174,7 @@ bool WasmScript::ClearBreakPoint(DirectHandle<Script> script, int position,
SetBreakOnEntryFlag(*script, false);
} else {
// Remove the breakpoint from DebugInfo and recompile.
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
script->wasm_native_module();
const wasm::WasmModule* module = native_module->module();
int func_index = GetContainingWasmFunction(module, position);
diff --git a/deps/v8/src/wasm/wasm-engine.cc b/deps/v8/src/wasm/wasm-engine.cc
index 3b90aa42ec0..09ed7759a8d 100644
--- a/deps/v8/src/wasm/wasm-engine.cc
+++ b/deps/v8/src/wasm/wasm-engine.cc
@@ -136,6 +136,13 @@ WasmOrphanedGlobalHandle* WasmEngine::NewOrphanedGlobalHandle(
return orphan;
}
+void WasmEngine::DestroyOrphanedGlobalHandle(WasmOrphanedGlobalHandle* that) {
+ // Acquire the lock because updating the linked list must not happen
+ // concurrently with {NewOrphanedGlobalHandle} inserting a node.
+ base::MutexGuard guard(&mutex_);
+ WasmOrphanedGlobalHandle::Destroy(that);
+}
+
// static
void WasmEngine::FreeAllOrphanedGlobalHandles(WasmOrphanedGlobalHandle* start) {
// This is meant to be called from ~Isolate, so we no longer care about
@@ -213,7 +220,7 @@ class ClearWeakScriptHandleTask : public CancelableTask {
// it might well be too late to do that safely).
void RunInternal() override {
- WasmOrphanedGlobalHandle::Destroy(handle_);
+ GetWasmEngine()->DestroyOrphanedGlobalHandle(handle_);
handle_ = nullptr;
}
@@ -949,14 +956,14 @@ DirectHandle<Script> CreateWasmScript(
}
// Use the given shared {NativeModule}, but increase its reference count by
- // allocating a new {Managed<T>} that the {Script} references.
+ // allocating a new {CppGCManaged<T>} that the {Script} references.
size_t code_size_estimate = native_module->committed_code_space();
size_t memory_estimate =
code_size_estimate +
wasm::WasmCodeManager::EstimateNativeModuleMetaDataSize(module);
- DirectHandle<Managed<wasm::NativeModule>> managed_native_module =
- Managed<wasm::NativeModule>::From(isolate, memory_estimate,
- std::move(native_module));
+ DirectHandle<CppGCManaged<wasm::NativeModule>> managed_native_module =
+ CppGCManaged<wasm::NativeModule>::Create(isolate, memory_estimate,
+ std::move(native_module));
DirectHandle<Script> script =
isolate->factory()->NewScript(isolate->factory()->undefined_value());
@@ -1658,7 +1665,7 @@ void WasmEngine::FreeNativeModule(NativeModule* native_module) {
// Flush the Wasm code lookup cache, since it may refer to some
// code within native modules that we are going to release (if a
- // Managed<wasm::NativeModule> object is no longer referenced).
+ // CppGCManaged<wasm::NativeModule> object is no longer referenced).
GetWasmCodeManager()->FlushCodeLookupCache(isolate);
// {CodeToLogPerScript} keeps the NativeModule alive, so if it dies, there
diff --git a/deps/v8/src/wasm/wasm-engine.h b/deps/v8/src/wasm/wasm-engine.h
index 952a38b2ae6..89e9135a92c 100644
--- a/deps/v8/src/wasm/wasm-engine.h
+++ b/deps/v8/src/wasm/wasm-engine.h
@@ -432,6 +432,7 @@ class V8_EXPORT_PRIVATE WasmEngine {
static WasmOrphanedGlobalHandle* NewOrphanedGlobalHandle(
WasmOrphanedGlobalHandle** pointer);
+ void DestroyOrphanedGlobalHandle(WasmOrphanedGlobalHandle* that);
static void FreeAllOrphanedGlobalHandles(WasmOrphanedGlobalHandle* start);
size_t NativeModuleCount() const;
diff --git a/deps/v8/src/wasm/wasm-external-refs.cc b/deps/v8/src/wasm/wasm-external-refs.cc
index 8c4b20ba9af..582631e38eb 100644
--- a/deps/v8/src/wasm/wasm-external-refs.cc
+++ b/deps/v8/src/wasm/wasm-external-refs.cc
@@ -1362,6 +1362,7 @@ void cont_bind(Address cont_raw, wasm::StackMemory* stack, int num_args,
stack->bind_arguments(num_args);
stack->set_signature_id(CanonicalTypeIndex{new_sig});
stack->set_current_continuation(cont);
+ stack->set_contains_only_old_pointers(false);
}
intptr_t switch_to_the_central_stack(Isolate* isolate, uintptr_t current_sp) {
diff --git a/deps/v8/src/wasm/wasm-feature-flags.h b/deps/v8/src/wasm/wasm-feature-flags.h
deleted file mode 100644
index 3efce4004f9..00000000000
--- a/deps/v8/src/wasm/wasm-feature-flags.h
+++ /dev/null
@@ -1,145 +0,0 @@
-// Copyright 2018 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef V8_WASM_WASM_FEATURE_FLAGS_H_
-#define V8_WASM_WASM_FEATURE_FLAGS_H_
-
-#if !V8_ENABLE_WEBASSEMBLY
-#error This header should only be included if WebAssembly is enabled.
-#endif // !V8_ENABLE_WEBASSEMBLY
-
-// Each entry in this file generates a V8 command-line flag with the prefix
-// "--wasm-".
-//
-// For example, to enable "my_feature", pass
-// --wasm-my-feature to d8, or
-// --js-flags=--wasm-my-feature to Chrome.
-//
-// For backward compatibility, the prefix "--experimental-wasm-" is also
-// supported as a temporary alias (to be dropped in V8 v15.3).
-//
-// To disable "my_feature", add the "--no-" prefix:
-// --no-wasm-my-feature.
-//
-// See https://github.com/WebAssembly/proposals for an overview of current
-// WebAssembly proposals.
-
-// Experimental features (disabled by default).
-#define FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(V) /* (force 80 columns) */ \
- /* Instruction Tracing tool convention (early prototype, might change) */ \
- /* Tool convention: https://github.com/WebAssembly/tool-conventions */ \
- /* V8 side owner: jabraham */ \
- V(instruction_tracing, "instruction tracing section", false) \
- \
- /* Shared-Everything Threads proposal. */ \
- /* https://github.com/WebAssembly/shared-everything-threads */ \
- /* V8 side owner: manoskouk */ \
- V(shared, "shared-everything threads", false) \
- \
- /* FP16 proposal. */ \
- /* https://github.com/WebAssembly/half-precision */ \
- /* V8 side owner: dahlb */ \
- V(fp16, "fp16", false) \
- \
- /* Memory Control proposal */ \
- /* https://github.com/WebAssembly/memory-control */ \
- /* V8 side owner: ahaas */ \
- V(memory_control, "memory control", false) \
- /* Core stack switching, main proposal */ \
- /* https://github.com/WebAssembly/stack-switching */ \
- /* V8 side owner: fgm, thibaudm */ \
- V(wasmfx, "core stack switching", false) \
- \
- /* Compilation hints */ \
- /* https://github.com/WebAssembly/compilation-hints */ \
- /* V8 side owner: ecmziegler, manoskouk */ \
- V(compilation_hints, "compilation hints", false) \
- \
- /* V8 side owner: thibaudm */ \
- V(growable_stacks, "growable stacks for jspi", false) \
- \
- /* Compact Import Section proposal. */ \
- /* https://github.com/WebAssembly/compact-import-section */ \
- /* V8 side owner: ryandiaz */ \
- V(compact_imports, "compact import section", false)
-
-// #############################################################################
-// Pre-staged features (disabled by default, but enabled via
-// --experimental-fuzzing). Pre-staged features get limited fuzzer coverage, and
-// should come with their own tests. Features typically spend about 2-4 weeks in
-// this stage before being moved to the staging phase. It's therefore expected
-// that this list is empty most of the time and that features spend extended
-// time right before or after this phase.
-#define FOREACH_WASM_PRE_STAGING_FEATURE_FLAG(V) /* (force 80 columns) */ \
- /* Reference-Typed Strings Proposal. */ \
- /* https://github.com/WebAssembly/stringref */ \
- /* V8 side owner: jkummerow */ \
- V(stringref, "reference-typed strings", false) \
- \
- /* Imported Strings TextEncoder/TextDecoder post-MVP extension. */ \
- /* No upstream repo yet. */ \
- /* V8 side owner: jkummerow */ \
- V(imported_strings_utf8, "imported strings (utf8 features)", false) \
- \
- /* Wide Arithmetic proposal */ \
- /* https://github.com/WebAssembly/wide-arithmetic */ \
- /* V8 side owner: ryandiaz */ \
- V(wide_arithmetic, "wide arithmetic", false) \
- \
- /* Acq-Rel memory ordering from Shared-Everything Threads proposal. */ \
- /* Part of https://github.com/WebAssembly/shared-everything-threads */ \
- /* V8 side owner: rezvan */ \
- V(acquire_release, "acquire_release memory ordering", false) \
- // add pre-staged features right before this line
-
-// #############################################################################
-// Staged features (disabled by default, but enabled via --wasm-staging (also
-// exposed as chrome://flags/#enable-experimental-webassembly-features). Staged
-// features get limited fuzzer coverage, and should come with their own tests.
-// They are not run through all fuzzers though and don't get much exposure in
-// the wild. Staged features are not necessarily fully stabilized. They should
-// be shipped with enough lead time to the next branch to allow for
-// stabilization.
-// Consider adding a chromium-side use counter if you want to track usage in the
-// wild (also see {V8::UseCounterFeature}).
-#define FOREACH_WASM_STAGING_FEATURE_FLAG(V) /* (force 80 columns) */ \
- /* Custom Descriptors proposal. */ \
- /* https://github.com/WebAssembly/custom-descriptors */ \
- /* Note: the JS Interop part of the proposal is enabled by */ \
- /* --wasm-js-interop for now. */ \
- /* V8 side owner: jkummerow */ \
- /* Staged (without JS Interop) in v14.8 */ \
- V(custom_descriptors, "custom descriptors", false)
-
-// #############################################################################
-// Shipped features (enabled by default). Remove the feature flag once they hit
-// stable and are expected to stay enabled.
-#define FOREACH_WASM_SHIPPED_FEATURE_FLAG(V) /* (force 80 columns) */ \
- /* Legacy exception handling proposal. */ \
- /* https://github.com/WebAssembly/exception-handling */ \
- /* V8 side owner: thibaudm */ \
- /* Staged in v8.9 */ \
- /* Shipped in v9.5 */ \
- V(legacy_eh, "legacy exception handling opcodes", true)
-
-// Combination of all available wasm feature flags.
-#define FOREACH_WASM_FEATURE_FLAG(V) \
- FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(V) \
- FOREACH_WASM_PRE_STAGING_FEATURE_FLAG(V) \
- FOREACH_WASM_STAGING_FEATURE_FLAG(V) \
- FOREACH_WASM_SHIPPED_FEATURE_FLAG(V)
-
-// Consistency check: Experimental and staged features are off by default.
-#define CHECK_WASM_FEATURE_OFF_BY_DEFAULT(name, desc, enabled) \
- static_assert(enabled == false);
-#define CHECK_WASM_FEATURE_ON_BY_DEFAULT(name, desc, enabled) \
- static_assert(enabled == true);
-FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(CHECK_WASM_FEATURE_OFF_BY_DEFAULT)
-FOREACH_WASM_PRE_STAGING_FEATURE_FLAG(CHECK_WASM_FEATURE_OFF_BY_DEFAULT)
-FOREACH_WASM_STAGING_FEATURE_FLAG(CHECK_WASM_FEATURE_OFF_BY_DEFAULT)
-FOREACH_WASM_SHIPPED_FEATURE_FLAG(CHECK_WASM_FEATURE_ON_BY_DEFAULT)
-#undef CHECK_WASM_FEATURE_OFF_BY_DEFAULT
-#undef CHECK_WASM_FEATURE_ON_BY_DEFAULT
-
-#endif // V8_WASM_WASM_FEATURE_FLAGS_H_
diff --git a/deps/v8/src/wasm/wasm-features.h b/deps/v8/src/wasm/wasm-features.h
index 7719a009ee9..d140b794a12 100644
--- a/deps/v8/src/wasm/wasm-features.h
+++ b/deps/v8/src/wasm/wasm-features.h
@@ -17,7 +17,7 @@
#include "src/base/small-vector.h"
#include "src/common/globals.h"
// The feature flags are declared in their own header.
-#include "src/wasm/wasm-feature-flags.h"
+#include "src/flags/feature-flags.h"
// Features that are always enabled and do not have a flag.
#define FOREACH_WASM_NON_FLAG_FEATURE(V) \
@@ -40,7 +40,19 @@
V(sign_extension_ops) \
V(jspi) \
V(exnref) \
- V(branch_hinting)
+ V(branch_hinting) \
+ V(gc_allocation)
+
+#define IGNORE_NON_WASM_FEATURE(feat, ...)
+#define FOREACH_WASM_FEATURE_FLAG(V) \
+ FOREACH_EXPERIMENTAL_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, V, \
+ IGNORE_NON_WASM_FEATURE) \
+ FOREACH_PRE_STAGED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, V, \
+ IGNORE_NON_WASM_FEATURE) \
+ FOREACH_STAGED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, V, \
+ IGNORE_NON_WASM_FEATURE) \
+ FOREACH_SHIPPED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE, V, \
+ IGNORE_NON_WASM_FEATURE)
// All features, including features that do not have flags.
#define FOREACH_WASM_FEATURE(V) \
diff --git a/deps/v8/src/wasm/wasm-js.cc b/deps/v8/src/wasm/wasm-js.cc
index 63d4ee47b33..97709612398 100644
--- a/deps/v8/src/wasm/wasm-js.cc
+++ b/deps/v8/src/wasm/wasm-js.cc
@@ -27,6 +27,7 @@
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-function.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/shared-function-info.h"
#include "src/objects/templates.h"
@@ -168,7 +169,7 @@ std::shared_ptr<WasmStreaming> WasmStreaming::Unpack(Isolate* isolate,
TRACE_EVENT("v8.wasm", "wasm.WasmStreaming.Unpack");
i::HandleScope scope(reinterpret_cast<i::Isolate*>(isolate));
auto managed =
- i::Cast<i::Managed<WasmStreaming>>(Utils::OpenDirectHandle(*value));
+ i::Cast<i::CppGCManaged<WasmStreaming>>(Utils::OpenDirectHandle(*value));
return managed->ptr().as_shared_ptr();
}
@@ -238,11 +239,16 @@ class WasmModuleCompilation::Impl {
const std::shared_ptr<i::wasm::StreamingDecoder> streaming_decoder_;
};
-// TODO(clemensb): Pass enabled features and compile time imports.
-WasmModuleCompilation::WasmModuleCompilation()
- : impl_(std::make_unique<Impl>(WasmEnabledFeatures::FromFlags(),
- CompileTimeImports{})) {
+// TODO(clemensb): Pass enabled features.
+WasmModuleCompilation::WasmModuleCompilation(const CompileOptions& options)
+ : impl_(std::make_unique<Impl>(
+ WasmEnabledFeatures::FromFlags(),
+ i::wasm::CompileTimeImportsFromOptions(options))) {
TRACE_EVENT("v8.wasm", "wasm.ModuleCompilation");
+ if (!options.source_url.empty()) {
+ impl_->SetUrl(
+ base::VectorOf(options.source_url.data(), options.source_url.size()));
+ }
}
WasmModuleCompilation::~WasmModuleCompilation() = default;
@@ -835,14 +841,14 @@ void StartAsyncCompilationWithResolver(
return;
}
- // Allocate the streaming decoder in a Managed so we can pass it to the
+ // Allocate the streaming decoder in a CppGCManaged so we can pass it to the
// embedder.
std::shared_ptr<WasmStreaming> streaming = std::make_shared<WasmStreaming>(
std::make_unique<WasmStreaming::WasmStreamingImpl>(
i_isolate, js_api_scope.api_name(), std::move(compile_imports),
resolver));
- i::DirectHandle<i::Managed<WasmStreaming>> data =
- i::Managed<WasmStreaming>::From(i_isolate, 0, streaming);
+ i::DirectHandle<i::CppGCManaged<WasmStreaming>> data =
+ i::CppGCManaged<WasmStreaming>::Create(i_isolate, 0, streaming);
DCHECK_NOT_NULL(i_isolate->wasm_streaming_callback());
Local<v8::Function> compile_callback, reject_callback;
@@ -1583,44 +1589,23 @@ void WebAssemblyTableImpl(const v8::FunctionCallbackInfo<v8::Value>& info) {
DCHECK(!type.has_index()); // The JS API can't express type indices.
i::wasm::CanonicalValueType canonical_type{type};
- i::DirectHandle<i::WasmDispatchTable> dispatch_table;
- i::DirectHandle<i::WasmTableObject> table_obj = i::WasmTableObject::New(
- i_isolate, i::DirectHandle<i::WasmTrustedInstanceData>(), type,
- canonical_type, initial, maybe_maximum.has_value(),
- maybe_maximum.value_or(0) /* note: unused if previous param is false */,
- DefaultReferenceValue(i_isolate, type), address_type, &dispatch_table);
-
- // The infrastructure for `new Foo` calls allocates an object, which is
- // available here as {info.This()}. We're going to discard this object
- // and use {table_obj} instead, but it does have the correct prototype,
- // which we must harvest from it. This makes a difference when the JS
- // constructor function wasn't {WebAssembly.Table} directly, but some
- // subclass: {table_obj} has {WebAssembly.Table}'s prototype at this
- // point, so we must overwrite that with the correct prototype for {Foo}.
- if (!TransferPrototype(i_isolate, table_obj,
- Utils::OpenDirectHandle(*info.This()))) {
- return js_api_scope.AssertException();
- }
+ i::DirectHandle<i::Object> initial_value;
if (initial > 0 && info.Length() >= 2 && !info[1]->IsUndefined()) {
i::DirectHandle<i::Object> element = Utils::OpenDirectHandle(*info[1]);
const char* error_message;
- if (!i::WasmTableObject::JSToWasmElement(i_isolate, table_obj, element,
- &error_message)
- .ToHandle(&element)) {
+ if (!i::wasm::JSToWasmObject(i_isolate, element, canonical_type,
+ &error_message)
+ .ToHandle(&initial_value)) {
thrower.TypeError(
"Argument 2 must be undefined or a value of type compatible "
"with the type of the new table: %s.",
error_message);
return;
}
- for (uint32_t index = 0; index < initial; ++index) {
- i::WasmTableObject::Set(i_isolate, table_obj, dispatch_table, index,
- element);
- }
- } else if (initial > 0) {
- DCHECK_EQ(type, table_obj->unsafe_type());
- if (type.is_abstract_ref()) {
+ } else {
+ initial_value = DefaultReferenceValue(i_isolate, type);
+ if (initial > 0 && type.is_abstract_ref()) {
switch (type.generic_kind()) {
case i::wasm::GenericKind::kString:
thrower.TypeError(
@@ -1636,6 +1621,26 @@ void WebAssemblyTableImpl(const v8::FunctionCallbackInfo<v8::Value>& info) {
}
}
}
+
+ i::DirectHandle<i::WasmDispatchTable> dispatch_table;
+ i::DirectHandle<i::WasmTableObject> table_obj = i::WasmTableObject::New(
+ i_isolate, i::DirectHandle<i::WasmTrustedInstanceData>(), type,
+ canonical_type, initial, maybe_maximum.has_value(),
+ maybe_maximum.value_or(0) /* note: unused if previous param is false */,
+ initial_value, address_type, &dispatch_table);
+
+ // The infrastructure for `new Foo` calls allocates an object, which is
+ // available here as {info.This()}. We're going to discard this object
+ // and use {table_obj} instead, but it does have the correct prototype,
+ // which we must harvest from it. This makes a difference when the JS
+ // constructor function wasn't {WebAssembly.Table} directly, but some
+ // subclass: {table_obj} has {WebAssembly.Table}'s prototype at this
+ // point, so we must overwrite that with the correct prototype for {Foo}.
+ if (!TransferPrototype(i_isolate, table_obj,
+ Utils::OpenDirectHandle(*info.This()))) {
+ return js_api_scope.AssertException();
+ }
+
v8::ReturnValue<v8::Value> return_value = info.GetReturnValue();
return_value.Set(Utils::ToLocal(i::Cast<i::JSObject>(table_obj)));
}
@@ -2632,7 +2637,8 @@ void WebAssemblyMemoryGrowImpl(
if (!maybe_delta_pages) return js_api_scope.AssertException();
uint64_t delta_pages = *maybe_delta_pages;
- i::Managed<i::BackingStore>::Ptr backing_store = receiver->backing_store();
+ i::CppGCManaged<i::BackingStore>::Ptr backing_store =
+ receiver->backing_store();
#ifdef DEBUG
if (i::Tagged<i::JSArrayBuffer> buffer;
TryCast(receiver->array_buffer(), &buffer)) {
@@ -3576,6 +3582,27 @@ void WasmJs::InstallMemoryControl(Isolate* isolate,
context->set_wasm_memory_map_descriptor_constructor(*constructor_handle);
}
+namespace wasm {
+CompileTimeImports CompileTimeImportsFromOptions(
+ const v8::WasmModuleObject::CompileOptions& options) {
+ CompileTimeImports result;
+ using Builtins = v8::WasmModuleObject::CompileOptions::Builtins;
+ if (options.builtins & Builtins::kJsString) {
+ result.Add(CompileTimeImport::kJsString);
+ }
+ if (options.imported_string_constants_module != nullptr) {
+ result.constants_module() = options.imported_string_constants_module;
+ result.Add(CompileTimeImport::kStringConstants);
+ }
+ // Mirror the JS `WebAssembly.Module` constructor, which disables denormal
+ // floats at compile time when the host FPU flushes them.
+ if (base::FPU::GetFlushDenormals()) {
+ result.Add(CompileTimeImport::kDisableDenormalFloats);
+ }
+ return result;
+}
+} // namespace wasm
+
// static
CompileTimeImports WasmJs::CompileTimeImportsFromArgument(
DirectHandle<Object> arg, Isolate* isolate,
diff --git a/deps/v8/src/wasm/wasm-js.h b/deps/v8/src/wasm/wasm-js.h
index 630011b967a..a11b13f7177 100644
--- a/deps/v8/src/wasm/wasm-js.h
+++ b/deps/v8/src/wasm/wasm-js.h
@@ -11,6 +11,7 @@
#include <memory>
+#include "include/v8-wasm.h"
#include "src/common/globals.h"
#include "src/wasm/wasm-features.h"
@@ -18,7 +19,6 @@ namespace v8 {
class Value;
template <typename T>
class FunctionCallbackInfo;
-class WasmStreaming;
} // namespace v8
namespace v8::internal {
@@ -30,6 +30,11 @@ class StreamingDecoder;
V8_EXPORT_PRIVATE std::unique_ptr<WasmStreaming> StartStreamingForTesting(
Isolate*, std::shared_ptr<wasm::CompilationResultResolver>);
+// Convert compile options from the public API into compile-time imports,
+// including the host-FPU denormal handling applied to all compilations.
+V8_EXPORT_PRIVATE CompileTimeImports
+CompileTimeImportsFromOptions(const v8::WasmModuleObject::CompileOptions&);
+
#define WASM_JS_EXTERNAL_REFERENCE_LIST(V) \
V(WebAssemblyCompile) \
V(WebAssemblyException) \
diff --git a/deps/v8/src/wasm/wasm-memory-map-descriptor.cc b/deps/v8/src/wasm/wasm-memory-map-descriptor.cc
index 53c4286730e..e273dc88513 100644
--- a/deps/v8/src/wasm/wasm-memory-map-descriptor.cc
+++ b/deps/v8/src/wasm/wasm-memory-map-descriptor.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "include/v8config.h" // For V8_TARGET_OS_LINUX.
+#include "include/v8config.h" // For V8_OS_LINUX && !V8_OS_ANDROID.
-#if V8_TARGET_OS_LINUX
+#if V8_OS_LINUX && !V8_OS_ANDROID
#include <sys/mman.h>
#include <sys/stat.h>
#include <unistd.h>
@@ -12,7 +12,7 @@
// Since we don't need `sys/mman.h`'s `MAP_TYPE`, we undefine it immediately
// after the `#include`.
#undef MAP_TYPE
-#endif // V8_TARGET_OS_LINUX
+#endif // V8_OS_LINUX && !V8_OS_ANDROID
#include "include/cppgc/allocation.h"
#include "include/v8-cppgc.h"
@@ -32,7 +32,7 @@ WasmMemoryMapDescriptor::WasmMemoryMapDescriptor(PlatformFileDescriptor fd,
WasmMemoryMapDescriptor::~WasmMemoryMapDescriptor() {
mapped_memory_.Reset();
-#if V8_TARGET_OS_LINUX
+#if V8_OS_LINUX && !V8_OS_ANDROID
// TODO(crbug.com/339678654): Define a constant somewhere in the platform
// instead of hardcoding -1 here.
if (fd_ownership_ == FdOwnership::kAnonymousFdOwnedByV8 &&
@@ -74,7 +74,7 @@ v8::Local<v8::Object> WasmMemoryMapDescriptor::NewFromFileDescriptor(
v8::MaybeLocal<v8::Object> WasmMemoryMapDescriptor::NewFromAnonymous(
v8::Isolate* isolate, size_t length, v8::Local<v8::Object> wrapper) {
CHECK(v8_flags.wasm_memory_control);
-#if V8_TARGET_OS_LINUX
+#if V8_OS_LINUX && !V8_OS_ANDROID
int fd = memfd_create("wasm_memory_map_descriptor", MFD_CLOEXEC);
if (fd == -1) return {};
if (ftruncate(fd, length) == -1) {
@@ -96,7 +96,7 @@ size_t WasmMemoryMapDescriptor::Map(v8::Isolate* isolate,
isolate->ThrowError("WasmMemoryMapDescriptor::Map called more than once");
return 0;
}
- Managed<BackingStore>::Ptr backing_store = memory->backing_store();
+ CppGCManaged<BackingStore>::Ptr backing_store = memory->backing_store();
if (backing_store->is_shared()) {
// TODO(ahaas): Handle concurrent calls to `MapDescriptor`. To prevent
// concurrency issues, we disable `MapDescriptor` for shared wasm memories
@@ -109,7 +109,7 @@ size_t WasmMemoryMapDescriptor::Map(v8::Isolate* isolate,
return 0;
}
-#if V8_TARGET_OS_LINUX
+#if V8_OS_LINUX && !V8_OS_ANDROID
uint8_t* target =
reinterpret_cast<uint8_t*>(backing_store->buffer_start()) + offset;
@@ -155,7 +155,7 @@ bool WasmMemoryMapDescriptor::Unmap(v8::Isolate* isolate) {
mapped_memory_.Reset();
CHECK(!memory.is_null());
- Managed<BackingStore>::Ptr backing_store = memory->backing_store();
+ CppGCManaged<BackingStore>::Ptr backing_store = memory->backing_store();
// The following checks already passed during `MapDescriptor`, and they should
// still pass.
@@ -165,7 +165,7 @@ bool WasmMemoryMapDescriptor::Unmap(v8::Isolate* isolate) {
CHECK_GE(size_ + offset_, size_);
CHECK_LE(size_ + offset_, backing_store->byte_length());
-#if V8_TARGET_OS_LINUX
+#if V8_OS_LINUX && !V8_OS_ANDROID
uint8_t* target =
reinterpret_cast<uint8_t*>(backing_store->buffer_start()) + offset_;
diff --git a/deps/v8/src/wasm/wasm-module.cc b/deps/v8/src/wasm/wasm-module.cc
index 4b9d2b5e25a..4affa84d537 100644
--- a/deps/v8/src/wasm/wasm-module.cc
+++ b/deps/v8/src/wasm/wasm-module.cc
@@ -375,7 +375,7 @@ DirectHandle<JSArray> GetImports(Isolate* isolate,
DirectHandle<String> tag_string = factory->InternalizeUtf8String("tag");
// Create the result array.
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const WasmModule* module = native_module->module();
base::Vector<const uint8_t> wire_bytes = native_module->wire_bytes();
@@ -474,7 +474,7 @@ DirectHandle<JSArray> GetExports(Isolate* isolate,
DirectHandle<String> tag_string = factory->InternalizeUtf8String("tag");
// Create the result array.
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const WasmModule* module = native_module->module();
int num_exports = static_cast<int>(module->export_table.size());
@@ -534,7 +534,7 @@ DirectHandle<JSArray> GetCustomSections(
DirectHandle<String> name, ErrorThrower* thrower) {
Factory* factory = isolate->factory();
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
base::Vector<const uint8_t> wire_bytes = native_module->wire_bytes();
std::vector<CustomSectionOffset> custom_sections =
diff --git a/deps/v8/src/wasm/wasm-objects-inl.h b/deps/v8/src/wasm/wasm-objects-inl.h
index 396ae324162..9e467a624d4 100644
--- a/deps/v8/src/wasm/wasm-objects-inl.h
+++ b/deps/v8/src/wasm/wasm-objects-inl.h
@@ -25,7 +25,7 @@
#include "src/objects/heap-number-inl.h"
#include "src/objects/heap-object-field-inl.h"
#include "src/objects/heap-object.h"
-#include "src/objects/managed.h"
+#include "src/objects/managed-inl.h"
#include "src/objects/object-predicates-inl.h"
#include "src/objects/pod-array-inl.h"
#include "src/objects/slots-inl.h"
@@ -64,12 +64,12 @@ namespace v8::internal {
}
// WasmModuleObject
-Tagged<Managed<wasm::NativeModule>> WasmModuleObject::managed_native_module()
- const {
+Tagged<CppGCManaged<wasm::NativeModule>>
+WasmModuleObject::managed_native_module() const {
return managed_native_module_.load();
}
void WasmModuleObject::set_managed_native_module(
- Tagged<Managed<wasm::NativeModule>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<wasm::NativeModule>> value, WriteBarrierMode mode) {
managed_native_module_.store(this, value, mode);
}
@@ -78,7 +78,7 @@ void WasmModuleObject::set_script(Tagged<Script> value, WriteBarrierMode mode) {
script_.store(this, value, mode);
}
-Managed<wasm::NativeModule>::Ptr WasmModuleObject::native_module() {
+CppGCManaged<wasm::NativeModule>::Ptr WasmModuleObject::native_module() {
return managed_native_module()->ptr();
}
@@ -92,11 +92,12 @@ void WasmMemoryObject::set_array_buffer(
array_buffer_.store(this, value, mode);
}
-Tagged<Managed<BackingStore>> WasmMemoryObject::managed_backing_store() const {
+Tagged<CppGCManaged<BackingStore>> WasmMemoryObject::managed_backing_store()
+ const {
return managed_backing_store_.load();
}
void WasmMemoryObject::set_managed_backing_store(
- Tagged<Managed<BackingStore>> value, WriteBarrierMode mode) {
+ Tagged<CppGCManaged<BackingStore>> value, WriteBarrierMode mode) {
managed_backing_store_.store(this, value, mode);
}
@@ -122,7 +123,7 @@ void WasmMemoryObject::set_address_type(wasm::AddressType value) {
address_type_ = static_cast<uint8_t>(value);
}
-Managed<BackingStore>::Ptr WasmMemoryObject::backing_store() const {
+CppGCManaged<BackingStore>::Ptr WasmMemoryObject::backing_store() const {
return managed_backing_store()->ptr();
}
@@ -936,10 +937,10 @@ void WasmInternalFunction::set_call_target(WasmCodePointer code_pointer) {
}
// WasmCapiFunctionData
-Tagged<Foreign> WasmCapiFunctionData::embedder_data() const {
+Tagged<CppGCManagedBase> WasmCapiFunctionData::embedder_data() const {
return embedder_data_.load();
}
-void WasmCapiFunctionData::set_embedder_data(Tagged<Foreign> value,
+void WasmCapiFunctionData::set_embedder_data(Tagged<CppGCManagedBase> value,
WriteBarrierMode mode) {
embedder_data_.store(this, value, mode);
}
@@ -1318,6 +1319,10 @@ void WasmStruct::EncodeInstanceSizeInMap(int instance_size, Tagged<Map> map) {
static_assert(0xFFFF > ((kHeaderSize + wasm::kMaxValueTypeSize *
wasm::kV8MaxWasmStructFields) >>
kObjectAlignmentBits));
+ static_assert(0xFFFF >
+ ((WasmCustomMap::kHeaderSize +
+ wasm::kMaxValueTypeSize * wasm::kV8MaxWasmStructFields) >>
+ kObjectAlignmentBits));
map->SetWasmByte1((instance_size >> kObjectAlignmentBits) & 0xff);
map->SetWasmByte2(instance_size >> (8 + kObjectAlignmentBits));
}
@@ -1332,11 +1337,18 @@ int WasmStruct::GcSafeSize(Tagged<Map> map) {
return DecodeInstanceSizeFromMap(map);
}
+int WasmStruct::FieldOffset(const wasm::StructType* type, int field_index) {
+ int header_size = type->is_descriptor() ? WasmCustomMap::kHeaderSize
+ : WasmStruct::kHeaderSize;
+ return header_size + type->field_offset(field_index);
+}
+
Address WasmStruct::RawFieldAddress(int raw_offset) {
int offset = WasmStruct::kHeaderSize + raw_offset;
return FIELD_ADDR(Tagged<WasmStruct>(this), offset);
}
+// TODO(jkummerow): Stop shadowing {HeapObject::RawField} maybe?
ObjectSlot WasmStruct::RawField(int raw_offset) {
return ObjectSlot(RawFieldAddress(raw_offset));
}
@@ -1361,6 +1373,41 @@ void WasmStruct::set_described_rtt(Tagged<Map> value, WriteBarrierMode mode) {
CONDITIONAL_WRITE_BARRIER(Tagged<HeapObject>(this), kHeaderSize, value, mode);
}
+Address WasmCustomMap::RawFieldAddress(int raw_offset) {
+ int offset = WasmCustomMap::kHeaderSize + raw_offset;
+ return FIELD_ADDR(Tagged<WasmCustomMap>(this), offset);
+}
+
+// TODO(jkummerow): Stop shadowing {HeapObject::RawField} maybe?
+ObjectSlot WasmCustomMap::RawField(int raw_offset) {
+ return ObjectSlot(RawFieldAddress(raw_offset));
+}
+
+Tagged<Union<WasmCustomMapWrapper, Null>> WasmCustomMap::js_wrapper() const {
+ return js_wrapper_.load();
+}
+void WasmCustomMap::set_js_wrapper(
+ Tagged<Union<WasmCustomMapWrapper, Null>> wrapper, WriteBarrierMode mode) {
+ js_wrapper_.store(this, wrapper, mode);
+}
+
+Tagged<NativeContext> WasmCustomMap::native_context_for_wrapper() const {
+ return native_context_for_wrapper_.load();
+}
+void WasmCustomMap::set_native_context_for_wrapper(
+ Tagged<NativeContext> context, WriteBarrierMode mode) {
+ native_context_for_wrapper_.store(this, context, mode);
+}
+
+Tagged<WasmCustomMap> WasmCustomMapWrapper::wrapped() const {
+ return wrapped_.load();
+}
+
+void WasmCustomMapWrapper::set_wrapped(Tagged<WasmCustomMap> custom_map,
+ WriteBarrierMode mode) {
+ wrapped_.store(this, custom_map, mode);
+}
+
uint32_t WasmArray::length() const { return length_; }
void WasmArray::set_length(uint32_t value) { length_ = value; }
diff --git a/deps/v8/src/wasm/wasm-objects.cc b/deps/v8/src/wasm/wasm-objects.cc
index 1b930d6d4ef..e29f1dc3f94 100644
--- a/deps/v8/src/wasm/wasm-objects.cc
+++ b/deps/v8/src/wasm/wasm-objects.cc
@@ -117,17 +117,18 @@ using WasmModule = wasm::WasmModule;
DirectHandle<WasmModuleObject> WasmModuleObject::New(
Isolate* isolate, std::shared_ptr<wasm::NativeModule> native_module,
DirectHandle<Script> script) {
- DirectHandle<Managed<wasm::NativeModule>> managed_native_module;
+ DirectHandle<CppGCManaged<wasm::NativeModule>> managed_native_module;
if (script->type() == Script::Type::kWasm) {
managed_native_module = direct_handle(
- Cast<Managed<wasm::NativeModule>>(script->wasm_managed_native_module()),
+ 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 = Managed<wasm::NativeModule>::From(
+ managed_native_module = CppGCManaged<wasm::NativeModule>::Create(
isolate, memory_estimate, std::move(native_module));
}
DirectHandle<WasmModuleObject> module_object = Cast<WasmModuleObject>(
@@ -146,21 +147,19 @@ DirectHandle<String> WasmModuleObject::ExtractUtf8StringFromModuleBytes(
DCHECK(unibrow::Utf8::ValidateEncoding(name_vec.begin(), name_vec.size()));
auto* factory = isolate->factory();
DCHECK_IMPLIES(shared, !internalize);
- return internalize ? factory->InternalizeUtf8String(
- base::Vector<const char>::cast(name_vec))
- : shared
- ? factory
- ->NewSharedStringFromUtf8(
- base::Vector<const char>::cast(name_vec))
- .ToHandleChecked()
+ return internalize
+ ? factory->InternalizeUtf8String(
+ base::Vector<const char>::cast(name_vec))
: factory
- ->NewStringFromUtf8(base::Vector<const char>::cast(name_vec))
+ ->NewStringFromUtf8(
+ name_vec, UnicodeConfig(unibrow::Utf8Variant::kLossyUtf8,
+ SharedFlag{false}, shared))
.ToHandleChecked();
}
MaybeDirectHandle<String> WasmModuleObject::GetModuleNameOrNull(
Isolate* isolate, DirectHandle<WasmModuleObject> module_object) {
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const WasmModule* module = native_module->module();
if (!module->name.is_set()) return {};
@@ -171,7 +170,7 @@ MaybeDirectHandle<String> WasmModuleObject::GetModuleNameOrNull(
MaybeDirectHandle<String> WasmModuleObject::GetFunctionNameOrNull(
Isolate* isolate, DirectHandle<WasmModuleObject> module_object,
uint32_t func_index) {
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const WasmModule* module = native_module->module();
DCHECK_LT(func_index, module->functions.size());
@@ -187,7 +186,7 @@ base::Vector<const uint8_t> WasmModuleObject::GetRawFunctionName(
if (func_index == wasm::kAnonymousFuncIndex) {
return base::Vector<const uint8_t>({nullptr, 0});
}
- Managed<wasm::NativeModule>::Ptr native_mod = native_module();
+ CppGCManaged<wasm::NativeModule>::Ptr native_mod = native_module();
const WasmModule* module = native_mod->module();
DCHECK_GT(module->functions.size(), func_index);
wasm::ModuleWireBytes wire_bytes(native_mod->wire_bytes());
@@ -197,6 +196,41 @@ base::Vector<const uint8_t> WasmModuleObject::GetRawFunctionName(
return base::Vector<const uint8_t>::cast(name);
}
+namespace {
+void UpdateDispatchTableMultiple(Isolate* isolate,
+ DirectHandle<WasmDispatchTable> dispatch_table,
+ int start_index, int count,
+ DirectHandle<Object> external) {
+ if (WasmExportedFunction::IsWasmExportedFunction(*external)) {
+ auto exported_function = Cast<WasmExportedFunction>(external);
+ auto func_data = exported_function->shared()->wasm_exported_function_data();
+ DirectHandle<WasmTrustedInstanceData> target_instance_data(
+ func_data->instance_data(), isolate);
+ int func_index = func_data->function_index();
+ const wasm::WasmModule* module = target_instance_data->module();
+ SBXCHECK_BOUNDS(func_index, module->functions.size());
+ auto* wasm_function = module->functions.data() + func_index;
+ for (int i = 0; i < count; ++i) {
+ WasmTableObject::UpdateDispatchTable(isolate, dispatch_table,
+ start_index + i, wasm_function,
+ target_instance_data
+#if V8_ENABLE_DRUMBRAKE
+ ,
+ func_index
+#endif // V8_ENABLE_DRUMBRAKE
+ );
+ }
+ } else {
+ DCHECK(WasmCapiFunction::IsWasmCapiFunction(*external));
+ for (int i = 0; i < count; ++i) {
+ WasmTableObject::UpdateDispatchTable(isolate, dispatch_table,
+ start_index + i,
+ Cast<WasmCapiFunction>(external));
+ }
+ }
+}
+} // namespace
+
DirectHandle<WasmTableObject> WasmTableObject::New(
Isolate* isolate, DirectHandle<WasmTrustedInstanceData> trusted_data,
wasm::ValueType type, wasm::CanonicalValueType canonical_type,
@@ -207,7 +241,7 @@ DirectHandle<WasmTableObject> WasmTableObject::New(
DCHECK_LE(initial, wasm::max_table_size());
DirectHandle<FixedArray> entries = isolate->factory()->NewFixedArray(initial);
- for (int i = 0; i < static_cast<int>(initial); ++i) {
+ for (uint32_t i = 0; i < initial; ++i) {
entries->set(i, *initial_value);
}
bool is_function_table = canonical_type.IsFunctionType();
@@ -216,6 +250,18 @@ DirectHandle<WasmTableObject> WasmTableObject::New(
? isolate->factory()->NewWasmDispatchTable(initial, canonical_type)
: isolate->factory()->empty_wasm_dispatch_table();
+ if (is_function_table && initial > 0 && !IsWasmNull(*initial_value) &&
+ IsWasmFuncRef(*initial_value)) {
+ DirectHandle<Object> external =
+ WasmInternalFunction::GetOrCreateExternal(direct_handle(
+ Cast<WasmFuncRef>(*initial_value)->internal(isolate), isolate));
+
+ // The entries array was filled with *initial_value above, so this loop
+ // only has to do the dispatch-table half.
+ UpdateDispatchTableMultiple(isolate, dispatch_table, 0,
+ static_cast<int>(initial), external);
+ }
+
DirectHandle<UnionOf<Undefined, Number, BigInt>> max =
isolate->factory()->undefined_value();
if (has_maximum) {
@@ -356,27 +402,8 @@ void WasmTableObject::SetFunctionTableEntry(
DirectHandle<Object> external = WasmInternalFunction::GetOrCreateExternal(
direct_handle(Cast<WasmFuncRef>(*entry)->internal(isolate), isolate));
- if (WasmExportedFunction::IsWasmExportedFunction(*external)) {
- auto exported_function = Cast<WasmExportedFunction>(external);
- auto func_data = exported_function->shared()->wasm_exported_function_data();
- DirectHandle<WasmTrustedInstanceData> target_instance_data(
- func_data->instance_data(), isolate);
- int func_index = func_data->function_index();
- const WasmModule* module = target_instance_data->module();
- SBXCHECK_BOUNDS(func_index, module->functions.size());
- auto* wasm_function = module->functions.data() + func_index;
- UpdateDispatchTable(isolate, dispatch_table, entry_index, wasm_function,
- target_instance_data
-#if V8_ENABLE_DRUMBRAKE
- ,
- func_index
-#endif // V8_ENABLE_DRUMBRAKE
- );
- } else {
- DCHECK(WasmCapiFunction::IsWasmCapiFunction(*external));
- UpdateDispatchTable(isolate, dispatch_table, entry_index,
- Cast<WasmCapiFunction>(external));
- }
+ UpdateDispatchTableMultiple(isolate, dispatch_table, entry_index, 1,
+ external);
table->entries()->set(entry_index, *entry);
}
@@ -790,9 +817,9 @@ DirectHandle<WasmMemoryObject> WasmMemoryObject::New(
: !maybe_buffer.IsEmpty()
? maybe_buffer.ToHandleChecked()->GetByteLength()
: 0;
- DirectHandle<Managed<BackingStore>> managed_backing_store =
- Managed<BackingStore>::From(isolate, byte_size, backing_store,
- AllocationType::kOld);
+ DirectHandle<CppGCManaged<BackingStore>> managed_backing_store =
+ CppGCManaged<BackingStore>::Create(isolate, byte_size, backing_store,
+ AllocationType::kOld);
DirectHandle<JSFunction> memory_ctor(
isolate->native_context()->wasm_memory_constructor(), isolate);
@@ -816,7 +843,8 @@ DirectHandle<WasmMemoryObject> WasmMemoryObject::New(
} else if (backing_store && backing_store->is_shared()) {
// Only Wasm memory can be shared (in contrast to asm.js memory).
DCHECK(backing_store->is_wasm_memory());
- backing_store->AttachSharedWasmMemoryObject(isolate, memory_object);
+ GlobalBackingStoreRegistry::AddSharedWasmMemoryObject(
+ isolate, backing_store, memory_object);
}
return memory_object;
@@ -910,7 +938,8 @@ void WasmMemoryObject::SetNewBuffer(Isolate* isolate,
// Only Wasm memory can be shared, and it always has a backing store.
std::shared_ptr<BackingStore> backing_store = new_buffer->GetBackingStore();
DCHECK(backing_store->is_wasm_memory());
- backing_store->AttachSharedWasmMemoryObject(isolate, memory);
+ GlobalBackingStoreRegistry::AddSharedWasmMemoryObject(
+ isolate, backing_store, memory);
}
if (is_resizable) {
memory->FixUpResizableArrayBuffer(*new_buffer);
@@ -988,7 +1017,7 @@ void WasmMemoryObject::FixUpResizableArrayBuffer(
// static
DirectHandle<JSArrayBuffer> WasmMemoryObject::RefreshBuffer(
Isolate* isolate, DirectHandle<WasmMemoryObject> memory_object,
- Managed<BackingStore>::Ptr backing_store,
+ CppGCManaged<BackingStore>::Ptr backing_store,
std::optional<ResizableFlag> override_resizable) {
DCHECK_EQ(backing_store.raw(), memory_object->backing_store().raw());
@@ -1015,7 +1044,8 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
uint32_t pages) {
TRACE_EVENT("v8.wasm", "wasm.GrowMemory");
- Managed<BackingStore>::Ptr backing_store = memory_object->backing_store();
+ CppGCManaged<BackingStore>::Ptr backing_store =
+ memory_object->backing_store();
DCHECK_NOT_NULL(backing_store);
DirectHandle<JSArrayBuffer> maybe_old_buffer;
@@ -1087,7 +1117,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
// read-modify-write behavior required by the spec.
uint32_t result = static_cast<int32_t>(result_inplace.value());
memory_object->managed_backing_store()->UpdateEstimatedSize(
- isolate, backing_store->byte_length());
+ backing_store->byte_length(), isolate);
return result; // success
}
@@ -1106,7 +1136,7 @@ int32_t WasmMemoryObject::Grow(Isolate* isolate,
memory_object->UpdateInstances(isolate);
DCHECK_EQ(result_inplace.value(), old_pages);
memory_object->managed_backing_store()->UpdateEstimatedSize(
- isolate, backing_store->byte_length());
+ backing_store->byte_length(), isolate);
return static_cast<int32_t>(result_inplace.value()); // success
}
DCHECK(!has_old_buffer || !maybe_old_buffer->is_resizable_by_js());
@@ -1181,7 +1211,8 @@ DirectHandle<JSArrayBuffer> WasmMemoryObject::ChangeArrayBufferResizability(
return buffer;
}
- Managed<BackingStore>::Ptr backing_store = memory_object->backing_store();
+ CppGCManaged<BackingStore>::Ptr backing_store =
+ memory_object->backing_store();
// For shared memory the flag on the backing store is not authoritative.
// Since the AB is never detached, we just update the AB and use that as the
// authoritative source of resizability.
@@ -1880,7 +1911,8 @@ wasm::WasmValue WasmTrustedInstanceData::GetGlobalValue(
}
const wasm::CanonicalStructType* WasmStruct::GcSafeType(Tagged<Map> map) {
- DCHECK_EQ(WASM_STRUCT_TYPE, map->instance_type());
+ DCHECK(map->instance_type() == WASM_STRUCT_TYPE ||
+ map->instance_type() == WASM_CUSTOM_MAP_TYPE);
Tagged<HeapObject> raw = Cast<HeapObject>(map->constructor_or_back_pointer());
// The {WasmTypeInfo} might be in the middle of being moved, which is why we
// can't read its map for a checked cast. But we can rely on its native type
@@ -1889,6 +1921,7 @@ const wasm::CanonicalStructType* WasmStruct::GcSafeType(Tagged<Map> map) {
return wasm::GetTypeCanonicalizer()->LookupStruct(type_info->type_index());
}
+// TODO(jkummerow): To be replaced by WasmCustomMap::AllocateUninitialized.
// Allocates a Wasm Struct that is a descriptor for another type, leaving
// its fields uninitialized.
// Descriptor structs have a 1:1 relationship with the internal "RTT" (aka
@@ -1925,6 +1958,7 @@ DirectHandle<WasmStruct> WasmStruct::AllocateDescriptorUninitialized(
Isolate* isolate, DirectHandle<WasmTrustedInstanceData> trusted_data,
wasm::ModuleTypeIndex index, DirectHandle<Map> map,
DirectHandle<Object> first_field) {
+ DCHECK(!v8_flags.wasm_merged_descriptors);
const wasm::WasmModule* module = trusted_data->module();
const wasm::TypeDefinition& type = module->type(index);
DCHECK(type.is_descriptor());
@@ -1961,13 +1995,91 @@ DirectHandle<WasmStruct> WasmStruct::AllocateDescriptorUninitialized(
return descriptor;
}
-wasm::WasmValue WasmStruct::GetFieldValue(uint32_t index) {
+// Allocates a Wasm Struct that is a descriptor for another type, leaving
+// its fields uninitialized.
+// Custom Descriptor structs are subtypes of Map, so they begin with all the
+// inherited Map fields, and add their custom struct fields afterwards.
+// RTTs with custom descriptors always are subtypes of the canonical RTT for
+// the same type, so that canonical RTT is installed as the super-RTT.
+// The RTT/map of the descriptor itself is provided by the caller as {map}.
+//
+// The eventual on-heap object structure will be something like the following,
+// where (A) is the object returned by this function. There will likely be
+// many instances of (C), and they will be allocated (much) later, by one or
+// more {struct.new} instructions that take (A) as input.
+// (D) is the {map} passed to this function.
+// Notably, (D) encodes how big (A) is; its instance_size field will have
+// the {kVariableSizeSentinel}, and it will use the {EncodeInstanceSizeInMap}
+// machinery to store the actual instance size.
+//
+// Wasm struct (C): Wasm Custom Map (A):
+// +-----------+ +------------+
+// | Map |------------>| Map (D) |
+// +-----------+ +------------+
+// | hash | | ... |
+// +-----------+ | Map fields |
+// | fields... | | ... |
+// | | +------------+
+// +-----------+ | fields... |
+// | |
+// +------------+
+// static
+DirectHandle<WasmCustomMap> WasmCustomMap::AllocateUninitialized(
+ Isolate* isolate, DirectHandle<WasmTrustedInstanceData> trusted_data,
+ wasm::ModuleTypeIndex index, DirectHandle<Map> map,
+ DirectHandle<Object> first_field) {
+ DCHECK(v8_flags.wasm_merged_descriptors);
+ const wasm::WasmModule* module = trusted_data->module();
+ const wasm::TypeDefinition& type = module->type(index);
+ DCHECK(type.is_descriptor());
+ // TODO(jkummerow): Figure out support for shared objects.
+ if (type.is_shared) UNIMPLEMENTED();
+ wasm::CanonicalTypeIndex described_index =
+ module->canonical_type_id(type.describes);
+ DirectHandle<Map> rtt_parent{
+ Cast<Map>(trusted_data->managed_object_maps()->get(type.describes.index)),
+ isolate};
+ DirectHandle<NativeContext> context(
+ Cast<NativeContext>(trusted_data->native_context()), isolate);
+ // There's always at least one supertype for {rtt_parent}.
+ const wasm::TypeDefinition& described_type = module->type(type.describes);
+ int num_supertypes = described_type.subtyping_depth + 1;
+ DirectHandle<JSPrototype> prototype;
+ if (v8_flags.wasm_js_interop && !IsSmi(*first_field) &&
+ IsJSReceiver(Cast<HeapObject>(*first_field))) {
+ prototype = direct_handle(Cast<JSReceiver>(*first_field), isolate);
+ // Optimize {prototype} as prototype, so that {Map::SetPrototype} below
+ // won't allocate while trying to do that implicitly.
+ if (IsJSObjectThatCanBeTrackedAsPrototype(*prototype)) {
+ JSObject::OptimizeAsPrototype(Cast<JSObject>(prototype), true);
+ }
+ }
+ int described_size = described_type.is_descriptor()
+ ? WasmCustomMap::Size(described_type.struct_type)
+ : WasmStruct::Size(described_type.struct_type);
+ InstanceType described_instance_type =
+ described_type.is_descriptor() ? WASM_CUSTOM_MAP_TYPE : WASM_STRUCT_TYPE;
+ DirectHandle<WasmCustomMap> descriptor =
+ isolate->factory()->NewWasmCustomMapUninitialized(
+ type.struct_type, described_index, described_size,
+ described_instance_type, rtt_parent, num_supertypes, map);
+ DisallowGarbageCollection no_gc;
+ if (!prototype.is_null()) {
+ Map::SetPrototype(isolate, descriptor, prototype);
+ }
+ return descriptor;
+}
+
+namespace {
+
+wasm::WasmValue GetFieldValueImpl(HeapObject* obj, uint32_t index,
+ int header_size) {
const wasm::CanonicalStructType* type =
wasm::GetTypeCanonicalizer()->LookupStruct(
- map()->wasm_type_info()->type_index());
+ obj->map()->wasm_type_info()->type_index());
wasm::CanonicalValueType field_type = type->field(index);
- int field_offset = WasmStruct::kHeaderSize + type->field_offset(index);
- Address field_address = this->field_address(field_offset);
+ int field_offset = header_size + type->field_offset(index);
+ Address field_address = obj->GetFieldAddress(field_offset);
switch (field_type.kind()) {
#define CASE_TYPE(valuetype, ctype) \
case wasm::valuetype: \
@@ -1981,7 +2093,7 @@ wasm::WasmValue WasmStruct::GetFieldValue(uint32_t index) {
base::ReadUnalignedValue<uint16_t>(field_address)));
case wasm::kRef:
case wasm::kRefNull: {
- DirectHandle<Object> ref(TaggedField<Object>::load(this, field_offset),
+ DirectHandle<Object> ref(TaggedField<Object>::load(obj, field_offset),
Isolate::Current());
return wasm::WasmValue(ref, field_type);
}
@@ -1993,6 +2105,50 @@ wasm::WasmValue WasmStruct::GetFieldValue(uint32_t index) {
UNREACHABLE();
}
+} // namespace
+
+// Atomic accesses to fields in descriptors require 8-byte alignment.
+static_assert(WasmCustomMap::kHeaderSize % 8 == 0);
+
+wasm::WasmValue WasmStruct::GetFieldValue(uint32_t index) {
+ return GetFieldValueImpl(this, index, WasmStruct::kHeaderSize);
+}
+
+wasm::WasmValue WasmCustomMap::GetFieldValue(uint32_t index) {
+ return GetFieldValueImpl(this, index, WasmCustomMap::kHeaderSize);
+}
+
+DirectHandle<WasmCustomMapWrapper> WasmCustomMap::CreateJSWrapper(
+ Isolate* isolate, DirectHandle<WasmCustomMap> wasm_custom_map) {
+ DCHECK(IsNull(wasm_custom_map->js_wrapper()));
+ SharedFlag shared = wasm_custom_map->wasm_type_info()->type().is_shared();
+ // Create a fresh map because WasmCustomMaps are conceptually tied to
+ // prototypes and shouldn't share their maps.
+ AllocationType map_allocation =
+ shared ? AllocationType::kSharedMap : AllocationType::kMap;
+ AllocationType obj_allocation =
+ shared ? AllocationType::kSharedOld : AllocationType::kOld;
+ DirectHandle<Map> meta_map(
+ wasm_custom_map->native_context_for_wrapper()->meta_map(), isolate);
+ constexpr int kNumProperties = 0;
+ constexpr int kInstanceSize = WasmCustomMapWrapper::kHeaderSize;
+ DirectHandle<Map> map = isolate->factory()->NewMapWithMetaMap(
+ meta_map, WASM_CUSTOM_MAP_WRAPPER_TYPE, kInstanceSize,
+ TERMINAL_FAST_ELEMENTS_KIND, kNumProperties, map_allocation);
+ DirectHandle<WasmCustomMapWrapper> wrapper =
+ Cast<WasmCustomMapWrapper>(isolate->factory()->NewJSObjectFromMap(
+ map, obj_allocation, DirectHandle<AllocationSite>::null(),
+ NewJSObjectType::kNoEmbedderFieldsAndNoApiWrapper));
+ wrapper->set_wrapped(*wasm_custom_map);
+ Tagged<JSPrototype> maybe_prototype = wasm_custom_map->map()->prototype();
+ if (!IsNull(maybe_prototype)) {
+ wrapper->map()->set_prototype(maybe_prototype);
+ }
+ wrapper->map()->set_is_extensible(false);
+ wasm_custom_map->set_js_wrapper(*wrapper);
+ return wrapper;
+}
+
wasm::WasmValue WasmArray::GetElement(uint32_t index) {
wasm::CanonicalValueType element_type =
map()->wasm_type_info()->element_type();
@@ -2714,7 +2870,8 @@ bool WasmCapiFunction::IsWasmCapiFunction(Tagged<Object> object) {
}
DirectHandle<WasmCapiFunction> WasmCapiFunction::New(
- Isolate* isolate, Address call_target, DirectHandle<Foreign> embedder_data,
+ Isolate* isolate, Address call_target,
+ DirectHandle<CppGCManagedBase> embedder_data,
const wasm::CanonicalSig* sig) {
// TODO(jkummerow): Install a JavaScript wrapper. For now, calling
// these functions directly is unsupported; they can only be called
@@ -2835,7 +2992,15 @@ DirectHandle<Map> CreateStructMap(
// We have to use the variable size sentinel because the instance size
// stored directly in a Map is capped at 255 pointer sizes.
const int map_instance_size = kVariableSizeSentinel;
- const InstanceType instance_type = WASM_STRUCT_TYPE;
+ int real_instance_size;
+ InstanceType instance_type;
+ if (type->is_descriptor() && v8_flags.wasm_merged_descriptors) {
+ instance_type = WASM_CUSTOM_MAP_TYPE;
+ real_instance_size = WasmCustomMap::Size(type);
+ } else {
+ instance_type = WASM_STRUCT_TYPE;
+ real_instance_size = WasmStruct::Size(type);
+ }
// TODO(jkummerow): If NO_ELEMENTS were supported, we could use that here.
const ElementsKind elements_kind = TERMINAL_FAST_ELEMENTS_KIND;
const wasm::CanonicalValueType no_array_element = wasm::kWasmBottom;
@@ -2854,13 +3019,13 @@ DirectHandle<Map> CreateStructMap(
map = isolate->factory()->NewContextlessMap(
instance_type, map_instance_size, elements_kind, inobject_properties);
} else {
+ DCHECK(!v8_flags.wasm_merged_descriptors);
map = isolate->factory()->NewContextfulMap(
opt_native_context, instance_type, map_instance_size, elements_kind,
inobject_properties);
}
map->set_wasm_type_info(*type_info);
map->set_is_extensible(false);
- const int real_instance_size = WasmStruct::Size(type);
WasmStruct::EncodeInstanceSizeInMap(real_instance_size, *map);
return map;
}
@@ -2958,22 +3123,19 @@ DirectHandle<WasmExceptionTag> WasmExceptionTag::New(Isolate* isolate,
}
namespace {
-constexpr int32_t kInt31MaxValue = 0x3fffffff;
-constexpr int32_t kInt31MinValue = -kInt31MaxValue - 1;
-
-// Tries to canonicalize a HeapNumber to an i31ref Smi. Returns the original
-// HeapNumber if it fails.
+// Tries to canonicalize a HeapNumber to an i31ref Smi. If it fails, tries to
+// share the input if necessary; otherwise returns the original HeapNumber.
DirectHandle<Object> CanonicalizeHeapNumber(DirectHandle<Object> number,
Isolate* isolate,
SharedFlag is_shared) {
auto heap_number = Cast<HeapNumber>(number);
double double_value = heap_number->value();
- if (double_value >= kInt31MinValue && double_value <= kInt31MaxValue &&
- !IsMinusZero(double_value) &&
+ if (double_value >= wasm::kInt31MinValue &&
+ double_value <= wasm::kInt31MaxValue && !IsMinusZero(double_value) &&
double_value == FastI2D(FastD2I(double_value))) {
return direct_handle(Smi::FromInt(FastD2I(double_value)), isolate);
}
- if (is_shared && !HeapLayout::InWritableSharedSpace(*heap_number)) {
+ if (is_shared && !HeapLayout::InAnySharedSpace(*heap_number)) {
return isolate->factory()->NewHeapNumber<AllocationType::kSharedOld>(
double_value);
}
@@ -2988,7 +3150,7 @@ DirectHandle<Object> CanonicalizeSmi(DirectHandle<Object> smi, Isolate* isolate,
int32_t value = Cast<Smi>(*smi).value();
- if (value <= kInt31MaxValue && value >= kInt31MinValue) {
+ if (value <= wasm::kInt31MaxValue && value >= wasm::kInt31MinValue) {
return smi;
} else if (is_shared) {
return isolate->factory()->NewHeapNumber<AllocationType::kSharedOld>(value);
@@ -3035,6 +3197,13 @@ inline bool ConvertToSharedIfExpected(Isolate* isolate,
}
return true;
}
+
+inline DirectHandle<WasmCustomMap> UnwrapCustomMap(Isolate* isolate,
+ DirectHandle<Object> value) {
+ DCHECK(IsWasmCustomMapWrapper(*value));
+ DirectHandle<WasmCustomMapWrapper> obj = Cast<WasmCustomMapWrapper>(value);
+ return direct_handle(obj->wrapped(), isolate);
+}
} // namespace
MaybeDirectHandle<Object> JSToWasmObject(Isolate* isolate,
@@ -3113,6 +3282,15 @@ MaybeDirectHandle<Object> JSToWasmObject(Isolate* isolate,
return {};
}
return value;
+ } else if (IsWasmCustomMapWrapper(*value)) {
+ DirectHandle<WasmCustomMap> wasm_obj = UnwrapCustomMap(isolate, value);
+ Tagged<WasmTypeInfo> type_info = wasm_obj->map()->wasm_type_info();
+ CanonicalTypeIndex actual_type = type_info->type_index();
+ if (!type_canonicalizer->IsCanonicalSubtype(actual_type, expected)) {
+ *error_message = "object is not a subtype of expected type";
+ return {};
+ }
+ return wasm_obj;
} else {
*error_message = "JS object does not match expected wasm type";
return {};
@@ -3150,6 +3328,9 @@ MaybeDirectHandle<Object> JSToWasmObject(Isolate* isolate,
error_message)) {
return {};
}
+ if (IsWasmCustomMapWrapper(*value)) {
+ return UnwrapCustomMap(isolate, value);
+ }
if (!IsNull(*value)) return value;
*error_message = "null is not allowed for (ref any)";
return {};
@@ -3167,6 +3348,9 @@ MaybeDirectHandle<Object> JSToWasmObject(Isolate* isolate,
if (IsWasmStruct(*value)) {
return value;
}
+ if (IsWasmCustomMapWrapper(*value)) {
+ return UnwrapCustomMap(isolate, value);
+ }
*error_message =
"structref object must be null (if nullable) or a wasm struct";
return {};
@@ -3196,6 +3380,11 @@ MaybeDirectHandle<Object> JSToWasmObject(Isolate* isolate,
return {};
}
return value;
+ } else if (IsWasmCustomMapWrapper(*value)) {
+ if (!CheckExpectedSharedness(isolate, value, expected, error_message)) {
+ return {};
+ }
+ return UnwrapCustomMap(isolate, value);
}
*error_message =
"eqref object must be null (if nullable), or a wasm "
@@ -3293,6 +3482,11 @@ DirectHandle<Object> WasmToJSObject(Isolate* isolate,
if (HeapLayout::InWritableSharedSpace(*string)) {
return String::Unshare(isolate, string);
}
+ } else if (IsWasmCustomMap(*value)) {
+ DirectHandle<WasmCustomMap> map = Cast<WasmCustomMap>(value);
+ Tagged<Object> maybe_wrapper = map->js_wrapper();
+ if (!IsNull(maybe_wrapper)) return direct_handle(maybe_wrapper, isolate);
+ return WasmCustomMap::CreateJSWrapper(isolate, map);
}
return value;
}
diff --git a/deps/v8/src/wasm/wasm-objects.h b/deps/v8/src/wasm/wasm-objects.h
index 3d90fc04ffe..957d019e33a 100644
--- a/deps/v8/src/wasm/wasm-objects.h
+++ b/deps/v8/src/wasm/wasm-objects.h
@@ -144,17 +144,18 @@ V8_OBJECT class WasmModuleObject : public JSObject {
public:
using Super = JSObject;
- inline Tagged<Managed<wasm::NativeModule>> managed_native_module() const
+ inline Tagged<CppGCManaged<wasm::NativeModule>> managed_native_module() const
V8_LIFETIME_BOUND;
inline void set_managed_native_module(
- Tagged<Managed<wasm::NativeModule>> value,
+ Tagged<CppGCManaged<wasm::NativeModule>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline Tagged<Script> script() const V8_LIFETIME_BOUND;
inline void set_script(Tagged<Script> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Managed<wasm::NativeModule>::Ptr native_module() V8_LIFETIME_BOUND;
+ inline CppGCManaged<wasm::NativeModule>::Ptr native_module()
+ V8_LIFETIME_BOUND;
// Dispatched behavior.
DECL_PRINTER(WasmModuleObject)
@@ -195,7 +196,7 @@ V8_OBJECT class WasmModuleObject : public JSObject {
Isolate*, base::Vector<const uint8_t> wire_bytes, wasm::WireBytesRef,
InternalizeString, SharedFlag shared = SharedFlag{false});
- TaggedMember<Managed<wasm::NativeModule>> managed_native_module_;
+ TaggedMember<CppGCManaged<wasm::NativeModule>> managed_native_module_;
TaggedMember<Script> script_;
} V8_OBJECT_END;
@@ -361,8 +362,6 @@ inline constexpr int WasmTableObject::kTrustedDataOffsetEnd =
offsetof(WasmTableObject, trusted_data_) + kTrustedPointerSize - 1;
inline constexpr int WasmTableObject::kHeaderSize = sizeof(WasmTableObject);
-
-
// Representation of a WebAssembly.Memory JavaScript-level object.
V8_OBJECT class WasmMemoryObject : public JSObject {
public:
@@ -374,9 +373,9 @@ V8_OBJECT class WasmMemoryObject : public JSObject {
inline void set_array_buffer(Tagged<UnionOf<JSArrayBuffer, Undefined>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
- inline Tagged<Managed<BackingStore>> managed_backing_store() const;
+ inline Tagged<CppGCManaged<BackingStore>> managed_backing_store() const;
inline void set_managed_backing_store(
- Tagged<Managed<BackingStore>> value,
+ Tagged<CppGCManaged<BackingStore>> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
inline int maximum_pages() const;
@@ -401,7 +400,7 @@ V8_OBJECT class WasmMemoryObject : public JSObject {
}
#endif // TAGGED_SIZE_8_BYTES
- inline Managed<BackingStore>::Ptr backing_store() const;
+ inline CppGCManaged<BackingStore>::Ptr backing_store() const;
// Add a use of this memory object to the given instance. This updates the
// internal weak list of instances that use this memory and also updates the
@@ -458,7 +457,7 @@ V8_OBJECT class WasmMemoryObject : public JSObject {
// bit on the backing store is not authoritative).
static DirectHandle<JSArrayBuffer> RefreshBuffer(
Isolate* isolate, DirectHandle<WasmMemoryObject> memory,
- Managed<BackingStore>::Ptr backing_store,
+ CppGCManaged<BackingStore>::Ptr backing_store,
std::optional<ResizableFlag> override_resizable = {});
V8_EXPORT_PRIVATE static int32_t Grow(Isolate*,
@@ -484,7 +483,7 @@ V8_OBJECT class WasmMemoryObject : public JSObject {
static const int kHeaderSize;
TaggedMember<UnionOf<JSArrayBuffer, Undefined>> array_buffer_;
- TaggedMember<Managed<BackingStore>> managed_backing_store_;
+ TaggedMember<CppGCManaged<BackingStore>> managed_backing_store_;
TaggedMember<Smi> maximum_pages_;
TaggedMember<WeakArrayList> instances_;
uint8_t address_type_;
@@ -575,6 +574,8 @@ class FeedbackConstants {
// This object lives in trusted space and is never modified from user space.
V8_OBJECT class V8_EXPORT_PRIVATE WasmTrustedInstanceData
: public ExposedTrustedObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
DECL_OPTIONAL_ACCESSORS(instance_object, Tagged<WasmInstanceObject>)
DECL_OPTIONAL_ACCESSORS(native_context, Tagged<NativeContext>)
@@ -936,6 +937,8 @@ class WasmDispatchTableData {
// WasmTrustedInstanceData which uses the table. It is used from generated code
// for executing indirect calls.
V8_OBJECT class WasmDispatchTable : public ExposedTrustedObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
#if V8_ENABLE_DRUMBRAKE
static const uint32_t kInvalidFunctionIndex = UINT_MAX;
@@ -1067,6 +1070,8 @@ V8_OBJECT class WasmDispatchTable : public ExposedTrustedObject {
} V8_OBJECT_END;
V8_OBJECT class WasmDispatchTableForImports : public TrustedObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
class BodyDescriptor;
@@ -1162,6 +1167,8 @@ V8_OBJECT class WasmDispatchTableForImports : public TrustedObject {
// A Wasm exception that has been thrown out of Wasm code.
V8_OBJECT class V8_EXPORT_PRIVATE WasmExceptionPackage : public JSObject {
+ V8_IT_NO_AUTO_DISPATCH;
+
public:
static DirectHandle<WasmExceptionPackage> New(
Isolate* isolate, DirectHandle<WasmExceptionTag> exception_tag,
@@ -1218,6 +1225,8 @@ bool UseGenericWasmToJSWrapper(wasm::ImportCallKind kind,
// A Wasm function that is wrapped and exported to JavaScript.
// Representation of WebAssembly.Function JavaScript-level object.
class WasmExportedFunction : public JSFunction {
+ V8_IT_REUSE_PARENT;
+
public:
V8_EXPORT_PRIVATE static bool IsWasmExportedFunction(Tagged<Object> object);
@@ -1247,13 +1256,15 @@ class WasmExportedFunction : public JSFunction {
// An external function exposed to Wasm via the C/C++ API.
class WasmCapiFunction : public JSFunction {
+ V8_IT_REUSE_PARENT;
+
public:
static bool IsWasmCapiFunction(Tagged<Object> object);
- static DirectHandle<WasmCapiFunction> New(Isolate* isolate,
- Address call_target,
- DirectHandle<Foreign> embedder_data,
- const wasm::CanonicalSig* sig);
+ static DirectHandle<WasmCapiFunction> New(
+ Isolate* isolate, Address call_target,
+ DirectHandle<CppGCManagedBase> embedder_data,
+ const wasm::CanonicalSig* sig);
// TODO(clemensb): Remove this accessor.
const wasm::CanonicalSig* sig() const;
@@ -1269,6 +1280,8 @@ class WasmCapiFunction : public JSFunction {
// - {WasmExportedFunction}: A proper Wasm function exported from a module.
// - {WasmCapiFunction}: A function constructed via the C/C++ API.
class WasmExternalFunction : public JSFunction {
+ V8_IT_REUSE_PARENT;
+
public:
static bool IsWasmExternalFunction(Tagged<Object> object);
@@ -1276,6 +1289,8 @@ class WasmExternalFunction : public JSFunction {
};
V8_OBJECT class WasmFunctionData : public ExposedTrustedObject {
+ V8_IT_OWN_TYPE;
+
public:
DECL_CODE_POINTER_ACCESSORS(wrapper_code)
DECL_PROTECTED_POINTER_ACCESSORS(internal, WasmInternalFunction)
@@ -1528,8 +1543,8 @@ inline constexpr int WasmFuncRef::kSize = sizeof(WasmFuncRef);
V8_OBJECT class WasmCapiFunctionData : public WasmFunctionData {
public:
- inline Tagged<Foreign> embedder_data() const;
- inline void set_embedder_data(Tagged<Foreign> value,
+ inline Tagged<CppGCManagedBase> embedder_data() const;
+ inline void set_embedder_data(Tagged<CppGCManagedBase> value,
WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
DECL_PRINTER(WasmCapiFunctionData)
@@ -1541,7 +1556,7 @@ V8_OBJECT class WasmCapiFunctionData : public WasmFunctionData {
static const int kSize;
public:
- TaggedMember<Foreign> embedder_data_;
+ TaggedMember<CppGCManagedBase> embedder_data_;
} V8_OBJECT_END;
inline constexpr int WasmCapiFunctionData::kHeaderSize =
@@ -1719,6 +1734,8 @@ constexpr int WasmTypeInfo::SizeFor(int supertypes_length) {
// WasmArray). It carries no fields of its own; subclasses lay out their
// payload directly after the JSReceiver header.
V8_OBJECT class WasmObject : public JSReceiver {
+ V8_IT_ABSTRACT;
+
public:
static const int kHeaderSize;
@@ -1734,6 +1751,8 @@ V8_OBJECT class WasmObject : public JSReceiver {
inline constexpr int WasmObject::kHeaderSize = sizeof(WasmObject);
V8_OBJECT class WasmStruct : public WasmObject {
+ V8_IT_ORDER(LAST);
+
public:
static const wasm::CanonicalStructType* GcSafeType(Tagged<Map> map);
static inline int Size(const wasm::StructType* type);
@@ -1743,6 +1762,9 @@ V8_OBJECT class WasmStruct : public WasmObject {
Tagged<Map> map);
static inline int DecodeInstanceSizeFromMap(Tagged<Map> map);
+ // Useful for both WasmStruct and WasmCustomMap; {type} distinguishes.
+ static inline int FieldOffset(const wasm::StructType* type, int field_index);
+
// Returns the address of the field at given offset.
inline Address RawFieldAddress(int raw_offset);
@@ -1773,24 +1795,112 @@ V8_OBJECT class WasmStruct : public WasmObject {
inline constexpr int WasmStruct::kHeaderSize = sizeof(WasmStruct);
int WasmStruct::Size(const wasm::StructType* type) {
- // Object size must fit into a Smi (because of filler objects), and its
+ // Object size must fit into a Smi (because of runtime functions), and its
// computation must not overflow.
static_assert(Smi::kMaxValue <= kMaxInt);
DCHECK_LE(type->total_fields_size(), Smi::kMaxValue - kHeaderSize);
+ DCHECK_IMPLIES(v8_flags.wasm_merged_descriptors, !type->is_descriptor());
return std::max(kHeaderSize + static_cast<int>(type->total_fields_size()),
Heap::kMinObjectSizeInTaggedWords * kTaggedSize);
}
int WasmStruct::Size(const wasm::CanonicalStructType* type) {
- // Object size must fit into a Smi (because of filler objects), and its
+ // Object size must fit into a Smi (because of runtime functions), and its
// computation must not overflow.
static_assert(Smi::kMaxValue <= kMaxInt);
DCHECK_LE(type->total_fields_size(), Smi::kMaxValue - kHeaderSize);
+ DCHECK_IMPLIES(v8_flags.wasm_merged_descriptors, !type->is_descriptor());
return std::max(kHeaderSize + static_cast<int>(type->total_fields_size()),
Heap::kMinObjectSizeInTaggedWords * kTaggedSize);
}
+V8_OBJECT class WasmCustomMap : public Map {
+ public:
+ static inline int Size(const wasm::StructType* type);
+ static inline int Size(const wasm::CanonicalStructType* type);
+
+ static DirectHandle<WasmCustomMap> AllocateUninitialized(
+ Isolate* isolate, DirectHandle<WasmTrustedInstanceData> trusted_data,
+ wasm::ModuleTypeIndex index, DirectHandle<Map> map,
+ DirectHandle<Object> first_field);
+
+ inline Tagged<Union<WasmCustomMapWrapper, Null>> js_wrapper() const;
+ inline void set_js_wrapper(Tagged<Union<WasmCustomMapWrapper, Null>> wrapper,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
+ inline Tagged<NativeContext> native_context_for_wrapper() const;
+ inline void set_native_context_for_wrapper(
+ Tagged<NativeContext> context,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
+ // Returns the address of the field at given offset.
+ inline Address RawFieldAddress(int raw_offset);
+
+ // Returns the ObjectSlot for tagged value at given offset.
+ inline ObjectSlot RawField(int raw_offset);
+
+ V8_EXPORT_PRIVATE wasm::WasmValue GetFieldValue(uint32_t field_index);
+
+ // Populates the {js_wrapper} slot with a suitable wrapper object.
+ static DirectHandle<WasmCustomMapWrapper> CreateJSWrapper(
+ Isolate* isolate, DirectHandle<WasmCustomMap> wasm_custom_map);
+
+ DECL_PRINTER(WasmCustomMap)
+ DECL_VERIFIER(WasmCustomMap)
+
+ class BodyDescriptor;
+
+ static const int kHeaderSize;
+
+ TaggedMember<Union<WasmCustomMapWrapper, Null>> js_wrapper_;
+ // To save memory, we could store the NativeContext in the {js_wrapper} field
+ // before allocating the wrapper, but that would make checking for the
+ // wrapper's presence more expensive.
+ TaggedMember<NativeContext> native_context_for_wrapper_;
+} V8_OBJECT_END;
+
+inline constexpr int WasmCustomMap::kHeaderSize = sizeof(WasmCustomMap);
+
+int WasmCustomMap::Size(const wasm::StructType* type) {
+ // Object size must fit into a Smi (because of runtime functions), and its
+ // computation must not overflow.
+ static_assert(Smi::kMaxValue <= kMaxInt);
+ static_assert(Heap::kMinObjectSizeInTaggedWords * kTaggedSize <= kHeaderSize);
+ DCHECK_LE(type->total_fields_size(), Smi::kMaxValue - kHeaderSize);
+ DCHECK(type->is_descriptor());
+ return kHeaderSize + static_cast<int>(type->total_fields_size());
+}
+
+int WasmCustomMap::Size(const wasm::CanonicalStructType* type) {
+ // Object size must fit into a Smi (because of runtime functions), and its
+ // computation must not overflow.
+ static_assert(Smi::kMaxValue <= kMaxInt);
+ static_assert(Heap::kMinObjectSizeInTaggedWords * kTaggedSize <= kHeaderSize);
+ DCHECK_LE(type->total_fields_size(), Smi::kMaxValue - kHeaderSize);
+ DCHECK(type->is_descriptor());
+ return kHeaderSize + static_cast<int>(type->total_fields_size());
+}
+
+V8_OBJECT class WasmCustomMapWrapper : public JSObject {
+ public:
+ inline Tagged<WasmCustomMap> wrapped() const;
+ inline void set_wrapped(Tagged<WasmCustomMap> custom_map,
+ WriteBarrierMode mode = UPDATE_WRITE_BARRIER);
+
+ DECL_PRINTER(WasmCustomMapWrapper)
+ DECL_VERIFIER(WasmCustomMapWrapper)
+
+ static const int kHeaderSize;
+
+ TaggedMember<WasmCustomMap> wrapped_;
+} V8_OBJECT_END;
+
+inline constexpr int WasmCustomMapWrapper::kHeaderSize =
+ sizeof(WasmCustomMapWrapper);
+
V8_OBJECT class WasmArray : public WasmObject {
+ V8_IT_ORDER(FIRST);
+
public:
inline uint32_t length() const;
inline void set_length(uint32_t value);
@@ -1973,13 +2083,11 @@ V8_OBJECT class WasmFastApiCallData : public HeapObject {
static constexpr int SizeFor() { return sizeof(WasmFastApiCallData); }
-
TaggedMember<HeapObject> signature_;
TaggedMember<Object> callback_data_;
TaggedMember<MaybeObject> cached_map_;
} V8_OBJECT_END;
-
V8_OBJECT class WasmStringViewIter : public HeapObject {
public:
inline Tagged<String> string() const;
@@ -2004,22 +2112,25 @@ V8_OBJECT class WasmStringViewIter : public HeapObject {
} V8_OBJECT_END;
V8_OBJECT class WasmNull : public HeapObject {
+ V8_IT_NO_AUTO_DISPATCH;
+ V8_IT_OWN_TYPE;
+ V8_IT_NO_AUTO_CHECKER;
+
public:
#if V8_STATIC_ROOTS_BOOL || V8_STATIC_ROOTS_GENERATION_BOOL
// TODO(manoskouk): Make it smaller if able and needed.
- static constexpr int kPayloadSize = 64 * KB;
- // Payload should be a multiple of page size.
- static_assert(kPayloadSize % kMinimumOSPageSize == 0);
-
- Address payload() { return reinterpret_cast<Address>(this) + kPayloadOffset; }
-
- static const int kPayloadOffset;
- static const int kSizeWithPayload;
+ static constexpr int kSize = 64 * KB;
+ // Inaccessible region should be a multiple of page size.
+ static_assert(kSize % kMinimumOSPageSize == 0);
+ // Any wasm struct offset should fit in the object.
+ static_assert(kSize >=
+ std::max(WasmStruct::kHeaderSize, WasmCustomMap::kHeaderSize) +
+ (wasm::kMaxStructFieldIndexForImplicitNullCheck + 1) *
+ wasm::kMaxValueTypeSize);
+#else
+ static constexpr int kSize = sizeof(HeapObject);
#endif
- static const int kHeaderSize;
- static const int kSize;
-
DECL_PRINTER(WasmNull)
DECL_VERIFIER(WasmNull)
@@ -2028,21 +2139,6 @@ V8_OBJECT class WasmNull : public HeapObject {
class BodyDescriptor;
} V8_OBJECT_END;
-inline constexpr int WasmNull::kHeaderSize = sizeof(WasmNull);
-#if V8_STATIC_ROOTS_BOOL || V8_STATIC_ROOTS_GENERATION_BOOL
-inline constexpr int WasmNull::kPayloadOffset = WasmNull::kHeaderSize;
-inline constexpr int WasmNull::kSizeWithPayload =
- WasmNull::kPayloadOffset + WasmNull::kPayloadSize;
-inline constexpr int WasmNull::kSize = WasmNull::kSizeWithPayload;
-// Any wasm struct offset should fit in the object.
-static_assert(WasmNull::kSizeWithPayload >=
- WasmStruct::kHeaderSize +
- (wasm::kMaxStructFieldIndexForImplicitNullCheck + 1) *
- kSimd128Size);
-#else
-inline constexpr int WasmNull::kSize = WasmNull::kHeaderSize;
-#endif
-
#undef DECL_OPTIONAL_ACCESSORS
// If {opt_native_context} is not null, creates a contextful map bound to
diff --git a/deps/v8/src/wasm/wasm-objects.tq b/deps/v8/src/wasm/wasm-objects.tq
index 4b13b10452f..4d73d6dd41e 100644
--- a/deps/v8/src/wasm/wasm-objects.tq
+++ b/deps/v8/src/wasm/wasm-objects.tq
@@ -11,14 +11,14 @@
type PodArrayOfWasmValueType extends ByteArray
constexpr 'PodArray<wasm::ValueType>';
@useParentTypeChecker
-type ManagedWasmNativeModule extends Foreign
- constexpr 'Managed<wasm::NativeModule>';
+type ManagedWasmNativeModule extends CppGCManagedBase
+ constexpr 'CppGCManaged<wasm::NativeModule>';
@useParentTypeChecker
type TrustedManagedWasmNativeModule extends TrustedForeign
constexpr 'TrustedManaged<wasm::NativeModule>';
@useParentTypeChecker
-type ManagedBackingStore extends Foreign
- constexpr 'Managed<BackingStore>';
+type ManagedBackingStore extends CppGCManagedBase
+ constexpr 'CppGCManaged<BackingStore>';
type RawFunctionSigPtr extends RawPtr constexpr 'const wasm::CanonicalSig*';
@@ -163,7 +163,7 @@ extern operator '.instance_data' macro
@cppObjectLayoutDefinition
extern class WasmCapiFunctionData extends WasmFunctionData {
- embedder_data: Foreign; // Managed<wasm::FuncData>
+ embedder_data: CppGCManagedBase; // CppGCManaged<wasm::FuncData>
}
@cppObjectLayoutDefinition
@@ -321,6 +321,25 @@ extern class WasmArray extends WasmObject {
@if(TAGGED_SIZE_8_BYTES) optional_padding: uint32;
}
+// For Wasm structs with Custom Descriptor: begins with the regular fields
+// of a Map, then adds the custom descriptor's fields (which are accessible
+// to userspace).
+// When a WasmCustomMap is passed to JS (or converted to externref), we
+// switch to its {js_wrapper}.
+@cppObjectLayoutDefinition
+extern class WasmCustomMap extends Map {
+ js_wrapper: WasmCustomMapWrapper|Null;
+ // To save memory, we could store the NativeContext in the {js_wrapper} field
+ // before allocating the wrapper, but that would make checking for the
+ // wrapper's presence more expensive.
+ native_context_for_wrapper: NativeContext;
+}
+
+@cppObjectLayoutDefinition
+extern class WasmCustomMapWrapper extends JSObject {
+ wrapped: WasmCustomMap;
+}
+
@cppObjectLayoutDefinition
extern class WasmStringViewIter extends HeapObject {
string: String;
@@ -330,6 +349,8 @@ extern class WasmStringViewIter extends HeapObject {
}
@cppObjectLayoutDefinition
+@doNotGenerateCast
+@doNotGenerateInstanceTypeCheck
extern class WasmNull extends HeapObject {}
extern macro WasmNullConstant(): WasmNull;
diff --git a/deps/v8/src/wasm/wasm-opcodes.h b/deps/v8/src/wasm/wasm-opcodes.h
index d8a0f5ad83d..a78a0dea725 100644
--- a/deps/v8/src/wasm/wasm-opcodes.h
+++ b/deps/v8/src/wasm/wasm-opcodes.h
@@ -804,6 +804,7 @@ V8_EXPORT_PRIVATE bool IsJSCompatibleSignature(const CanonicalSig* sig);
V(StructWait, 0xfe05, _, "struct.wait") \
V(WaitqueueNotify, 0xfe06, _, "waitqueue.notify") \
V(WaitqueueNew, 0xfe07, _, "waitqueue.new") \
+ V(Publish, 0xfe0f, _, "publish") \
V(StructAtomicGet, 0xfe5c, _, "struct.atomic.get") \
V(StructAtomicGetS, 0xfe5d, _, "struct.atomic.get_s") \
V(StructAtomicGetU, 0xfe5e, _, "struct.atomic.get_u") \
diff --git a/deps/v8/src/wasm/wasm-subtyping.cc b/deps/v8/src/wasm/wasm-subtyping.cc
index e76d639437f..1956c8d004c 100644
--- a/deps/v8/src/wasm/wasm-subtyping.cc
+++ b/deps/v8/src/wasm/wasm-subtyping.cc
@@ -42,11 +42,11 @@ bool ValidStructSubtypeDefinition(ModuleTypeIndex subtype_index,
}
}
if (sub_def.descriptor.valid()) {
- // If a type has a descriptor, its supertype must either have no descriptor,
- // or the supertype's descriptor must be a declared supertype of the
+ // If a type has a descriptor, its supertype must also have a descriptor,
+ // and the supertype's descriptor must be a declared supertype of the
// subtype's descriptor.
- if (super_def.descriptor.valid() &&
- module->supertype(sub_def.descriptor) != super_def.descriptor) {
+ if (!super_def.descriptor.valid()) return false;
+ if (module->supertype(sub_def.descriptor) != super_def.descriptor) {
return false;
}
} else {
diff --git a/deps/v8/test/BUILD.gn b/deps/v8/test/BUILD.gn
index eda127d882d..a4c092a9635 100644
--- a/deps/v8/test/BUILD.gn
+++ b/deps/v8/test/BUILD.gn
@@ -83,6 +83,7 @@ group("d8_pgo") {
data_deps = [
"..:d8",
"..:v8_python_base",
+ "..:v8_dump_build_config",
]
data = [
diff --git a/deps/v8/test/cctest/BUILD.gn b/deps/v8/test/cctest/BUILD.gn
index 5c91009bb9a..fdd414cdb6a 100644
--- a/deps/v8/test/cctest/BUILD.gn
+++ b/deps/v8/test/cctest/BUILD.gn
@@ -147,7 +147,6 @@ v8_cluster_source_set("cctest_sources") {
"test-icache.cc",
"test-inobject-slack-tracking.cc",
"test-js-weak-refs.cc",
- "test-liveedit.cc",
"test-lockers.cc",
"test-mementos.cc",
"test-orderedhashtable.cc",
@@ -281,6 +280,7 @@ v8_cluster_source_set("cctest_sources") {
# test-run-native-calls uses wasm's LinkageAllocator.
"compiler/test-run-native-calls.cc",
+ "compiler/turboshaft-test-simd-shift.cc",
"test-js-to-wasm.cc",
"wasm/test-backing-store.cc",
"wasm/test-c-wasm-entry.cc",
diff --git a/deps/v8/test/cctest/cctest.h b/deps/v8/test/cctest/cctest.h
index 24c36426cda..909f3fcff16 100644
--- a/deps/v8/test/cctest/cctest.h
+++ b/deps/v8/test/cctest/cctest.h
@@ -38,6 +38,7 @@
#include "src/execution/isolate-inl.h"
#include "src/execution/simulator.h"
#include "src/heap/factory.h"
+#include "src/heap/local-heap-inl.h"
#include "src/objects/js-function.h"
#include "src/objects/objects.h"
#include "src/sandbox/sandboxable-thread.h"
@@ -597,7 +598,11 @@ class StreamerThread : public v8::base::Thread {
v8::ScriptCompiler::ScriptStreamingTask* task) {
StreamerThread thread(task);
CHECK(thread.Start());
- thread.Join();
+ {
+ i::Isolate* i_isolate = CcTest::i_isolate();
+ i_isolate->main_thread_local_heap()->ExecuteWhileParked(
+ [&thread]() { thread.Join(); });
+ }
}
explicit StreamerThread(v8::ScriptCompiler::ScriptStreamingTask* task)
diff --git a/deps/v8/test/cctest/cctest.status b/deps/v8/test/cctest/cctest.status
index 88195c635d1..c488e07a8be 100644
--- a/deps/v8/test/cctest/cctest.status
+++ b/deps/v8/test/cctest/cctest.status
@@ -51,9 +51,6 @@
# is enabled.
#'test-api-interceptors/Crash*': [FAIL, CRASH],
- # This test always fails. It tests that LiveEdit causes abort when turned off.
- 'test-debug/LiveEditDisabled': [FAIL],
-
# This test always fails. It tests that DisallowJavascriptExecutionScope
# works as intended.
'test-api/DisallowJavascriptExecutionScope': [FAIL],
@@ -97,7 +94,6 @@
'test-code-stub-assembler/PopAndReturnFromTFCBuiltinWithStackParameters' : [FAIL, ['official_build', CRASH]],
# Slow tests.
- 'test-api/FastApiCalls': [PASS, SLOW],
'test-api/InternalFieldsSubclassing': [PASS, SLOW],
'test-concurrent-allocation/ConcurrentAllocationInLargeSpace': [PASS, SLOW],
'test-cpu-profiler/NoProfilingProtectorCPUProfiler': [PASS, SLOW],
@@ -144,6 +140,59 @@
# TODO(https://crbug.com/467830526): Currently too flaky:
'test-mark-compact/RegressJoinThreadsOnIsolateDeinit': [SKIP],
+
+ ##############################################################################
+ # Behavioural differences between Maglev and Turbofan when the former is used
+ # for OptimizeFunctionOnNextCall or as a frontend for Turboshaft.
+ #
+ # Maglev doesn't support compiler::NodeObserver machinery.
+ 'test-js-to-wasm/TestFastJSWasmCall_I32Arg': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_Nop': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_MixedMistypedArgs': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_MistypedArgs': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_F64Result': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_MixedArgs': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_I64Result': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_NoArgs': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_I64Arg': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_I32ArgNotSmi': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_I64ArgExpectsBigInt': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_I32ArgDoesntExpectBigInt': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_VoidResult': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_I32Result': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_I64NegativeResult': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_F32Result': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_MismatchedArity': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_MultipleArgs': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_EagerDeopt': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_F64ArgDoesntExpectBigInt': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_ExternrefArg': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_F32Arg': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_F64Arg': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_NoReturnTypes': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_ExternrefNullArg': [SKIP],
+ 'test-js-to-wasm/TestFastJSWasmCall_F32ArgDoesntExpectBigInt': [SKIP],
+ 'test-calls-with-arraylike-or-spread/ReduceJSCallWithArrayLike': [SKIP],
+ 'test-calls-with-arraylike-or-spread/ReduceJSCallWithSpread': [SKIP],
+ 'test-calls-with-arraylike-or-spread/ReduceJSCreateBoundFunction': [SKIP],
+ 'test-calls-with-arraylike-or-spread/ReduceJSCreateClosure': [SKIP],
+ 'test-verify-type/TestVerifyType': [SKIP],
+ 'test-js-to-wasm/*': [SKIP],
+ # Maglev doesn't support FastApi calls.
+ 'test-api/FastApiCalls': [SKIP, SLOW],
+ 'test-api/FastApiCallWithAllocationAndGCInJS': [SKIP],
+ 'test-api/FastApiCallWithAllocationAndGCInC': [SKIP],
+ 'test-api/FastApiSequenceOverloads': [SKIP],
+ 'test-api/FastApiCallRecursionNoException': [SKIP],
+ 'test-api/FastApiCallRecursionWithException': [SKIP],
+ 'test-api/FastApiCallWithThrowInReentrantCode': [SKIP],
+ 'test-api/FastApiCallsString': [SKIP],
+ # Maglev is still missing some optimizations compared to Turbofan, which means
+ # that some old Turbofan tests don't pass when using Maglev as a frontend for
+ # Turboshaft.
+ 'test-cpu-profiler/FastApiCPUProfiler': [SKIP],
+ 'test-run-unwinding-info/RunUnwindingInfo': [SKIP],
+
}], # ALWAYS
##############################################################################
@@ -161,6 +210,17 @@
# into the handler after the stack has drifted from the context on the
# signal.
'test-cpu-profiler/*': [SKIP],
+
+ # Slow tests on TSAN
+ 'test-heap/Regress8014': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Add_Consts': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Sub_Consts': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Mul_Consts': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Div_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Add_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Sub_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Mul_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Div_Consts': [SKIP],
}],
##############################################################################
@@ -546,6 +606,15 @@
##############################################################################
['variant == stress_incremental_marking', {
'test-heap-profiler/SamplingHeapProfiler': [SKIP],
+ # Tests time out in stress_incremental_marking.
+ 'test-run-wasm/RunWasmTurbofan_Float32Add_Consts': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Sub_Consts': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Mul_Consts': [SKIP],
+ 'test-run-wasm/RunWasmTurbofan_Float32Div_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Add_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Sub_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Mul_Consts': [SKIP],
+ 'test-run-wasm/RunWasmLiftoff_Float32Div_Consts': [SKIP],
# BUG(https://crbug.com/v8/12999): Very slow test.
'test-api/InternalFieldsSubclassing': [PASS, ['mode == debug and arch == ia32', SKIP]],
@@ -668,6 +737,7 @@
'turboshaft-test-branch-combine/*': [SKIP],
'turboshaft-test-compare-combine/*': [SKIP],
'turboshaft-test-select-combine/*': [SKIP],
+ 'turboshaft-test-simd-shift/*': [SKIP],
'test-unwinder-code-pages/PCIsInV8_LargeCodeObject_CodePagesAPI': [SKIP],
'test-heap-profiler/WeakReference': [SKIP],
@@ -807,62 +877,6 @@
'test-concurrent-shared-function-info/TestConcurrentSharedFunctionInfo': [SKIP],
}], # variant == assert_types
-##############################################################################
-# Behavioural differences between Maglev and Turbofan when the former is used
-# for OptimizeFunctionOnNextCall or as a frontend for Turboshaft.
-['variant in (stress_maglev, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future)', {
- # Maglev doesn't support compiler::NodeObserver machinery.
- 'test-js-to-wasm/TestFastJSWasmCall_I32Arg': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_Nop': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_MixedMistypedArgs': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_MistypedArgs': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_F64Result': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_MixedArgs': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_I64Result': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_NoArgs': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_I64Arg': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_I32ArgNotSmi': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_I64ArgExpectsBigInt': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_I32ArgDoesntExpectBigInt': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_VoidResult': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_I32Result': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_I64NegativeResult': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_LazyDeopt_F32Result': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_MismatchedArity': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_MultipleArgs': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_EagerDeopt': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_F64ArgDoesntExpectBigInt': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_ExternrefArg': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_F32Arg': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_F64Arg': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_NoReturnTypes': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_ExternrefNullArg': [FAIL],
- 'test-js-to-wasm/TestFastJSWasmCall_F32ArgDoesntExpectBigInt': [FAIL],
- 'test-calls-with-arraylike-or-spread/ReduceJSCallWithArrayLike': [FAIL],
- 'test-calls-with-arraylike-or-spread/ReduceJSCallWithSpread': [FAIL],
- 'test-calls-with-arraylike-or-spread/ReduceJSCreateBoundFunction': [FAIL],
- 'test-calls-with-arraylike-or-spread/ReduceJSCreateClosure': [FAIL],
- 'test-verify-type/TestVerifyType': [FAIL],
- 'test-js-to-wasm/*': [SKIP],
- # Maglev doesn't support FastApi calls.
- 'test-api/FastApiCalls': [FAIL],
- 'test-api/FastApiCallWithAllocationAndGCInJS': [FAIL],
- 'test-api/FastApiCallWithAllocationAndGCInC': [FAIL],
- 'test-api/FastApiSequenceOverloads': [FAIL],
- 'test-api/FastApiCallRecursionNoException': [FAIL],
- 'test-api/FastApiCallRecursionWithException': [FAIL],
- 'test-api/FastApiCallWithThrowInReentrantCode': [FAIL],
- 'test-api/FastApiCallsString': [FAIL],
-}], # variant in (stress_maglev, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future)
-
-# Maglev is still missing some optimizations compared to Turbofan, which means
-# that some old Turbofan tests don't pass when using Maglev as a frontend for
-# Turboshaft.
-['variant in (turbolev, turbolev_future, stress_turbolev_future)', {
- 'test-cpu-profiler/FastApiCPUProfiler': [SKIP],
- 'test-run-unwinding-info/RunUnwindingInfo': [SKIP],
-}],
-
['direct_handle', {
# Needs --predictable.
'test-serialize/StaticRootsPredictableSnapshot': [SKIP],
diff --git a/deps/v8/test/cctest/compiler/test-code-generator.cc b/deps/v8/test/cctest/compiler/test-code-generator.cc
index 0994e2462e4..3e1b186c0c2 100644
--- a/deps/v8/test/cctest/compiler/test-code-generator.cc
+++ b/deps/v8/test/cctest/compiler/test-code-generator.cc
@@ -16,6 +16,7 @@
#include "src/compiler/linkage.h"
#include "src/execution/isolate.h"
#include "src/objects/heap-number-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "test/cctest/cctest.h"
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 62779e43dca..912329d7ab9 100644
--- a/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/deps/v8/test/cctest/compiler/test-js-typed-lowering.cc
@@ -150,7 +150,6 @@ class JSTypedLoweringTester : public HandleAndZoneScope,
}
Node* Unop(const Operator* op, Node* input) {
- DCHECK(!JSOperator::IsUnaryWithFeedback(op->opcode()));
// JS unops also require context, effect, and control
if (OperatorProperties::GetFrameStateInputCount(op) > 0) {
CHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(op));
diff --git a/deps/v8/test/cctest/compiler/test-multiple-return.cc b/deps/v8/test/cctest/compiler/test-multiple-return.cc
index c5a24ced13f..0cfab87f73c 100644
--- a/deps/v8/test/cctest/compiler/test-multiple-return.cc
+++ b/deps/v8/test/cctest/compiler/test-multiple-return.cc
@@ -198,7 +198,7 @@ void TestReturnMultipleValues(MachineType type, int min_count, int max_count) {
->AllocateAndInitializeEntry(wasm_code->instruction_start(),
wasm_code->signature_hash());
- RawMachineAssemblerTester<int32_t> mt(CodeKind::JS_TO_WASM_FUNCTION);
+ RawMachineAssemblerTester<int32_t> mt;
const int input_count = 2 + param_count;
Node* call_inputs[2 + kMaxParamCount];
call_inputs[0] = mt.IntPtrConstant(code_pointer.value());
diff --git a/deps/v8/test/cctest/compiler/turboshaft-test-simd-shift.cc b/deps/v8/test/cctest/compiler/turboshaft-test-simd-shift.cc
new file mode 100644
index 00000000000..d72a6834354
--- /dev/null
+++ b/deps/v8/test/cctest/compiler/turboshaft-test-simd-shift.cc
@@ -0,0 +1,382 @@
+// 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/base/logging.h"
+#include "src/codegen/cpu-features.h"
+#include "src/objects/objects-inl.h"
+#include "test/cctest/cctest.h"
+#include "test/cctest/compiler/turboshaft-codegen-tester.h"
+#include "test/common/value-helper.h"
+
+#if V8_ENABLE_WEBASSEMBLY
+
+namespace v8::internal::compiler::turboshaft {
+
+namespace {
+
+bool SimdIsSupported() { return CpuFeatures::SupportsSimd128(); }
+
+} // namespace
+
+// Tests for I8x16ShrS (8-bit lane signed right shift)
+TEST(SimdShift_I8x16ShrS_ShiftMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(7); // lane_size - 1 for 8-bit lane
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI8x16ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int8_t src[16] = {-128, -64, -1, 0, 1, 64, 127, -5,
+ 10, -100, 120, -127, 42, -42, 0, 127};
+ alignas(16) int8_t dst[16] = {0};
+ alignas(16) int8_t expected[16];
+ for (int i = 0; i < 16; ++i) {
+ expected[i] = src[i] >> 7;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 16; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I8x16ShrS_ShiftNonMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(3);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI8x16ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int8_t src[16] = {-128, -64, -1, 0, 1, 64, 127, -5,
+ 10, -100, 120, -127, 42, -42, 0, 127};
+ alignas(16) int8_t dst[16] = {0};
+ alignas(16) int8_t expected[16];
+ for (int i = 0; i < 16; ++i) {
+ expected[i] = src[i] >> 3;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 16; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I8x16ShrS_VariableShift) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(
+ MachineType::Pointer(), MachineType::Pointer(), MachineType::Int32());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex shift = m.Parameter(2);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI8x16ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int8_t src[16] = {-128, -64, -1, 0, 1, 64, 127, -5,
+ 10, -100, 120, -127, 42, -42, 0, 127};
+ alignas(16) int8_t dst[16] = {0};
+
+ for (int s : {0, 1, 3, 7, 8, 9, 15}) {
+ alignas(16) int8_t expected[16];
+ for (int i = 0; i < 16; ++i) {
+ expected[i] = src[i] >> (s % 8);
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst), s);
+ for (int i = 0; i < 16; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+ }
+}
+
+// Tests for I16x8ShrS (16-bit lane signed right shift)
+TEST(SimdShift_I16x8ShrS_ShiftMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(15); // lane_size - 1 for 16-bit lane
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI16x8ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int16_t src[8] = {-32768, -16384, -1, 0, 1, 16384, 32767, -42};
+ alignas(16) int16_t dst[8] = {0};
+ alignas(16) int16_t expected[8];
+ for (int i = 0; i < 8; ++i) {
+ expected[i] = src[i] >> 15;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 8; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I16x8ShrS_ShiftNonMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(7);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI16x8ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int16_t src[8] = {-32768, -16384, -1, 0, 1, 16384, 32767, -42};
+ alignas(16) int16_t dst[8] = {0};
+ alignas(16) int16_t expected[8];
+ for (int i = 0; i < 8; ++i) {
+ expected[i] = src[i] >> 7;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 8; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I16x8ShrS_VariableShift) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(
+ MachineType::Pointer(), MachineType::Pointer(), MachineType::Int32());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex shift = m.Parameter(2);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI16x8ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int16_t src[8] = {-32768, -16384, -1, 0, 1, 16384, 32767, -42};
+ alignas(16) int16_t dst[8] = {0};
+
+ for (int s : {0, 1, 7, 15, 16, 17, 31}) {
+ alignas(16) int16_t expected[8];
+ for (int i = 0; i < 8; ++i) {
+ expected[i] = src[i] >> (s % 16);
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst), s);
+ for (int i = 0; i < 8; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+ }
+}
+
+// Tests for I32x4ShrS (32-bit lane signed right shift)
+TEST(SimdShift_I32x4ShrS_ShiftMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(31); // lane_size - 1 for 32-bit lane
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI32x4ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int32_t src[4] = {-2147483647 - 1, -1000, 0, 2147483647};
+ alignas(16) int32_t dst[4] = {0};
+ alignas(16) int32_t expected[4];
+ for (int i = 0; i < 4; ++i) {
+ expected[i] = src[i] >> 31;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 4; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I32x4ShrS_ShiftNonMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(16);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI32x4ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int32_t src[4] = {-2147483647 - 1, -1000, 0, 2147483647};
+ alignas(16) int32_t dst[4] = {0};
+ alignas(16) int32_t expected[4];
+ for (int i = 0; i < 4; ++i) {
+ expected[i] = src[i] >> 16;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 4; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I32x4ShrS_VariableShift) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(
+ MachineType::Pointer(), MachineType::Pointer(), MachineType::Int32());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex shift = m.Parameter(2);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI32x4ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16) int32_t src[4] = {-2147483647 - 1, -1000, 0, 2147483647};
+ alignas(16) int32_t dst[4] = {0};
+
+ for (int s : {0, 1, 16, 31, 32, 33, 63}) {
+ alignas(16) int32_t expected[4];
+ for (int i = 0; i < 4; ++i) {
+ expected[i] = src[i] >> (s % 32);
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst), s);
+ for (int i = 0; i < 4; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+ }
+}
+
+// Tests for I64x2ShrS (64-bit lane signed right shift)
+TEST(SimdShift_I64x2ShrS_ShiftMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(63); // lane_size - 1 for 64-bit lane
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI64x2ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16)
+ int64_t src[2] = {-9223372036854775807LL - 1, 9223372036854775807LL};
+ alignas(16) int64_t dst[2] = {0};
+ alignas(16) int64_t expected[2];
+ for (int i = 0; i < 2; ++i) {
+ expected[i] = src[i] >> 63;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 2; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I64x2ShrS_ShiftNonMaxImmediate) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(MachineType::Pointer(),
+ MachineType::Pointer());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex shift = m.Word32Constant(32);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI64x2ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16)
+ int64_t src[2] = {-9223372036854775807LL - 1, 9223372036854775807LL};
+ alignas(16) int64_t dst[2] = {0};
+ alignas(16) int64_t expected[2];
+ for (int i = 0; i < 2; ++i) {
+ expected[i] = src[i] >> 32;
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst));
+ for (int i = 0; i < 2; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+}
+
+TEST(SimdShift_I64x2ShrS_VariableShift) {
+ if (!SimdIsSupported()) return;
+
+ RawMachineAssemblerTester<int32_t> m(
+ MachineType::Pointer(), MachineType::Pointer(), MachineType::Int32());
+ OpIndex src_ptr = m.Parameter(0);
+ OpIndex dst_ptr = m.Parameter(1);
+ OpIndex shift = m.Parameter(2);
+ OpIndex input = m.Load(MachineType::Simd128(), src_ptr);
+ OpIndex result =
+ m.Simd128Shift(input, shift, Simd128ShiftOp::Kind::kI64x2ShrS);
+ m.Store(MachineRepresentation::kSimd128, dst_ptr, result,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Return(m.Word32Constant(0));
+
+ alignas(16)
+ int64_t src[2] = {-9223372036854775807LL - 1, 9223372036854775807LL};
+ alignas(16) int64_t dst[2] = {0};
+
+ for (int s : {0, 1, 32, 63, 64, 65, 127}) {
+ alignas(16) int64_t expected[2];
+ for (int i = 0; i < 2; ++i) {
+ expected[i] = src[i] >> (s % 64);
+ }
+
+ m.Call(static_cast<void*>(src), static_cast<void*>(dst), s);
+ for (int i = 0; i < 2; ++i) {
+ CHECK_EQ(expected[i], dst[i]);
+ }
+ }
+}
+
+} // namespace v8::internal::compiler::turboshaft
+
+#endif // V8_ENABLE_WEBASSEMBLY
diff --git a/deps/v8/test/cctest/heap/heap-tester.h b/deps/v8/test/cctest/heap/heap-tester.h
index 7bfcfe3ddc1..8c5ab02339a 100644
--- a/deps/v8/test/cctest/heap/heap-tester.h
+++ b/deps/v8/test/cctest/heap/heap-tester.h
@@ -34,9 +34,7 @@
V(InvalidatedSlotsFastToSlow) \
V(InvalidatedSlotsSomeInvalidatedRanges) \
V(TestNewSpaceRefsInCopiedCode) \
- V(GCFlags) \
V(MarkCompactCollector) \
- V(MarkCompactEpochCounter) \
V(MemoryReducerActivationForSmallHeaps) \
V(NoPromotion) \
V(NumberStringCacheSize) \
@@ -52,12 +50,9 @@
V(Regress587004) \
V(Regress589413) \
V(Regress658718) \
- V(Regress670675) \
V(Regress777177) \
V(Regress779503) \
V(Regress791582) \
- V(Regress845060) \
- V(RegressMissingWriteBarrierInAllocate) \
V(WriteBarrier_Marking) \
V(WriteBarrier_MarkingExtension) \
V(WriteBarriersInCopyJSObject) \
diff --git a/deps/v8/test/cctest/heap/test-heap.cc b/deps/v8/test/cctest/heap/test-heap.cc
index 7535d46acd1..1d640d4b820 100644
--- a/deps/v8/test/cctest/heap/test-heap.cc
+++ b/deps/v8/test/cctest/heap/test-heap.cc
@@ -70,6 +70,7 @@
#include "src/objects/js-array-inl.h"
#include "src/objects/js-collection-inl.h"
#include "src/objects/managed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
#include "src/objects/slots.h"
@@ -93,3523 +94,149 @@ namespace heap {
static const int kPretenureCreationCount =
PretenuringHandler::GetMinMementoCountForTesting() + 1;
-static void CheckMap(Tagged<Map> map, int type, int instance_size) {
- CHECK(IsHeapObject(map));
- DCHECK(IsValidHeapObject(CcTest::heap(), map));
- CHECK_EQ(ReadOnlyRoots(CcTest::heap()).meta_map(), map->map());
- CHECK_EQ(type, map->instance_type());
- CHECK_EQ(instance_size, map->instance_size());
-}
-
-TEST(HeapMaps) {
- CcTest::InitializeVM();
- ReadOnlyRoots roots(CcTest::heap());
- CheckMap(roots.meta_map(), MAP_TYPE, kVariableSizeSentinel);
- CheckMap(roots.heap_number_map(), HEAP_NUMBER_TYPE, sizeof(HeapNumber));
- CheckMap(roots.fixed_array_map(), FIXED_ARRAY_TYPE, kVariableSizeSentinel);
- CheckMap(roots.hash_table_map(), HASH_TABLE_TYPE, kVariableSizeSentinel);
- CheckMap(roots.seq_two_byte_string_map(), SEQ_TWO_BYTE_STRING_TYPE,
- kVariableSizeSentinel);
-}
-static void VerifyStoredPrototypeMap(Isolate* isolate,
- int stored_map_context_index,
- int stored_ctor_context_index) {
- DirectHandle<Context> context = isolate->native_context();
- DirectHandle<Map> this_map(
- Cast<Map>(context->GetNoCell(stored_map_context_index)), isolate);
- DirectHandle<JSFunction> fun(
- Cast<JSFunction>(context->GetNoCell(stored_ctor_context_index)), isolate);
- DirectHandle<JSObject> proto(Cast<JSObject>(fun->initial_map()->prototype()),
- isolate);
- DirectHandle<Map> that_map(proto->map(), isolate);
- CHECK(proto->HasFastProperties());
- CHECK_EQ(*this_map, *that_map);
-}
-
-// Checks that critical maps stored on the context (mostly used for fast-path
-// checks) are unchanged after initialization.
-TEST(ContextMaps) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- HandleScope handle_scope(isolate);
- VerifyStoredPrototypeMap(isolate,
- Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
- Context::STRING_FUNCTION_INDEX);
- VerifyStoredPrototypeMap(isolate, Context::REGEXP_PROTOTYPE_MAP_INDEX,
- Context::REGEXP_FUNCTION_INDEX);
-}
-TEST(InitialObjects) {
- LocalContext env;
+static void OptimizeEmptyFunction(const char* name) {
HandleScope scope(CcTest::i_isolate());
- DirectHandle<Context> context = v8::Utils::OpenDirectHandle(*env);
- // Initial ArrayIterator prototype.
- CHECK_EQ(context->initial_array_iterator_prototype(),
- *v8::Utils::OpenDirectHandle(
- *CompileRun("[][Symbol.iterator]().__proto__")));
- // Initial Array prototype.
- CHECK_EQ(context->initial_array_prototype(),
- *v8::Utils::OpenDirectHandle(*CompileRun("Array.prototype")));
- // Initial Generator prototype.
- CHECK_EQ(context->initial_generator_prototype(),
- *v8::Utils::OpenDirectHandle(
- *CompileRun("(function*(){}).__proto__.prototype")));
- // Initial Iterator prototype.
- CHECK_EQ(context->initial_iterator_prototype(),
- *v8::Utils::OpenDirectHandle(
- *CompileRun("[][Symbol.iterator]().__proto__.__proto__")));
- // Initial Object prototype.
- CHECK_EQ(context->initial_object_prototype(),
- *v8::Utils::OpenDirectHandle(*CompileRun("Object.prototype")));
-}
-
-static void CheckOddball(Isolate* isolate, Tagged<Object> obj,
- const char* string) {
- CHECK(IsOddball(obj));
- Handle<Object> handle(obj, isolate);
- Tagged<Object> print_string =
- *Object::ToString(isolate, handle).ToHandleChecked();
- CHECK(Cast<String>(print_string)->IsOneByteEqualTo(base::CStrVector(string)));
-}
-
-static void CheckSmi(Isolate* isolate, int value, const char* string) {
- Handle<Object> handle(Smi::FromInt(value), isolate);
- Tagged<Object> print_string =
- *Object::ToString(isolate, handle).ToHandleChecked();
- CHECK(Cast<String>(print_string)->IsOneByteEqualTo(base::CStrVector(string)));
-}
-
-static void CheckNumber(Isolate* isolate, double value, const char* string) {
- Handle<Object> number = isolate->factory()->NewNumber(value);
- CHECK(IsNumber(*number));
- DirectHandle<Object> print_string =
- Object::ToString(isolate, number).ToHandleChecked();
- CHECK(
- Cast<String>(*print_string)->IsOneByteEqualTo(base::CStrVector(string)));
-}
-
-void CheckEmbeddedObjectsAreEqual(Isolate* isolate, DirectHandle<Code> lhs,
- DirectHandle<Code> rhs) {
- int mode_mask = RelocInfo::ModeMask(RelocInfo::FULL_EMBEDDED_OBJECT);
- RelocIterator lhs_it(*lhs, mode_mask);
- RelocIterator rhs_it(*rhs, mode_mask);
- while (!lhs_it.done() && !rhs_it.done()) {
- CHECK_EQ(lhs_it.rinfo()->target_object(), rhs_it.rinfo()->target_object());
-
- lhs_it.next();
- rhs_it.next();
- }
- CHECK(lhs_it.done() == rhs_it.done());
-}
-
-static void CheckGcSafeFindCodeForInnerPointer(Isolate* isolate) {
- // Test GcSafeFindCodeForInnerPointer
-#define __ assm.
-
- Assembler assm(isolate->allocator(), AssemblerOptions{});
-
- __ nop(); // supported on all architectures
-
- CodeDesc desc;
- assm.GetCode(isolate, &desc);
- DirectHandle<InstructionStream> code(
- Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING)
- .Build()
- ->instruction_stream(),
- isolate);
- CHECK(IsInstructionStream(*code));
-
- Tagged<HeapObject> obj = Cast<HeapObject>(*code);
- Address obj_addr = obj.address();
-
- for (int i = 0; i < obj->Size(); i += kTaggedSize) {
- Tagged<Code> lookup_result =
- isolate->heap()->FindCodeForInnerPointer(obj_addr + i);
- CHECK_EQ(*code, lookup_result->instruction_stream());
- }
-
- DirectHandle<InstructionStream> copy(
- Factory::CodeBuilder(isolate, desc, CodeKind::FOR_TESTING)
- .Build()
- ->instruction_stream(),
- isolate);
- Tagged<HeapObject> obj_copy = Cast<HeapObject>(*copy);
- Tagged<Code> not_right = isolate->heap()->FindCodeForInnerPointer(
- obj_copy.address() + obj_copy->Size() / 2);
- CHECK_NE(not_right->instruction_stream(), *code);
- CHECK_EQ(not_right->instruction_stream(), *copy);
-}
-
-TEST(HandleNull) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- HandleScope outer_scope(isolate);
- LocalContext context;
- DirectHandle<Object> n(Tagged<Object>(kNullAddress), isolate);
- CHECK(!n.is_null());
-}
-
-TEST(HeapObjects) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
-
- HandleScope sc(isolate);
- DirectHandle<Object> value = factory->NewNumber(1.000123);
- CHECK(IsHeapNumber(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(1.000123, Object::NumberValue(*value));
-
- value = factory->NewNumber(1.0);
- CHECK(IsSmi(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(1.0, Object::NumberValue(*value));
-
- value = factory->NewNumberFromInt(1024);
- CHECK(IsSmi(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(1024.0, Object::NumberValue(*value));
-
- value = factory->NewNumberFromInt(Smi::kMinValue);
- CHECK(IsSmi(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(Smi::kMinValue, Cast<Smi>(*value).value());
-
- value = factory->NewNumberFromInt(Smi::kMaxValue);
- CHECK(IsSmi(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(Smi::kMaxValue, Cast<Smi>(*value).value());
-
-#if !defined(V8_TARGET_ARCH_64_BIT)
- // TODO(lrn): We need a NumberFromIntptr function in order to test this.
- value = factory->NewNumberFromInt(Smi::kMinValue - 1);
- CHECK(IsHeapNumber(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(static_cast<double>(Smi::kMinValue - 1),
- Object::NumberValue(*value));
-#endif
-
- value = factory->NewNumberFromUint(static_cast<uint32_t>(Smi::kMaxValue) + 1);
- CHECK(IsHeapNumber(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(static_cast<double>(static_cast<uint32_t>(Smi::kMaxValue) + 1),
- Object::NumberValue(*value));
-
- value = factory->NewNumberFromUint(static_cast<uint32_t>(1) << 31);
- CHECK(IsHeapNumber(*value));
- CHECK(IsNumber(*value));
- CHECK_EQ(static_cast<double>(static_cast<uint32_t>(1) << 31),
- Object::NumberValue(*value));
-
- // nan oddball checks
- CHECK(IsNumber(*factory->nan_value()));
- CHECK(std::isnan(Object::NumberValue(*factory->nan_value())));
-
- DirectHandle<String> s = factory->NewStringFromStaticChars("fisk hest ");
- CHECK(IsString(*s));
- CHECK_EQ(10, s->length());
-
- DirectHandle<String> object_string = Cast<String>(factory->Object_string());
- DirectHandle<JSGlobalObject> global(
- CcTest::i_isolate()->context()->global_object(), isolate);
- CHECK(Just(true) ==
- JSReceiver::HasOwnProperty(isolate, global, object_string));
-
- // Check ToString for oddballs
- ReadOnlyRoots roots(heap);
- CheckOddball(isolate, roots.true_value(), "true");
- CheckOddball(isolate, roots.false_value(), "false");
- CheckOddball(isolate, roots.null_value(), "null");
- CheckOddball(isolate, roots.undefined_value(), "undefined");
-
- // Check ToString for Smis
- CheckSmi(isolate, 0, "0");
- CheckSmi(isolate, 42, "42");
- CheckSmi(isolate, -42, "-42");
-
- // Check ToString for Numbers
- CheckNumber(isolate, 1.1, "1.1");
-
- CheckGcSafeFindCodeForInnerPointer(isolate);
-}
-
-TEST(Tagging) {
- CcTest::InitializeVM();
- int request = 24;
- CHECK_EQ(request, static_cast<int>(OBJECT_POINTER_ALIGN(request)));
- CHECK(IsSmi(Smi::FromInt(42)));
- CHECK(IsSmi(Smi::FromInt(Smi::kMinValue)));
- CHECK(IsSmi(Smi::FromInt(Smi::kMaxValue)));
-}
-
-TEST(GarbageCollection) {
- if (v8_flags.single_generation) return;
-
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- HandleScope sc(isolate);
- // Check GC.
- heap::InvokeMinorGC(CcTest::heap());
-
- DirectHandle<JSGlobalObject> global(
- CcTest::i_isolate()->context()->global_object(), isolate);
- DirectHandle<String> name = factory->InternalizeUtf8String("theFunction");
- DirectHandle<String> prop_name = factory->InternalizeUtf8String("theSlot");
- DirectHandle<String> prop_namex = factory->InternalizeUtf8String("theSlotx");
- DirectHandle<String> obj_name = factory->InternalizeUtf8String("theObject");
- DirectHandle<Smi> twenty_three(Smi::FromInt(23), isolate);
- DirectHandle<Smi> twenty_four(Smi::FromInt(24), isolate);
-
- {
- HandleScope inner_scope(isolate);
- // Allocate a function and keep it in global object's property.
- DirectHandle<JSFunction> function = factory->NewFunctionForTesting(name);
- Object::SetProperty(isolate, global, name, function).Check();
- // Allocate an object. Unrooted after leaving the scope.
- DirectHandle<JSObject> obj = factory->NewJSObject(function);
- Object::SetProperty(isolate, obj, prop_name, twenty_three).Check();
- Object::SetProperty(isolate, obj, prop_namex, twenty_four).Check();
-
- CHECK_EQ(Smi::FromInt(23),
- *Object::GetProperty(isolate, obj, prop_name).ToHandleChecked());
- CHECK_EQ(Smi::FromInt(24),
- *Object::GetProperty(isolate, obj, prop_namex).ToHandleChecked());
- }
-
- heap::InvokeMinorGC(CcTest::heap());
-
- // Function should be alive.
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, global, name));
- // Check function is retained.
- DirectHandle<Object> func_value =
- Object::GetProperty(isolate, global, name).ToHandleChecked();
- CHECK(IsJSFunction(*func_value));
- DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
-
- {
- HandleScope inner_scope(isolate);
- // Allocate another object, make it reachable from global.
- DirectHandle<JSObject> obj = factory->NewJSObject(function);
- Object::SetProperty(isolate, global, obj_name, obj).Check();
- Object::SetProperty(isolate, obj, prop_name, twenty_three).Check();
- }
-
- // After gc, it should survive.
- heap::InvokeMinorGC(CcTest::heap());
-
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, global, obj_name));
- DirectHandle<Object> obj =
- Object::GetProperty(isolate, global, obj_name).ToHandleChecked();
- CHECK(IsJSObject(*obj));
- CHECK_EQ(Smi::FromInt(23),
- *Object::GetProperty(isolate, Cast<JSObject>(obj), prop_name)
- .ToHandleChecked());
-}
-
-static void VerifyStringAllocation(Isolate* isolate, const char* string) {
- HandleScope scope(isolate);
- DirectHandle<String> s = isolate->factory()
- ->NewStringFromUtf8(base::CStrVector(string))
- .ToHandleChecked();
- CHECK_EQ(strlen(string), s->length());
- for (uint32_t index = 0; index < s->length(); index++) {
- CHECK_EQ(static_cast<uint16_t>(string[index]), s->Get(index));
- }
-}
-
-TEST(String) {
- CcTest::InitializeVM();
- Isolate* isolate = reinterpret_cast<Isolate*>(CcTest::isolate());
-
- VerifyStringAllocation(isolate, "a");
- VerifyStringAllocation(isolate, "ab");
- VerifyStringAllocation(isolate, "abc");
- VerifyStringAllocation(isolate, "abcd");
- VerifyStringAllocation(isolate, "fiskerdrengen er paa havet");
-}
-
-TEST(LocalHandles) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- v8::HandleScope scope(CcTest::isolate());
- const char* name = "Kasper the spunky";
- DirectHandle<String> string = factory->NewStringFromAsciiChecked(name);
- CHECK_EQ(strlen(name), string->length());
-}
-
-TEST(GlobalHandles) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- GlobalHandles* global_handles = isolate->global_handles();
-
- Handle<Object> h1;
- Handle<Object> h2;
- Handle<Object> h3;
- Handle<Object> h4;
-
- {
- HandleScope scope(isolate);
-
- DirectHandle<Object> i = factory->NewStringFromStaticChars("fisk");
- DirectHandle<Object> u = factory->NewNumber(1.12344);
-
- h1 = global_handles->Create(*i);
- h2 = global_handles->Create(*u);
- h3 = global_handles->Create(*i);
- h4 = global_handles->Create(*u);
- }
-
- // after gc, it should survive
- heap::InvokeMinorGC(CcTest::heap());
-
- CHECK(IsString(*h1));
- CHECK(IsHeapNumber(*h2));
- CHECK(IsString(*h3));
- CHECK(IsHeapNumber(*h4));
-
- CHECK_EQ(*h3, *h1);
- GlobalHandles::Destroy(h1.location());
- GlobalHandles::Destroy(h3.location());
-
- CHECK_EQ(*h4, *h2);
- GlobalHandles::Destroy(h2.location());
- GlobalHandles::Destroy(h4.location());
-}
-
-static bool WeakPointerCleared = false;
-
-static void TestWeakGlobalHandleCallback(
- const v8::WeakCallbackInfo<void>& data) {
- std::pair<v8::Persistent<v8::Value>*, int>* p =
- reinterpret_cast<std::pair<v8::Persistent<v8::Value>*, int>*>(
- data.GetParameter());
- if (p->second == 1234) WeakPointerCleared = true;
- p->first->Reset();
-}
-
-TEST(WeakGlobalUnmodifiedApiHandlesScavenge) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- LocalContext context;
- Factory* factory = isolate->factory();
- GlobalHandles* global_handles = isolate->global_handles();
-
- WeakPointerCleared = false;
-
- IndirectHandle<Object> h1;
- IndirectHandle<Object> h2;
-
- {
- HandleScope scope(isolate);
-
- // Create an Api object that is unmodified.
- Local<v8::Function> function = FunctionTemplate::New(context.isolate())
- ->GetFunction(context.local())
- .ToLocalChecked();
- Local<v8::Object> i =
- function->NewInstance(context.local()).ToLocalChecked();
- DirectHandle<Object> u = factory->NewNumber(1.12344);
-
- h1 = global_handles->Create(*u);
- h2 = global_handles->Create(internal::ValueHelper::ValueAsAddress(*i));
- }
-
- std::pair<Handle<Object>*, int> handle_and_id(&h2, 1234);
- GlobalHandles::MakeWeak(
- h2.location(), reinterpret_cast<void*>(&handle_and_id),
- &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter);
-
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- v8_flags.single_generation ? heap::InvokeMajorGC(heap)
- : heap::InvokeMinorGC(heap);
- }
-
- CHECK(IsHeapNumber(*h1));
- CHECK(WeakPointerCleared);
- GlobalHandles::Destroy(h1.location());
-}
-
-TEST(WeakGlobalHandlesMark) {
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = isolate->factory();
- GlobalHandles* global_handles = isolate->global_handles();
-
- WeakPointerCleared = false;
-
- IndirectHandle<Object> h1;
- IndirectHandle<Object> h2;
-
- {
- HandleScope scope(isolate);
-
- DirectHandle<Object> i = factory->NewStringFromStaticChars("fisk");
- DirectHandle<Object> u = factory->NewNumber(1.12344);
-
- h1 = global_handles->Create(*i);
- h2 = global_handles->Create(*u);
- }
-
- // Make sure the objects are promoted.
- heap::EmptyNewSpaceUsingGC(heap);
- CHECK(!HeapLayout::InYoungGeneration(*h1) &&
- !HeapLayout::InYoungGeneration(*h2));
-
- std::pair<Handle<Object>*, int> handle_and_id(&h2, 1234);
- GlobalHandles::MakeWeak(
- h2.location(), reinterpret_cast<void*>(&handle_and_id),
- &TestWeakGlobalHandleCallback, v8::WeakCallbackType::kParameter);
-
- // Incremental marking potentially marked handles before they turned weak.
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(IsString(*h1));
- CHECK(WeakPointerCleared);
- GlobalHandles::Destroy(h1.location());
-}
-
-TEST(DeleteWeakGlobalHandle) {
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = isolate->factory();
- GlobalHandles* global_handles = isolate->global_handles();
-
- WeakPointerCleared = false;
- IndirectHandle<Object> h;
- {
- HandleScope scope(isolate);
-
- DirectHandle<Object> i = factory->NewStringFromStaticChars("fisk");
- h = global_handles->Create(*i);
- }
-
- std::pair<Handle<Object>*, int> handle_and_id(&h, 1234);
- GlobalHandles::MakeWeak(h.location(), reinterpret_cast<void*>(&handle_and_id),
- &TestWeakGlobalHandleCallback,
- v8::WeakCallbackType::kParameter);
- CHECK(!WeakPointerCleared);
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(WeakPointerCleared);
-}
-
-TEST(BytecodeArray) {
- if (!v8_flags.compact) return;
- if (v8_flags.precise_object_pinning) return;
- static const uint8_t kRawBytes[] = {0xC3, 0x7E, 0xA5, 0x5A};
- static const int kRawBytesSize = sizeof(kRawBytes);
- static const int32_t kFrameSize = 32;
- static const uint16_t kParameterCount = 2;
- static const uint16_t kMaxArguments = 0;
-
- ManualGCScope manual_gc_scope;
- heap::ManualEvacuationCandidatesSelectionScope
- manual_evacuation_candidate_selection_scope(manual_gc_scope);
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
- Factory* factory = isolate->factory();
- HandleScope scope(isolate);
-
- // Ensures that the BytecodeArray isn't allocated on a NEVER_EVACUATE page.
- heap::AbandonCurrentlyFreeMemory(
- CcTest::i_isolate()->heap()->trusted_space());
-
- heap::SimulateFullSpace(heap->old_space());
- IndirectHandle<TrustedFixedArray> constant_pool =
- factory->NewTrustedFixedArray(5);
- for (int i = 0; i < 5; i++) {
- IndirectHandle<Object> number = factory->NewHeapNumber(i);
- constant_pool->set(i, *number);
- }
-
- IndirectHandle<TrustedByteArray> handler_table =
- factory->NewTrustedByteArray(3);
-
- // Allocate and initialize BytecodeArray
- IndirectHandle<BytecodeArray> array = factory->NewBytecodeArray(
- kRawBytesSize, kRawBytes, kFrameSize, kParameterCount, kMaxArguments,
- constant_pool, handler_table);
-
- CHECK(IsBytecodeArray(*array));
-
-#ifdef V8_ENABLE_SANDBOX
- // BytecodeArrays are not exposed to the sandbox ("published") immediately
- // after allocation. Instead, this only happens once the bytecode has been
- // verified. This way, we ensure that we only execute safe bytecode.
- CHECK(!array->IsPublished(isolate));
- NoOpBytecodeVerifier::Verify(isolate, array);
- CHECK(array->IsPublished(isolate));
-#endif // V8_ENABLE_SANDBOX
-
- CHECK_EQ(array->length(), (int)sizeof(kRawBytes));
- CHECK_EQ(array->frame_size(), kFrameSize);
- CHECK_EQ(array->parameter_count(), kParameterCount);
- CHECK_EQ(array->constant_pool(), *constant_pool);
- CHECK_EQ(array->handler_table(), *handler_table);
- CHECK_LE(array->address(), array->GetFirstBytecodeAddress());
- CHECK_GE(array->address() + array->BytecodeArraySize(),
- array->GetFirstBytecodeAddress() + array->length());
- for (int i = 0; i < kRawBytesSize; i++) {
- CHECK_EQ(Memory<uint8_t>(array->GetFirstBytecodeAddress() + i),
- kRawBytes[i]);
- CHECK_EQ(array->get(i), kRawBytes[i]);
- }
-
- Tagged<TrustedFixedArray> old_constant_pool_address = *constant_pool;
-
- // Perform a full garbage collection and force the constant pool to be on an
- // evacuation candidate.
- NormalPage* evac_page = NormalPage::FromHeapObject(*constant_pool);
- heap::ForceEvacuationCandidate(evac_page);
- {
- // We need to invoke GC without stack, otherwise no compaction is performed.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // BytecodeArray should survive.
- CHECK_EQ(array->length(), kRawBytesSize);
- CHECK_EQ(array->frame_size(), kFrameSize);
- for (int i = 0; i < kRawBytesSize; i++) {
- CHECK_EQ(array->get(i), kRawBytes[i]);
- CHECK_EQ(Memory<uint8_t>(array->GetFirstBytecodeAddress() + i),
- kRawBytes[i]);
- }
-
- // Constant pool should have been migrated.
- CHECK_EQ(array->constant_pool().ptr(), constant_pool->ptr());
- CHECK_NE(array->constant_pool().ptr(), old_constant_pool_address.ptr());
+ base::EmbeddedVector<char, 256> source;
+ base::SNPrintF(source,
+ "function %s() { return 0; }"
+ "%%PrepareFunctionForOptimization(%s);"
+ "%s(); %s();"
+ "%%OptimizeFunctionOnNextCall(%s);"
+ "%s();",
+ name, name, name, name, name, name);
+ CompileRun(source.begin());
}
-static const char* not_so_random_string_table[] = {
- "abstract", "boolean", "break", "byte", "case",
- "catch", "char", "class", "const", "continue",
- "debugger", "default", "delete", "do", "double",
- "else", "enum", "export", "extends", "false",
- "final", "finally", "float", "for", "function",
- "goto", "if", "implements", "import", "in",
- "instanceof", "int", "interface", "long", "native",
- "new", "null", "package", "private", "protected",
- "public", "return", "short", "static", "super",
- "switch", "synchronized", "this", "throw", "throws",
- "transient", "true", "try", "typeof", "var",
- "void", "volatile", "while", "with", nullptr};
-
-static void CheckInternalizedStrings(const char** strings) {
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- for (const char* string = *strings; *strings != nullptr;
- string = *strings++) {
- HandleScope scope(isolate);
- DirectHandle<String> a =
- isolate->factory()->InternalizeUtf8String(base::CStrVector(string));
- // InternalizeUtf8String may return a failure if a GC is needed.
- CHECK(IsInternalizedString(*a));
- DirectHandle<String> b = factory->InternalizeUtf8String(string);
- CHECK_EQ(*b, *a);
- CHECK(b->IsOneByteEqualTo(base::CStrVector(string)));
- b = isolate->factory()->InternalizeUtf8String(base::CStrVector(string));
- CHECK_EQ(*b, *a);
- CHECK(b->IsOneByteEqualTo(base::CStrVector(string)));
+// Count the number of native contexts in the weak list of native contexts.
+int CountNativeContexts() {
+ int count = 0;
+ Tagged<Object> object = CcTest::heap()->native_contexts_list();
+ while (!IsUndefined(object)) {
+ count++;
+ object = Cast<Context>(object)->next_context_link();
}
+ return count;
}
-TEST(StringTable) {
- CcTest::InitializeVM();
-
- v8::HandleScope sc(CcTest::isolate());
- CheckInternalizedStrings(not_so_random_string_table);
- CheckInternalizedStrings(not_so_random_string_table);
-}
-
-TEST(FunctionAllocation) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- v8::HandleScope sc(CcTest::isolate());
- DirectHandle<String> name = factory->InternalizeUtf8String("theFunction");
- DirectHandle<JSFunction> function = factory->NewFunctionForTesting(name);
-
- DirectHandle<Smi> twenty_three(Smi::FromInt(23), isolate);
- DirectHandle<Smi> twenty_four(Smi::FromInt(24), isolate);
-
- DirectHandle<String> prop_name = factory->InternalizeUtf8String("theSlot");
- DirectHandle<JSObject> obj = factory->NewJSObject(function);
- Object::SetProperty(isolate, obj, prop_name, twenty_three).Check();
- CHECK_EQ(Smi::FromInt(23),
- *Object::GetProperty(isolate, obj, prop_name).ToHandleChecked());
- // Check that we can add properties to function objects.
- Object::SetProperty(isolate, function, prop_name, twenty_four).Check();
- CHECK_EQ(
- Smi::FromInt(24),
- *Object::GetProperty(isolate, function, prop_name).ToHandleChecked());
-}
-
-TEST(ObjectProperties) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- v8::HandleScope sc(CcTest::isolate());
- DirectHandle<String> object_string(
- Cast<String>(ReadOnlyRoots(CcTest::heap()).Object_string()), isolate);
- DirectHandle<Object> object =
- Object::GetProperty(isolate, CcTest::i_isolate()->global_object(),
- object_string)
- .ToHandleChecked();
- DirectHandle<JSFunction> constructor = Cast<JSFunction>(object);
- DirectHandle<JSObject> obj = factory->NewJSObject(constructor);
- DirectHandle<String> first = factory->InternalizeUtf8String("first");
- DirectHandle<String> second = factory->InternalizeUtf8String("second");
-
- DirectHandle<Smi> one(Smi::FromInt(1), isolate);
- DirectHandle<Smi> two(Smi::FromInt(2), isolate);
-
- // check for empty
- CHECK(Just(false) == JSReceiver::HasOwnProperty(isolate, obj, first));
-
- // add first
- Object::SetProperty(isolate, obj, first, one).Check();
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, first));
-
- // delete first
- CHECK(Just(true) ==
- JSReceiver::DeleteProperty(isolate, obj, first, LanguageMode::kSloppy));
- CHECK(Just(false) == JSReceiver::HasOwnProperty(isolate, obj, first));
-
- // add first and then second
- Object::SetProperty(isolate, obj, first, one).Check();
- Object::SetProperty(isolate, obj, second, two).Check();
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, first));
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, second));
-
- // delete first and then second
- CHECK(Just(true) ==
- JSReceiver::DeleteProperty(isolate, obj, first, LanguageMode::kSloppy));
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, second));
- CHECK(Just(true) == JSReceiver::DeleteProperty(isolate, obj, second,
- LanguageMode::kSloppy));
- CHECK(Just(false) == JSReceiver::HasOwnProperty(isolate, obj, first));
- CHECK(Just(false) == JSReceiver::HasOwnProperty(isolate, obj, second));
-
- // add first and then second
- Object::SetProperty(isolate, obj, first, one).Check();
- Object::SetProperty(isolate, obj, second, two).Check();
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, first));
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, second));
-
- // delete second and then first
- CHECK(Just(true) == JSReceiver::DeleteProperty(isolate, obj, second,
- LanguageMode::kSloppy));
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, first));
- CHECK(Just(true) ==
- JSReceiver::DeleteProperty(isolate, obj, first, LanguageMode::kSloppy));
- CHECK(Just(false) == JSReceiver::HasOwnProperty(isolate, obj, first));
- CHECK(Just(false) == JSReceiver::HasOwnProperty(isolate, obj, second));
-
- // check string and internalized string match
- const char* string1 = "fisk";
- DirectHandle<String> s1 = factory->NewStringFromAsciiChecked(string1);
- Object::SetProperty(isolate, obj, s1, one).Check();
- DirectHandle<String> s1_string = factory->InternalizeUtf8String(string1);
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, s1_string));
-
- // check internalized string and string match
- const char* string2 = "fugl";
- DirectHandle<String> s2_string = factory->InternalizeUtf8String(string2);
- Object::SetProperty(isolate, obj, s2_string, one).Check();
- DirectHandle<String> s2 = factory->NewStringFromAsciiChecked(string2);
- CHECK(Just(true) == JSReceiver::HasOwnProperty(isolate, obj, s2));
-}
-
-TEST(JSObjectMaps) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- v8::HandleScope sc(CcTest::isolate());
- DirectHandle<String> name = factory->InternalizeUtf8String("theFunction");
- DirectHandle<JSFunction> function = factory->NewFunctionForTesting(name);
-
- DirectHandle<String> prop_name = factory->InternalizeUtf8String("theSlot");
- DirectHandle<JSObject> obj = factory->NewJSObject(function);
- DirectHandle<Map> initial_map(function->initial_map(), isolate);
-
- // Set a propery
- DirectHandle<Smi> twenty_three(Smi::FromInt(23), isolate);
- Object::SetProperty(isolate, obj, prop_name, twenty_three).Check();
- CHECK_EQ(Smi::FromInt(23),
- *Object::GetProperty(isolate, obj, prop_name).ToHandleChecked());
-
- // Check the map has changed
- CHECK(*initial_map != obj->map());
-}
-
-// Checks that extended Maps handling works as expected regarding Map
-// transitions, object creation and so on.
-TEST(JSInterceptorMap) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = CcTest::heap();
-
- HandleScope sc(isolate);
-
- DirectHandle<InterceptorInfo> named_interceptor =
- factory->NewInterceptorInfo(InterceptorKind::kNamed);
- DirectHandle<InterceptorInfo> indexed_interceptor =
- factory->NewInterceptorInfo(InterceptorKind::kIndexed);
-
- DirectHandle<Map> last_map;
- {
- HandleScope sc1(isolate);
-
- const size_t N = 100;
- DirectHandleVector<JSObject> objects(isolate);
- objects.reserve(N);
- DirectHandle<JSInterceptorMap> map;
-
- for (size_t i = 0; i < N; i++) {
- if (i % 10 == 0) {
- // Create a fresh map every now and then.
- const int inobject_properties = 2;
- map = Cast<JSInterceptorMap>(factory->NewExtendedMapWithMetaMap(
- isolate->meta_map(), ExtendedMapKind::kJSInterceptorMap,
- JS_OBJECT_TYPE,
- JSObject::kHeaderSize + inobject_properties * kTaggedSize,
- TERMINAL_FAST_ELEMENTS_KIND, inobject_properties));
- map->init_flags_and_clear_extended_padding();
- map->set_named_interceptor(*named_interceptor);
- map->set_indexed_interceptor(*indexed_interceptor);
- map->set_fast_case_validity_cell(
- ReadOnlyRoots(isolate).invalid_prototype_validity_cell());
- }
-
- Handle<JSObject> obj = factory->NewJSObjectFromMap(map);
- Object::SetProperty(isolate, obj, factory->a_string(), obj).Check();
- Object::SetProperty(isolate, obj, factory->b_string(), obj).Check();
- Object::SetProperty(isolate, obj, factory->c_string(), obj).Check();
- Object::SetProperty(isolate, obj, factory->d_string(), obj).Check();
-
-#ifdef VERIFY_HEAP
- obj->HeapObjectVerify(isolate);
- obj->map()->HeapObjectVerify(isolate);
-#endif // VERIFY_HEAP
- objects.emplace_back(obj);
- if (i == N / 2) {
- InvokeMajorGC(heap);
- InvokeMajorGC(heap);
- }
- }
-
- InvokeMajorGC(heap);
- InvokeMajorGC(heap);
- last_map = sc1.CloseAndEscape(map);
- }
- InvokeMajorGC(heap);
- InvokeMajorGC(heap);
-
- CHECK(IsJSObjectMap(*last_map));
- CHECK(last_map->is_extended_map());
-
- CHECK_EQ(UncheckedCast<ExtendedMap>(last_map)->map_kind(),
- ExtendedMapKind::kJSInterceptorMap);
- DirectHandle<JSInterceptorMap> map = Cast<JSInterceptorMap>(last_map);
- CHECK_EQ(map->named_interceptor(), *named_interceptor);
- CHECK_EQ(map->indexed_interceptor(), *indexed_interceptor);
-}
-
-TEST(JSArray) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- v8::HandleScope sc(CcTest::isolate());
- DirectHandle<String> name = factory->InternalizeUtf8String("Array");
- DirectHandle<Object> fun_obj =
- Object::GetProperty(isolate, CcTest::i_isolate()->global_object(), name)
- .ToHandleChecked();
- DirectHandle<JSFunction> function = Cast<JSFunction>(fun_obj);
-
- // Allocate the object.
- DirectHandle<Object> element;
- DirectHandle<JSObject> object = factory->NewJSObject(function);
- DirectHandle<JSArray> array = Cast<JSArray>(object);
- // We just initialized the VM, no heap allocation failure yet.
- JSArray::Initialize(isolate, array, 0);
-
- // Set array length to 0.
- JSArray::SetLength(isolate, array, 0);
- CHECK_EQ(Smi::zero(), array->length());
- // Must be in fast mode.
- CHECK(array->HasSmiOrObjectElements());
-
- // array[length] = name.
- Object::SetElement(isolate, array, 0, name, ShouldThrow::kDontThrow).Check();
- CHECK_EQ(Smi::FromInt(1), array->length());
- element = i::Object::GetElement(isolate, array, 0).ToHandleChecked();
- CHECK_EQ(*element, *name);
-
- // Set array length with larger than smi value.
- JSArray::SetLength(isolate, array, static_cast<uint32_t>(Smi::kMaxValue) + 1);
-
- uint32_t int_length = 0;
- CHECK(Object::ToArrayIndex(array->length(), &int_length));
- CHECK_EQ(static_cast<uint32_t>(Smi::kMaxValue) + 1, int_length);
- CHECK(array->HasDictionaryElements()); // Must be in slow mode.
-
- // array[length] = name.
- Object::SetElement(isolate, array, int_length, name, ShouldThrow::kDontThrow)
- .Check();
- uint32_t new_int_length = 0;
- CHECK(Object::ToArrayIndex(array->length(), &new_int_length));
- CHECK_EQ(static_cast<double>(int_length), new_int_length - 1);
- element = Object::GetElement(isolate, array, int_length).ToHandleChecked();
- CHECK_EQ(*element, *name);
- element = Object::GetElement(isolate, array, 0).ToHandleChecked();
- CHECK_EQ(*element, *name);
-}
-
-TEST(JSObjectCopy) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- v8::HandleScope sc(CcTest::isolate());
- DirectHandle<String> object_string(
- Cast<String>(ReadOnlyRoots(CcTest::heap()).Object_string()), isolate);
- DirectHandle<Object> object =
- Object::GetProperty(isolate, CcTest::i_isolate()->global_object(),
- object_string)
- .ToHandleChecked();
- DirectHandle<JSFunction> constructor = Cast<JSFunction>(object);
- Handle<JSObject> obj = factory->NewJSObject(constructor);
- DirectHandle<String> first = factory->InternalizeUtf8String("first");
- DirectHandle<String> second = factory->InternalizeUtf8String("second");
-
- DirectHandle<Smi> one(Smi::FromInt(1), isolate);
- DirectHandle<Smi> two(Smi::FromInt(2), isolate);
-
- Object::SetProperty(isolate, obj, first, one).Check();
- Object::SetProperty(isolate, obj, second, two).Check();
-
- Object::SetElement(isolate, obj, 0, first, ShouldThrow::kDontThrow).Check();
- Object::SetElement(isolate, obj, 1, second, ShouldThrow::kDontThrow).Check();
-
- // Make the clone.
- DirectHandle<Object> value1, value2;
- DirectHandle<JSObject> clone = factory->CopyJSObject(obj);
- CHECK(!clone.is_identical_to(obj));
-
- value1 = Object::GetElement(isolate, obj, 0).ToHandleChecked();
- value2 = Object::GetElement(isolate, clone, 0).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
- value1 = Object::GetElement(isolate, obj, 1).ToHandleChecked();
- value2 = Object::GetElement(isolate, clone, 1).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
-
- value1 = Object::GetProperty(isolate, obj, first).ToHandleChecked();
- value2 = Object::GetProperty(isolate, clone, first).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
- value1 = Object::GetProperty(isolate, obj, second).ToHandleChecked();
- value2 = Object::GetProperty(isolate, clone, second).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
-
- // Flip the values.
- Object::SetProperty(isolate, clone, first, two).Check();
- Object::SetProperty(isolate, clone, second, one).Check();
-
- Object::SetElement(isolate, clone, 0, second, ShouldThrow::kDontThrow)
- .Check();
- Object::SetElement(isolate, clone, 1, first, ShouldThrow::kDontThrow).Check();
-
- value1 = Object::GetElement(isolate, obj, 1).ToHandleChecked();
- value2 = Object::GetElement(isolate, clone, 0).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
- value1 = Object::GetElement(isolate, obj, 0).ToHandleChecked();
- value2 = Object::GetElement(isolate, clone, 1).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
-
- value1 = Object::GetProperty(isolate, obj, second).ToHandleChecked();
- value2 = Object::GetProperty(isolate, clone, first).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
- value1 = Object::GetProperty(isolate, obj, first).ToHandleChecked();
- value2 = Object::GetProperty(isolate, clone, second).ToHandleChecked();
- CHECK_EQ(*value1, *value2);
-}
-
-TEST(StringAllocation) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
-
- const unsigned char chars[] = {0xE5, 0xA4, 0xA7};
- for (int length = 0; length < 100; length++) {
- v8::HandleScope scope(CcTest::isolate());
- char* non_one_byte = NewArray<char>(3 * length + 1);
- char* one_byte = NewArray<char>(length + 1);
- non_one_byte[3 * length] = 0;
- one_byte[length] = 0;
- for (int i = 0; i < length; i++) {
- one_byte[i] = 'a';
- non_one_byte[3 * i] = chars[0];
- non_one_byte[3 * i + 1] = chars[1];
- non_one_byte[3 * i + 2] = chars[2];
- }
- DirectHandle<String> non_one_byte_sym = factory->InternalizeUtf8String(
- base::Vector<const char>(non_one_byte, 3 * length));
- CHECK_EQ(length, non_one_byte_sym->length());
- DirectHandle<String> one_byte_sym =
- factory->InternalizeString(base::OneByteVector(one_byte, length));
- CHECK_EQ(length, one_byte_sym->length());
- CHECK(one_byte_sym->HasHashCode());
- DirectHandle<String> non_one_byte_str =
- factory
- ->NewStringFromUtf8(
- base::Vector<const char>(non_one_byte, 3 * length))
- .ToHandleChecked();
- CHECK_EQ(length, non_one_byte_str->length());
- DirectHandle<String> one_byte_str =
- factory->NewStringFromUtf8(base::Vector<const char>(one_byte, length))
- .ToHandleChecked();
- CHECK_EQ(length, one_byte_str->length());
- DeleteArray(non_one_byte);
- DeleteArray(one_byte);
- }
-}
-
-static int ObjectsFoundInHeap(Heap* heap, Handle<Object> objs[], int size) {
- // Count the number of objects found in the heap.
- int found_count = 0;
- HeapObjectIterator iterator(heap);
- for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
- obj = iterator.Next()) {
- for (int i = 0; i < size; i++) {
- // V8_EXTERNAL_CODE_SPACE specific: we might be comparing
- // InstructionStream object with non-InstructionStream object here and it
- // might produce false positives because operator== for tagged values
- // compares only lower 32 bits when pointer compression is enabled.
- if ((*objs[i]).ptr() == obj.ptr()) {
- found_count++;
- }
- }
- }
- return found_count;
-}
-
-TEST(Iteration) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- v8::HandleScope scope(CcTest::isolate());
-
- // Array of objects to scan heap for.
- const int objs_count = 6;
- Handle<Object> objs[objs_count];
- int next_objs_index = 0;
-
- // Allocate a JS array to OLD_SPACE and NEW_SPACE
- objs[next_objs_index++] = factory->NewJSArray(10);
- objs[next_objs_index++] =
- factory->NewJSArray(10, HOLEY_ELEMENTS, AllocationType::kOld);
-
- // Allocate a small string to OLD_DATA_SPACE and NEW_SPACE
- objs[next_objs_index++] = factory->NewStringFromStaticChars("abcdefghij");
- objs[next_objs_index++] =
- factory->NewStringFromStaticChars("abcdefghij", AllocationType::kOld);
-
- // Allocate a large string (for large object space).
- int large_size = kMaxRegularHeapObjectSize + 1;
- char* str = new char[large_size];
- for (int i = 0; i < large_size - 1; ++i) str[i] = 'a';
- str[large_size - 1] = '\0';
- objs[next_objs_index++] =
- factory->NewStringFromAsciiChecked(str, AllocationType::kOld);
- delete[] str;
-
- // Add a Map object to look for.
- objs[next_objs_index++] =
- Handle<Map>(Cast<HeapObject>(*objs[0])->map(), isolate);
-
- CHECK_EQ(objs_count, next_objs_index);
- CHECK_EQ(objs_count, ObjectsFoundInHeap(CcTest::heap(), objs, objs_count));
-}
-
-TEST(TestBytecodeFlushing) {
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- v8_flags.turbofan = false;
- i::v8_flags.optimize_for_size = false;
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
-#ifdef V8_ENABLE_SPARKPLUG
- v8_flags.always_sparkplug = false;
-#endif // V8_ENABLE_SPARKPLUG
- i::v8_flags.flush_bytecode = true;
- i::v8_flags.allow_natives_syntax = true;
-
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- Isolate* i_isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = i_isolate->factory();
-
- {
- v8::HandleScope scope(isolate);
- v8::Context::New(isolate)->Enter();
- const char* source =
- "function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "};"
- "foo()";
- IndirectHandle<String> foo_name = factory->InternalizeUtf8String("foo");
-
- // This compile will add the code to the compilation cache.
- {
- v8::HandleScope new_scope(isolate);
- CompileRun(source);
- }
-
- // Check function is compiled.
- IndirectHandle<Object> func_value =
- Object::GetProperty(i_isolate, i_isolate->global_object(), foo_name)
- .ToHandleChecked();
- CHECK(IsJSFunction(*func_value));
- IndirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
- CHECK(function->shared()->is_compiled());
-
- // The code will survive at least two GCs.
- {
- // In this test, we need to invoke GC without stack, otherwise some
- // objects may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(function->shared()->is_compiled());
-
- i::SharedFunctionInfo::EnsureOldForTesting(function->shared());
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // foo should no longer be in the compilation cache
- CHECK(!function->shared()->is_compiled());
- CHECK(!function->is_compiled(i_isolate));
- // Call foo to get it recompiled.
- CompileRun("foo()");
- CHECK(function->shared()->is_compiled());
- CHECK(function->is_compiled(i_isolate));
- }
-}
-
-static void TestMultiReferencedBytecodeFlushing(bool sparkplug_compile) {
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- v8_flags.turbofan = false;
- i::v8_flags.optimize_for_size = false;
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
-#ifdef V8_ENABLE_SPARKPLUG
- v8_flags.always_sparkplug = false;
- v8_flags.flush_baseline_code = true;
-#else
- if (sparkplug_compile) return;
-#endif // V8_ENABLE_SPARKPLUG
- i::v8_flags.flush_bytecode = true;
- i::v8_flags.allow_natives_syntax = true;
-
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- Isolate* i_isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = i_isolate->factory();
-
- {
- v8::HandleScope scope(isolate);
- v8::Context::New(isolate)->Enter();
- const char* source =
- "function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "};"
- "foo()";
- IndirectHandle<String> foo_name = factory->InternalizeUtf8String("foo");
-
- // This compile will add the code to the compilation cache.
- {
- v8::HandleScope new_scope(isolate);
- CompileRun(source);
- }
-
- // Check function is compiled.
- IndirectHandle<Object> func_value =
- Object::GetProperty(i_isolate, i_isolate->global_object(), foo_name)
- .ToHandleChecked();
- CHECK(IsJSFunction(*func_value));
- IndirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
- IndirectHandle<SharedFunctionInfo> shared(function->shared(), i_isolate);
- CHECK(shared->is_compiled());
-
- // Make a copy of the SharedFunctionInfo which points to the same bytecode.
- IndirectHandle<SharedFunctionInfo> copy =
- i_isolate->factory()->CloneSharedFunctionInfo(shared);
-
- if (sparkplug_compile) {
- v8::HandleScope baseline_compilation_scope(isolate);
- IsCompiledScope is_compiled_scope = copy->is_compiled_scope(i_isolate);
- Compiler::CompileSharedWithBaseline(
- i_isolate, copy, Compiler::CLEAR_EXCEPTION, &is_compiled_scope);
- }
-
- i::SharedFunctionInfo::EnsureOldForTesting(*shared);
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // shared SFI is marked old but BytecodeArray is kept alive by copy.
- CHECK(shared->is_compiled());
- CHECK(copy->is_compiled());
- CHECK(function->is_compiled(i_isolate));
-
- // The feedback metadata for both SharedFunctionInfo instances should have
- // been reset.
- CHECK(shared->HasFeedbackMetadata());
- CHECK(copy->HasFeedbackMetadata());
- }
-}
-
-TEST(TestMultiReferencedBytecodeFlushing) {
- TestMultiReferencedBytecodeFlushing(/*sparkplug_compile=*/false);
-}
-
-TEST(TestMultiReferencedBytecodeFlushingWithSparkplug) {
- TestMultiReferencedBytecodeFlushing(/*sparkplug_compile=*/true);
-}
-
-TEST(TestMultiReferencedBytecodeFlushingBothOld) {
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- v8_flags.turbofan = false;
- i::v8_flags.optimize_for_size = false;
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
-#ifdef V8_ENABLE_SPARKPLUG
- v8_flags.always_sparkplug = false;
- v8_flags.flush_baseline_code = true;
-#endif // V8_ENABLE_SPARKPLUG
- i::v8_flags.flush_bytecode = true;
- i::v8_flags.allow_natives_syntax = true;
-
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- Isolate* i_isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = i_isolate->factory();
-
- {
- v8::HandleScope scope(isolate);
- v8::Context::New(isolate)->Enter();
- const char* source =
- "function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "};"
- "foo()";
- IndirectHandle<String> foo_name = factory->InternalizeUtf8String("foo");
-
- // This compile will add the code to the compilation cache.
- {
- v8::HandleScope new_scope(isolate);
- CompileRun(source);
- }
-
- // Check function is compiled.
- IndirectHandle<Object> func_value =
- Object::GetProperty(i_isolate, i_isolate->global_object(), foo_name)
- .ToHandleChecked();
- CHECK(IsJSFunction(*func_value));
- IndirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
- IndirectHandle<SharedFunctionInfo> shared(function->shared(), i_isolate);
- CHECK(shared->is_compiled());
-
- // Make a copy of the SharedFunctionInfo which points to the same bytecode.
- IndirectHandle<SharedFunctionInfo> copy =
- i_isolate->factory()->CloneSharedFunctionInfo(shared);
-
- // Verify that both SFIs share the same BytecodeArray.
- CHECK_EQ(shared->GetBytecodeArray(i_isolate),
- copy->GetBytecodeArray(i_isolate));
-
- i::SharedFunctionInfo::EnsureOldForTesting(*shared);
- i::SharedFunctionInfo::EnsureOldForTesting(*copy);
-
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // Both should be decompiled (flushed) because both were old.
- CHECK(!shared->is_compiled());
- CHECK(!copy->is_compiled());
- }
-}
-
-HEAP_TEST(Regress10560) {
- i::v8_flags.flush_bytecode = true;
- i::v8_flags.allow_natives_syntax = true;
- // Disable flags that allocate a feedback vector eagerly.
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- i::v8_flags.turbofan = false;
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
-#ifdef V8_ENABLE_SPARKPLUG
- v8_flags.always_sparkplug = false;
-#endif // V8_ENABLE_SPARKPLUG
- i::v8_flags.lazy_feedback_allocation = true;
-
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- Isolate* i_isolate = CcTest::i_isolate();
- Factory* factory = i_isolate->factory();
- Heap* heap = i_isolate->heap();
-
- {
- v8::HandleScope scope(isolate);
- const char* source =
- "function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "};"
- "foo()";
- DirectHandle<String> foo_name = factory->InternalizeUtf8String("foo");
- CompileRun(source);
-
- // Check function is compiled.
- DirectHandle<Object> func_value =
- Object::GetProperty(i_isolate, i_isolate->global_object(), foo_name)
- .ToHandleChecked();
- CHECK(IsJSFunction(*func_value));
- DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
- CHECK(function->shared()->is_compiled());
- CHECK(!function->has_feedback_vector());
-
- // Pre-age bytecode so it will be flushed on next run.
- CHECK(function->shared()->HasBytecodeArray());
- SharedFunctionInfo::EnsureOldForTesting(function->shared());
-
- heap::SimulateFullSpace(heap->old_space());
-
- // Just check bytecode isn't flushed still
- CHECK(function->shared()->is_compiled());
-
- heap->set_force_gc_on_next_allocation(true);
-
- // Allocate feedback vector.
- IsCompiledScope is_compiled_scope(
- function->shared()->is_compiled_scope(i_isolate));
- JSFunction::EnsureFeedbackVector(i_isolate, function, &is_compiled_scope);
-
- CHECK(function->has_feedback_vector());
- CHECK(function->shared()->is_compiled());
- CHECK(function->is_compiled(i_isolate));
- }
-}
-
-UNINITIALIZED_TEST(Regress10843) {
- v8_flags.max_semi_space_size = 2;
- v8_flags.min_semi_space_size = 2;
- v8_flags.max_old_space_size = 8;
- v8_flags.compact_on_every_full_gc = true;
- v8::Isolate::CreateParams create_params;
- create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- v8::Isolate* isolate = v8::Isolate::New(create_params);
- Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
- Factory* factory = i_isolate->factory();
- Heap* heap = i_isolate->heap();
- bool callback_was_invoked = false;
-
- heap->AddNearHeapLimitCallback(
- [](void* data, size_t current_heap_limit,
- size_t initial_heap_limit) -> size_t {
- *reinterpret_cast<bool*>(data) = true;
- return current_heap_limit * 2;
- },
- &callback_was_invoked);
-
- {
- v8::Isolate::Scope isolate_scope(isolate);
- PtrComprCageAccessScope ptr_compr_cage_access_scope(i_isolate);
- HandleScope scope(i_isolate);
- std::vector<Handle<FixedArray>> arrays;
- for (int i = 0; i < 140; i++) {
- arrays.push_back(factory->NewFixedArray(10000));
- }
- heap::InvokeMajorGC(heap);
- heap::InvokeMajorGC(heap);
- for (int i = 0; i < 40; i++) {
- arrays.push_back(factory->NewFixedArray(10000));
- }
- heap::InvokeMajorGC(heap);
- for (int i = 0; i < 100; i++) {
- arrays.push_back(factory->NewFixedArray(10000));
- }
- heap::InvokeMajorGC(heap);
- CHECK(callback_was_invoked);
- }
- isolate->Dispose();
-}
-
-size_t near_heap_limit_invocation_count = 0;
-size_t InvokeGCNearHeapLimitCallback(void* data, size_t current_heap_limit,
- size_t initial_heap_limit) {
- near_heap_limit_invocation_count++;
- if (near_heap_limit_invocation_count > 1) {
- // We are already in a GC triggered in this callback, raise the limit
- // to avoid an OOM.
- return current_heap_limit * 5;
- }
-
- DCHECK_EQ(near_heap_limit_invocation_count, 1);
- // Operations that may cause GC (e.g. taking heap snapshots) in the
- // near heap limit callback should not hit the AllowGarbageCollection
- // assertion.
- static_cast<v8::Isolate*>(data)->GetHeapProfiler()->TakeHeapSnapshot();
- return current_heap_limit * 5;
-}
-
-UNINITIALIZED_TEST(Regress12777) {
- v8::Isolate::CreateParams create_params;
- create_params.constraints.set_max_old_generation_size_in_bytes(10 * i::MB);
- create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- v8::Isolate* isolate = v8::Isolate::New(create_params);
-
- isolate->AddNearHeapLimitCallback(InvokeGCNearHeapLimitCallback, isolate);
-
- {
- v8::Isolate::Scope isolate_scope(isolate);
-
- Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
- // Allocate data to trigger the NearHeapLimitCallback.
- HandleScope scope(i_isolate);
- int length = 2 * i::MB / i::kTaggedSize;
- std::vector<Handle<FixedArray>> arrays;
- for (int i = 0; i < 5; i++) {
- arrays.push_back(i_isolate->factory()->NewFixedArray(length));
- }
- heap::InvokeMajorGC(i_isolate->heap());
- for (int i = 0; i < 5; i++) {
- arrays.push_back(i_isolate->factory()->NewFixedArray(length));
- }
- heap::InvokeMajorGC(i_isolate->heap());
- for (int i = 0; i < 5; i++) {
- arrays.push_back(i_isolate->factory()->NewFixedArray(length));
- }
-
- // Normally, taking a heap snapshot in the near heap limit would result in
- // a full GC, then the overhead of the promotions would cause another
- // invocation of the heap limit callback and it can raise the limit in
- // the second call to avoid an OOM, so we test that the callback can
- // indeed raise the limit this way in this case. When there is only one
- // generation, however, there would not be the overhead of promotions so the
- // callback may not be triggered again during the generation of the heap
- // snapshot. In that case we only need to check that the callback is called
- // and it can perform GC-triggering operations just fine there.
- size_t minimum_callback_invocation_count =
- v8_flags.single_generation ? 1 : 2;
- CHECK_GE(near_heap_limit_invocation_count,
- minimum_callback_invocation_count);
- }
-
- isolate->GetHeapProfiler()->DeleteAllHeapSnapshots();
- isolate->Dispose();
-}
-
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
-TEST(TestOptimizeAfterBytecodeFlushingCandidate) {
- if (v8_flags.single_generation) return;
- v8_flags.turbofan = true;
-#ifdef V8_ENABLE_SPARKPLUG
- v8_flags.always_sparkplug = false;
-#endif // V8_ENABLE_SPARKPLUG
- i::v8_flags.optimize_for_size = false;
- i::v8_flags.incremental_marking = true;
- i::v8_flags.flush_bytecode = true;
- i::v8_flags.allow_natives_syntax = true;
- ManualGCScope manual_gc_scope;
-
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = isolate->factory();
-
- v8::HandleScope outer_scope(CcTest::isolate());
- const char* source =
- "function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "};"
- "foo()";
- IndirectHandle<String> foo_name = factory->InternalizeUtf8String("foo");
-
- // This compile will add the code to the compilation cache.
- {
- v8::HandleScope scope(CcTest::isolate());
- CompileRun(source);
- }
-
- // Check function is compiled.
- IndirectHandle<Object> func_value =
- Object::GetProperty(isolate, isolate->global_object(), foo_name)
- .ToHandleChecked();
- CHECK(IsJSFunction(*func_value));
- IndirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
- CHECK(function->shared()->is_compiled());
-
- // The code will survive at least two GCs.
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(function->shared()->is_compiled());
-
- i::SharedFunctionInfo::EnsureOldForTesting(function->shared());
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- CHECK(!function->shared()->is_compiled());
- CHECK(!function->is_compiled(isolate));
-
- // This compile will compile the function again.
- {
- v8::HandleScope scope(CcTest::isolate());
- CompileRun("foo();");
- }
-
- SharedFunctionInfo::EnsureOldForTesting(function->shared());
- heap::SimulateIncrementalMarking(CcTest::heap());
-
- // Force optimization while incremental marking is active and while
- // the function is enqueued as a candidate.
- {
- v8::HandleScope scope(CcTest::isolate());
- CompileRun(
- "%PrepareFunctionForOptimization(foo); foo();"
- "%OptimizeFunctionOnNextCall(foo); foo();");
- }
-
- // Simulate one final GC and make sure the candidate wasn't flushed.
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(function->shared()->is_compiled());
- CHECK(function->is_compiled(isolate));
-}
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
-
-void CompilationCacheCachingBehavior(bool retain_script) {
- // If we do not have the compilation cache turned off, this test is invalid.
- if (!v8_flags.compilation_cache) {
- return;
- }
- if (!v8_flags.flush_bytecode ||
- (v8_flags.always_sparkplug && !v8_flags.flush_baseline_code)) {
- return;
- }
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- Factory* factory = isolate->factory();
- CompilationCache* compilation_cache = isolate->compilation_cache();
- LanguageMode language_mode = LanguageMode::kSloppy;
-
- v8::HandleScope outer_scope(CcTest::isolate());
- const char* raw_source = retain_script ? "function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "};"
- "foo();"
- : "(function foo() {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- "})();";
- IndirectHandle<String> source = factory->InternalizeUtf8String(raw_source);
-
- {
- v8::HandleScope scope(CcTest::isolate());
- CompileRun(raw_source);
- }
-
- // The script should be in the cache now.
- {
- v8::HandleScope scope(CcTest::isolate());
- ScriptDetails script_details(Handle<Object>(),
- v8::ScriptOriginOptions(true, false));
- auto lookup_result =
- compilation_cache->LookupScript(source, script_details, language_mode);
- CHECK(!lookup_result.toplevel_sfi().is_null());
- }
-
- // Check that the code cache entry survives at least one GC.
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- {
- v8::HandleScope scope(CcTest::isolate());
- ScriptDetails script_details(Handle<Object>(),
- v8::ScriptOriginOptions(true, false));
- auto lookup_result =
- compilation_cache->LookupScript(source, script_details, language_mode);
- CHECK(!lookup_result.toplevel_sfi().is_null());
-
- // Progress code age until it's old and ready for GC.
- DirectHandle<SharedFunctionInfo> shared =
- lookup_result.toplevel_sfi().ToHandleChecked();
- CHECK(shared->HasBytecodeArray());
- SharedFunctionInfo::EnsureOldForTesting(*shared);
- }
-
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- // The first GC flushes the BytecodeArray from the SFI.
- heap::InvokeMajorGC(heap);
- // The second GC removes the SFI from the compilation cache.
- heap::InvokeMajorGC(heap);
- }
-
- {
- v8::HandleScope scope(CcTest::isolate());
- // Ensure code aging cleared the entry from the cache.
- ScriptDetails script_details(Handle<Object>(),
- v8::ScriptOriginOptions(true, false));
- auto lookup_result =
- compilation_cache->LookupScript(source, script_details, language_mode);
- CHECK(lookup_result.toplevel_sfi().is_null());
- CHECK_EQ(retain_script, !lookup_result.script().is_null());
- }
-}
-
-TEST(CompilationCacheCachingBehaviorDiscardScript) {
- CompilationCacheCachingBehavior(false);
-}
-
-TEST(CompilationCacheCachingBehaviorRetainScript) {
- CompilationCacheCachingBehavior(true);
-}
-
-namespace {
-
-template <typename T>
-DirectHandle<SharedFunctionInfo> GetSharedFunctionInfo(
- v8::Local<T> function_or_script) {
- DirectHandle<JSFunction> i_function =
- Cast<JSFunction>(v8::Utils::OpenDirectHandle(*function_or_script));
- return direct_handle(i_function->shared(), CcTest::i_isolate());
-}
-
-template <typename T>
-void AgeBytecode(v8::Local<T> function_or_script) {
- DirectHandle<SharedFunctionInfo> shared =
- GetSharedFunctionInfo(function_or_script);
- CHECK(shared->HasBytecodeArray());
- SharedFunctionInfo::EnsureOldForTesting(*shared);
-}
-
-void CompilationCacheRegeneration(bool retain_root_sfi, bool flush_root_sfi,
- bool flush_eager_sfi) {
- // If the compilation cache is turned off, this test is invalid.
- if (!v8_flags.compilation_cache) {
- return;
- }
-
- // Skip test if code flushing was disabled.
- if (!v8_flags.flush_bytecode ||
- (v8_flags.always_sparkplug && !v8_flags.flush_baseline_code)) {
- return;
- }
-
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
-
- const char* source =
- "({"
- " lazyFunction: function () {"
- " var x = 42;"
- " var y = 42;"
- " var z = x + y;"
- " },"
- " eagerFunction: (function () {"
- " var x = 43;"
- " var y = 43;"
- " var z = x + y;"
- " })"
- "})";
-
- v8::Global<v8::Script> outer_function;
- v8::Global<v8::Function> lazy_function;
- v8::Global<v8::Function> eager_function;
-
- {
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> context =
- v8::Isolate::GetCurrent()->GetCurrentContext();
- v8::Local<v8::Script> script = v8_compile(v8_str(source));
- outer_function.Reset(CcTest::isolate(), script);
-
- // Even though the script has not executed, it should already be parsed.
- DirectHandle<SharedFunctionInfo> script_sfi = GetSharedFunctionInfo(script);
- CHECK(script_sfi->is_compiled());
-
- v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
-
- // Now that the script has run, we can get references to the inner
- // functions, and verify that the eager parsing heuristics are behaving as
- // expected.
- v8::Local<v8::Object> result_obj =
- result->ToObject(context).ToLocalChecked();
- v8::Local<v8::Value> lazy_function_value =
- result_obj->GetRealNamedProperty(context, v8_str("lazyFunction"))
- .ToLocalChecked();
- CHECK(lazy_function_value->IsFunction());
- CHECK(!GetSharedFunctionInfo(lazy_function_value)->is_compiled());
- lazy_function.Reset(CcTest::isolate(),
- lazy_function_value.As<v8::Function>());
- v8::Local<v8::Value> eager_function_value =
- result_obj->GetRealNamedProperty(context, v8_str("eagerFunction"))
- .ToLocalChecked();
- CHECK(eager_function_value->IsFunction());
- eager_function.Reset(CcTest::isolate(),
- eager_function_value.As<v8::Function>());
- CHECK(GetSharedFunctionInfo(eager_function_value)->is_compiled());
- }
-
- {
- v8::HandleScope scope(CcTest::isolate());
-
- // Progress code age until it's old and ready for GC.
- if (flush_root_sfi) {
- v8::Local<v8::Script> outer_function_value =
- outer_function.Get(CcTest::isolate());
- AgeBytecode(outer_function_value);
- }
- if (flush_eager_sfi) {
- v8::Local<v8::Function> eager_function_value =
- eager_function.Get(CcTest::isolate());
- AgeBytecode(eager_function_value);
- }
- if (!retain_root_sfi) {
- outer_function.Reset();
- }
- }
-
- {
- // In these tests, we need to invoke GC without stack, otherwise some
- // objects may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
-
- if (v8_flags.stress_incremental_marking) {
- // This GC finishes incremental marking if it is already running. If
- // incremental marking was already running we would not flush the code
- // right away.
- heap::InvokeMajorGC(heap);
- }
-
- // The first GC performs code flushing.
- heap::InvokeMajorGC(heap);
- // The second GC clears the entry from the compilation cache.
- heap::InvokeMajorGC(heap);
- }
-
- // The root SharedFunctionInfo can be retained either by a Global in this
- // function or by the compilation cache.
- bool root_sfi_should_still_exist = retain_root_sfi || !flush_root_sfi;
-
- {
- v8::HandleScope scope(CcTest::isolate());
-
- // The lazy function should still not be compiled.
- DirectHandle<SharedFunctionInfo> lazy_sfi =
- GetSharedFunctionInfo(lazy_function.Get(CcTest::isolate()));
- CHECK(!lazy_sfi->is_compiled());
-
- // The eager function may have had its bytecode flushed.
- DirectHandle<SharedFunctionInfo> eager_sfi =
- GetSharedFunctionInfo(eager_function.Get(CcTest::isolate()));
- CHECK_EQ(!flush_eager_sfi, eager_sfi->is_compiled());
-
- // Check whether the root SharedFunctionInfo is still reachable from the
- // Script.
- DirectHandle<Script> script(Cast<Script>(lazy_sfi->script()), isolate);
- bool root_sfi_still_exists = false;
- Tagged<MaybeObject> maybe_root_sfi =
- script->infos()->get(kFunctionLiteralIdTopLevel);
- if (Tagged<HeapObject> sfi_or_undefined;
- maybe_root_sfi.GetHeapObject(&sfi_or_undefined)) {
- root_sfi_still_exists = !IsUndefined(sfi_or_undefined);
- }
- CHECK_EQ(root_sfi_should_still_exist, root_sfi_still_exists);
- }
-
- {
- // Run the script again and check that no SharedFunctionInfos were
- // duplicated, and that the expected ones were compiled.
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> context =
- v8::Isolate::GetCurrent()->GetCurrentContext();
- v8::Local<v8::Script> script = v8_compile(v8_str(source));
-
- // The script should be compiled by now.
- DirectHandle<SharedFunctionInfo> script_sfi = GetSharedFunctionInfo(script);
- CHECK(script_sfi->is_compiled());
-
- // This compilation should not have created a new root SharedFunctionInfo if
- // one already existed.
- if (retain_root_sfi) {
- DirectHandle<SharedFunctionInfo> old_script_sfi =
- GetSharedFunctionInfo(outer_function.Get(CcTest::isolate()));
- CHECK_EQ(*old_script_sfi, *script_sfi);
- }
-
- DirectHandle<SharedFunctionInfo> old_lazy_sfi =
- GetSharedFunctionInfo(lazy_function.Get(CcTest::isolate()));
- CHECK(!old_lazy_sfi->is_compiled());
-
- // The only way for the eager function to be uncompiled at this point is if
- // it was flushed but the root function was not.
- DirectHandle<SharedFunctionInfo> old_eager_sfi =
- GetSharedFunctionInfo(eager_function.Get(CcTest::isolate()));
- CHECK_EQ(!(flush_eager_sfi && !flush_root_sfi),
- old_eager_sfi->is_compiled());
-
- v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
-
- // Check that both functions reused the existing SharedFunctionInfos.
- v8::Local<v8::Object> result_obj =
- result->ToObject(context).ToLocalChecked();
- v8::Local<v8::Value> lazy_function_value =
- result_obj->GetRealNamedProperty(context, v8_str("lazyFunction"))
- .ToLocalChecked();
- CHECK(lazy_function_value->IsFunction());
- DirectHandle<SharedFunctionInfo> lazy_sfi =
- GetSharedFunctionInfo(lazy_function_value);
- CHECK_EQ(*old_lazy_sfi, *lazy_sfi);
- v8::Local<v8::Value> eager_function_value =
- result_obj->GetRealNamedProperty(context, v8_str("eagerFunction"))
- .ToLocalChecked();
- CHECK(eager_function_value->IsFunction());
- DirectHandle<SharedFunctionInfo> eager_sfi =
- GetSharedFunctionInfo(eager_function_value);
- CHECK_EQ(*old_eager_sfi, *eager_sfi);
- }
-}
-
-} // namespace
-
-TEST(CompilationCacheRegeneration0) {
- CompilationCacheRegeneration(false, false, false);
-}
-TEST(CompilationCacheRegeneration1) {
- CompilationCacheRegeneration(false, false, true);
-}
-TEST(CompilationCacheRegeneration2) {
- CompilationCacheRegeneration(false, true, false);
-}
-TEST(CompilationCacheRegeneration3) {
- CompilationCacheRegeneration(false, true, true);
-}
-TEST(CompilationCacheRegeneration4) {
- CompilationCacheRegeneration(true, false, false);
-}
-TEST(CompilationCacheRegeneration5) {
- CompilationCacheRegeneration(true, false, true);
-}
-TEST(CompilationCacheRegeneration6) {
- CompilationCacheRegeneration(true, true, false);
-}
-TEST(CompilationCacheRegeneration7) {
- CompilationCacheRegeneration(true, true, true);
-}
-
-static void OptimizeEmptyFunction(const char* name) {
- HandleScope scope(CcTest::i_isolate());
- base::EmbeddedVector<char, 256> source;
- base::SNPrintF(source,
- "function %s() { return 0; }"
- "%%PrepareFunctionForOptimization(%s);"
- "%s(); %s();"
- "%%OptimizeFunctionOnNextCall(%s);"
- "%s();",
- name, name, name, name, name, name);
- CompileRun(source.begin());
-}
-
-// Count the number of native contexts in the weak list of native contexts.
-int CountNativeContexts() {
- int count = 0;
- Tagged<Object> object = CcTest::heap()->native_contexts_list();
- while (!IsUndefined(object)) {
- count++;
- object = Cast<Context>(object)->next_context_link();
- }
- return count;
-}
-
-TEST(TestInternalWeakLists) {
- v8_flags.allow_natives_syntax = true;
-
- // Some flags turn Scavenge collections into Mark-sweep collections
- // and hence are incompatible with this test case.
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation) {
- return;
- }
- v8_flags.retain_maps_for_n_gc = 0;
-
- static const int kNumTestContexts = 10;
-
- ManualGCScope manual_gc_scope;
- v8::Isolate* v8_isolate = CcTest::isolate();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- HandleScope scope(isolate);
- v8::Global<v8::Context> ctx[kNumTestContexts];
- if (!isolate->use_optimizer()) return;
-
- CHECK_EQ(0, CountNativeContexts());
-
- // Create a number of global contests which gets linked together.
- for (int i = 0; i < kNumTestContexts; i++) {
- // Create a handle scope so no contexts or function objects get stuck in the
- // outer handle scope.
- HandleScope new_scope(isolate);
-
- ctx[i].Reset(v8_isolate, v8::Context::New(v8_isolate));
-
- // Collect garbage that might have been created by one of the
- // installed extensions.
- isolate->compilation_cache()->Clear();
- {
- // In this test, we need to invoke GC without stack, otherwise some
- // objects may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- CHECK_EQ(i + 1, CountNativeContexts());
-
- ctx[i].Get(v8_isolate)->Enter();
-
- OptimizeEmptyFunction("f1");
- OptimizeEmptyFunction("f2");
- OptimizeEmptyFunction("f3");
- OptimizeEmptyFunction("f4");
- OptimizeEmptyFunction("f5");
-
- // Remove function f1, and
- CompileRun("f1=null");
-
- // Scavenge treats these references as strong.
- for (int j = 0; j < 10; j++) {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMinorGC(heap);
- }
-
- // Mark compact handles the weak references.
- isolate->compilation_cache()->Clear();
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // Get rid of f3 and f5 in the same way.
- CompileRun("f3=null");
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- for (int j = 0; j < 10; j++) {
- heap::InvokeMinorGC(heap);
- }
- heap::InvokeMajorGC(heap);
- }
- CompileRun("f5=null");
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- for (int j = 0; j < 10; j++) {
- heap::InvokeMinorGC(heap);
- }
- heap::InvokeMajorGC(heap);
- }
- ctx[i].Get(v8_isolate)->Exit();
- }
-
- // Force compilation cache cleanup.
- heap->NotifyContextDisposed(true);
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // Dispose the native contexts one by one.
- for (int i = 0; i < kNumTestContexts; i++) {
- ctx[i].Reset();
-
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
-
- // Scavenge treats these references as strong.
- for (int j = 0; j < 10; j++) {
- heap::InvokeMinorGC(heap);
- CHECK_EQ(kNumTestContexts - i, CountNativeContexts());
- }
- // Mark-compact handles the weak references.
- heap::InvokeMajorGC(heap);
-
- CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts());
- }
-
- CHECK_EQ(0, CountNativeContexts());
-}
-
-TEST(TestSizeOfRegExpCode) {
- if (!v8_flags.regexp_optimization) return;
- v8_flags.stress_concurrent_allocation = false;
-
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- HandleScope scope(isolate);
-
- LocalContext context;
-
- CHECK_EQ(i::RegExp::kMaxOptimizedPatternLength, 20 * KB);
-
- // Compile a regexp that is much larger if we are using regexp optimizations.
- CompileRun(
- "var reg_exp_source = '(?:a|bc|def|ghij|klmno|pqrstu)';"
- "var half_size_reg_exp;"
- "while (reg_exp_source.length < 20 * 1024) {"
- " half_size_reg_exp = reg_exp_source;"
- " reg_exp_source = reg_exp_source + reg_exp_source;"
- "}"
- // Flatten string.
- "reg_exp_source.match(/f/);");
-
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- // Get initial heap size after several full GCs, which will stabilize
- // the heap size and return with sweeping finished completely.
- heap::InvokeMemoryReducingMajorGCs(heap);
- if (heap->sweeping_in_progress()) {
- heap->EnsureSweepingCompleted(
- Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
- }
- int initial_size = static_cast<int>(heap->SizeOfObjects());
-
- CompileRun("'foo'.match(reg_exp_source);");
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- int size_with_regexp = static_cast<int>(heap->SizeOfObjects());
-
- CompileRun("'foo'.match(half_size_reg_exp);");
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- int size_with_optimized_regexp = static_cast<int>(heap->SizeOfObjects());
-
- int size_of_regexp_code = size_with_regexp - initial_size;
-
- // On some platforms the debug-code flag causes huge amounts of regexp code
- // to be emitted, breaking this test.
- if (!v8_flags.debug_code) {
- CHECK_LE(size_of_regexp_code, 1 * MB);
- }
-
- // Small regexp is half the size, but compiles to more than twice the code
- // due to the optimization steps.
- CHECK_GE(size_with_optimized_regexp,
- size_with_regexp + size_of_regexp_code * 2);
-}
-
-HEAP_TEST(TestSizeOfObjects) {
- v8_flags.stress_concurrent_allocation = false;
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
-
- // Disable LAB, such that calculations with SizeOfObjects() and object size
- // are correct.
- heap->DisableInlineAllocation();
-
- // Get initial heap size after several full GCs, which will stabilize
- // the heap size and return with sweeping finished completely.
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- if (heap->sweeping_in_progress()) {
- heap->EnsureSweepingCompleted(
- Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
- }
- int initial_size = static_cast<int>(heap->SizeOfObjects());
-
- {
- HandleScope scope(isolate);
- // Allocate objects on several different old-space pages so that
- // concurrent sweeper threads will be busy sweeping the old space on
- // subsequent GC runs.
- AlwaysAllocateScopeForTesting always_allocate(heap);
- int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
- for (int i = 1; i <= 100; i++) {
- isolate->factory()->NewFixedArray(8192, AllocationType::kOld);
- CHECK_EQ(initial_size + i * filler_size,
- static_cast<int>(heap->SizeOfObjects()));
- }
- }
-
- // The heap size should go back to initial size after a full GC, even
- // though sweeping didn't finish yet.
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- // Normally sweeping would not be complete here, but no guarantees.
- CHECK_EQ(initial_size, static_cast<int>(heap->SizeOfObjects()));
- // Waiting for sweeper threads should not change heap size.
- if (heap->sweeping_in_progress()) {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
- CHECK_EQ(initial_size, static_cast<int>(heap->SizeOfObjects()));
-}
-
-TEST(TestAlignmentCalculations) {
- // Maximum fill amounts are consistent.
- int maximum_double_misalignment = kDoubleSize - kTaggedSize;
- int max_word_fill = MainAllocator::GetMaximumFillToAlign(kTaggedAligned);
- CHECK_EQ(0, max_word_fill);
- int max_double_fill = MainAllocator::GetMaximumFillToAlign(kDoubleAligned);
- CHECK_EQ(maximum_double_misalignment, max_double_fill);
- int max_double_unaligned_fill =
- MainAllocator::GetMaximumFillToAlign(kDoubleUnaligned);
- CHECK_EQ(maximum_double_misalignment, max_double_unaligned_fill);
-
- Address base = kNullAddress;
- int fill = 0;
-
- // Word alignment never requires fill.
- fill = MainAllocator::GetFillToAlign(base, kTaggedAligned);
- CHECK_EQ(0, fill);
- fill = MainAllocator::GetFillToAlign(base + kTaggedSize, kTaggedAligned);
- CHECK_EQ(0, fill);
-
- // No fill is required when address is double aligned.
- fill = MainAllocator::GetFillToAlign(base, kDoubleAligned);
- CHECK_EQ(0, fill);
- // Fill is required if address is not double aligned.
- fill = MainAllocator::GetFillToAlign(base + kTaggedSize, kDoubleAligned);
- CHECK_EQ(maximum_double_misalignment, fill);
- // kDoubleUnaligned has the opposite fill amounts.
- fill = MainAllocator::GetFillToAlign(base, kDoubleUnaligned);
- CHECK_EQ(maximum_double_misalignment, fill);
- fill = MainAllocator::GetFillToAlign(base + kTaggedSize, kDoubleUnaligned);
- CHECK_EQ(0, fill);
-}
-
-static Tagged<HeapObject> AllocateAligned(MainAllocator* allocator, int size,
- AllocationAlignment alignment) {
- Heap* heap = CcTest::heap();
- AllocationResult allocation = allocator->AllocateRawForceAlignmentForTesting(
- size, alignment, AllocationOrigin::kRuntime);
- Tagged<HeapObject> obj;
- allocation.To(&obj);
- heap->CreateFillerObjectAt(obj.address(), size);
- return obj;
-}
-
-TEST(TestAlignedAllocation) {
- if (v8_flags.single_generation) return;
- // Double misalignment is 4 on 32-bit platforms or when pointer compression
- // is enabled, 0 on 64-bit ones when pointer compression is disabled.
- const intptr_t double_misalignment = kDoubleSize - kTaggedSize;
- Address start;
- Tagged<HeapObject> obj;
- Tagged<HeapObject> filler;
- if (double_misalignment) {
- MainAllocator* allocator =
- CcTest::heap()->allocator()->new_space_allocator();
-
- // Make one allocation to force allocating an allocation area. Using
- // kDoubleSize to not change space alignment
- USE(allocator->AllocateRaw(SafeHeapObjectSize(kDoubleSize), kDoubleAligned,
- AllocationOrigin::kRuntime, AllocationHint()));
-
- // Allocate a pointer sized object that must be double aligned at an
- // aligned address.
- start = allocator->AlignTopForTesting(kDoubleAligned, 0);
- obj = AllocateAligned(allocator, kTaggedSize, kDoubleAligned);
- CHECK(IsAligned(obj.address(), kDoubleAlignment));
- // There is no filler.
- CHECK_EQ(start, obj.address());
-
- // Allocate a second pointer sized object that must be double aligned at an
- // unaligned address.
- start = allocator->AlignTopForTesting(kDoubleAligned, kTaggedSize);
- obj = AllocateAligned(allocator, kTaggedSize, kDoubleAligned);
- CHECK(IsAligned(obj.address(), kDoubleAlignment));
- // There is a filler object before the object.
- filler = HeapObject::FromAddress(start);
- CHECK(obj != filler && IsFreeSpaceOrFiller(filler) &&
- filler->Size() == kTaggedSize);
- CHECK_EQ(start + double_misalignment, obj->address());
-
- // Similarly for kDoubleUnaligned.
- start = allocator->AlignTopForTesting(kDoubleUnaligned, 0);
- obj = AllocateAligned(allocator, kTaggedSize, kDoubleUnaligned);
- CHECK(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
- CHECK_EQ(start, obj->address());
-
- start = allocator->AlignTopForTesting(kDoubleUnaligned, kTaggedSize);
- obj = AllocateAligned(allocator, kTaggedSize, kDoubleUnaligned);
- CHECK(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
- // There is a filler object before the object.
- filler = HeapObject::FromAddress(start);
- CHECK(obj != filler && IsFreeSpaceOrFiller(filler) &&
- filler->Size() == kTaggedSize);
- CHECK_EQ(start + kTaggedSize, obj->address());
- }
-}
-
-static Tagged<HeapObject> OldSpaceAllocateAligned(
- int size, AllocationAlignment alignment) {
- Heap* heap = CcTest::heap();
- AllocationResult allocation =
- heap->allocator()
- ->old_space_allocator()
- ->AllocateRawForceAlignmentForTesting(size, alignment,
- AllocationOrigin::kRuntime);
- Tagged<HeapObject> obj;
- allocation.To(&obj);
- heap->CreateFillerObjectAt(obj.address(), size);
- return obj;
-}
-
-// Get old space allocation into the desired alignment.
-static Address AlignOldSpace(AllocationAlignment alignment, int offset) {
- LinearAllocationArea* old_space =
- &CcTest::i_isolate()->isolate_data()->old_allocation_info();
- int fill = MainAllocator::GetFillToAlign(old_space->top(), alignment);
- int allocation = fill + offset;
- if (allocation) {
- OldSpaceAllocateAligned(allocation, kTaggedAligned);
- }
- Address top = old_space->top();
- // Now force the remaining allocation onto the free list.
- CcTest::heap()->FreeMainThreadLinearAllocationAreas();
- return top;
-}
-
-// Test the case where allocation must be done from the free list, so filler
-// may precede or follow the object.
-TEST(TestAlignedOverAllocation) {
- if (v8_flags.stress_concurrent_allocation) return;
- ManualGCScope manual_gc_scope;
- Heap* heap = CcTest::heap();
- // Test checks for fillers before and behind objects and requires a fresh
- // page and empty free list.
- heap::AbandonCurrentlyFreeMemory(heap->old_space());
- // Allocate a dummy object to properly set up the linear allocation info.
- AllocationResult dummy =
- heap->allocator()->old_space_allocator()->AllocateRaw(
- SafeHeapObjectSize(kTaggedSize), kTaggedAligned,
- AllocationOrigin::kRuntime, AllocationHint());
- CHECK(!dummy.IsFailure());
- heap->CreateFillerObjectAt(dummy.ToObjectChecked().address(), kTaggedSize);
-
- // Double misalignment is 4 on 32-bit platforms or when pointer compression
- // is enabled, 0 on 64-bit ones when pointer compression is disabled.
- const intptr_t double_misalignment = kDoubleSize - kTaggedSize;
- Address start;
- Tagged<HeapObject> obj;
- Tagged<HeapObject> filler;
- if (double_misalignment) {
- start = AlignOldSpace(kDoubleAligned, 0);
- obj = OldSpaceAllocateAligned(kTaggedSize, kDoubleAligned);
- // The object is aligned.
- CHECK(IsAligned(obj.address(), kDoubleAlignment));
- // Try the opposite alignment case.
- start = AlignOldSpace(kDoubleAligned, kTaggedSize);
- obj = OldSpaceAllocateAligned(kTaggedSize, kDoubleAligned);
- CHECK(IsAligned(obj.address(), kDoubleAlignment));
- filler = HeapObject::FromAddress(start);
- CHECK(obj != filler);
- CHECK(IsFreeSpaceOrFiller(filler));
- CHECK_EQ(kTaggedSize, filler->Size());
- CHECK(obj != filler && IsFreeSpaceOrFiller(filler) &&
- filler->Size() == kTaggedSize);
-
- // Similarly for kDoubleUnaligned.
- start = AlignOldSpace(kDoubleUnaligned, 0);
- obj = OldSpaceAllocateAligned(kTaggedSize, kDoubleUnaligned);
- // The object is aligned.
- CHECK(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
- // Try the opposite alignment case.
- start = AlignOldSpace(kDoubleUnaligned, kTaggedSize);
- obj = OldSpaceAllocateAligned(kTaggedSize, kDoubleUnaligned);
- CHECK(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
- filler = HeapObject::FromAddress(start);
- CHECK(obj != filler && IsFreeSpaceOrFiller(filler) &&
- filler->Size() == kTaggedSize);
- }
-}
-
-TEST(HeapNumberAlignment) {
- if (!v8_flags.allocation_site_pretenuring) return;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
- HandleScope sc(isolate);
-
- const auto required_alignment = HeapObject::RequiredAlignment(
- InSharedSpace{false}, *factory->heap_number_map());
- const int maximum_misalignment =
- MainAllocator::GetMaximumFillToAlign(required_alignment);
-
- for (int offset = 0; offset <= maximum_misalignment; offset += kTaggedSize) {
- if (!v8_flags.single_generation) {
- heap->allocator()->new_space_allocator()->AlignTopForTesting(
- required_alignment, offset);
- DirectHandle<Object> number_new = factory->NewNumber(1.000123);
- CHECK(IsHeapNumber(*number_new));
- CHECK(HeapLayout::InYoungGeneration(*number_new));
- CHECK_EQ(
- 0, MainAllocator::GetFillToAlign(
- Cast<HeapObject>(*number_new).address(), required_alignment));
- }
-
- AlignOldSpace(required_alignment, offset);
- DirectHandle<Object> number_old =
- factory->NewNumber<AllocationType::kOld>(1.000321);
- CHECK(IsHeapNumber(*number_old));
- CHECK(heap->InOldSpace(*number_old));
- CHECK_EQ(0,
- MainAllocator::GetFillToAlign(
- Cast<HeapObject>(*number_old).address(), required_alignment));
- }
-}
-
-TEST(TestSizeOfObjectsVsHeapObjectIteratorPrecision) {
- if (v8_flags.stress_concurrent_allocation) {
- return;
- }
- CcTest::InitializeVM();
- // Disable LAB, such that calculations with SizeOfObjects() and object size
- // are correct.
- CcTest::heap()->DisableInlineAllocation();
- HeapObjectIterator iterator(CcTest::heap());
- intptr_t size_of_objects_1 = CcTest::heap()->SizeOfObjects();
- intptr_t size_of_objects_2 = 0;
- for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
- obj = iterator.Next()) {
- if (!IsFreeSpace(obj)) {
- size_of_objects_2 += obj->Size();
- }
- }
- // Delta must be within 5% of the larger result.
- // TODO(gc): Tighten this up by distinguishing between byte
- // arrays that are real and those that merely mark free space
- // on the heap.
- if (size_of_objects_1 > size_of_objects_2) {
- intptr_t delta = size_of_objects_1 - size_of_objects_2;
- PrintF("Heap::SizeOfObjects: %" V8PRIdPTR
- ", "
- "Iterator: %" V8PRIdPTR
- ", "
- "delta: %" V8PRIdPTR "\n",
- size_of_objects_1, size_of_objects_2, delta);
- CHECK_GT(size_of_objects_1 / 20, delta);
- } else {
- intptr_t delta = size_of_objects_2 - size_of_objects_1;
- PrintF("Heap::SizeOfObjects: %" V8PRIdPTR
- ", "
- "Iterator: %" V8PRIdPTR
- ", "
- "delta: %" V8PRIdPTR "\n",
- size_of_objects_1, size_of_objects_2, delta);
- CHECK_GT(size_of_objects_2 / 20, delta);
- }
-}
-
-static int NumberOfGlobalObjects() {
- int count = 0;
- HeapObjectIterator iterator(CcTest::heap());
- for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
- obj = iterator.Next()) {
- if (IsJSGlobalObject(obj)) count++;
- }
- return count;
-}
-
-// Test that we don't embed maps from foreign contexts into
-// optimized code.
-TEST(LeakNativeContextViaMap) {
- v8_flags.allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- Heap* heap = CcTest::heap();
- v8::HandleScope outer_scope(isolate);
- v8::Persistent<v8::Context> ctx1p;
- v8::Persistent<v8::Context> ctx2p;
- {
- v8::HandleScope scope(isolate);
- ctx1p.Reset(isolate, v8::Context::New(isolate));
- ctx2p.Reset(isolate, v8::Context::New(isolate));
- v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
- }
-
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(2, NumberOfGlobalObjects());
-
- {
- v8::HandleScope inner_scope(isolate);
- CompileRun("var v = {x: 42}");
- v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
- v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
- v8::Local<v8::Value> v =
- ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked();
- ctx2->Enter();
- CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust());
- v8::Local<v8::Value> res = CompileRun(
- "function f() { return o.x; }"
- "%PrepareFunctionForOptimization(f);"
- "for (var i = 0; i < 10; ++i) f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
- CHECK_EQ(42, res->Int32Value(ctx2).FromJust());
- CHECK(ctx2->Global()
- ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0))
- .FromJust());
- ctx2->Exit();
- v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
- ctx1p.Reset();
- isolate->ContextDisposedNotification(
- v8::ContextDependants::kSomeDependants);
- }
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(1, NumberOfGlobalObjects());
- ctx2p.Reset();
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(0, NumberOfGlobalObjects());
-}
-
-// Test that we don't embed functions from foreign contexts into
-// optimized code.
-TEST(LeakNativeContextViaFunction) {
- v8_flags.allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- Heap* heap = CcTest::heap();
- v8::HandleScope outer_scope(isolate);
- v8::Persistent<v8::Context> ctx1p;
- v8::Persistent<v8::Context> ctx2p;
- {
- v8::HandleScope scope(isolate);
- ctx1p.Reset(isolate, v8::Context::New(isolate));
- ctx2p.Reset(isolate, v8::Context::New(isolate));
- v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
- }
-
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(2, NumberOfGlobalObjects());
-
- {
- v8::HandleScope inner_scope(isolate);
- CompileRun("var v = function() { return 42; }");
- v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
- v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
- v8::Local<v8::Value> v =
- ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked();
- ctx2->Enter();
- CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust());
- v8::Local<v8::Value> res = CompileRun(
- "function f(x) { return x(); }"
- "%PrepareFunctionForOptimization(f);"
- "for (var i = 0; i < 10; ++i) f(o);"
- "%OptimizeFunctionOnNextCall(f);"
- "f(o);");
- CHECK_EQ(42, res->Int32Value(ctx2).FromJust());
- CHECK(ctx2->Global()
- ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0))
- .FromJust());
- ctx2->Exit();
- ctx1->Exit();
- ctx1p.Reset();
- isolate->ContextDisposedNotification(
- v8::ContextDependants::kSomeDependants);
- }
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(1, NumberOfGlobalObjects());
- ctx2p.Reset();
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(0, NumberOfGlobalObjects());
-}
-
-TEST(LeakNativeContextViaMapKeyed) {
- v8_flags.allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- Heap* heap = CcTest::heap();
- v8::HandleScope outer_scope(isolate);
- v8::Persistent<v8::Context> ctx1p;
- v8::Persistent<v8::Context> ctx2p;
- {
- v8::HandleScope scope(isolate);
- ctx1p.Reset(isolate, v8::Context::New(isolate));
- ctx2p.Reset(isolate, v8::Context::New(isolate));
- v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
- }
-
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(2, NumberOfGlobalObjects());
-
- {
- v8::HandleScope inner_scope(isolate);
- CompileRun("var v = [42, 43]");
- v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
- v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
- v8::Local<v8::Value> v =
- ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked();
- ctx2->Enter();
- CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust());
- v8::Local<v8::Value> res = CompileRun(
- "function f() { return o[0]; }"
- "%PrepareFunctionForOptimization(f);"
- "for (var i = 0; i < 10; ++i) f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
- CHECK_EQ(42, res->Int32Value(ctx2).FromJust());
- CHECK(ctx2->Global()
- ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0))
- .FromJust());
- ctx2->Exit();
- ctx1->Exit();
- ctx1p.Reset();
- isolate->ContextDisposedNotification(
- v8::ContextDependants::kSomeDependants);
- }
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(1, NumberOfGlobalObjects());
- ctx2p.Reset();
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(0, NumberOfGlobalObjects());
-}
-
-TEST(LeakNativeContextViaMapProto) {
- v8_flags.allow_natives_syntax = true;
- v8::Isolate* isolate = CcTest::isolate();
- Heap* heap = CcTest::heap();
- v8::HandleScope outer_scope(isolate);
- v8::Persistent<v8::Context> ctx1p;
- v8::Persistent<v8::Context> ctx2p;
- {
- v8::HandleScope scope(isolate);
- ctx1p.Reset(isolate, v8::Context::New(isolate));
- ctx2p.Reset(isolate, v8::Context::New(isolate));
- v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
- }
-
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(2, NumberOfGlobalObjects());
-
- {
- v8::HandleScope inner_scope(isolate);
- CompileRun("var v = { y: 42}");
- v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
- v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
- v8::Local<v8::Value> v =
- ctx1->Global()->Get(ctx1, v8_str("v")).ToLocalChecked();
- ctx2->Enter();
- CHECK(ctx2->Global()->Set(ctx2, v8_str("o"), v).FromJust());
- v8::Local<v8::Value> res = CompileRun(
- "function f() {"
- " var p = {x: 42};"
- " p.__proto__ = o;"
- " return p.x;"
- "}"
- "%PrepareFunctionForOptimization(f);"
- "for (var i = 0; i < 10; ++i) f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
- CHECK_EQ(42, res->Int32Value(ctx2).FromJust());
- CHECK(ctx2->Global()
- ->Set(ctx2, v8_str("o"), v8::Int32::New(isolate, 0))
- .FromJust());
- ctx2->Exit();
- ctx1->Exit();
- ctx1p.Reset();
- isolate->ContextDisposedNotification(
- v8::ContextDependants::kSomeDependants);
- }
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(1, NumberOfGlobalObjects());
- ctx2p.Reset();
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMemoryReducingMajorGCs(heap);
- }
- CHECK_EQ(0, NumberOfGlobalObjects());
-}
-
-TEST(InstanceOfStubWriteBarrier) {
- if (!v8_flags.incremental_marking) return;
- ManualGCScope manual_gc_scope;
- v8_flags.allow_natives_syntax = true;
-#ifdef VERIFY_HEAP
- v8_flags.verify_heap = true;
-#endif
-
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- if (!isolate->use_optimizer()) return;
- v8::HandleScope outer_scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
-
- // Store native context in global as well to make it part of the root set when
- // starting incremental marking. This will ensure that function will be part
- // of the transitive closure during incremental marking.
- v8::Global<v8::Context> global_ctx(CcTest::isolate(), ctx);
-
- {
- v8::HandleScope scope(CcTest::isolate());
- CompileRun(
- "function foo () { }"
- "function mkbar () { return new (new Function(\"\")) (); }"
- "function f (x) { return (x instanceof foo); }"
- "function g () { f(mkbar()); }"
- "%PrepareFunctionForOptimization(f);"
- "f(new foo()); f(new foo());"
- "%OptimizeFunctionOnNextCall(f);"
- "f(new foo()); g();");
- }
-
- IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- marking->Stop();
- CcTest::heap()->StartIncrementalMarking(i::GCFlag::kNoFlags,
- i::GarbageCollectionReason::kTesting);
-
- i::DirectHandle<JSFunction> f = i::Cast<JSFunction>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Function>::Cast(
- CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
-
- CHECK(f->HasAttachedOptimizedCode(isolate));
-
- MarkingState* marking_state = CcTest::heap()->marking_state();
-
- static constexpr auto kStepSize = v8::base::TimeDelta::FromMilliseconds(100);
- while (!marking_state->IsMarked(f->code(isolate))) {
- // Discard any pending GC requests otherwise we will get GC when we enter
- // code below.
- CHECK(!marking->IsMajorMarkingComplete());
- marking->AdvanceForTesting(kStepSize);
- }
-
- CHECK(marking->IsMarking());
-
- {
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Object> global = CcTest::global();
- v8::Local<v8::Function> g = v8::Local<v8::Function>::Cast(
- global->Get(ctx, v8_str("g")).ToLocalChecked());
- g->Call(ctx, global, 0, nullptr).ToLocalChecked();
- }
-
- heap::InvokeMajorGC(CcTest::heap());
-}
-
-HEAP_TEST(GCFlags) {
- if (!v8_flags.incremental_marking) return;
- CcTest::InitializeVM();
- Heap* heap = CcTest::heap();
-
- heap->current_gc_flags_ = GCFlag::kNoFlags;
- // Check whether we appropriately reset flags after GC.
- heap::InvokeMajorGC(CcTest::heap(), GCFlag::kReduceMemoryFootprint);
- CHECK_EQ(heap->current_gc_flags_, GCFlag::kNoFlags);
-
- if (heap->sweeping_in_progress()) {
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
-
- IncrementalMarking* marking = heap->incremental_marking();
- marking->Stop();
- heap->StartIncrementalMarking(GCFlag::kReduceMemoryFootprint,
- GarbageCollectionReason::kTesting);
- CHECK(heap->current_gc_flags_ & GCFlag::kReduceMemoryFootprint);
-
- heap::InvokeMajorGC(heap, GCFlag::kNoFlags);
- CHECK_EQ(heap->current_gc_flags_, GCFlag::kNoFlags);
-}
-
-HEAP_TEST(Regress845060) {
- if (v8_flags.single_generation) return;
- // Regression test for crbug.com/845060, where a raw pointer to a string's
- // data was kept across an allocation. If the allocation causes GC and
- // moves the string, such raw pointers become invalid.
- v8_flags.allow_natives_syntax = true;
- v8_flags.stress_incremental_marking = false;
- v8_flags.stress_compaction = false;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- LocalContext context;
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
-
- // Preparation: create a string in new space.
- Local<Value> str = CompileRun("var str = (new Array(10000)).join('x'); str");
- CHECK(HeapLayout::InYoungGeneration(*v8::Utils::OpenDirectHandle(*str)));
-
- // Use kReduceMemoryFootprintMask to unmap from space after scavenging.
- heap->StartIncrementalMarking(i::GCFlag::kReduceMemoryFootprint,
- GarbageCollectionReason::kTesting);
-
- // Run the test (which allocates results) until the original string was
- // promoted to old space. Unmapping of from_space causes accesses to any
- // stale raw pointers to crash.
- CompileRun("while (%InYoungGeneration(str)) { str.split(''); }");
- CHECK(!HeapLayout::InYoungGeneration(*v8::Utils::OpenDirectHandle(*str)));
-}
-
-TEST(OptimizedPretenuringAllocationFolding) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array();"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = [[{}], [1.1]];"
- " }"
- " return elements[number_elements-1]"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- v8::Local<v8::Value> int_array =
- v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked();
- i::DirectHandle<JSObject> int_array_handle = i::Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(int_array)));
- v8::Local<v8::Value> double_array =
- v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked();
- i::DirectHandle<JSObject> double_array_handle = i::Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(double_array)));
-
- i::DirectHandle<JSReceiver> o =
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res));
- CHECK(CcTest::heap()->InOldSpace(*o));
- CHECK(CcTest::heap()->InOldSpace(*int_array_handle));
- CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements()));
- CHECK(CcTest::heap()->InOldSpace(*double_array_handle));
- CHECK(CcTest::heap()->InOldSpace(double_array_handle->elements()));
-}
-
-TEST(OptimizedPretenuringObjectArrayLiterals) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = [{}, {}, {}];"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
-
- CHECK(CcTest::heap()->InOldSpace(o->elements()));
- CHECK(CcTest::heap()->InOldSpace(*o));
-}
-
-TEST(OptimizedPretenuringNestedInObjectProperties) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- // Keep the nested literal alive while its root is freed
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(
- source.as_vector(),
- "let number_elements = %d;"
- "let elements = new Array(number_elements);"
- "function f() {"
- " for (let i = 0; i < number_elements; i++) {"
- " let l = {a: {b: {c: {d: {e: 2.2}, e: 3.3}, g: {h: 1.1}}}}; "
- " elements[i] = l.a.b.c.d;"
- " }"
- " return elements[number_elements-1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'}); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
-
- // Nested literal sites are only pretenured if the top level
- // literal is pretenured
- CHECK(HeapLayout::InYoungGeneration(*o));
-}
-
-TEST(OptimizedPretenuringMixedInObjectProperties) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = {a: {c: 2.2, d: {}}, b: 1.1};"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
-
- CHECK(CcTest::heap()->InOldSpace(*o));
- FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0);
- FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1);
- CHECK(CcTest::heap()->InOldSpace(o->RawFastPropertyAt(idx1)));
- CHECK(CcTest::heap()->InOldSpace(o->RawFastPropertyAt(idx2)));
-
- Tagged<JSObject> inner_object = Cast<JSObject>(o->RawFastPropertyAt(idx1));
- CHECK(CcTest::heap()->InOldSpace(inner_object));
- CHECK(CcTest::heap()->InOldSpace(inner_object->RawFastPropertyAt(idx1)));
- CHECK(CcTest::heap()->InOldSpace(inner_object->RawFastPropertyAt(idx2)));
-}
-
-TEST(OptimizedPretenuringDoubleArrayProperties) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = {a: 1.1, b: 2.2};"
- " }"
- " return elements[i - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
-
- CHECK(CcTest::heap()->InOldSpace(*o));
- CHECK_EQ(o->property_array(),
- ReadOnlyRoots(CcTest::heap()).empty_property_array());
-}
-
-TEST(OptimizedPretenuringDoubleArrayLiterals) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = [1.1, 2.2, 3.3];"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
-
- CHECK(CcTest::heap()->InOldSpace(o->elements()));
- CHECK(CcTest::heap()->InOldSpace(*o));
-}
-
-TEST(OptimizedPretenuringNestedMixedArrayLiterals) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = [[{}, {}, {}], [1.1, 2.2, 3.3]];"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- v8::Local<v8::Value> int_array =
- v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked();
- i::DirectHandle<JSObject> int_array_handle = i::Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(int_array)));
- v8::Local<v8::Value> double_array =
- v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked();
- i::DirectHandle<JSObject> double_array_handle = i::Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(double_array)));
-
- DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
- CHECK(CcTest::heap()->InOldSpace(*o));
- CHECK(CcTest::heap()->InOldSpace(*int_array_handle));
- CHECK(CcTest::heap()->InOldSpace(int_array_handle->elements()));
- CHECK(CcTest::heap()->InOldSpace(*double_array_handle));
- CHECK(CcTest::heap()->InOldSpace(double_array_handle->elements()));
-}
-
-TEST(OptimizedPretenuringNestedObjectLiterals) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = [[{}, {}, {}],[{}, {}, {}]];"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- v8::Local<v8::Value> int_array_1 =
- v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked();
- DirectHandle<JSObject> int_array_handle_1 = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(int_array_1)));
- v8::Local<v8::Value> int_array_2 =
- v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked();
- DirectHandle<JSObject> int_array_handle_2 = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(int_array_2)));
-
- DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
- CHECK(CcTest::heap()->InOldSpace(*o));
- CHECK(CcTest::heap()->InOldSpace(*int_array_handle_1));
- CHECK(CcTest::heap()->InOldSpace(int_array_handle_1->elements()));
- CHECK(CcTest::heap()->InOldSpace(*int_array_handle_2));
- CHECK(CcTest::heap()->InOldSpace(int_array_handle_2->elements()));
-}
-
-TEST(OptimizedPretenuringNestedDoubleLiterals) {
- v8_flags.allow_natives_syntax = true;
- v8_flags.expose_gc = true;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
- ManualGCScope manual_gc_scope;
- GrowNewSpaceToMaximumCapacity(CcTest::heap());
-
- auto source = base::OwnedVector<char>::NewForOverwrite(1024);
- base::SNPrintF(source.as_vector(),
- "var number_elements = %d;"
- "var elements = new Array(number_elements);"
- "function f() {"
- " for (var i = 0; i < number_elements; i++) {"
- " elements[i] = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];"
- " }"
- " return elements[number_elements - 1];"
- "};"
- "%%PrepareFunctionForOptimization(f);"
- "f(); gc({type: 'minor'});"
- "f(); f();"
- "%%OptimizeFunctionOnNextCall(f);"
- "f();",
- kPretenureCreationCount);
-
- v8::Local<v8::Value> res = CompileRun(source.begin());
-
- v8::Local<v8::Value> double_array_1 =
- v8::Object::Cast(*res)->Get(ctx, v8_str("0")).ToLocalChecked();
- i::DirectHandle<JSObject> double_array_handle_1 =
- i::Cast<JSObject>(v8::Utils::OpenDirectHandle(
- *v8::Local<v8::Object>::Cast(double_array_1)));
- v8::Local<v8::Value> double_array_2 =
- v8::Object::Cast(*res)->Get(ctx, v8_str("1")).ToLocalChecked();
- i::DirectHandle<JSObject> double_array_handle_2 =
- Cast<JSObject>(v8::Utils::OpenDirectHandle(
- *v8::Local<v8::Object>::Cast(double_array_2)));
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
- CHECK(CcTest::heap()->InOldSpace(*o));
- CHECK(CcTest::heap()->InOldSpace(*double_array_handle_1));
- CHECK(CcTest::heap()->InOldSpace(double_array_handle_1->elements()));
- CHECK(CcTest::heap()->InOldSpace(*double_array_handle_2));
- CHECK(CcTest::heap()->InOldSpace(double_array_handle_2->elements()));
-}
-
-// Test regular array literals allocation.
-TEST(OptimizedAllocationArrayLiterals) {
- v8_flags.allow_natives_syntax = true;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- if (!CcTest::i_isolate()->use_optimizer()) return;
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking) {
- return;
- }
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
- v8::Local<v8::Value> res = CompileRun(
- "function f() {"
- " var numbers = new Array(1, 2, 3);"
- " numbers[0] = 3.14;"
- " return numbers;"
- "};"
- "%PrepareFunctionForOptimization(f);"
- "f(); f(); f();"
- "%OptimizeFunctionOnNextCall(f);"
- "f();");
- CHECK_EQ(static_cast<int>(3.14), v8::Object::Cast(*res)
- ->Get(ctx, v8_str("0"))
- .ToLocalChecked()
- ->Int32Value(ctx)
- .FromJust());
-
- i::DirectHandle<JSObject> o = Cast<JSObject>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(res)));
-
- CHECK(InCorrectGeneration(o->elements()));
-}
-
-static int CountMapTransitions(i::Isolate* isolate, Tagged<Map> map) {
- return TransitionsAccessor(isolate, map).NumberOfTransitions();
-}
-
-// Test that map transitions are cleared and maps are collected with
-// incremental marking as well.
-TEST(Regress1465) {
- if (!v8_flags.incremental_marking) return;
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
- v8_flags.allow_natives_syntax = true;
- v8_flags.trace_incremental_marking = true;
- v8_flags.retain_maps_for_n_gc = 0;
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- i::Isolate* i_isolate = CcTest::i_isolate();
- Heap* heap = CcTest::heap();
- v8::HandleScope scope(isolate);
- static const int transitions_count = 256;
-
- CompileRun("function F() {}");
- {
- AlwaysAllocateScopeForTesting always_allocate(heap);
- for (int i = 0; i < transitions_count; i++) {
- base::EmbeddedVector<char, 64> buffer;
- base::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
- CompileRun(buffer.begin());
- }
- CompileRun("var root = new F;");
- }
-
- i::IndirectHandle<JSReceiver> root =
- v8::Utils::OpenIndirectHandle(*v8::Local<v8::Object>::Cast(
- CcTest::global()
- ->Get(isolate->GetCurrentContext(), v8_str("root"))
- .ToLocalChecked()));
-
- // Count number of live transitions before marking.
- int transitions_before = CountMapTransitions(i_isolate, root->map());
- CompileRun("%DebugPrint(root);");
- CHECK_EQ(transitions_count, transitions_before);
-
- heap::SimulateIncrementalMarking(heap);
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // Count number of live transitions after marking. Note that one transition
- // is left, because 'o' still holds an instance of one transition target.
- int transitions_after = CountMapTransitions(i_isolate, root->map());
- CompileRun("%DebugPrint(root);");
- CHECK_EQ(1, transitions_after);
-}
-
-#ifdef DEBUG
-
-static i::Handle<JSObject> GetByName(const char* name) {
- return i::Cast<i::JSObject>(
- v8::Utils::OpenHandle(*v8::Local<v8::Object>::Cast(
- CcTest::global()
- ->Get(CcTest::isolate()->GetCurrentContext(), v8_str(name))
- .ToLocalChecked())));
-}
-
-static void AddTransitions(int transitions_count) {
- AlwaysAllocateScopeForTesting always_allocate(CcTest::i_isolate()->heap());
- for (int i = 0; i < transitions_count; i++) {
- base::EmbeddedVector<char, 64> buffer;
- base::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
- CompileRun(buffer.begin());
- }
-}
-
-static void AddPropertyTo(int gc_count, DirectHandle<JSObject> object,
- const char* property_name) {
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- DirectHandle<String> prop_name =
- factory->InternalizeUtf8String(property_name);
- DirectHandle<Smi> twenty_three(Smi::FromInt(23), isolate);
- HeapAllocator::SetAllocationGcInterval(gc_count);
- v8_flags.gc_global = true;
- v8_flags.retain_maps_for_n_gc = 0;
- CcTest::heap()->set_allocation_timeout(gc_count);
- Object::SetProperty(isolate, object, prop_name, twenty_three).Check();
-}
-
-TEST(TransitionArrayShrinksDuringAllocToZero) {
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- i::Isolate* i_isolate = CcTest::i_isolate();
- v8::HandleScope scope(CcTest::isolate());
- static const int transitions_count = 10;
- CompileRun("function F() { }");
- AddTransitions(transitions_count);
- CompileRun("var root = new F;");
- IndirectHandle<JSObject> root = GetByName("root");
-
- // Count number of live transitions before marking.
- int transitions_before = CountMapTransitions(i_isolate, root->map());
- CHECK_EQ(transitions_count, transitions_before);
-
- // Get rid of o
- CompileRun(
- "o = new F;"
- "root = new F");
- root = GetByName("root");
- AddPropertyTo(2, root, "funny");
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(
- CcTest::heap());
- heap::InvokeMinorGC(CcTest::heap());
- }
-
- // Count number of live transitions after marking. Note that one transition
- // is left, because 'o' still holds an instance of one transition target.
- int transitions_after =
- CountMapTransitions(i_isolate, Cast<Map>(root->map()->GetBackPointer()));
- CHECK_EQ(1, transitions_after);
-}
-
-TEST(TransitionArrayShrinksDuringAllocToOne) {
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- i::Isolate* i_isolate = CcTest::i_isolate();
- v8::HandleScope scope(CcTest::isolate());
- static const int transitions_count = 10;
- CompileRun("function F() {}");
- AddTransitions(transitions_count);
- CompileRun("var root = new F;");
- IndirectHandle<JSObject> root = GetByName("root");
-
- // Count number of live transitions before marking.
- int transitions_before = CountMapTransitions(i_isolate, root->map());
- CHECK_EQ(transitions_count, transitions_before);
-
- root = GetByName("root");
- AddPropertyTo(2, root, "funny");
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(
- CcTest::heap());
- heap::InvokeMinorGC(CcTest::heap());
- }
-
- // Count number of live transitions after marking. Note that one transition
- // is left, because 'o' still holds an instance of one transition target.
- int transitions_after =
- CountMapTransitions(i_isolate, Cast<Map>(root->map()->GetBackPointer()));
- CHECK_EQ(2, transitions_after);
-}
-
-TEST(TransitionArrayShrinksDuringAllocToOnePropertyFound) {
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
+TEST(TestInternalWeakLists) {
v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- i::Isolate* i_isolate = CcTest::i_isolate();
- v8::HandleScope scope(CcTest::isolate());
- static const int transitions_count = 10;
- CompileRun("function F() {}");
- AddTransitions(transitions_count);
- CompileRun("var root = new F;");
- DirectHandle<JSObject> root = GetByName("root");
-
- // Count number of live transitions before marking.
- int transitions_before = CountMapTransitions(i_isolate, root->map());
- CHECK_EQ(transitions_count, transitions_before);
-
- root = GetByName("root");
- AddPropertyTo(0, root, "prop9");
- heap::InvokeMajorGC(CcTest::heap());
- // Count number of live transitions after marking. Note that one transition
- // is left, because 'o' still holds an instance of one transition target.
- int transitions_after =
- CountMapTransitions(i_isolate, Cast<Map>(root->map()->GetBackPointer()));
- CHECK_EQ(1, transitions_after);
-}
-#endif // DEBUG
+ // Some flags turn Scavenge collections into Mark-sweep collections
+ // and hence are incompatible with this test case.
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation) {
+ return;
+ }
+ v8_flags.retain_maps_for_n_gc = 0;
+
+ static const int kNumTestContexts = 10;
-TEST(ReleaseOverReservedPages) {
- if (!v8_flags.compact) return;
- v8_flags.trace_gc = true;
- // The optimizer can allocate stuff, messing up the test.
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- v8_flags.turbofan = false;
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- // - Parallel compaction increases fragmentation, depending on how existing
- // memory is distributed. Since this is non-deterministic because of
- // concurrent sweeping, we disable it for this test.
- // - Concurrent sweeping adds non determinism, depending on when memory is
- // available for further reuse.
- // - Fast evacuation of pages may result in a different page count in old
- // space.
ManualGCScope manual_gc_scope;
- v8_flags.page_promotion = false;
- v8_flags.parallel_compaction = false;
- CcTest::InitializeVM();
+ v8::Isolate* v8_isolate = CcTest::isolate();
Isolate* isolate = CcTest::i_isolate();
- // If there's snapshot available, we don't know whether 20 small arrays will
- // fit on the initial pages.
- if (!isolate->snapshot_available()) return;
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
+ Heap* heap = CcTest::heap();
+ HandleScope scope(isolate);
+ v8::Global<v8::Context> ctx[kNumTestContexts];
+ if (!isolate->use_optimizer()) return;
- // Ensure that the young generation is empty.
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::EmptyNewSpaceUsingGC(heap);
- }
- static const int number_of_test_pages = 20;
+ CHECK_EQ(0, CountNativeContexts());
- // Prepare many pages with low live-bytes count.
- PagedSpace* old_space = heap->old_space();
- const int initial_page_count = old_space->CountTotalPages();
- const int overall_page_count = number_of_test_pages + initial_page_count;
+ // Create a number of global contests which gets linked together.
+ for (int i = 0; i < kNumTestContexts; i++) {
+ // Create a handle scope so no contexts or function objects get stuck in the
+ // outer handle scope.
+ HandleScope new_scope(isolate);
- Global<v8::FixedArray> fixed_arrays[number_of_test_pages];
- {
- v8::HandleScope scope(CcTest::isolate());
+ ctx[i].Reset(v8_isolate, v8::Context::New(v8_isolate));
- for (int i = 0; i < number_of_test_pages; i++) {
- AlwaysAllocateScopeForTesting always_allocate(heap);
- {
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::SimulateFullSpace(old_space);
+ // Collect garbage that might have been created by one of the
+ // installed extensions.
+ isolate->compilation_cache()->Clear();
+ {
+ // In this test, we need to invoke GC without stack, otherwise some
+ // objects may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ heap::InvokeMajorGC(heap);
+ }
+
+ CHECK_EQ(i + 1, CountNativeContexts());
+
+ ctx[i].Get(v8_isolate)->Enter();
+
+ OptimizeEmptyFunction("f1");
+ OptimizeEmptyFunction("f2");
+ OptimizeEmptyFunction("f3");
+ OptimizeEmptyFunction("f4");
+ OptimizeEmptyFunction("f5");
+
+ // Remove function f1, and
+ CompileRun("f1=null");
+
+ // Scavenge treats these references as strong.
+ for (int j = 0; j < 10; j++) {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ heap::InvokeMinorGC(heap);
+ }
+
+ // Mark compact handles the weak references.
+ isolate->compilation_cache()->Clear();
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ heap::InvokeMajorGC(heap);
+ }
+
+ // Get rid of f3 and f5 in the same way.
+ CompileRun("f3=null");
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ for (int j = 0; j < 10; j++) {
+ heap::InvokeMinorGC(heap);
+ }
+ heap::InvokeMajorGC(heap);
+ }
+ CompileRun("f5=null");
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ for (int j = 0; j < 10; j++) {
+ heap::InvokeMinorGC(heap);
}
- Handle<FixedArray> fixed_array =
- factory->NewFixedArray(1, AllocationType::kOld);
- fixed_arrays[i].Reset(CcTest::isolate(),
- v8::Utils::FixedArrayToLocal(fixed_array));
+ heap::InvokeMajorGC(heap);
}
+ ctx[i].Get(v8_isolate)->Exit();
+ }
+
+ // Force compilation cache cleanup.
+ heap->NotifyContextDisposed(true);
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ heap::InvokeMajorGC(heap);
}
- CHECK_EQ(overall_page_count, old_space->CountTotalPages());
+ // Dispose the native contexts one by one.
+ for (int i = 0; i < kNumTestContexts; i++) {
+ ctx[i].Reset();
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- // Triggering one GC will cause a lot of garbage to be discovered but
- // even spread across all allocated pages.
- heap::InvokeMajorGC(heap);
- CHECK_GE(overall_page_count, old_space->CountTotalPages());
+ // Scavenge treats these references as strong.
+ for (int j = 0; j < 10; j++) {
+ heap::InvokeMinorGC(heap);
+ CHECK_EQ(kNumTestContexts - i, CountNativeContexts());
+ }
+ // Mark-compact handles the weak references.
+ heap::InvokeMajorGC(heap);
- // Triggering subsequent GCs should cause at least half of the pages
- // to be released to the OS after at most two cycles.
- heap::InvokeMajorGC(heap);
- CHECK_GE(overall_page_count, old_space->CountTotalPages());
- heap::InvokeMajorGC(heap);
- CHECK_GE(number_of_test_pages,
- (old_space->CountTotalPages() - initial_page_count) * 2);
+ CHECK_EQ(kNumTestContexts - i - 1, CountNativeContexts());
+ }
- // Triggering a last-resort GC should cause all pages to be released to the
- // OS so that other processes can seize the memory.
- const int page_count_before_memory_reducing_gcs =
- old_space->CountTotalPages();
- heap::InvokeMemoryReducingMajorGCs(heap);
- // With precise object pinning, some pages may be pinned and thus not
- // evacuated. It is therefore not guararnteed that the page count can return
- // to the initial count.
- CHECK_GE(v8_flags.precise_object_pinning
- ? page_count_before_memory_reducing_gcs
- : initial_page_count,
- old_space->CountTotalPages());
+ CHECK_EQ(0, CountNativeContexts());
}
static int forced_gc_counter = 0;
@@ -3712,33 +339,6 @@ static void CheckVectorIC(DirectHandle<JSFunction> f, int slot_index,
CHECK(nexus.ic_state() == desired_state);
}
-TEST(IncrementalMarkingPreservesMonomorphicConstructor) {
- if (!v8_flags.incremental_marking) return;
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- v8::Local<v8::Context> ctx = CcTest::isolate()->GetCurrentContext();
- // Prepare function f that contains a monomorphic IC for object
- // originating from the same native context.
- CompileRun(
- "function fun() { this.x = 1; };"
- "function f(o) { return new o(); }"
- "%EnsureFeedbackVectorForFunction(f);"
- "f(fun); f(fun);");
- DirectHandle<JSFunction> f = Cast<JSFunction>(
- v8::Utils::OpenDirectHandle(*v8::Local<v8::Function>::Cast(
- CcTest::global()->Get(ctx, v8_str("f")).ToLocalChecked())));
-
- DirectHandle<FeedbackVector> vector(f->feedback_vector(),
- CcTest::i_isolate());
- CHECK(vector->Get(FeedbackSlot(0)).IsWeakOrCleared());
-
- heap::SimulateIncrementalMarking(CcTest::heap());
- heap::InvokeMajorGC(CcTest::heap());
-
- CHECK(vector->Get(FeedbackSlot(0)).IsWeakOrCleared());
-}
-
TEST(IncrementalMarkingPreservesMonomorphicIC) {
if (!v8_flags.use_ic) return;
if (!v8_flags.incremental_marking) return;
@@ -3943,301 +543,14 @@ UNINITIALIZED_TEST(ReleaseStackTraceData) {
static const char* setter = "error.stack = 0";
ReleaseStackTraceDataTest(isolate, source1, setter);
- ReleaseStackTraceDataTest(isolate, source2, setter);
- ReleaseStackTraceDataTest(isolate, source1, getter);
- ReleaseStackTraceDataTest(isolate, source2, getter);
- }
- isolate->Dispose();
-}
-
-
-TEST(Regress169928) {
- v8_flags.allow_natives_syntax = true;
-#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- v8_flags.turbofan = false;
-#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- LocalContext env;
- Factory* factory = isolate->factory();
- v8::HandleScope scope(CcTest::isolate());
-
- // Some flags turn Scavenge collections into Mark-sweep collections
- // and hence are incompatible with this test case.
- if (v8_flags.gc_global || v8_flags.stress_compaction ||
- v8_flags.stress_incremental_marking || v8_flags.single_generation ||
- v8_flags.minor_ms) {
- return;
- }
-
- // Prepare the environment
- CompileRun(
- "function fastliteralcase(literal, value) {"
- " literal[0] = value;"
- " return literal;"
- "}"
- "function get_standard_literal() {"
- " var literal = [1, 2, 3];"
- " return literal;"
- "}"
- "obj = fastliteralcase(get_standard_literal(), 1);"
- "obj = fastliteralcase(get_standard_literal(), 1.5);"
- "obj = fastliteralcase(get_standard_literal(), 2);");
-
- // prepare the heap
- v8::Local<v8::String> mote_code_string =
- v8_str("fastliteralcase(mote, 2.5);");
-
- v8::Local<v8::String> array_name = v8_str("mote");
- CHECK(CcTest::global()
- ->Set(env.local(), array_name, v8::Int32::New(CcTest::isolate(), 0))
- .FromJust());
-
- // First make sure we flip spaces
- heap::InvokeMinorGC(CcTest::heap());
-
- // Allocate the object.
- DirectHandle<FixedArray> array_data =
- factory->NewFixedArray(2, AllocationType::kYoung);
- array_data->set(0, Smi::FromInt(1));
- array_data->set(1, Smi::FromInt(2));
-
- heap::FillCurrentPageButNBytes(
- SemiSpaceNewSpace::From(CcTest::heap()->new_space()),
- JSArray::kHeaderSize + sizeof(AllocationMemento) + kTaggedSize);
-
- DirectHandle<JSArray> array =
- factory->NewJSArrayWithElements(array_data, PACKED_SMI_ELEMENTS);
-
- CHECK_EQ(Smi::FromInt(2), array->length());
- CHECK(array->HasSmiOrObjectElements());
-
- // We need filler the size of AllocationMemento object, plus an extra
- // fill pointer value.
- Tagged<HeapObject> obj;
- AllocationResult allocation =
- CcTest::heap()->allocator()->new_space_allocator()->AllocateRaw(
- SafeHeapObjectSize(sizeof(AllocationMemento) + kTaggedSize),
- kTaggedAligned, AllocationOrigin::kRuntime, AllocationHint());
- CHECK(allocation.To(&obj));
- Address addr_obj = obj.address();
- CcTest::heap()->CreateFillerObjectAt(addr_obj,
- sizeof(AllocationMemento) + kTaggedSize);
-
- // Give the array a name, making sure not to allocate strings.
- v8::Local<v8::Object> array_obj = v8::Utils::ToLocal(array);
- CHECK(CcTest::global()->Set(env.local(), array_name, array_obj).FromJust());
-
- // This should crash with a protection violation if we are running a build
- // with the bug.
- AlwaysAllocateScopeForTesting aa_scope(isolate->heap());
- v8::Script::Compile(env.local(), mote_code_string)
- .ToLocalChecked()
- ->Run(env.local())
- .ToLocalChecked();
-}
-
-TEST(LargeObjectSlotRecording) {
- if (!v8_flags.incremental_marking) return;
- if (!v8_flags.compact) return;
- ManualGCScope manual_gc_scope;
- heap::ManualEvacuationCandidatesSelectionScope
- manual_evacuation_candidate_selection_scope(manual_gc_scope);
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
-
- int size = std::max(1000000, kMaxRegularHeapObjectSize + KB);
- const int kStep = size / 10;
-
- Global<v8::FixedArray> lit_global;
- Global<v8::FixedArray> lo_global;
- Tagged<FixedArray> old_location;
- {
- HandleScope scope(isolate);
-
- // Create an object on an evacuation candidate.
- heap::SimulateFullSpace(heap->old_space());
- IndirectHandle<FixedArray> lit =
- isolate->factory()->NewFixedArray(4, AllocationType::kOld);
- NormalPage* evac_page = NormalPage::FromHeapObject(*lit);
- heap::ForceEvacuationCandidate(evac_page);
- old_location = *lit;
-
- // Allocate a large object.
- CHECK_LT(kMaxRegularHeapObjectSize, size);
- IndirectHandle<FixedArray> lo =
- isolate->factory()->NewFixedArray(size, AllocationType::kOld);
- CHECK(heap->lo_space()->Contains(*lo));
-
- // Start incremental marking to active write barrier.
- heap::SimulateIncrementalMarking(heap, false);
-
- // Create references from the large object to the object on the evacuation
- // candidate.
- for (int i = 0; i < size; i += kStep) {
- lo->set(i, *lit);
- CHECK(lo->get(i) == old_location);
- }
-
- heap::SimulateIncrementalMarking(heap, true);
- lit_global.Reset(CcTest::isolate(), v8::Utils::FixedArrayToLocal(lit));
- lo_global.Reset(CcTest::isolate(), v8::Utils::FixedArrayToLocal(lo));
- }
-
- // Move the evacuation candidate object.
- {
- // We need to invoke GC without stack, otherwise no compaction is performed.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- {
- v8::HandleScope scope(CcTest::isolate());
- IndirectHandle<FixedArray> lit =
- v8::Utils::OpenHandle(*lit_global.Get(CcTest::isolate()));
- IndirectHandle<FixedArray> lo =
- v8::Utils::OpenHandle(*lo_global.Get(CcTest::isolate()));
- // Verify that the pointers in the large object got updated.
- for (int i = 0; i < size; i += kStep) {
- CHECK_EQ(lo->get(i).ptr(), lit->ptr());
- CHECK_NE(lo->get(i).ptr(), old_location.ptr());
- }
- }
-}
-
-class DummyVisitor : public RootVisitor {
- public:
- void VisitRootPointers(Root root, const char* description,
- FullObjectSlot start, FullObjectSlot end) override {}
-};
-
-TEST(PersistentHandles) {
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
- v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
- HandleScopeData* data = isolate->handle_scope_data();
- IndirectHandle<Object> init(ReadOnlyRoots(heap).empty_string(), isolate);
- while (data->next < data->limit) {
- IndirectHandle<Object> obj(ReadOnlyRoots(heap).empty_string(), isolate);
- }
- // An entire block of handles has been filled.
- // Next handle would require a new block.
- CHECK(data->next == data->limit);
-
- PersistentHandlesScope persistent(isolate);
- DummyVisitor visitor;
- isolate->handle_scope_implementer()->Iterate(&visitor);
- persistent.Detach();
-}
-
-static void TestFillersFromPersistentHandles(bool promote) {
- // We assume that the fillers can only arise when left-trimming arrays.
- ManualGCScope manual_gc_scope;
- Isolate* isolate = CcTest::i_isolate();
- Heap* heap = isolate->heap();
- v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
-
- const size_t n = 10;
- DirectHandle<FixedArray> array = isolate->factory()->NewFixedArray(n);
-
- if (promote) {
- // Age the array so it's ready for promotion on next GC.
- heap::InvokeMinorGC(heap);
- }
- CHECK(HeapLayout::InYoungGeneration(*array));
-
- PersistentHandlesScope persistent_scope(isolate);
-
- // Trim the array three times to different sizes so all kinds of fillers are
- // created and tracked by the persistent handles.
- DirectHandle<FixedArrayBase> filler_1(*array, isolate);
- DirectHandle<FixedArrayBase> filler_2(heap->LeftTrimFixedArray(*filler_1, 1),
- isolate);
- DirectHandle<FixedArrayBase> filler_3(heap->LeftTrimFixedArray(*filler_2, 2),
- isolate);
- DirectHandle<FixedArrayBase> tail(heap->LeftTrimFixedArray(*filler_3, 3),
- isolate);
-
- std::unique_ptr<PersistentHandles> persistent_handles(
- persistent_scope.Detach());
-
- // GC should retain the trimmed array but drop all of the three fillers.
- heap::InvokeMinorGC(heap);
- if (!v8_flags.single_generation) {
- if (promote) {
- CHECK(heap->InOldSpace(*tail));
- } else {
- CHECK(HeapLayout::InYoungGeneration(*tail));
- }
- }
- CHECK_EQ(n - 6, tail->length().value());
- CHECK(!IsHeapObject(*filler_1));
- CHECK(!IsHeapObject(*filler_2));
- CHECK(!IsHeapObject(*filler_3));
-}
-
-TEST(DoNotEvacuateFillersFromPersistentHandles) {
- if (v8_flags.single_generation || v8_flags.move_object_start) return;
- TestFillersFromPersistentHandles(false /*promote*/);
-}
-
-TEST(DoNotPromoteFillersFromPersistentHandles) {
- if (v8_flags.single_generation || v8_flags.move_object_start) return;
- TestFillersFromPersistentHandles(true /*promote*/);
-}
-
-TEST(IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
- if (!v8_flags.incremental_marking) return;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- CompileRun(
- "function f(n) {"
- " var a = new Array(n);"
- " for (var i = 0; i < n; i += 100) a[i] = i;"
- "};"
- "f(10 * 1024 * 1024);");
- IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- if (marking->IsStopped()) {
- CcTest::heap()->StartIncrementalMarking(
- i::GCFlag::kNoFlags, i::GarbageCollectionReason::kTesting);
- }
- heap::SimulateIncrementalMarking(CcTest::heap());
- CHECK(marking->IsMajorMarkingComplete());
-}
-
-TEST(DisableInlineAllocation) {
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- CompileRun(
- "function test() {"
- " var x = [];"
- " for (var i = 0; i < 10; i++) {"
- " x[i] = [ {}, [1,2,3], [1,x,3] ];"
- " }"
- "}"
- "function run() {"
- " %PrepareFunctionForOptimization(test);"
- " %OptimizeFunctionOnNextCall(test);"
- " test();"
- " %DeoptimizeFunction(test);"
- "}");
-
- // Warm-up with inline allocation enabled.
- CompileRun("test(); test(); run();");
-
- // Run test with inline allocation disabled.
- CcTest::heap()->DisableInlineAllocation();
- CompileRun("run()");
-
- // Run test with inline allocation re-enabled.
- CcTest::heap()->EnableInlineAllocation();
- CompileRun("run()");
+ ReleaseStackTraceDataTest(isolate, source2, setter);
+ ReleaseStackTraceDataTest(isolate, source1, getter);
+ ReleaseStackTraceDataTest(isolate, source2, getter);
+ }
+ isolate->Dispose();
}
+
static int AllocationSitesCount(Heap* heap) {
int count = 0;
for (Tagged<Object> site = heap->allocation_sites_list();
@@ -4269,77 +582,6 @@ static int SlimAllocationSiteCount(Heap* heap) {
return count;
}
-TEST(EnsureAllocationSiteDependentCodesProcessed) {
- if (!V8_ALLOCATION_SITE_TRACKING_BOOL) {
- return;
- }
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- v8::internal::Heap* heap = CcTest::heap();
- GlobalHandles* global_handles = isolate->global_handles();
-
- if (!isolate->use_optimizer()) return;
-
- // The allocation site at the head of the list is ours.
- IndirectHandle<AllocationSite> site;
- {
- LocalContext context;
- v8::HandleScope scope(CcTest::isolate());
-
- int count = AllocationSitesCount(heap);
- CompileRun(
- "var bar = function() { return (new Array()); };"
- "%PrepareFunctionForOptimization(bar);"
- "var a = bar();"
- "bar();"
- "bar();");
-
- // One allocation site should have been created.
- int new_count = AllocationSitesCount(heap);
- CHECK_EQ(new_count, (count + 1));
- site = Cast<AllocationSite>(global_handles->Create(
- Cast<AllocationSite>(heap->allocation_sites_list())));
-
- CompileRun("%OptimizeFunctionOnNextCall(bar); bar();");
-
- IndirectHandle<JSFunction> bar_handle = Cast<JSFunction>(
- v8::Utils::OpenIndirectHandle(*v8::Local<v8::Function>::Cast(
- CcTest::global()
- ->Get(context.local(), v8_str("bar"))
- .ToLocalChecked())));
-
- // Expect a dependent code object for transitioning and pretenuring.
- Tagged<DependentCode> dependency = site->dependent_code();
- CHECK_NE(dependency,
- DependentCode::empty_dependent_code(ReadOnlyRoots(isolate)));
- CHECK_EQ(dependency->length().value(), DependentCode::kSlotsPerEntry);
- Tagged<MaybeObject> code =
- dependency->Get(0 + DependentCode::kCodeSlotOffset);
- CHECK(code.IsWeak());
- CHECK_EQ(bar_handle->code(isolate),
- Cast<CodeWrapper>(code.GetHeapObjectAssumeWeak())->code(isolate));
- Tagged<Smi> groups =
- dependency->Get(0 + DependentCode::kGroupsSlotOffset).ToSmi();
- CHECK_EQ(static_cast<DependentCode::DependencyGroups>(groups.value()),
- DependentCode::kAllocationSiteTransitionChangedGroup |
- DependentCode::kAllocationSiteTenuringChangedGroup);
- }
-
- // Now make sure that a gc should get rid of the function, even though we
- // still have the allocation site alive.
- for (int i = 0; i < 4; i++) {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- // The site still exists because of our global handle, but the code is no
- // longer referred to by dependent_code().
- CHECK(site->dependent_code()->Get(0).IsCleared());
-}
-
void CheckNumberOfAllocations(Heap* heap, const char* source,
int expected_full_alloc,
int expected_slim_alloc) {
@@ -4679,271 +921,6 @@ static DirectHandle<InstructionStream> DummyOptimizedCode(Isolate* isolate) {
return code;
}
-static bool weak_ic_cleared = false;
-
-static void ClearWeakIC(
- const v8::WeakCallbackInfo<v8::Persistent<v8::Object>>& data) {
- printf("clear weak is called\n");
- weak_ic_cleared = true;
- data.GetParameter()->Reset();
-}
-
-TEST(WeakFunctionInConstructor) {
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- v8::internal::Heap* heap = CcTest::heap();
- LocalContext env;
- v8::HandleScope scope(isolate);
-
- CompileRun(
- "function createObj(obj) {"
- " return new obj();"
- "}");
- i::IndirectHandle<JSFunction> createObj = Cast<JSFunction>(
- v8::Utils::OpenIndirectHandle(*v8::Local<v8::Function>::Cast(
- CcTest::global()
- ->Get(env.local(), v8_str("createObj"))
- .ToLocalChecked())));
-
- v8::Persistent<v8::Object> garbage;
- {
- v8::HandleScope new_scope(isolate);
- const char* source =
- " (function() {"
- " function hat() { this.x = 5; }"
- " %EnsureFeedbackVectorForFunction(hat);"
- " %EnsureFeedbackVectorForFunction(createObj);"
- " createObj(hat);"
- " createObj(hat);"
- " return hat;"
- " })();";
- garbage.Reset(isolate, CompileRun(env.local(), source)
- .ToLocalChecked()
- ->ToObject(env.local())
- .ToLocalChecked());
- }
- weak_ic_cleared = false;
- garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter);
- {
- // In this test, we need to invoke GC without stack, otherwise some objects
- // may not be reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(weak_ic_cleared);
-
- // We've determined the constructor in createObj has had it's weak cell
- // cleared. Now, verify that one additional call with a new function
- // allows monomorphicity.
- IndirectHandle<FeedbackVector> feedback_vector(createObj->feedback_vector(),
- CcTest::i_isolate());
- for (int i = 0; i < 20; i++) {
- Tagged<MaybeObject> slot_value = feedback_vector->Get(FeedbackSlot(0));
- CHECK(slot_value.IsWeakOrCleared());
- if (slot_value.IsCleared()) break;
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
-
- Tagged<MaybeObject> slot_value = feedback_vector->Get(FeedbackSlot(0));
- CHECK(slot_value.IsCleared());
- CompileRun(
- "function coat() { this.x = 6; }"
- "createObj(coat);");
- slot_value = feedback_vector->Get(FeedbackSlot(0));
- CHECK(slot_value.IsWeak());
-}
-
-// Checks that the value returned by execution of the source is weak.
-void CheckWeakness(const char* source) {
- v8_flags.stress_compaction = false;
- v8_flags.stress_incremental_marking = false;
- v8_flags.allow_natives_syntax = true;
- CcTest::InitializeVM();
- v8::Isolate* isolate = CcTest::isolate();
- Heap* heap = CcTest::heap();
- LocalContext env;
- v8::HandleScope scope(isolate);
- v8::Persistent<v8::Object> garbage;
- {
- v8::HandleScope new_scope(isolate);
- garbage.Reset(isolate, CompileRun(env.local(), source)
- .ToLocalChecked()
- ->ToObject(env.local())
- .ToLocalChecked());
- }
- weak_ic_cleared = false;
- garbage.SetWeak(&garbage, &ClearWeakIC, v8::WeakCallbackType::kParameter);
- {
- // We need to invoke GC without stack, otherwise some objects may not be
- // reclaimed because of conservative stack scanning.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- CHECK(weak_ic_cleared);
-}
-
-// Each of the following "weak IC" tests creates an IC that embeds a map with
-// the prototype pointing to _proto_ and checks that the _proto_ dies on GC.
-TEST(WeakMapInMonomorphicLoadIC) {
- CheckWeakness(
- "function loadIC(obj) {"
- " return obj.name;"
- "}"
- "%EnsureFeedbackVectorForFunction(loadIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " loadIC(obj);"
- " loadIC(obj);"
- " loadIC(obj);"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInPolymorphicLoadIC) {
- CheckWeakness(
- "function loadIC(obj) {"
- " return obj.name;"
- "}"
- "%EnsureFeedbackVectorForFunction(loadIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " loadIC(obj);"
- " loadIC(obj);"
- " loadIC(obj);"
- " var poly = Object.create(proto);"
- " poly.x = true;"
- " loadIC(poly);"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInMonomorphicKeyedLoadIC) {
- CheckWeakness(
- "function keyedLoadIC(obj, field) {"
- " return obj[field];"
- "}"
- "%EnsureFeedbackVectorForFunction(keyedLoadIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " keyedLoadIC(obj, 'name');"
- " keyedLoadIC(obj, 'name');"
- " keyedLoadIC(obj, 'name');"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInPolymorphicKeyedLoadIC) {
- CheckWeakness(
- "function keyedLoadIC(obj, field) {"
- " return obj[field];"
- "}"
- "%EnsureFeedbackVectorForFunction(keyedLoadIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " keyedLoadIC(obj, 'name');"
- " keyedLoadIC(obj, 'name');"
- " keyedLoadIC(obj, 'name');"
- " var poly = Object.create(proto);"
- " poly.x = true;"
- " keyedLoadIC(poly, 'name');"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInMonomorphicStoreIC) {
- CheckWeakness(
- "function storeIC(obj, value) {"
- " obj.name = value;"
- "}"
- "%EnsureFeedbackVectorForFunction(storeIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " storeIC(obj, 'x');"
- " storeIC(obj, 'x');"
- " storeIC(obj, 'x');"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInPolymorphicStoreIC) {
- CheckWeakness(
- "function storeIC(obj, value) {"
- " obj.name = value;"
- "}"
- "%EnsureFeedbackVectorForFunction(storeIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " storeIC(obj, 'x');"
- " storeIC(obj, 'x');"
- " storeIC(obj, 'x');"
- " var poly = Object.create(proto);"
- " poly.x = true;"
- " storeIC(poly, 'x');"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInMonomorphicKeyedStoreIC) {
- CheckWeakness(
- "function keyedStoreIC(obj, field, value) {"
- " obj[field] = value;"
- "}"
- "%EnsureFeedbackVectorForFunction(keyedStoreIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " keyedStoreIC(obj, 'x');"
- " keyedStoreIC(obj, 'x');"
- " keyedStoreIC(obj, 'x');"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInPolymorphicKeyedStoreIC) {
- CheckWeakness(
- "function keyedStoreIC(obj, field, value) {"
- " obj[field] = value;"
- "}"
- "%EnsureFeedbackVectorForFunction(keyedStoreIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " keyedStoreIC(obj, 'x');"
- " keyedStoreIC(obj, 'x');"
- " keyedStoreIC(obj, 'x');"
- " var poly = Object.create(proto);"
- " poly.x = true;"
- " keyedStoreIC(poly, 'x');"
- " return proto;"
- " })();");
-}
-
-TEST(WeakMapInMonomorphicCompareNilIC) {
- v8_flags.allow_natives_syntax = true;
- CheckWeakness(
- "function compareNilIC(obj) {"
- " return obj == null;"
- "}"
- "%EnsureFeedbackVectorForFunction(compareNilIC);"
- " (function() {"
- " var proto = {'name' : 'weak'};"
- " var obj = Object.create(proto);"
- " compareNilIC(obj);"
- " compareNilIC(obj);"
- " compareNilIC(obj);"
- " return proto;"
- " })();");
-}
DirectHandle<JSFunction> GetFunctionByName(Isolate* isolate, const char* name) {
DirectHandle<String> str = isolate->factory()->InternalizeUtf8String(name);
@@ -6281,7 +2258,6 @@ TEST(YoungGenerationLargeObjectAllocationScavenge) {
Isolate* isolate = heap->isolate();
if (!isolate->serializer_enabled()) return;
- // TODO(hpayer): Update the test as soon as we have a tenure limit for LO.
DirectHandle<FixedArray> array_small =
isolate->factory()->NewFixedArray(200000);
MemoryChunk* chunk = MemoryChunk::FromHeapObject(*array_small);
@@ -6313,7 +2289,6 @@ TEST(YoungGenerationLargeObjectAllocationMarkCompact) {
Isolate* isolate = heap->isolate();
if (!isolate->serializer_enabled()) return;
- // TODO(hpayer): Update the test as soon as we have a tenure limit for LO.
DirectHandle<FixedArray> array_small =
isolate->factory()->NewFixedArray(200000);
MemoryChunk* chunk = MemoryChunk::FromHeapObject(*array_small);
@@ -6390,370 +2365,6 @@ TEST(UncommitUnusedLargeObjectMemory) {
CHECK_EQ(shrinked_size, page->CommittedPhysicalMemory());
}
-template <RememberedSetType direction>
-static size_t GetRememberedSetSize(Tagged<HeapObject> obj) {
- size_t count = 0;
- auto chunk = MutablePage::FromHeapObject(CcTest::i_isolate(), obj);
- RememberedSet<direction>::Iterate(
- chunk,
- [&count](MaybeObjectSlot slot) {
- count++;
- return KEEP_SLOT;
- },
- SlotSet::KEEP_EMPTY_BUCKETS);
- return count;
-}
-
-TEST(RememberedSet_InsertOnWriteBarrier) {
- if (v8_flags.single_generation) return;
- v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
- heap::SealCurrentObjects(heap);
- HandleScope scope(isolate);
-
- // Allocate an object in old space.
- DirectHandle<FixedArray> arr =
- factory->NewFixedArray(3, AllocationType::kOld);
-
- // Add into 'arr' references to young objects.
- {
- HandleScope scope_inner(isolate);
- DirectHandle<Object> number = factory->NewHeapNumber(42);
- arr->set(0, *number);
- arr->set(1, *number);
- arr->set(2, *number);
- DirectHandle<Object> number_other = factory->NewHeapNumber(24);
- arr->set(2, *number_other);
- }
- // Remembered sets track *slots* pages with cross-generational pointers, so
- // must have recorded three of them each exactly once.
- CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*arr));
-}
-
-TEST(RememberedSet_InsertInLargePage) {
- if (v8_flags.single_generation) return;
- v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
- heap::SealCurrentObjects(heap);
- HandleScope scope(isolate);
-
- // Allocate an object in Large space.
- const int count = std::max(FixedArray::kMaxRegularLength + 1, 128 * KB);
- DirectHandle<FixedArray> arr =
- factory->NewFixedArray(count, AllocationType::kOld);
- CHECK(heap->lo_space()->Contains(*arr));
- CHECK_EQ(0, GetRememberedSetSize<OLD_TO_NEW>(*arr));
-
- // Create OLD_TO_NEW references from the large object so that the
- // corresponding slots end up in different SlotSets.
- {
- HandleScope short_lived(isolate);
- DirectHandle<Object> number = factory->NewHeapNumber(42);
- arr->set(0, *number);
- arr->set(count - 1, *number);
- }
- CHECK_EQ(2, GetRememberedSetSize<OLD_TO_NEW>(*arr));
-}
-
-TEST(RememberedSet_RemoveStaleOnScavenge) {
- if (v8_flags.single_generation || v8_flags.stress_incremental_marking) return;
- v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
- heap::SealCurrentObjects(heap);
- HandleScope scope(isolate);
-
- // Allocate an object in old space and add into it references to young.
- DirectHandle<FixedArray> arr =
- factory->NewFixedArray(3, AllocationType::kOld);
- {
- HandleScope scope_inner(isolate);
- DirectHandle<Object> number = factory->NewHeapNumber(42);
- arr->set(0, *number); // will be trimmed away
- arr->set(1, *number); // will be replaced with #undefined
- arr->set(2, *number); // will be promoted into old
- }
- CHECK_EQ(3, GetRememberedSetSize<OLD_TO_NEW>(*arr));
-
- arr->set(1, ReadOnlyRoots(CcTest::heap()).undefined_value());
- DirectHandle<FixedArrayBase> tail(heap->LeftTrimFixedArray(*arr, 1), isolate);
-
- // The first slot should be removed from the remembered set since the length
- // is now in that place and represented as a uint32_t.
- CHECK_EQ(2, GetRememberedSetSize<OLD_TO_NEW>(*tail));
-
- // Run GC to promote the remaining young object and fixup the stale entries in
- // the remembered set.
- heap::EmptyNewSpaceUsingGC(heap);
- CHECK_EQ(0, GetRememberedSetSize<OLD_TO_NEW>(*tail));
-}
-
-// The OLD_TO_OLD remembered set is created temporary by GC and is cleared at
-// the end of the pass. There is no way to observe it so the test only checks
-// that compaction has happened and otherwise relies on code's self-validation.
-TEST(RememberedSet_OldToOld) {
- if (v8_flags.stress_incremental_marking) return;
- v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
- ManualGCScope manual_gc_scope;
- heap::ManualEvacuationCandidatesSelectionScope
- manual_evacuation_candidate_selection_scope(manual_gc_scope);
- CcTest::InitializeVM();
- Isolate* isolate = CcTest::i_isolate();
- Factory* factory = isolate->factory();
- Heap* heap = isolate->heap();
- heap::SealCurrentObjects(heap);
-
- Global<v8::FixedArray> arr_global;
- Tagged<FixedArray> prev_location;
- {
- HandleScope scope(isolate);
-
- IndirectHandle<FixedArray> arr =
- factory->NewFixedArray(10, AllocationType::kOld);
- {
- HandleScope short_lived(isolate);
- factory->NewFixedArray(100, AllocationType::kOld);
- }
- IndirectHandle<Object> ref =
- factory->NewFixedArray(100, AllocationType::kOld);
- arr->set(0, *ref);
-
- // To force compaction of the old space, fill it with garbage and start a
- // new page (so that the page with 'arr' becomes subject to compaction).
- {
- HandleScope short_lived(isolate);
- heap::SimulateFullSpace(heap->old_space());
- factory->NewFixedArray(100, AllocationType::kOld);
- }
-
- heap::ForceEvacuationCandidate(NormalPage::FromHeapObject(*arr));
- prev_location = *arr;
- arr_global.Reset(CcTest::isolate(), v8::Utils::FixedArrayToLocal(arr));
- }
- {
- // This GC pass will evacuate the page with 'arr'/'ref' so it will have to
- // create OLD_TO_OLD remembered set to track the reference.
- // We need to invoke GC without stack, otherwise no compaction is performed.
- DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
- heap::InvokeMajorGC(heap);
- }
- {
- v8::HandleScope scope(CcTest::isolate());
- IndirectHandle<FixedArray> arr =
- v8::Utils::OpenHandle(*arr_global.Get(CcTest::isolate()));
- CHECK_NE(prev_location.ptr(), arr->ptr());
- }
-}
-
-TEST(RememberedSetRemoveRange) {
- if (v8_flags.single_generation) return;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- Isolate* isolate = heap->isolate();
-
- DirectHandle<FixedArray> array = isolate->factory()->NewFixedArray(
- NormalPage::kPageSize / kTaggedSize, AllocationType::kOld);
- MutablePage* chunk = MutablePage::FromHeapObject(isolate, *array);
- CHECK_EQ(chunk->owner_identity(), LO_SPACE);
- Address start = array->address();
- // Maps slot to boolean indicator of whether the slot should be in the set.
- std::map<Address, bool> slots;
- slots[start + 0] = true;
- slots[start + kTaggedSize] = true;
- slots[start + NormalPage::kPageSize - kTaggedSize] = true;
- slots[start + NormalPage::kPageSize] = true;
- slots[start + NormalPage::kPageSize + kTaggedSize] = true;
- slots[chunk->area_end() - kTaggedSize] = true;
-
- for (auto x : slots) {
- RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>(
- chunk, chunk->Offset(x.first));
- }
-
- RememberedSet<OLD_TO_NEW>::Iterate(
- chunk,
- [&slots](MaybeObjectSlot slot) {
- CHECK(slots[slot.address()]);
- return KEEP_SLOT;
- },
- SlotSet::FREE_EMPTY_BUCKETS);
-
- RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, start + kTaggedSize,
- SlotSet::FREE_EMPTY_BUCKETS);
- slots[start] = false;
- RememberedSet<OLD_TO_NEW>::Iterate(
- chunk,
- [&slots](MaybeObjectSlot slot) {
- CHECK(slots[slot.address()]);
- return KEEP_SLOT;
- },
- SlotSet::FREE_EMPTY_BUCKETS);
-
- RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start + kTaggedSize,
- start + NormalPage::kPageSize,
- SlotSet::FREE_EMPTY_BUCKETS);
- slots[start + kTaggedSize] = false;
- slots[start + NormalPage::kPageSize - kTaggedSize] = false;
- RememberedSet<OLD_TO_NEW>::Iterate(
- chunk,
- [&slots](MaybeObjectSlot slot) {
- CHECK(slots[slot.address()]);
- return KEEP_SLOT;
- },
- SlotSet::FREE_EMPTY_BUCKETS);
-
- RememberedSet<OLD_TO_NEW>::RemoveRange(
- chunk, start, start + NormalPage::kPageSize + kTaggedSize,
- SlotSet::FREE_EMPTY_BUCKETS);
- slots[start + NormalPage::kPageSize] = false;
- RememberedSet<OLD_TO_NEW>::Iterate(
- chunk,
- [&slots](MaybeObjectSlot slot) {
- CHECK(slots[slot.address()]);
- return KEEP_SLOT;
- },
- SlotSet::FREE_EMPTY_BUCKETS);
-
- RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, chunk->area_end() - kTaggedSize,
- chunk->area_end(),
- SlotSet::FREE_EMPTY_BUCKETS);
- slots[chunk->area_end() - kTaggedSize] = false;
- RememberedSet<OLD_TO_NEW>::Iterate(
- chunk,
- [&slots](MaybeObjectSlot slot) {
- CHECK(slots[slot.address()]);
- return KEEP_SLOT;
- },
- SlotSet::FREE_EMPTY_BUCKETS);
-}
-
-HEAP_TEST(Regress670675) {
- 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);
-
- heap->EnsureSweepingCompleted(
- Heap::SweepingForcedFinalizationMode::kUnifiedHeap,
- CompleteSweepingReason::kTesting);
- heap->tracer()->StopFullCycleIfFinished();
- i::IncrementalMarking* marking = CcTest::heap()->incremental_marking();
- if (marking->IsStopped()) {
- SafepointScope safepoint_scope(heap->isolate(),
- kGlobalSafepointForSharedSpaceIsolate);
- heap->tracer()->StartCycle(
- GarbageCollector::MARK_COMPACTOR, GarbageCollectionReason::kTesting,
- "collector cctest", GCTracer::MarkingType::kIncremental);
- marking->Start(GarbageCollector::MARK_COMPACTOR,
- i::GarbageCollectionReason::kTesting, "testing");
- }
- size_t array_length = 128 * KB;
- size_t n = heap->OldGenerationSpaceAvailable() / array_length;
- for (size_t i = 0; i < n + 60; i++) {
- {
- HandleScope inner_scope(isolate);
- isolate->factory()->NewFixedArray(static_cast<int>(array_length),
- AllocationType::kOld);
- }
- if (marking->IsStopped()) break;
- marking->AdvanceForTesting(v8::base::TimeDelta::FromMillisecondsD(0.1));
- }
- DCHECK(marking->IsStopped());
-}
-
-HEAP_TEST(RegressMissingWriteBarrierInAllocate) {
- if (!v8_flags.incremental_marking) return;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- LocalContext env;
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- Isolate* isolate = heap->isolate();
- heap::InvokeMajorGC(heap);
- heap::SimulateIncrementalMarking(heap, false);
- DirectHandle<Map> map;
- {
- AlwaysAllocateScopeForTesting always_allocate(heap);
- map = isolate->factory()->NewContextfulMapForCurrentContext(
- JS_OBJECT_TYPE, JSObject::kHeaderSize);
- }
- CHECK(heap->incremental_marking()->black_allocation());
- DirectHandle<JSObject> object;
- {
- AlwaysAllocateScopeForTesting always_allocate(heap);
- object = direct_handle(Cast<JSObject>(isolate->factory()->NewForTest(
- map, AllocationType::kOld)),
- isolate);
- }
- // Initialize backing stores to ensure object is valid.
- ReadOnlyRoots roots(isolate);
- object->set_raw_properties_or_hash(roots.empty_property_array(),
- SKIP_WRITE_BARRIER);
- object->set_elements(roots.empty_fixed_array(), SKIP_WRITE_BARRIER);
-
- // The object is black. If Factory::New sets the map without write-barrier,
- // then the map is white and will be freed prematurely.
- heap::SimulateIncrementalMarking(heap, true);
- heap::InvokeMajorGC(heap);
- if (heap->sweeping_in_progress()) {
- heap->EnsureSweepingCompleted(Heap::SweepingForcedFinalizationMode::kV8Only,
- CompleteSweepingReason::kTesting);
- }
- CHECK(IsMap(object->map()));
-}
-
-HEAP_TEST(MarkCompactEpochCounter) {
- if (!v8_flags.incremental_marking) return;
- ManualGCScope manual_gc_scope;
- CcTest::InitializeVM();
- v8::HandleScope scope(CcTest::isolate());
- Heap* heap = CcTest::heap();
- unsigned epoch0 = heap->mark_compact_collector()->epoch();
- heap::InvokeMajorGC(heap);
- unsigned epoch1 = heap->mark_compact_collector()->epoch();
- CHECK_EQ(epoch0 + 1, epoch1);
- heap::SimulateIncrementalMarking(heap, true);
- heap::InvokeMajorGC(heap);
- unsigned epoch2 = heap->mark_compact_collector()->epoch();
- CHECK_EQ(epoch1 + 1, epoch2);
- heap::InvokeMinorGC(heap);
- unsigned epoch3 = heap->mark_compact_collector()->epoch();
- CHECK_EQ(epoch2, epoch3);
-}
-
-UNINITIALIZED_TEST(ReinitializeStringHashSeed) {
- // Enable rehashing and create an isolate and context.
- i::v8_flags.rehash_snapshot = true;
- for (int i = 1; i < 3; i++) {
- i::v8_flags.hash_seed = 1337 * i;
- v8::Isolate::CreateParams create_params;
- create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
- v8::Isolate* isolate = v8::Isolate::New(create_params);
- {
- v8::Isolate::Scope isolate_scope(isolate);
- CHECK_EQ(static_cast<uint64_t>(1337 * i),
- HashSeed(reinterpret_cast<i::Isolate*>(isolate)).seed());
- v8::HandleScope handle_scope(isolate);
- v8::Local<v8::Context> context = v8::Context::New(isolate);
- CHECK(!context.IsEmpty());
- v8::Context::Scope context_scope(context);
- }
- isolate->Dispose();
- }
-}
-
const int kHeapLimit = 100 * MB;
Isolate* oom_isolate = nullptr;
@@ -7097,10 +2708,7 @@ void HeapTester::UncommitUnusedMemory(Heap* heap) {
class DeleteNative {
public:
- static constexpr ExternalPointerTag kManagedTag = kGenericManagedTag;
- static void Deleter(void* arg) {
- delete reinterpret_cast<DeleteNative*>(arg);
- }
+ static constexpr ManagedTypeId kTypeID = ManagedTypeId::kTestDeleteNative;
};
// The test only runs on 64-bit, because it simulates allocating ~9Gb
@@ -7112,7 +2720,7 @@ TEST(Regress8014) {
{
HandleScope scope(isolate);
for (int i = 0; i < 10000; i++) {
- auto handle = Managed<DeleteNative>::From(
+ auto handle = CppGCManaged<DeleteNative>::Create(
isolate, 1000000, std::make_shared<DeleteNative>());
USE(handle);
}
diff --git a/deps/v8/test/cctest/test-api-interceptors.cc b/deps/v8/test/cctest/test-api-interceptors.cc
index 98460097ac7..fef08bfaa21 100644
--- a/deps/v8/test/cctest/test-api-interceptors.cc
+++ b/deps/v8/test/cctest/test-api-interceptors.cc
@@ -2990,6 +2990,55 @@ THREADED_TEST(PropertyDefinerCallbackInDefineNamedOwnIC) {
}
}
+namespace {
+int descriptor_callback_count;
+v8::Intercepted CheckDescriptorInDefineNamedOwnICCallback(
+ Local<Name> name, const v8::PropertyDescriptor& desc,
+ const v8::PropertyCallbackInfo<Boolean>& info) {
+ ++descriptor_callback_count;
+ CHECK(desc.has_value());
+ CHECK_EQ(42, desc.value()
+ ->Int32Value(info.GetIsolate()->GetCurrentContext())
+ .FromJust());
+ CHECK(desc.has_writable());
+ CHECK(desc.writable());
+ CHECK(desc.has_enumerable());
+ CHECK(desc.enumerable());
+ CHECK(desc.has_configurable());
+ CHECK(desc.configurable());
+ return v8::Intercepted::kYes;
+}
+} // namespace
+
+THREADED_TEST(PropertyDefinerCallbackDescriptorInDefineNamedOwnIC) {
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext env;
+ v8::Local<v8::FunctionTemplate> templ =
+ v8::FunctionTemplate::New(CcTest::isolate());
+ templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ nullptr, nullptr, nullptr, nullptr, nullptr,
+ CheckDescriptorInDefineNamedOwnICCallback));
+ Local<Object> obj = templ->GetFunction(env.local())
+ .ToLocalChecked()
+ ->NewInstance(env.local())
+ .ToLocalChecked();
+ env->Global()->Set(env.local(), v8_str("obj"), obj).FromJust();
+
+ descriptor_callback_count = 0;
+ CompileRun(R"(
+ class Base {
+ constructor(arg) {
+ return arg;
+ }
+ }
+ class Derived extends Base {
+ field = 42;
+ }
+ new Derived(obj);
+ )");
+ CHECK_EQ(1, descriptor_callback_count);
+}
+
namespace {
v8::Intercepted EmptyPropertyDescriptorCallback(
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
@@ -4273,8 +4322,8 @@ THREADED_TEST(IndexedInterceptorOnProto) {
namespace {
-void CheckIndexedInterceptorHasIC(v8::IndexedPropertyGetterCallbackV2 getter,
- v8::IndexedPropertyQueryCallbackV2 query,
+void CheckIndexedInterceptorHasIC(v8::IndexedPropertyGetterCallback getter,
+ v8::IndexedPropertyQueryCallback query,
const char* source, int expected) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -5391,8 +5440,7 @@ THREADED_TEST(NullNamedInterceptor) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
- static_cast<v8::NamedPropertyGetterCallback>(nullptr)));
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(nullptr));
LocalContext context;
templ->Set(CcTest::isolate(), "x", v8_num(42));
v8::Local<v8::Object> obj =
@@ -5409,8 +5457,7 @@ THREADED_TEST(NullIndexedInterceptor) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Local<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
- static_cast<v8::IndexedPropertyGetterCallbackV2>(nullptr)));
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(nullptr));
LocalContext context;
templ->Set(CcTest::isolate(), "42", v8_num(42));
v8::Local<v8::Object> obj =
@@ -5658,11 +5705,9 @@ THREADED_TEST(GetOwnPropertyNamesWithInterceptor) {
obj_template->Set(isolate, "7", v8::Integer::New(isolate, 7));
obj_template->Set(isolate, "x", v8::Integer::New(isolate, 42));
obj_template->SetHandler(v8::IndexedPropertyHandlerConfiguration(
- static_cast<v8::IndexedPropertyGetterCallbackV2>(nullptr), nullptr,
- nullptr, nullptr, IndexedPropertyEnumerator));
+ nullptr, nullptr, nullptr, nullptr, IndexedPropertyEnumerator));
obj_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
- static_cast<v8::NamedPropertyGetterCallback>(nullptr), nullptr, nullptr,
- nullptr, NamedPropertyEnumerator));
+ nullptr, nullptr, nullptr, nullptr, NamedPropertyEnumerator));
LocalContext context;
v8::Local<v8::Object> global = context->Global();
@@ -5727,8 +5772,7 @@ THREADED_TEST(GetOwnPropertyNamesWithIndexedInterceptorExceptions_regress4026) {
obj_template->Set(isolate, "x", v8::Integer::New(isolate, 42));
// First just try a failing indexed interceptor.
obj_template->SetHandler(v8::IndexedPropertyHandlerConfiguration(
- static_cast<v8::IndexedPropertyGetterCallbackV2>(nullptr), nullptr,
- nullptr, nullptr, IndexedPropertyEnumeratorException));
+ nullptr, nullptr, nullptr, nullptr, IndexedPropertyEnumeratorException));
LocalContext context;
v8::Local<v8::Object> global = context->Global();
diff --git a/deps/v8/test/cctest/test-api-stack-traces.cc b/deps/v8/test/cctest/test-api-stack-traces.cc
index 0bda6c06582..d81238b9c30 100644
--- a/deps/v8/test/cctest/test-api-stack-traces.cc
+++ b/deps/v8/test/cctest/test-api-stack-traces.cc
@@ -440,34 +440,6 @@ TEST(CaptureStackTraceForUncaughtException) {
CHECK_EQ(1, report_count);
}
-TEST(CaptureStackTraceForUncaughtExceptionHugeStackTraceLimit) {
- LocalContext env;
- v8::Isolate* isolate = env.isolate();
- v8::HandleScope scope(isolate);
- isolate->SetCaptureStackTraceForUncaughtExceptions(true);
-
- CompileRun(
- "function foo() { return new Error().stack; }\n"
- "function bar() { return foo(); }\n"
- "function stackWithLimit(limit) {\n"
- " Error.stackTraceLimit = limit;\n"
- " return bar();\n"
- "}\n");
- Local<Value> expected = CompileRun("stackWithLimit(10)");
- CHECK(expected->IsString());
-
- // For these limits, limit * CallSiteInfo::Fields::kCount overflows.
- for (const char* limit : {"858993460", "858993461", "Infinity"}) {
- std::string source = std::string("stackWithLimit(") + limit + ")";
- CHECK(CompileRun(source.c_str())->StrictEquals(expected));
- }
-
- // Small limits must still trim the stack trace.
- CHECK(CompileRun("stackWithLimit(1).split('\\n').length === 2")->IsTrue());
-
- isolate->SetCaptureStackTraceForUncaughtExceptions(false);
-}
-
// Test uncaught exception in a setter
const char uncaught_setter_exception_source[] =
"var setters = ['column', 'lineNumber', 'scriptName',\n"
diff --git a/deps/v8/test/cctest/test-api-typed-array.cc b/deps/v8/test/cctest/test-api-typed-array.cc
index dfc2d030462..1878d748dc0 100644
--- a/deps/v8/test/cctest/test-api-typed-array.cc
+++ b/deps/v8/test/cctest/test-api-typed-array.cc
@@ -6,6 +6,7 @@
#include "src/base/strings.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-array-buffer.h"
+#include "src/objects/object-conversions-inl.h"
#include "test/cctest/heap/heap-utils.h"
#include "test/cctest/test-api.h"
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 2d38d994ea3..2c5d1dceebb 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -82,6 +82,7 @@
#include "src/objects/js-promise-inl.h"
#include "src/objects/lookup.h"
#include "src/objects/map-updater.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/string-inl.h"
#include "src/objects/synthetic-module-inl.h"
@@ -9042,6 +9043,28 @@ THREADED_TEST(StringWrite) {
}
}
+THREADED_TEST(NewFromTwoBytePreservesNonLatin1Characters) {
+ LocalContext context;
+ v8::Isolate* isolate = context.isolate();
+ v8::HandleScope scope(isolate);
+
+ // Exercise the word-at-a-time one-byte check in String::NonOneByteStart.
+ constexpr int kLength = static_cast<int>(sizeof(uintptr_t));
+ alignas(uintptr_t) const uint16_t input[kLength] = {0x3000};
+ Local<String> string =
+ String::NewFromTwoByte(isolate, input, v8::NewStringType::kNormal,
+ kLength)
+ .ToLocalChecked();
+
+ CHECK_EQ(kLength, string->Length());
+ CHECK(!string->IsOneByte());
+ uint16_t output[kLength];
+ string->Write(isolate, 0, kLength, output);
+ for (int i = 0; i < kLength; ++i) {
+ CHECK_EQ(input[i], output[i]);
+ }
+}
+
static void Utf16Helper(LocalContext& context, const char* name,
const char* lengths_name, int len) {
Local<v8::Array> a = Local<v8::Array>::Cast(
@@ -22491,6 +22514,26 @@ TEST(RequestInterruptSmallScripts) {
CHECK(interrupt_was_called);
}
+#ifdef V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
+static bool interrupt_check_no_js = false;
+void DisallowJsInterruptCallback(v8::Isolate* isolate, void* data) {
+ CHECK(!i::AllowJavascriptExecution::IsAllowed(
+ reinterpret_cast<i::Isolate*>(isolate)));
+ interrupt_check_no_js = true;
+}
+
+TEST(RequestInterruptDisallowsJavascript) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+
+ interrupt_check_no_js = false;
+ isolate->RequestInterrupt(&DisallowJsInterruptCallback, nullptr);
+ CompileRun("(function(x){return x;})(1);");
+ CHECK(interrupt_check_no_js);
+}
+#endif // V8_DISALLOW_JS_IN_API_INTERRUPTS_IS_CHECKED
+
static v8::Global<Value> function_new_expected_env_global;
static void FunctionNewCallback(const v8::FunctionCallbackInfo<Value>& info) {
v8::Isolate* isolate = info.GetIsolate();
@@ -23805,6 +23848,123 @@ TEST_WITH_PLATFORM(DumpOnJavascriptExecution, MockPlatform) {
CHECK(platform.dump_without_crashing_called());
}
+namespace {
+void TestMicrotaskCheckpointCallback(v8::Local<v8::Data> data) {
+ int* count = GetData<int>(data);
+ (*count)++;
+}
+void TestMicrotaskFunctionCallback(
+ const v8::FunctionCallbackInfo<v8::Value>& info) {
+ int* count = GetData<int>(info);
+ (*count)++;
+}
+} // namespace
+
+TEST(MicrotaskCheckpointDisallowJavascriptExecutionScope) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+ v8::MicrotaskQueue* microtask_queue = env.local()->GetMicrotaskQueue();
+
+ // 1. Explicit policy: C++ microtask callback with CRASH_ON_FAILURE.
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kExplicit);
+ int microtasks_run_count = 0;
+ microtask_queue->EnqueueMicrotask(isolate, TestMicrotaskCheckpointCallback,
+ MakeData(isolate, µtasks_run_count));
+ {
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(0, microtasks_run_count);
+ }
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(1, microtasks_run_count);
+
+ // 2. Explicit policy: JS function microtask callback with CRASH_ON_FAILURE.
+ microtasks_run_count = 0;
+ v8::Local<v8::FunctionTemplate> t =
+ v8::FunctionTemplate::New(isolate, TestMicrotaskFunctionCallback,
+ MakeData(isolate, µtasks_run_count));
+ v8::Local<v8::Function> fn = t->GetFunction(env.local()).ToLocalChecked();
+ microtask_queue->EnqueueMicrotask(isolate, fn);
+ {
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(0, microtasks_run_count);
+ }
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(1, microtasks_run_count);
+
+ // 3. THROW_ON_FAILURE.
+ microtasks_run_count = 0;
+ microtask_queue->EnqueueMicrotask(isolate, TestMicrotaskCheckpointCallback,
+ MakeData(isolate, µtasks_run_count));
+ {
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::THROW_ON_FAILURE);
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(0, microtasks_run_count);
+ }
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(1, microtasks_run_count);
+
+ // 4. DUMP_ON_FAILURE.
+ microtasks_run_count = 0;
+ microtask_queue->EnqueueMicrotask(isolate, TestMicrotaskCheckpointCallback,
+ MakeData(isolate, µtasks_run_count));
+ {
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::DUMP_ON_FAILURE);
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(0, microtasks_run_count);
+ }
+ v8::MicrotasksScope::PerformCheckpoint(isolate);
+ CHECK_EQ(1, microtasks_run_count);
+
+ // 5. Scoped policy: MicrotasksScope destructor inside
+ // DisallowJavascriptExecutionScope.
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kScoped);
+ microtasks_run_count = 0;
+ microtask_queue->EnqueueMicrotask(isolate, TestMicrotaskCheckpointCallback,
+ MakeData(isolate, µtasks_run_count));
+ {
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ {
+ v8::MicrotasksScope microtasks_scope(env.local(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ }
+ CHECK_EQ(0, microtasks_run_count);
+ }
+ {
+ v8::MicrotasksScope microtasks_scope(env.local(),
+ v8::MicrotasksScope::kRunMicrotasks);
+ }
+ CHECK_EQ(1, microtasks_run_count);
+
+ // 6. kAuto policy: top-level Api call (v8::Object::HasOwnProperty()) inside
+ // DisallowJavascriptExecutionScope.
+ isolate->SetMicrotasksPolicy(v8::MicrotasksPolicy::kAuto);
+ microtasks_run_count = 0;
+ microtask_queue->EnqueueMicrotask(isolate, TestMicrotaskCheckpointCallback,
+ MakeData(isolate, µtasks_run_count));
+ {
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ CHECK(env->Global()->HasOwnProperty(env.local(), v8_str("foo")).IsJust());
+ CHECK_EQ(0, microtasks_run_count);
+ }
+ CHECK(env->Global()->HasOwnProperty(env.local(), v8_str("foo")).IsJust());
+ CHECK_EQ(1, microtasks_run_count);
+}
+
TEST(Regress354123) {
LocalContext current;
v8::Isolate* isolate = current.isolate();
@@ -24961,33 +25121,52 @@ TEST(CodeCache) {
isolate2->Dispose();
}
-v8::MaybeLocal<Value> UnexpectedSyntheticModuleEvaluationStepsCallback(
+v8::MaybeLocal<Promise> UnexpectedSyntheticModuleEvaluationStepsCallback(
Local<Context> context, Local<Module> module) {
CHECK_WITH_MSG(false, "Unexpected call to synthetic module re callback");
}
static int synthetic_module_callback_count;
-v8::MaybeLocal<Value> SyntheticModuleEvaluationStepsCallback(
+v8::MaybeLocal<Promise> SyntheticModuleEvaluationStepsCallback(
Local<Context> context, Local<Module> module) {
synthetic_module_callback_count++;
- return v8::Undefined(reinterpret_cast<v8::Isolate*>(CcTest::isolate()));
+ Local<v8::Promise::Resolver> resolver =
+ v8::Promise::Resolver::New(context).ToLocalChecked();
+ resolver->Resolve(context, v8::Undefined(CcTest::isolate())).Check();
+ return resolver->GetPromise();
}
-v8::MaybeLocal<Value> SyntheticModuleEvaluationStepsCallbackFail(
+v8::MaybeLocal<Promise> SyntheticModuleEvaluationStepsCallbackFail(
Local<Context> context, Local<Module> module) {
synthetic_module_callback_count++;
CcTest::isolate()->ThrowException(
v8_str("SyntheticModuleEvaluationStepsCallbackFail exception"));
- return v8::MaybeLocal<Value>();
+ return v8::MaybeLocal<Promise>();
+}
+
+// Deprecated version of the evaluation steps, returning a MaybeLocal<Value>
+// that holds a Promise.
+// TODO(https://crbug.com/545375591): Remove together with
+// v8::Module::LegacySyntheticModuleEvaluationSteps.
+v8::MaybeLocal<Value> LegacySyntheticModuleEvaluationStepsCallback(
+ Local<Context> context, Local<Module> module) {
+ synthetic_module_callback_count++;
+ Local<v8::Promise::Resolver> resolver =
+ v8::Promise::Resolver::New(context).ToLocalChecked();
+ resolver->Resolve(context, v8::Undefined(CcTest::isolate())).Check();
+ return resolver->GetPromise();
}
-v8::MaybeLocal<Value> SyntheticModuleEvaluationStepsCallbackSetExport(
+v8::MaybeLocal<Promise> SyntheticModuleEvaluationStepsCallbackSetExport(
Local<Context> context, Local<Module> module) {
Maybe<bool> set_export_result = module->SetSyntheticModuleExport(
CcTest::isolate(), v8_str("test_export"), v8_num(42));
CHECK(set_export_result.FromJust());
- return v8::Undefined(reinterpret_cast<v8::Isolate*>(CcTest::isolate()));
+ Local<v8::Promise::Resolver> resolver =
+ v8::Promise::Resolver::New(context).ToLocalChecked();
+ resolver->Resolve(context, v8::Undefined(CcTest::isolate())).Check();
+ return resolver->GetPromise();
}
namespace {
@@ -25318,7 +25497,44 @@ TEST(SyntheticModuleEvaluationStepsNoThrow) {
context, export_names, SyntheticModuleEvaluationStepsCallback);
CHECK_EQ(synthetic_module_callback_count, 0);
Local<Value> completion_value = module->Evaluate(context).ToLocalChecked();
- CHECK(completion_value->IsUndefined());
+ CHECK(completion_value->IsPromise());
+ Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value));
+ CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
+ CHECK(promise->Result()->IsUndefined());
+ CHECK_EQ(synthetic_module_callback_count, 1);
+ CHECK_EQ(module->GetStatus(), Module::kEvaluated);
+}
+
+// Covers the deprecated evaluation steps version, where the returned Promise is
+// only checked at runtime.
+// TODO(https://crbug.com/545375591): Remove together with
+// v8::Module::LegacySyntheticModuleEvaluationSteps.
+TEST(SyntheticModuleEvaluationStepsLegacyCallback) {
+ synthetic_module_callback_count = 0;
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::Isolate::Scope iscope(isolate);
+ v8::HandleScope scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ v8::Context::Scope cscope(context);
+
+ auto export_names = std::to_array<Local<v8::String>>({v8_str("default")});
+
+ START_ALLOW_USE_DEPRECATED()
+ Local<Module> module = v8::Module::CreateSyntheticModule(
+ isolate,
+ v8_str("SyntheticModuleEvaluationStepsLegacyCallback-"
+ "TestSyntheticModule"),
+ export_names, LegacySyntheticModuleEvaluationStepsCallback);
+ END_ALLOW_USE_DEPRECATED()
+ module->InstantiateModule(context, UnexpectedModuleResolveCallback)
+ .ToChecked();
+
+ CHECK_EQ(synthetic_module_callback_count, 0);
+ Local<Value> completion_value = module->Evaluate(context).ToLocalChecked();
+ CHECK(completion_value->IsPromise());
+ Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value));
+ CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
CHECK_EQ(synthetic_module_callback_count, 1);
CHECK_EQ(module->GetStatus(), Module::kEvaluated);
}
@@ -25376,7 +25592,10 @@ TEST(SyntheticModuleEvaluationStepsSetExport) {
CHECK(IsUndefined(test_export_cell->value()));
Local<Value> completion_value = module->Evaluate(context).ToLocalChecked();
- CHECK(completion_value->IsUndefined());
+ CHECK(completion_value->IsPromise());
+ Local<v8::Promise> promise(Local<v8::Promise>::Cast(completion_value));
+ CHECK_EQ(promise->State(), v8::Promise::kFulfilled);
+ CHECK(promise->Result()->IsUndefined());
CHECK_EQ(42, i::Object::NumberValue(test_export_cell->value()));
CHECK_EQ(module->GetStatus(), Module::kEvaluated);
}
@@ -26206,6 +26425,8 @@ TEST(FutexInterruption) {
timeout_thread.Join();
}
+
+
TEST(StackCheckTermination) {
v8::Isolate* isolate = CcTest::isolate();
i::Isolate* i_isolate = CcTest::i_isolate();
@@ -27304,7 +27525,7 @@ MaybeLocal<Module> CheckResolveModuleWithImportSource(
return v8::Module::CreateSyntheticModule(
isolate, v8_str("my-mod"), {},
- [](Local<Context> context, Local<Module> module) -> MaybeLocal<Value> {
+ [](Local<Context> context, Local<Module> module) -> MaybeLocal<Promise> {
// Do nothing.
Local<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(context).ToLocalChecked();
@@ -30652,17 +30873,10 @@ TEST(CodeLikeFunction) {
}
namespace {
-#ifdef V8_CPPGC_MICROTASK_QUEUE
template <typename T>
T* GetRaw(T* ptr) {
return ptr;
}
-#else
-template <typename T>
-T* GetRaw(const std::unique_ptr<T>& ptr) {
- return ptr.get();
-}
-#endif // V8_CPPGC_MICROTASK_QUEUE
} // namespace
THREADED_TEST(MicrotaskQueueOfContext) {
@@ -30745,69 +30959,6 @@ TEST(TestSetSabConstructorEnabledCallback) {
CHECK(i_isolate->IsSharedArrayBufferConstructorEnabled(i_context));
}
-namespace {
-void NodeTypeCallback(const v8::FunctionCallbackInfo<v8::Value>& info) {
- CHECK(i::ValidateCallbackInfo(info));
- v8::Isolate* isolate = info.GetIsolate();
- info.GetReturnValue().Set(v8::Number::New(isolate, 1));
-}
-} // namespace
-
-TEST(EmbedderInstanceTypes) {
- LocalContext env;
- v8::Isolate* isolate = env.isolate();
- v8::HandleScope scope(isolate);
- i::v8_flags.experimental_embedder_instance_types = true;
- Local<FunctionTemplate> node = FunctionTemplate::New(isolate);
- Local<ObjectTemplate> proto_template = node->PrototypeTemplate();
-
- enum JSApiInstanceType : uint16_t {
- kGenericApiObject = 0, // FunctionTemplateInfo::kNoJSApiObjectType.
- kElement,
- kHTMLElement,
- kHTMLDivElement,
- };
-
- Local<FunctionTemplate> nodeType = v8::FunctionTemplate::New(
- isolate, NodeTypeCallback, Local<Value>(),
- v8::Signature::New(isolate, node), 0, v8::ConstructorBehavior::kThrow,
- v8::SideEffectType::kHasSideEffect, nullptr, kGenericApiObject, kElement,
- kHTMLDivElement);
- proto_template->SetAccessorProperty(
- String::NewFromUtf8Literal(isolate, "nodeType"), nodeType);
-
- Local<FunctionTemplate> element = FunctionTemplate::New(
- isolate, nullptr, Local<Value>(), Local<v8::Signature>(), 0,
- v8::ConstructorBehavior::kAllow, v8::SideEffectType::kHasSideEffect,
- nullptr, kElement);
- element->Inherit(node);
-
- Local<FunctionTemplate> html_element = FunctionTemplate::New(
- isolate, nullptr, Local<Value>(), Local<v8::Signature>(), 0,
- v8::ConstructorBehavior::kAllow, v8::SideEffectType::kHasSideEffect,
- nullptr, kHTMLElement);
- html_element->Inherit(element);
-
- Local<FunctionTemplate> div_element = FunctionTemplate::New(
- isolate, nullptr, Local<Value>(), Local<v8::Signature>(), 0,
- v8::ConstructorBehavior::kAllow, v8::SideEffectType::kHasSideEffect,
- nullptr, kHTMLDivElement);
- div_element->Inherit(html_element);
-
- CHECK(env->Global()
- ->Set(env.local(), v8_str("div"),
- div_element->GetFunction(env.local())
- .ToLocalChecked()
- ->NewInstance(env.local())
- .ToLocalChecked())
- .FromJust());
-
- CompileRun("var x = div.nodeType;");
-
- Local<Value> res =
- env->Global()->Get(env.local(), v8_str("x")).ToLocalChecked();
- CHECK_EQ(1, res->ToInt32(env.local()).ToLocalChecked()->Value());
-}
template <typename T>
void TestCopyAndMoveConstructionAndAssignment() {
@@ -31968,6 +32119,65 @@ TEST(ContinuationPreservedEmbedderDataV2_CppHeapExternal) {
isolate->Dispose();
}
+TEST(EmbedderDataAlignedPointers_CppHeapPointer) {
+ 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();
+
+ {
+ v8::HandleScope scope(isolate);
+ LocalContext env(isolate);
+ v8::Local<v8::Object> obj = v8::Object::New(isolate);
+
+ cppgc::Persistent<TestGarbagedCollectedData> cpp_object(
+ cppgc::MakeGarbageCollected<TestGarbagedCollectedData>(
+ cpp_heap->GetAllocationHandle()));
+
+ // Null pointer test.
+ (*env)->SetAlignedPointerInEmbedderData(
+ 0, static_cast<TestGarbagedCollectedData*>(nullptr),
+ v8::CppHeapPointerTag::kTagForTesting);
+ CHECK_EQ(
+ nullptr,
+ (*env)->GetAlignedPointerFromEmbedderData<TestGarbagedCollectedData>(
+ isolate, 0, v8::CppHeapPointerTag::kTagForTesting));
+ CHECK_EQ(nullptr, obj->GetAlignedPointerFromEmbedderDataInCreationContext(
+ isolate, 0, v8::CppHeapPointerTag::kTagForTesting));
+
+ // Valid cppgc object test.
+ (*env)->SetAlignedPointerInEmbedderData(
+ 1, cpp_object.Get(), v8::CppHeapPointerTag::kTagForTesting);
+ CHECK_EQ(
+ cpp_object.Get(),
+ (*env)->GetAlignedPointerFromEmbedderData<TestGarbagedCollectedData>(
+ isolate, 1, v8::CppHeapPointerTag::kTagForTesting));
+ CHECK_EQ(cpp_object.Get(),
+ obj->GetAlignedPointerFromEmbedderDataInCreationContext(
+ isolate, 1, v8::CppHeapPointerTag::kTagForTesting));
+
+ // Detached global proxy test.
+ v8::Local<v8::Object> global_obj = env->Global();
+ (*env)->SetAlignedPointerInEmbedderData(
+ 2, cpp_object.Get(), v8::CppHeapPointerTag::kTagForTesting);
+ CHECK_EQ(cpp_object.Get(),
+ global_obj->GetAlignedPointerFromEmbedderDataInCreationContext(
+ isolate, 2, v8::CppHeapPointerTag::kTagForTesting));
+
+ env->DetachGlobal();
+ CHECK_EQ(cpp_object.Get(),
+ global_obj->GetAlignedPointerFromEmbedderDataInCreationContext(
+ isolate, 2, v8::CppHeapPointerTag::kTagForTesting));
+ }
+
+ isolate->Exit();
+ isolate->Dispose();
+}
+
TEST(IsolateFree) {
v8::Isolate* isolate1 = v8::Isolate::Allocate();
v8::Isolate::Initialize(isolate1, CreateTestParams());
diff --git a/deps/v8/test/cctest/test-api.h b/deps/v8/test/cctest/test-api.h
index 4844a84b6d1..0c3ee7012bd 100644
--- a/deps/v8/test/cctest/test-api.h
+++ b/deps/v8/test/cctest/test-api.h
@@ -283,4 +283,10 @@ static T* GetData(const TCallbackInfo& info) {
v8::External::Cast(*info.Data())->Value(kTestConfigTag));
}
+template <typename T>
+static T* GetData(v8::Local<v8::Data> data) {
+ USE(MakeData);
+ return reinterpret_cast<T*>(v8::External::Cast(*data)->Value(kTestConfigTag));
+}
+
#endif // V8_TEST_CCTEST_TEST_API_H_
diff --git a/deps/v8/test/cctest/test-code-stub-assembler.cc b/deps/v8/test/cctest/test-code-stub-assembler.cc
index 3ee38f5c9e2..6f4ad2c4fab 100644
--- a/deps/v8/test/cctest/test-code-stub-assembler.cc
+++ b/deps/v8/test/cctest/test-code-stub-assembler.cc
@@ -24,6 +24,7 @@
#include "src/objects/dictionary-inl.h"
#include "src/objects/js-array-inl.h"
#include "src/objects/js-promise-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/ordered-hash-table-inl.h"
#include "src/objects/promise-inl.h"
diff --git a/deps/v8/test/cctest/test-cpu-profiler.cc b/deps/v8/test/cctest/test-cpu-profiler.cc
index f723523a7f6..c59754db467 100644
--- a/deps/v8/test/cctest/test-cpu-profiler.cc
+++ b/deps/v8/test/cctest/test-cpu-profiler.cc
@@ -43,6 +43,8 @@
#include "src/codegen/source-position-table.h"
#include "src/deoptimizer/deoptimize-reason.h"
#include "src/execution/embedder-state.h"
+#include "src/execution/frames-inl.h"
+#include "src/execution/frames.h"
#include "src/execution/isolate-inl.h"
#include "src/execution/protectors-inl.h"
#include "src/flags/flags.h"
@@ -5033,6 +5035,47 @@ TEST(CpuProfileJSONSerializationWithEscapedStrings) {
v8::JSON::Parse(context, json_string).ToLocalChecked();
}
+TEST(UnalignedFastCCallFP) {
+ CcTest::InitializeVM();
+ Isolate* isolate = CcTest::i_isolate();
+
+ // We want to construct a fake stack that looks like an EntryFrame,
+ // but with an unaligned next_fast_c_call_fp.
+
+ // Allocate some memory to act as our stack.
+ constexpr int kStackSize = 1024;
+ uint8_t stack[kStackSize];
+
+ Address fp = reinterpret_cast<Address>(&stack[512]);
+ Address sp = fp - 128;
+ Address pc = reinterpret_cast<Address>(
+ isolate->builtins()->code(Builtin::kJSEntry)->instruction_start());
+
+ // Set up the EntryFrame layout.
+ // We need frame type to be ENTRY.
+ base::Memory<Address>(fp + TypedFrameConstants::kFrameTypeOffset) =
+ StackFrame::TypeToMarker(StackFrame::ENTRY);
+
+ // Set up kNextFastCallFrameFPOffset
+ base::Memory<Address>(fp + EntryFrameConstants::kNextFastCallFrameFPOffset) =
+ fp + 1; // Unaligned but valid stack address!
+
+ // Set up kNextExitFrameFPOffset to a valid value just in case
+ base::Memory<Address>(fp + EntryFrameConstants::kNextExitFrameFPOffset) =
+ fp + 128; // valid-ish
+
+ // Iterate over it.
+ StackFrameIteratorForProfilerForTesting it(isolate, pc, fp, sp, kNullAddress,
+ sp);
+
+ // Advance should safely terminate because HasValidExitIfEntryFrame will
+ // return false when it sees the unaligned fast C call FP, instead of doing an
+ // unaligned read.
+ while (!it.done()) {
+ it.Advance();
+ }
+}
+
} // namespace test_cpu_profiler
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/test-debug.cc b/deps/v8/test/cctest/test-debug.cc
index 11cf0aa1e1f..bdc2f12d7f4 100644
--- a/deps/v8/test/cctest/test-debug.cc
+++ b/deps/v8/test/cctest/test-debug.cc
@@ -3487,7 +3487,7 @@ class ContextCheckEventListener : public v8::debug::DebugDelegate {
v8::debug::BreakReasons break_reasons) override {
CheckContext();
}
- void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited,
+ void ScriptCompiled(v8::Local<v8::debug::Script> script,
bool has_compile_error) override {
CheckContext();
}
@@ -3631,7 +3631,7 @@ TEST(EvalContextData) {
// Debug event listener which counts script compiled events.
class ScriptCompiledDelegate : public v8::debug::DebugDelegate {
public:
- void ScriptCompiled(v8::Local<v8::debug::Script>, bool,
+ void ScriptCompiled(v8::Local<v8::debug::Script>,
bool has_compile_error) override {
if (!has_compile_error) {
after_compile_event_count++;
@@ -4537,7 +4537,7 @@ TEST(DebugPromiseInterceptedByTryCatch) {
class NoInterruptsOnDebugEvent : public v8::debug::DebugDelegate {
public:
- void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited,
+ void ScriptCompiled(v8::Local<v8::debug::Script> script,
bool has_compile_error) override {
++after_compile_handler_depth_;
// Do not allow nested AfterCompile events.
@@ -4612,6 +4612,61 @@ TEST(BreakLocationIterator) {
DisableDebugger(isolate);
}
+TEST(EnsureBreakInfoFailedSourcePositions) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
+ v8::HandleScope scope(isolate);
+
+ v8::Local<v8::Value> result =
+ CompileRun("function f() { return 42; } f(); f");
+ DirectHandle<i::Object> function_obj = v8::Utils::OpenDirectHandle(*result);
+ DirectHandle<i::JSFunction> function = Cast<i::JSFunction>(function_obj);
+ Handle<i::SharedFunctionInfo> shared(function->shared(), i_isolate);
+
+ // Clear source position table if any so it needs collection.
+ shared->GetBytecodeArray(i_isolate)->clear_source_position_table(
+ v8::kReleaseStore);
+ CHECK(!shared->GetBytecodeArray(i_isolate)->HasSourcePositionTable());
+
+ // Simulate stack exhaustion by moving stack limit above current stack
+ // pointer. Using numeric_limits::max() - 1024 ensures it works on both 32-bit
+ // and 64-bit architectures without integer overflow.
+ uintptr_t original_limit = i_isolate->stack_guard()->real_climit();
+ uintptr_t exhausted_limit = std::numeric_limits<uintptr_t>::max() - 1024;
+ i_isolate->stack_guard()->SetStackLimit(exhausted_limit);
+
+ EnableDebugger(isolate);
+ // EnsureBreakInfo fails because source position collection fails due to
+ // exhausted stack.
+ CHECK(!i_isolate->debug()->EnsureBreakInfo(shared));
+ CHECK(!shared->HasBreakInfo(i_isolate));
+
+ // Verify SetBreakpoint also fails gracefully when stack is exhausted.
+ DirectHandle<i::BreakPoint> breakpoint = i_isolate->factory()->NewBreakPoint(
+ 1, i_isolate->factory()->empty_string());
+ int position = 0;
+ CHECK(!i_isolate->debug()->SetBreakpoint(shared, breakpoint, &position));
+
+ // Restore the original stack limit so stack is no longer exhausted.
+ i_isolate->stack_guard()->SetStackLimit(original_limit);
+
+ // When conditions are right, EnsureBreakInfo can be retried successfully.
+ CHECK(i_isolate->debug()->EnsureBreakInfo(shared));
+ CHECK(shared->HasBreakInfo(i_isolate));
+ CHECK(shared->GetBytecodeArray(i_isolate)->HasSourcePositionTable());
+
+ // Verify SetBreakpoint now succeeds.
+ CHECK(i_isolate->debug()->SetBreakpoint(shared, breakpoint, &position));
+
+ // Verify BreakIterator works without crash.
+ Handle<i::DebugInfo> debug_info(shared->GetDebugInfo(i_isolate), i_isolate);
+ i::BreakIterator iterator(debug_info);
+ CHECK(!iterator.Done());
+
+ DisableDebugger(isolate);
+}
+
class DebugStepOverFunctionWithCaughtExceptionListener
: public v8::debug::DebugDelegate {
public:
@@ -5218,7 +5273,7 @@ TEST(SourceInfo) {
namespace {
class SetBreakpointOnScriptCompiled : public v8::debug::DebugDelegate {
public:
- void ScriptCompiled(v8::Local<v8::debug::Script> script, bool is_live_edited,
+ void ScriptCompiled(v8::Local<v8::debug::Script> script,
bool has_compile_error) override {
v8::Local<v8::String> name;
if (!script->SourceURL().ToLocal(&name)) return;
@@ -5871,6 +5926,157 @@ TEST(GetPrivateAutoAccessors) {
}
}
+namespace {
+v8::Global<v8::Module> deferred_module_dependency;
+
+v8::MaybeLocal<v8::Module> DeferredModuleResolveCallback(
+ v8::Local<v8::Context> context, v8::Local<v8::String> specifier,
+ v8::Local<v8::FixedArray> import_attributes,
+ v8::Local<v8::Module> referrer) {
+ return deferred_module_dependency.Get(CcTest::isolate());
+}
+
+// Sets up `globalThis.ns`, the namespace of a deferred module whose body would
+// set `globalThis.evaluated`, and returns it. |dependency_source| must define
+// `globalThis.evaluated = true;` at the top level.
+v8::Local<v8::Object> SetUpDeferredModuleNamespace(
+ v8::Local<v8::Context> context, const char* dependency_source) {
+ v8::Isolate* v8_isolate = CcTest::isolate();
+ v8::ScriptOrigin dependency_origin(v8_str("dependency"), 0, 0, false, -1,
+ v8::Local<v8::Value>(), false, false,
+ true);
+ v8::ScriptCompiler::Source compiled_dependency_source(
+ v8_str(dependency_source), dependency_origin);
+ deferred_module_dependency.Reset(
+ v8_isolate,
+ v8::ScriptCompiler::CompileModule(v8_isolate, &compiled_dependency_source)
+ .ToLocalChecked());
+
+ v8::ScriptOrigin script_origin(v8_str("test"), 0, 0, false, -1,
+ v8::Local<v8::Value>(), false, false, true);
+ v8::ScriptCompiler::Source script_compiler_source(
+ v8_str("import defer * as ns from 'dependency';\n"
+ "globalThis.ns = ns;"),
+ script_origin);
+ v8::Local<v8::Module> module =
+ v8::ScriptCompiler::CompileModule(v8_isolate, &script_compiler_source)
+ .ToLocalChecked();
+ CHECK(module->InstantiateModule(context, DeferredModuleResolveCallback)
+ .ToChecked());
+ module->Evaluate(context).ToLocalChecked();
+
+ // Importing the module namespace does not evaluate the deferred module.
+ CHECK(context->Global()
+ ->Get(context, v8_str("evaluated"))
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ return context->Global()
+ ->Get(context, v8_str("ns"))
+ .ToLocalChecked()
+ .As<v8::Object>();
+}
+} // namespace
+
+// The inspector collects the private members of an object while JavaScript
+// execution is disallowed, so collecting them from a deferred module namespace
+// must not evaluate the module. See crbug.com/451791624.
+TEST(GetPrivateMembersDoesNotEvaluateDeferredModule) {
+ i::v8_flags.js_defer_import_eval = true;
+ LocalContext env;
+ v8::Isolate* v8_isolate = CcTest::isolate();
+ v8::HandleScope scope(v8_isolate);
+ v8::Local<v8::Context> context = env.local();
+
+ v8::Local<v8::Object> object =
+ SetUpDeferredModuleNamespace(context,
+ "globalThis.evaluated = true;\n"
+ "export const foo = 1;");
+ v8::LocalVector<v8::Value> names(v8_isolate);
+ v8::LocalVector<v8::Value> values(v8_isolate);
+ int filter =
+ static_cast<int>(v8::debug::PrivateMemberFilter::kPrivateFields) |
+ static_cast<int>(v8::debug::PrivateMemberFilter::kPrivateMethods) |
+ static_cast<int>(v8::debug::PrivateMemberFilter::kPrivateAccessors);
+ {
+ // Evaluating the deferred module here would be fatal.
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ v8_isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ CHECK(
+ v8::debug::GetPrivateMembers(context, object, filter, &names, &values));
+ }
+
+ CHECK_EQ(names.size(), 0);
+ CHECK(env->Global()
+ ->Get(context, v8_str("evaluated"))
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ deferred_module_dependency.Reset();
+}
+
+// The inspector enumerates the properties of an object while JavaScript
+// execution is disallowed. A deferred module namespace whose module has not run
+// yet therefore reports no properties at all: every export is uninitialized, so
+// listing one would either evaluate the module or throw for an export still in
+// TDZ. The [[ModuleStatus]] internal property describes such an object instead.
+TEST(PropertyIteratorDoesNotEvaluateDeferredModule) {
+ i::v8_flags.js_defer_import_eval = true;
+ LocalContext env;
+ v8::Isolate* v8_isolate = CcTest::isolate();
+ v8::HandleScope scope(v8_isolate);
+ v8::Local<v8::Context> context = env.local();
+
+ v8::Local<v8::Object> object =
+ SetUpDeferredModuleNamespace(context,
+ "globalThis.evaluated = true;\n"
+ "export const constExport = 1;\n"
+ "export let letExport = 2;");
+
+ {
+ // Evaluating the deferred module here would be fatal.
+ v8::Isolate::DisallowJavascriptExecutionScope no_js(
+ v8_isolate,
+ v8::Isolate::DisallowJavascriptExecutionScope::CRASH_ON_FAILURE);
+ auto iterator = v8::debug::PropertyIterator::Create(context, object);
+ CHECK(iterator);
+ CHECK(iterator->Done());
+ }
+
+ CHECK(env->Global()
+ ->Get(context, v8_str("evaluated"))
+ .ToLocalChecked()
+ ->IsUndefined());
+
+ // Reading an export still evaluates the module, and the namespace then
+ // enumerates like any other one.
+ CHECK(!object->Get(context, v8_str("constExport")).IsEmpty());
+ CHECK(env->Global()
+ ->Get(context, v8_str("evaluated"))
+ .ToLocalChecked()
+ ->IsTrue());
+
+ std::vector<std::string> names;
+ auto iterator = v8::debug::PropertyIterator::Create(context, object);
+ CHECK(iterator);
+ while (!iterator->Done()) {
+ v8::Local<v8::Name> name = iterator->name();
+ if (name->IsString()) {
+ v8::String::Utf8Value utf8(v8_isolate, name);
+ names.push_back(*utf8);
+ }
+ CHECK(iterator->Advance().FromJust());
+ }
+ std::sort(names.begin(), names.end());
+ names.erase(std::unique(names.begin(), names.end()), names.end());
+ CHECK_EQ(names.size(), 2);
+ CHECK_EQ(names[0], "constExport");
+ CHECK_EQ(names[1], "letExport");
+
+ deferred_module_dependency.Reset();
+}
+
namespace {
class SetTerminateOnResumeDelegate : public v8::debug::DebugDelegate {
public:
@@ -7065,8 +7271,7 @@ class FailedScriptCompiledDelegate : public v8::debug::DebugDelegate {
public:
explicit FailedScriptCompiledDelegate(v8::Isolate* isolate)
: isolate(isolate) {}
- void ScriptCompiled(v8::Local<v8::debug::Script> script, bool,
- bool) override {
+ void ScriptCompiled(v8::Local<v8::debug::Script> script, bool) override {
script_.Reset(isolate, script);
script_.SetWeak();
}
diff --git a/deps/v8/test/cctest/test-heap-profiler.cc b/deps/v8/test/cctest/test-heap-profiler.cc
index 06a6d8e45c1..902973afc62 100644
--- a/deps/v8/test/cctest/test-heap-profiler.cc
+++ b/deps/v8/test/cctest/test-heap-profiler.cc
@@ -2181,6 +2181,84 @@ TEST(NativeSnapshotObjectIdMoving) {
heap_profiler->StopTrackingHeapObjects();
}
+TEST(NativeSnapshotObjectIdReplaced) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+ v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
+
+ v8::Persistent<v8::String> wrapper(isolate, v8_str("wrapper"));
+ int native1;
+ int native2;
+ int replacement;
+
+ EmbedderGraphBuilderForNativeSnapshotObjectId::BuildParameter parameter{
+ &wrapper, &native1, &native2};
+ auto callback =
+ EmbedderGraphBuilderForNativeSnapshotObjectId::BuildEmbedderGraph;
+ heap_profiler->AddBuildEmbedderGraphCallback(callback, ¶meter);
+ CHECK(ValidateSnapshot(heap_profiler->TakeHeapSnapshot()));
+
+ const auto wrapper_id = heap_profiler->GetObjectId(&native2);
+ CHECK_NE(v8::HeapProfiler::kUnknownObjectId, wrapper_id);
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(wrapper.Get(isolate)));
+
+ CHECK(ValidateSnapshot(heap_profiler->TakeHeapSnapshot()));
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(&native2));
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(wrapper.Get(isolate)));
+
+ parameter.native2 = &replacement;
+ CHECK(ValidateSnapshot(heap_profiler->TakeHeapSnapshot()));
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(&replacement));
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(wrapper.Get(isolate)));
+ CHECK_EQ(v8::HeapProfiler::kUnknownObjectId,
+ heap_profiler->GetObjectId(&native2));
+
+ heap_profiler->RemoveBuildEmbedderGraphCallback(callback, ¶meter);
+ CHECK(ValidateSnapshot(heap_profiler->TakeHeapSnapshot()));
+ CHECK_EQ(v8::HeapProfiler::kUnknownObjectId,
+ heap_profiler->GetObjectId(&replacement));
+}
+
+TEST(NativeSnapshotObjectIdUnmerged) {
+ LocalContext env;
+ v8::Isolate* isolate = env.isolate();
+ v8::HandleScope scope(isolate);
+ v8::HeapProfiler* heap_profiler = isolate->GetHeapProfiler();
+
+ v8::Persistent<v8::String> wrapper(isolate, v8_str("wrapper"));
+ int native1;
+ int native2;
+ int replacement;
+
+ EmbedderGraphBuilderForNativeSnapshotObjectId::BuildParameter parameter{
+ &wrapper, &native1, &native2};
+ auto callback =
+ EmbedderGraphBuilderForNativeSnapshotObjectId::BuildEmbedderGraph;
+ heap_profiler->AddBuildEmbedderGraphCallback(callback, ¶meter);
+ CHECK(ValidateSnapshot(heap_profiler->TakeHeapSnapshot()));
+
+ const auto wrapper_id = heap_profiler->GetObjectId(&native2);
+ CHECK_NE(v8::HeapProfiler::kUnknownObjectId, wrapper_id);
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(wrapper.Get(isolate)));
+
+ // The old native object stays in the graph without its former wrapper.
+ parameter.native1 = &native2;
+ parameter.native2 = &replacement;
+
+ const v8::HeapSnapshot* snapshot = heap_profiler->TakeHeapSnapshot();
+ CHECK(ValidateSnapshot(snapshot));
+ const auto unmerged_id = heap_profiler->GetObjectId(&native2);
+ CHECK_NE(v8::HeapProfiler::kUnknownObjectId, unmerged_id);
+ CHECK_NE(wrapper_id, unmerged_id);
+ CHECK_NOT_NULL(snapshot->GetNodeById(unmerged_id));
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(&replacement));
+ CHECK_EQ(wrapper_id, heap_profiler->GetObjectId(wrapper.Get(isolate)));
+ CHECK_NOT_NULL(snapshot->GetNodeById(wrapper_id));
+
+ heap_profiler->RemoveBuildEmbedderGraphCallback(callback, ¶meter);
+}
+
TEST(DeleteAllHeapSnapshots) {
LocalContext env;
v8::HandleScope scope(env.isolate());
@@ -2841,6 +2919,9 @@ TEST(JSGeneratorObject) {
GetProperty(env.isolate(), g, v8::HeapGraphEdge::kInternal,
"parameters_and_registers");
CHECK(parameters_and_registers);
+ const v8::HeapGraphNode* continuation = GetProperty(
+ env.isolate(), g, v8::HeapGraphEdge::kInternal, "continuation");
+ CHECK(continuation);
}
bool HasWeakEdge(const v8::HeapGraphNode* node) {
@@ -4858,21 +4939,16 @@ TEST(HeapSnapshotWithWasmInstance) {
CheckProperties(isolate, module_node,
{"__proto__", "managed_native_module", "map", "script"});
// Check the "managed_native_module" specifically. It should say
- // "Managed<wasm::NativeModule>" and should have a reasonable size.
+ // "CppGCManaged<wasm::NativeModule>" and should have a reasonable size.
const v8::HeapGraphNode* managed_node =
GetProperty(isolate, module_node, v8::HeapGraphEdge::kInternal,
"managed_native_module");
CHECK_NOT_NULL(managed_node);
v8::String::Utf8Value managed_name{isolate, managed_node->GetName()};
-#if V8_ENABLE_SANDBOX
- CHECK_EQ(std::string_view{"system / Managed (WasmNativeModuleTag)"},
+ CHECK_EQ(std::string_view{"system / CppGCManaged (WasmNativeModule)"},
std::string_view{*managed_name});
- // The size of the Managed is computed from the size of the NativeModule. This
- // is multiple kB, just conservatively assume >= 500b here.
+ // The size of the CppGCManaged is computed from the size of the NativeModule.
+ // This is multiple kB, just conservatively assume >= 500b here.
CHECK_LE(500, managed_node->GetShallowSize());
-#else
- CHECK_EQ(std::string_view{"system / Foreign"},
- std::string_view{*managed_name});
-#endif // V8_ENABLE_SANDBOX
}
#endif // V8_ENABLE_WEBASSEMBLY
diff --git a/deps/v8/test/cctest/test-inobject-slack-tracking.cc b/deps/v8/test/cctest/test-inobject-slack-tracking.cc
index a74b20fa8eb..e455f378154 100644
--- a/deps/v8/test/cctest/test-inobject-slack-tracking.cc
+++ b/deps/v8/test/cctest/test-inobject-slack-tracking.cc
@@ -9,6 +9,7 @@
#include "src/api/api-inl.h"
#include "src/objects/heap-number-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "test/cctest/cctest.h"
diff --git a/deps/v8/test/cctest/test-liveedit.cc b/deps/v8/test/cctest/test-liveedit.cc
deleted file mode 100644
index 0ee0144307a..00000000000
--- a/deps/v8/test/cctest/test-liveedit.cc
+++ /dev/null
@@ -1,566 +0,0 @@
-// Copyright 2007-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include <stdlib.h>
-
-#include "include/v8-function.h"
-#include "src/api/api-inl.h"
-#include "src/debug/liveedit.h"
-#include "src/objects/objects-inl.h"
-#include "test/cctest/cctest.h"
-
-namespace v8 {
-namespace internal {
-namespace {
-void CompareStringsOneWay(const char* s1, const char* s2,
- int expected_diff_parameter,
- std::vector<SourceChangeRange>* changes) {
- i::Isolate* isolate = CcTest::i_isolate();
- i::Handle<i::String> i_s1 = isolate->factory()->NewStringFromAsciiChecked(s1);
- i::Handle<i::String> i_s2 = isolate->factory()->NewStringFromAsciiChecked(s2);
- changes->clear();
- LiveEdit::CompareStrings(isolate, i_s1, i_s2, changes);
-
- int len1 = static_cast<int>(strlen(s1));
- int len2 = static_cast<int>(strlen(s2));
-
- int pos1 = 0;
- int pos2 = 0;
-
- int diff_parameter = 0;
- for (const auto& diff : *changes) {
- int diff_pos1 = diff.start_position;
- int similar_part_length = diff_pos1 - pos1;
- int diff_pos2 = pos2 + similar_part_length;
-
- CHECK_EQ(diff_pos2, diff.new_start_position);
-
- for (int j = 0; j < similar_part_length; j++) {
- CHECK(pos1 + j < len1);
- CHECK(pos2 + j < len2);
- CHECK_EQ(s1[pos1 + j], s2[pos2 + j]);
- }
- int diff_len1 = diff.end_position - diff.start_position;
- int diff_len2 = diff.new_end_position - diff.new_start_position;
- diff_parameter += diff_len1 + diff_len2;
- pos1 = diff_pos1 + diff_len1;
- pos2 = diff_pos2 + diff_len2;
- }
- {
- // After last chunk.
- int similar_part_length = len1 - pos1;
- CHECK_EQ(similar_part_length, len2 - pos2);
- USE(len2);
- for (int j = 0; j < similar_part_length; j++) {
- CHECK(pos1 + j < len1);
- CHECK(pos2 + j < len2);
- CHECK_EQ(s1[pos1 + j], s2[pos2 + j]);
- }
- }
-
- if (expected_diff_parameter != -1) {
- CHECK_EQ(expected_diff_parameter, diff_parameter);
- }
-}
-
-void CompareStringsOneWay(const char* s1, const char* s2,
- int expected_diff_parameter = -1) {
- std::vector<SourceChangeRange> changes;
- CompareStringsOneWay(s1, s2, expected_diff_parameter, &changes);
-}
-
-void CompareStringsOneWay(const char* s1, const char* s2,
- std::vector<SourceChangeRange>* changes) {
- CompareStringsOneWay(s1, s2, -1, changes);
-}
-
-void CompareStrings(const char* s1, const char* s2,
- int expected_diff_parameter = -1) {
- CompareStringsOneWay(s1, s2, expected_diff_parameter);
- CompareStringsOneWay(s2, s1, expected_diff_parameter);
-}
-
-void CompareOneWayPlayWithLF(const char* s1, const char* s2) {
- std::string s1_one_line(s1);
- std::replace(s1_one_line.begin(), s1_one_line.end(), '\n', ' ');
- std::string s2_one_line(s2);
- std::replace(s2_one_line.begin(), s2_one_line.end(), '\n', ' ');
- CompareStringsOneWay(s1, s2, -1);
- CompareStringsOneWay(s1_one_line.c_str(), s2, -1);
- CompareStringsOneWay(s1, s2_one_line.c_str(), -1);
- CompareStringsOneWay(s1_one_line.c_str(), s2_one_line.c_str(), -1);
-}
-
-void CompareStringsPlayWithLF(const char* s1, const char* s2) {
- CompareOneWayPlayWithLF(s1, s2);
- CompareOneWayPlayWithLF(s2, s1);
-}
-} // anonymous namespace
-
-TEST(LiveEditDiffer) {
- v8::HandleScope handle_scope(CcTest::isolate());
- CompareStrings("zz1zzz12zz123zzz", "zzzzzzzzzz", 6);
- CompareStrings("zz1zzz12zz123zzz", "zz0zzz0zz0zzz", 9);
- CompareStrings("123456789", "987654321", 16);
- CompareStrings("zzz", "yyy", 6);
- CompareStrings("zzz", "zzz12", 2);
- CompareStrings("zzz", "21zzz", 2);
- CompareStrings("cat", "cut", 2);
- CompareStrings("ct", "cut", 1);
- CompareStrings("cat", "ct", 1);
- CompareStrings("cat", "cat", 0);
- CompareStrings("", "", 0);
- CompareStrings("cat", "", 3);
- CompareStrings("a cat", "a capybara", 7);
- CompareStrings("abbabababababaaabbabababababbabbbbbbbababa",
- "bbbbabababbbabababbbabababababbabbababa");
- CompareStringsPlayWithLF("", "");
- CompareStringsPlayWithLF("a", "b");
- CompareStringsPlayWithLF(
- "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway",
- "yesterday\nall\nmy\ntroubles\nseem\nso\nfar\naway");
- CompareStringsPlayWithLF(
- "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway",
- "\nall\nmy\ntroubles\nseemed\nso\nfar\naway");
- CompareStringsPlayWithLF(
- "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway",
- "all\nmy\ntroubles\nseemed\nso\nfar\naway");
- CompareStringsPlayWithLF(
- "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway",
- "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway\n");
- CompareStringsPlayWithLF(
- "yesterday\nall\nmy\ntroubles\nseemed\nso\nfar\naway",
- "yesterday\nall\nmy\ntroubles\nseemed\nso\n");
-}
-
-TEST(LiveEditTranslatePosition) {
- v8::HandleScope handle_scope(CcTest::isolate());
- std::vector<SourceChangeRange> changes;
- CompareStringsOneWay("a", "a", &changes);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 0), 0);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 1), 1);
- CompareStringsOneWay("a", "b", &changes);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 0), 0);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 1), 1);
- CompareStringsOneWay("ababa", "aaa", &changes);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 0), 0);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 1), 1);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 2), 1);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 3), 2);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 4), 2);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 5), 3);
- CompareStringsOneWay("ababa", "acaca", &changes);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 0), 0);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 1), 1);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 2), 2);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 3), 3);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 4), 4);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 5), 5);
- CompareStringsOneWay("aaa", "ababa", &changes);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 0), 0);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 1), 2);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 2), 4);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 3), 5);
- CompareStringsOneWay("aabbaaaa", "aaaabbaa", &changes);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 0), 0);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 1), 1);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 2), 2);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 3), 3);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 4), 2);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 5), 3);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 6), 6);
- CHECK_EQ(LiveEdit::TranslatePosition(changes, 8), 8);
-}
-
-namespace {
-void PatchFunctions(v8::Local<v8::Context> context, const char* source_a,
- const char* source_b,
- v8::debug::LiveEditResult* result = nullptr) {
- v8::Isolate* isolate = CcTest::isolate();
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- v8::EscapableHandleScope scope(isolate);
- v8::Local<v8::Script> script_a =
- v8::Script::Compile(context, v8_str(isolate, source_a)).ToLocalChecked();
- script_a->Run(context).ToLocalChecked();
- i::Handle<i::Script> i_script_a(
- i::Cast<i::Script>(
- v8::Utils::OpenDirectHandle(*script_a)->shared()->script()),
- i_isolate);
-
- if (result) {
- LiveEdit::PatchScript(
- i_isolate, i_script_a,
- i_isolate->factory()->NewStringFromAsciiChecked(source_b), false, false,
- result);
- if (result->status == v8::debug::LiveEditResult::COMPILE_ERROR) {
- result->message = scope.Escape(result->message);
- }
- } else {
- v8::debug::LiveEditResult r;
- LiveEdit::PatchScript(
- i_isolate, i_script_a,
- i_isolate->factory()->NewStringFromAsciiChecked(source_b), false, false,
- &r);
- CHECK_EQ(r.status, v8::debug::LiveEditResult::OK);
- }
-}
-} // anonymous namespace
-
-TEST(LiveEditPatchFunctions) {
- LocalContext env;
- v8::HandleScope scope(env.isolate());
- v8::Local<v8::Context> context = env.local();
- // Check that function is removed from compilation cache.
- i::v8_flags.allow_natives_syntax = true;
- PatchFunctions(context, "42;", "%AbortJS('')");
- PatchFunctions(context, "42;", "239;");
- i::v8_flags.allow_natives_syntax = false;
-
- // Basic test cases.
- PatchFunctions(context, "42;", "2;");
- PatchFunctions(context, "42;", " 42;");
- PatchFunctions(context, "42;", "42;");
- // Trivial return value change.
- PatchFunctions(context, "function foo() { return 1; }",
- "function foo() { return 42; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 42);
- // It is expected, we do not reevaluate top level function.
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var a = 3; function foo() { return a; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 1);
- // Throw exception since var b is not defined in original source.
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var b = 4; function foo() { return b; }");
- {
- v8::TryCatch try_catch(env.isolate());
- CompileRun("foo()");
- CHECK(try_catch.HasCaught());
- }
- // But user always can add new variable to function and use it.
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var b = 4; function foo() { var b = 5; return b; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 5);
-
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var b = 4; function foo() { var a = 6; return a; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 6);
-
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var d = (() => ({a:2}))(); function foo() { return d; }");
- {
- v8::TryCatch try_catch(env.isolate());
- CompileRun("foo()");
- CHECK(try_catch.HasCaught());
- }
-
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var b = 1; var a = 2; function foo() { return a; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 1);
-
- PatchFunctions(context, "var a = 1; function foo() { return a; }",
- "var b = 1; var a = 2; function foo() { return b; }");
- {
- v8::TryCatch try_catch(env.isolate());
- CompileRun("foo()");
- CHECK(try_catch.HasCaught());
- }
-
- PatchFunctions(context, "function foo() { var a = 1; return a; }",
- "function foo() { var b = 1; return b; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 1);
-
- PatchFunctions(context, "var a = 3; function foo() { var a = 1; return a; }",
- "function foo() { var b = 1; return a; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 3);
-
- PatchFunctions(context, "var a = 3; var c = 7; function foo() { return a; }",
- "var b = 5; var a = 3; function foo() { return b; }");
- {
- v8::TryCatch try_catch(env.isolate());
- CompileRun("foo()");
- CHECK(try_catch.HasCaught());
- }
-
- // Add argument.
- PatchFunctions(context, "function fooArgs(a1, b1) { return a1 + b1; }",
- "function fooArgs(a2, b2, c2) { return a2 + b2 + c2; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "fooArgs(1,2,3)")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 6);
-
- PatchFunctions(context, "function fooArgs(a1, b1) { return a1 + b1; }",
- "function fooArgs(a1, b1, c1) { return a1 + b1 + c1; }");
- CHECK_EQ(CompileRunChecked(env.isolate(), "fooArgs(1,2,3)")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 6);
-
- i::v8_flags.allow_natives_syntax = true;
- PatchFunctions(context,
- "function foo(a, b) { return a + b; }; "
- "%PrepareFunctionForOptimization(foo);"
- "%OptimizeFunctionOnNextCall(foo); foo(1,2);",
- "function foo(a, b) { return a * b; };");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo(5,7)")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 35);
- i::v8_flags.allow_natives_syntax = false;
-
- // Check inner function.
- PatchFunctions(
- context,
- "function foo(a,b) { function op(a,b) { return a + b } return op(a,b); }",
- "function foo(a,b) { function op(a,b) { return a * b } return op(a,b); "
- "}");
- CHECK_EQ(CompileRunChecked(env.isolate(), "foo(8,9)")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 72);
-
- // Update constructor.
- PatchFunctions(context,
- "class Foo { constructor(a,b) { this.data = a + b; } };",
- "class Foo { constructor(a,b) { this.data = a * b; } };");
- CHECK_EQ(CompileRunChecked(env.isolate(), "new Foo(4,5).data")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 20);
- // Change inner functions.
- PatchFunctions(
- context,
- "function f(evt) { function f2() {} f2(),f3(); function f3() {} } "
- "function f4() {}",
- "function f(evt) { function f2() { return 1; } return f2() + f3(); "
- "function f3() { return 2; } } function f4() {}");
- CHECK_EQ(CompileRunChecked(env.isolate(), "f()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 3);
- // Change usage of outer scope.
- PatchFunctions(context,
- "function ChooseAnimal(a, b) {\n "
- " if (a == 7 && b == 7) {\n"
- " return;\n"
- " }\n"
- " return function Chooser() {\n"
- " return 'Cat' + a;\n"
- " };\n"
- "}\n"
- "var old_closure = ChooseAnimal(2, 3);",
- "function ChooseAnimal(a, b) {\n "
- " if (a == 7 && b == 7) {\n"
- " return;\n"
- " }\n"
- " return function Chooser() {\n"
- " return 'Capybara' + b;\n"
- " };\n"
- "}\n");
- CompileRunChecked(env.isolate(), "var new_closure = ChooseAnimal(3, 4);");
-
- {
- v8::Local<v8::String> call_result =
- CompileRunChecked(env.isolate(), "new_closure()").As<v8::String>();
- v8::String::Utf8Value new_result_utf8(env.isolate(), call_result);
- CHECK_NOT_NULL(strstr(*new_result_utf8, "Capybara4"));
- call_result =
- CompileRunChecked(env.isolate(), "old_closure()").As<v8::String>();
- v8::String::Utf8Value old_result_utf8(env.isolate(), call_result);
- CHECK_NOT_NULL(strstr(*old_result_utf8, "Cat2"));
- }
-
- // Update const literals.
- PatchFunctions(context, "function foo() { return 'a' + 'b'; }",
- "function foo() { return 'c' + 'b'; }");
- {
- v8::Local<v8::String> result_str =
- CompileRunChecked(env.isolate(), "foo()").As<v8::String>();
- v8::String::Utf8Value new_result_utf8(env.isolate(), result_str);
- CHECK_NOT_NULL(strstr(*new_result_utf8, "cb"));
- }
-
- // TODO(kozyatinskiy): should work when we remove (.
- PatchFunctions(context, "f = () => 2", "f = a => a");
- CHECK_EQ(CompileRunChecked(env.isolate(), "f(3)")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 2);
-
- // Replace function with not a function.
- PatchFunctions(context, "f = () => 2", "f = a == 2");
- CHECK_EQ(CompileRunChecked(env.isolate(), "f(3)")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 2);
-
- // TODO(kozyatinskiy): should work when we put function into (...).
- PatchFunctions(context, "f = a => 2", "f = (a => 5)()");
- CHECK_EQ(CompileRunChecked(env.isolate(), "f()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 2);
-
- PatchFunctions(context,
- "f2 = null;\n"
- "f = () => {\n"
- " f2 = () => 5;\n"
- " return f2();\n"
- "}\n"
- "f()\n",
- "f2 = null;\n"
- "f = () => {\n"
- " for (var a = (() => 7)(), b = 0; a < 10; ++a,++b);\n"
- " return b;\n"
- "}\n"
- "f()\n");
- // TODO(kozyatinskiy): ditto.
- CHECK_EQ(CompileRunChecked(env.isolate(), "f2()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 5);
- CHECK_EQ(CompileRunChecked(env.isolate(), "f()")
- ->ToInt32(context)
- .ToLocalChecked()
- ->Value(),
- 3);
-}
-
-TEST(LiveEditCompileError) {
- LocalContext env;
- v8::HandleScope scope(env.isolate());
- v8::Local<v8::Context> context = env.local();
- debug::LiveEditResult result;
- PatchFunctions(
- context,
- "var something1 = 25; \n"
- " function ChooseAnimal() { return 'Cat'; } \n"
- " ChooseAnimal.Helper = function() { return 'Help!'; }\n",
- "var something1 = 25; \n"
- " function ChooseAnimal() { return 'Cap' + ) + 'bara'; "
- "} \n"
- " ChooseAnimal.Helper = function() { return 'Help!'; }\n",
- &result);
- CHECK_EQ(result.status, debug::LiveEditResult::COMPILE_ERROR);
- CHECK_EQ(result.line_number, 2);
- CHECK_EQ(result.column_number, 51);
- v8::String::Utf8Value result_message(env.isolate(), result.message);
- CHECK_NOT_NULL(
- strstr(*result_message, "Uncaught SyntaxError: Unexpected token ')'"));
-
- {
- v8::Local<v8::String> result_str =
- CompileRunChecked(env.isolate(), "ChooseAnimal()").As<v8::String>();
- v8::String::Utf8Value new_result_utf8(env.isolate(), result_str);
- CHECK_NOT_NULL(strstr(*new_result_utf8, "Cat"));
- }
-
- PatchFunctions(context, "function foo() {}",
- "function foo() { return a # b; }", &result);
- CHECK_EQ(result.status, debug::LiveEditResult::COMPILE_ERROR);
- CHECK_EQ(result.line_number, 1);
- CHECK_EQ(result.column_number, 26);
-}
-
-TEST(LiveEditFunctionExpression) {
- const char* original_source =
- "(function() {\n "
- " return 'Cat';\n"
- "})\n";
- const char* updated_source =
- "(function() {\n "
- " return 'Capy' + 'bara';\n"
- "})\n";
- LocalContext env;
- v8::HandleScope scope(env.isolate());
- v8::Local<v8::Context> context = env.local();
- v8::Isolate* isolate = env.isolate();
- i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
- v8::Local<v8::Script> script =
- v8::Script::Compile(context, v8_str(isolate, original_source))
- .ToLocalChecked();
- v8::Local<v8::Function> f =
- script->Run(context).ToLocalChecked().As<v8::Function>();
- i::Handle<i::Script> i_script(
- i::Cast<i::Script>(
- v8::Utils::OpenDirectHandle(*script)->shared()->script()),
- i_isolate);
- debug::LiveEditResult result;
- LiveEdit::PatchScript(
- i_isolate, i_script,
- i_isolate->factory()->NewStringFromAsciiChecked(updated_source), false,
- false, &result);
- CHECK_EQ(result.status, debug::LiveEditResult::OK);
- {
- v8::Local<v8::String> result_str =
- f->Call(context, context->Global(), 0, nullptr)
- .ToLocalChecked()
- .As<v8::String>();
- v8::String::Utf8Value new_result_utf8(env.isolate(), result_str);
- CHECK_NOT_NULL(strstr(*new_result_utf8, "Capybara"));
- }
-}
-} // namespace internal
-} // namespace v8
diff --git a/deps/v8/test/cctest/test-regexp.cc b/deps/v8/test/cctest/test-regexp.cc
index b0e2bfb2273..b71ad263900 100644
--- a/deps/v8/test/cctest/test-regexp.cc
+++ b/deps/v8/test/cctest/test-regexp.cc
@@ -135,7 +135,13 @@ class InterruptTest {
CHECK(string->ContainsOnlyOneByte());
// Internalize the subject by using it as a computed property name in an
// object.
- CompileRun("o = { [subject_string]: 'foo' }");
+ {
+ // This test is technically wrong for running JS in a C++ interrupt.
+ // However we know that the interuptee here is the regexp engine, which
+ // does not care.
+ Isolate::AllowJavascriptExecutionScope allow_script(isolate);
+ CompileRun("o = { [subject_string]: 'foo' }");
+ }
CHECK(string->IsOneByte());
}
diff --git a/deps/v8/test/cctest/test-serialize.cc b/deps/v8/test/cctest/test-serialize.cc
index c5fbaf92752..0bb7c47ad43 100644
--- a/deps/v8/test/cctest/test-serialize.cc
+++ b/deps/v8/test/cctest/test-serialize.cc
@@ -57,6 +57,7 @@
#include "src/numbers/hash-seed-inl.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-regexp-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/runtime/runtime.h"
#include "src/snapshot/code-serializer.h"
@@ -2905,6 +2906,81 @@ TEST(CodeSerializerExternalString) {
delete cache;
}
+namespace {
+
+// The addresses of these resources are registered as API external references
+// below, so that ObjectSerializer::SerializeExternalString() takes the "known
+// resource" path for the strings backed by them. This is the state an embedder
+// ends up in when it externalizes strings it also hands to the compiler, e.g.
+// builtin module sources that are later turned into a code cache.
+constexpr char kExternalCodeCacheSource[] =
+ "function f() { return 'abc'; }; f() + 'def';";
+constexpr char kExternalCodeCacheName[] = "external-script-name";
+
+SerializerOneByteResource external_code_cache_source_resource(
+ kExternalCodeCacheSource, sizeof(kExternalCodeCacheSource) - 1);
+SerializerOneByteResource external_code_cache_name_resource(
+ kExternalCodeCacheName, sizeof(kExternalCodeCacheName) - 1);
+
+const intptr_t external_code_cache_references[] = {
+ reinterpret_cast<intptr_t>(&external_code_cache_source_resource),
+ reinterpret_cast<intptr_t>(&external_code_cache_name_resource), 0};
+
+} // namespace
+
+// Serializing a live cached ExternalString must leave its resource_data_
+// (cached data pointer) external pointer handle intact, so that reads of the
+// string's characters from generated code keep working afterwards.
+UNINITIALIZED_TEST(CodeSerializerExternalStringResourceDataRestored) {
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
+ create_params.external_references = external_code_cache_references;
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope isolate_scope(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_string =
+ v8::String::NewExternalOneByte(isolate,
+ &external_code_cache_source_resource)
+ .ToLocalChecked();
+ v8::Local<v8::String> name_string =
+ v8::String::NewExternalOneByte(isolate,
+ &external_code_cache_name_resource)
+ .ToLocalChecked();
+ // Only cached external strings have a resource_data_ field.
+ CHECK(!Cast<ExternalString>(*Utils::OpenDirectHandle(*source_string))
+ ->is_uncached());
+ CHECK(!Cast<ExternalString>(*Utils::OpenDirectHandle(*name_string))
+ ->is_uncached());
+
+ v8::ScriptCompiler::Source source(source_string, {name_string});
+ v8::Local<v8::UnboundScript> script =
+ v8::ScriptCompiler::CompileUnboundScript(
+ isolate, &source, v8::ScriptCompiler::kEagerCompile)
+ .ToLocalChecked();
+
+ // Serializes the script name in every build, and additionally the script
+ // source in DEBUG builds - CodeSerializer::Serialize() only attaches the
+ // source instead of serializing it when DEBUG is not defined. Both strings
+ // stay live in this isolate afterwards.
+ std::unique_ptr<v8::ScriptCompiler::CachedData> cache(
+ v8::ScriptCompiler::CreateCodeCache(script));
+ CHECK(cache);
+
+ // Read the character data of both strings from generated code.
+ v8::Local<v8::Object> global = context->Global();
+ CHECK(global->Set(context, v8_str("source"), source_string).FromJust());
+ CHECK(global->Set(context, v8_str("name"), name_string).FromJust());
+ ExpectTrue("source.startsWith('function f()')");
+ ExpectTrue("source.indexOf('def') > 0");
+ ExpectTrue("name.startsWith('external-script')");
+ }
+ isolate->Dispose();
+}
+
TEST(CodeSerializerLargeExternalString) {
LocalContext context;
Isolate* isolate = CcTest::i_isolate();
@@ -4670,18 +4746,10 @@ UNINITIALIZED_TEST(SerializeContextData) {
v8::Local<v8::Context> context =
v8::Context::FromSnapshot(isolate, 0).ToLocalChecked();
CHECK_NULL(context->GetAlignedPointerFromEmbedderData(0, kRawDataTag));
- // It would be more consistent if the API would always null out pointers
- // stored in embedder slots (if no custom serializer/deserializer is
- // provided), but in the wide pointer case we don't actually know
- // whether it's a pointer or a Smi, so we just let these values pass
- // through.
- if (V8_ENABLE_SANDBOX_BOOL) {
- CHECK_NULL(
- context->GetAlignedPointerFromEmbedderData(1, kRawDataTag));
- } else {
- CHECK_EQ(raw_data,
- context->GetAlignedPointerFromEmbedderData(1, kRawDataTag));
- }
+ // Embedder pointers stored in embedder slots are always cleared during
+ // snapshot serialization if no custom serializer/deserializer is
+ // provided.
+ CHECK_NULL(context->GetAlignedPointerFromEmbedderData(1, kRawDataTag));
}
isolate->Dispose();
}
diff --git a/deps/v8/test/cctest/test-usecounters.cc b/deps/v8/test/cctest/test-usecounters.cc
index 81eccb52461..cbc43a08284 100644
--- a/deps/v8/test/cctest/test-usecounters.cc
+++ b/deps/v8/test/cctest/test-usecounters.cc
@@ -177,6 +177,110 @@ TEST(ArrayPrototypeHasElements) {
global_use_counts = nullptr;
}
+TEST(RegExpMatchAllUseCounters) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+ global_use_counts = use_counts;
+ CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+
+ // Normal RegExp matchAll: neither counter is triggered.
+ CompileRun("/a/g[Symbol.matchAll]('a');");
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Object without custom species:
+ CompileRun(
+ "const re0 = { flags: 'g', constructor: RegExp };"
+ "RegExp.prototype[Symbol.matchAll].call(re0, 'a');");
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning a global RegExp:
+ CompileRun(
+ "function CustomSpecies(pattern, flags) { return new RegExp(pattern, "
+ "flags); }"
+ "const re1 = { flags: 'g', constructor: { [Symbol.species]: "
+ "CustomSpecies } };"
+ "RegExp.prototype[Symbol.matchAll].call(re1, 'a');");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning a non-global RegExp:
+ CompileRun(
+ "function NonGlobalSpecies() { return /(?:)/; }"
+ "const re2 = { flags: 'g', constructor: { [Symbol.species]: "
+ "NonGlobalSpecies } };"
+ "RegExp.prototype[Symbol.matchAll].call(re2, 'a');");
+ CHECK_EQ(2, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning global RegExp with mismatched unicode flag:
+ CompileRun(
+ "function NonUnicodeSpecies() { return /a/g; }"
+ "const re3 = { flags: 'gu', constructor: { [Symbol.species]: "
+ "NonUnicodeSpecies } };"
+ "RegExp.prototype[Symbol.matchAll].call(re3, 'a');");
+ CHECK_EQ(3, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(2, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning global RegExp when receiver is non-global:
+ CompileRun(
+ "function GlobalSpecies() { return /a/g; }"
+ "const re4 = { flags: '', constructor: { [Symbol.species]: "
+ "GlobalSpecies } };"
+ "RegExp.prototype[Symbol.matchAll].call(re4, 'a');");
+ CHECK_EQ(4, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(3, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ global_use_counts = nullptr;
+}
+
+TEST(RegExpSplitUseCounters) {
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ LocalContext env;
+ int use_counts[v8::Isolate::kUseCounterFeatureCount] = {};
+ global_use_counts = use_counts;
+ CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback);
+
+ // Normal RegExp split: neither counter is triggered.
+ CompileRun("/a/[Symbol.split]('a-a');");
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning a sticky RegExp:
+ CompileRun(
+ "function CustomSpecies(pattern, flags) { return new RegExp(pattern, "
+ "flags); }"
+ "const re1 = { flags: '', constructor: { [Symbol.species]: "
+ "CustomSpecies } };"
+ "RegExp.prototype[Symbol.split].call(re1, 'a-a');");
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(0, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning a non-sticky RegExp:
+ CompileRun(
+ "function NonStickySpecies() { return /a/; }"
+ "const re2 = { flags: '', constructor: { [Symbol.species]: "
+ "NonStickySpecies } };"
+ "RegExp.prototype[Symbol.split].call(re2, 'a-a');");
+ CHECK_EQ(2, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(1, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ // Custom species returning sticky RegExp with mismatched unicode flag:
+ CompileRun(
+ "function NonUnicodeSplitSpecies() { return /a/y; }"
+ "const re3 = { flags: 'u', constructor: { [Symbol.species]: "
+ "NonUnicodeSplitSpecies } };"
+ "RegExp.prototype[Symbol.split].call(re3, 'a-a');");
+ CHECK_EQ(3, use_counts[v8::Isolate::kRegExpCustomSpecies]);
+ CHECK_EQ(2, use_counts[v8::Isolate::kRegExpMatcherFlagsMismatch]);
+
+ global_use_counts = nullptr;
+}
+
} // namespace test_usecounters
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/cctest/wasm/test-compilation-cache.cc b/deps/v8/test/cctest/wasm/test-compilation-cache.cc
index de5f0c42c02..151bdd28a3b 100644
--- a/deps/v8/test/cctest/wasm/test-compilation-cache.cc
+++ b/deps/v8/test/cctest/wasm/test-compilation-cache.cc
@@ -44,7 +44,7 @@ class TestResolver : public CompilationResultResolver {
}
private:
- Managed<NativeModule>::Ptr native_module_;
+ CppGCManaged<NativeModule>::Ptr native_module_;
std::atomic<int>* pending_;
};
@@ -85,7 +85,7 @@ ZoneBuffer GetValidModuleBytes(Zone* zone, uint8_t n) {
return buffer;
}
-Managed<NativeModule>::Ptr SyncCompile(base::Vector<const uint8_t> bytes) {
+CppGCManaged<NativeModule>::Ptr SyncCompile(base::Vector<const uint8_t> bytes) {
ErrorThrower thrower(CcTest::i_isolate(), "Test");
auto enabled_features = WasmEnabledFeatures::FromIsolate(CcTest::i_isolate());
DirectHandle<WasmModuleObject> module =
@@ -211,7 +211,7 @@ TEST(TestStreamingAndSyncCache) {
base::OwnedVector<uint8_t>::New(kPrefixSize + kFunctionSize);
memcpy(full_bytes.begin(), kPrefix, kPrefixSize);
memcpy(full_bytes.begin() + kPrefixSize, kFunctionA, kFunctionSize);
- Managed<NativeModule>::Ptr native_module_sync =
+ CppGCManaged<NativeModule>::Ptr native_module_sync =
SyncCompile(full_bytes.as_vector());
// Streaming compilation should just discard its native module now and use the
@@ -253,7 +253,7 @@ void TestModuleSharingBetweenIsolates() {
memcpy(full_bytes.begin(), kPrefix, kPrefixSize);
memcpy(full_bytes.begin() + kPrefixSize, kFunctionA, kFunctionSize);
ErrorThrower thrower(i_isolate, "Test");
- Managed<NativeModule>::Ptr native_module =
+ CppGCManaged<NativeModule>::Ptr native_module =
GetWasmEngine()
->SyncCompile(i_isolate, WasmEnabledFeatures::All(),
CompileTimeImports{}, &thrower,
diff --git a/deps/v8/test/cctest/wasm/test-fuzzer-steps.cc b/deps/v8/test/cctest/wasm/test-fuzzer-steps.cc
index f33f787b4f0..0db90da5f48 100644
--- a/deps/v8/test/cctest/wasm/test-fuzzer-steps.cc
+++ b/deps/v8/test/cctest/wasm/test-fuzzer-steps.cc
@@ -29,16 +29,16 @@ TEST(FuzzerStepsPrefixedOpcode) {
TEST(FuzzerStepsNonPrefixedOpcode) {
WasmRunner<uint32_t> r(TestExecutionTier::kLiftoffForFuzzing);
- // Entry: 16. MemoryGrow: 1000. Constant: 1. Total: 1017.
+ // Entry: 16. MemoryGrow: 10000. Constant: 1. Total: 10017.
r.builder().AddMemory(kWasmPageSize);
r.Build({WASM_MEMORY_GROW(WASM_I32V_1(1)), WASM_DROP, WASM_I32V_1(42)});
// 1. Run which does not trap.
- r.SetMaxSteps(2000);
+ r.SetMaxSteps(20000);
CHECK_EQ(42, r.Call());
// 2. Run which should trap.
- r.SetMaxSteps(500);
+ r.SetMaxSteps(5000);
r.CheckCallViaJSTraps();
}
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
index 368249acf46..d8e6d7247b6 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-module.cc
@@ -354,7 +354,7 @@ TEST(TestInterruptLoop) {
base::VectorOf(buffer))
.ToHandleChecked();
- Managed<BackingStore>::Ptr backing_store =
+ CppGCManaged<BackingStore>::Ptr backing_store =
instance->trusted_data(isolate)->memory_object(0)->backing_store();
std::atomic<int32_t>* memory_array =
reinterpret_cast<std::atomic<int32_t>*>(backing_store->buffer_start());
diff --git a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
index 3bf0235732f..96a4661b279 100644
--- a/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
+++ b/deps/v8/test/cctest/wasm/test-run-wasm-simd.cc
@@ -6556,6 +6556,150 @@ TEST(RunWasmTurbofan_ShuffleToS256Load8x8UExpectFail5) {
}
}
+// Test that Load8x8U revectorization still succeeds, and still produces
+// correct results, when a store intervenes between the load and the
+// shuffles. The vector load-transform is emitted at the load's own
+// position (see WasmRevecReducer::REDUCE_INPUT_GRAPH
+// (Simd128LoadTransform)), so it can't observe the later store.
+TEST(RunWasmTurbofan_ShuffleToS256Load8x8USideEffectCheck) {
+ EXPERIMENTAL_FLAG_SCOPE(revectorize);
+ if (!CpuFeatures::IsSupported(AVX2)) return;
+ WasmRunner<int8_t> r(TestExecutionTier::kTurbofan);
+ int8_t* memory = r.builder().AddMemoryElems<int8_t>(48);
+
+ constexpr std::array<int8_t, 16> shuffle0 = {16, 1, 2, 3, 17, 5, 6, 7,
+ 18, 9, 10, 11, 19, 13, 14, 15};
+ constexpr std::array<int8_t, 16> shuffle1 = {4, 17, 18, 19, 5, 21, 22, 23,
+ 6, 25, 26, 27, 7, 29, 30, 31};
+ uint8_t temp1 = r.AllocateLocal(kWasmS128);
+ std::array<uint8_t, kSimd128Size> all_zero = {0};
+
+ {
+ // Revectorization is expected to succeed despite the intervening store
+ // between load and shuffles, since the vector load-transform is emitted
+ // at the load's own position and can't observe the later store.
+ TSSimd256VerifyScope ts_scope(r.zone(),
+ TSSimd256VerifyScope::VerifyHaveAnySimd256Op);
+ r.Build({// Load from memory[0]
+ WASM_LOCAL_SET(temp1,
+ WASM_SIMD_LOAD_OP(kExprS128Load64Zero, WASM_ZERO)),
+ // Intervening store: write to memory[0]
+ WASM_STORE_MEM(MachineType::Int32(), WASM_ZERO, WASM_I32V(99)),
+ // Shuffles that match Load8x8U pattern
+ WASM_SIMD_STORE_MEM_OFFSET(
+ 8, WASM_ZERO,
+ WASM_SIMD_I8x16_SHUFFLE_OP(kExprI8x16Shuffle, shuffle0,
+ WASM_SIMD_CONSTANT(all_zero),
+ WASM_LOCAL_GET(temp1))),
+ WASM_SIMD_STORE_MEM_OFFSET(
+ 24, WASM_ZERO,
+ WASM_SIMD_I8x16_SHUFFLE_OP(kExprI8x16Shuffle, shuffle1,
+ WASM_LOCAL_GET(temp1),
+ WASM_SIMD_CONSTANT(all_zero))),
+ WASM_ONE});
+ }
+
+ // Initialize memory with test values matching Load8x8U test case
+ std::pair<std::vector<int8_t>, std::vector<int32_t>> test_case = {
+ {0, 1, 2, 3, 4, 5, 6, -1}, {0, 1, 2, 3, 4, 5, 6, 255}};
+ auto input = test_case.first;
+ auto expected_output = test_case.second;
+ for (int i = 0; i < 8; ++i) {
+ r.builder().WriteMemory(&memory[i], input[i]);
+ }
+ r.Call();
+
+ // Verify the result: shuffles produce expected values based on Load8x8U
+ // pattern. The load happens before the intervening store, so it reads the
+ // input values. The intervening store to memory[0] should not affect the
+ // shuffle results since they operate on the already-loaded value.
+ int32_t* memory_int32_t = reinterpret_cast<int32_t*>(memory);
+ for (int i = 0; i < 8; ++i) {
+ int32_t result = r.builder().ReadMemory(&memory_int32_t[i + 2]);
+ CHECK_EQ(expected_output[i], result);
+ }
+}
+
+// Test that Load8x8U revectorization is rejected when the shared load and
+// its consuming shuffles are not in the same basic block, since emitting
+// the vector load-transform at the load's own position is only sound when
+// it and the shuffles are reduced in the same relative order as they
+// appear here, which requires them to be in the same block.
+TEST(RunWasmTurbofan_ShuffleToS256Load8x8UDifferentBlock) {
+ EXPERIMENTAL_FLAG_SCOPE(revectorize);
+ if (!CpuFeatures::IsSupported(AVX2)) return;
+ WasmRunner<int32_t, int32_t> r(TestExecutionTier::kTurbofan);
+ r.builder().AddMemoryElems<int8_t>(48);
+
+ constexpr std::array<int8_t, 16> shuffle0 = {16, 1, 2, 3, 17, 5, 6, 7,
+ 18, 9, 10, 11, 19, 13, 14, 15};
+ constexpr std::array<int8_t, 16> shuffle1 = {4, 17, 18, 19, 5, 21, 22, 23,
+ 6, 25, 26, 27, 7, 29, 30, 31};
+ uint8_t temp1 = r.AllocateLocal(kWasmS128);
+ uint8_t temp2 = r.AllocateLocal(kWasmS128);
+ uint8_t temp3 = r.AllocateLocal(kWasmS128);
+ std::array<uint8_t, kSimd128Size> all_zero = {0};
+
+ TSSimd256VerifyScope ts_scope(r.zone(),
+ TSSimd256VerifyScope::VerifyHaveAnySimd256Op,
+ ExpectedResult::kFail);
+ r.Build(
+ {// Load in the entry block.
+ WASM_LOCAL_SET(temp1, WASM_SIMD_LOAD_OP(kExprS128Load64Zero, WASM_ZERO)),
+ // Shuffles and stores live in the if's block, not the entry block.
+ WASM_IF(
+ WASM_LOCAL_GET(0),
+ WASM_SEQ(
+ WASM_LOCAL_SET(temp2, WASM_SIMD_I8x16_SHUFFLE_OP(
+ kExprI8x16Shuffle, shuffle0,
+ WASM_SIMD_CONSTANT(all_zero),
+ WASM_LOCAL_GET(temp1))),
+ WASM_LOCAL_SET(temp3, WASM_SIMD_I8x16_SHUFFLE_OP(
+ kExprI8x16Shuffle, shuffle1,
+ WASM_LOCAL_GET(temp1),
+ WASM_SIMD_CONSTANT(all_zero))),
+ WASM_SIMD_STORE_MEM_OFFSET(8, WASM_ZERO, WASM_LOCAL_GET(temp2)),
+ WASM_SIMD_STORE_MEM_OFFSET(24, WASM_ZERO,
+ WASM_LOCAL_GET(temp3)))),
+ WASM_ONE});
+ r.Call(1);
+}
+
+// Test that Load splat revectorization is rejected when the shared load and
+// its consuming shuffle are not in the same basic block, similar to Load8x8U.
+TEST(RunWasmTurbofan_ShuffleToS256Load32SplatDifferentBlock) {
+ EXPERIMENTAL_FLAG_SCOPE(revectorize);
+ if (!CpuFeatures::IsSupported(AVX2)) return;
+ WasmRunner<int32_t, int32_t> r(TestExecutionTier::kTurbofan);
+ r.builder().AddMemoryElems<int32_t>(kWasmPageSize / sizeof(int32_t));
+
+ // Splat pattern: shuffle selecting lane 2 (bytes 8-11) repeated
+ constexpr Shuffle splat_shuffle = {8, 9, 10, 11, 8, 9, 10, 11,
+ 8, 9, 10, 11, 8, 9, 10, 11};
+ uint8_t temp1 = r.AllocateLocal(kWasmS128);
+ uint8_t temp2 = r.AllocateLocal(kWasmS128);
+
+ TSSimd256VerifyScope ts_scope(r.zone(),
+ TSSimd256VerifyScope::VerifyHaveAnySimd256Op,
+ ExpectedResult::kFail);
+ r.Build(
+ {// Load in the entry block.
+ WASM_LOCAL_SET(temp1, WASM_SIMD_LOAD_MEM(WASM_ZERO)),
+ // Shuffle and two adjacent stores live in the if's block, not the entry
+ // block. The two stores trigger revectorization pattern matching.
+ WASM_IF(
+ WASM_LOCAL_GET(0),
+ WASM_SEQ(WASM_LOCAL_SET(temp2, WASM_SIMD_I8x16_SHUFFLE_OP(
+ kExprI8x16Shuffle, splat_shuffle,
+ WASM_LOCAL_GET(temp1),
+ WASM_LOCAL_GET(temp1))),
+ WASM_SIMD_STORE_MEM(WASM_ZERO, WASM_LOCAL_GET(temp2)),
+ WASM_SIMD_STORE_MEM_OFFSET(16, WASM_ZERO,
+ WASM_LOCAL_GET(temp2)))),
+ WASM_ONE});
+ r.Call(1);
+}
+
template <typename T, bool use_memory64 = false>
void RunLoadSplatRevecTest(WasmOpcode op, WasmOpcode bin_op,
T (*expected_op)(T, T)) {
@@ -10885,6 +11029,44 @@ TEST(RunWasmTurbofan_ProjectionRevecExpectFail) {
#undef CALL_FUNCTION_WITH_DROP
}
+TEST(RunWasmTurbofan_RegressStoreInfoCompareCollision) {
+ if (!CpuFeatures::IsSupported(AVX2)) return;
+
+ EXPERIMENTAL_FLAG_SCOPE(revectorize);
+ WasmRunner<int32_t, int32_t> r(TestExecutionTier::kTurbofan);
+ TSSimd256VerifyScope ts_scope(
+ r.zone(), [](const compiler::turboshaft::Graph& graph) {
+ for (const compiler::turboshaft::Operation& op :
+ graph.AllOperations()) {
+ if (const auto* store = op.TryCast<compiler::turboshaft::StoreOp>()) {
+ if (store->stored_rep ==
+ compiler::turboshaft::MemoryRepresentation::Simd256()) {
+ return true;
+ }
+ }
+ }
+ return false;
+ });
+
+ uint8_t temp1 = r.AllocateLocal(kWasmS128);
+ r.builder().AddMemoryElems<int32_t>(kWasmPageSize / 4,
+ wasm::AddressType::kI32);
+
+ r.Build(
+ {WASM_LOCAL_SET(temp1, WASM_SIMD_I32x4_SPLAT(WASM_I32V_1(42))),
+ // Store 3: offset = 16, indexc = 64
+ WASM_SIMD_STORE_MEM_OFFSET(16, WASM_I32V_2(64), WASM_LOCAL_GET(temp1)),
+ // Store 2: offset = 0, indexc = 64
+ WASM_SIMD_STORE_MEM(WASM_I32V_2(64), WASM_LOCAL_GET(temp1)),
+ // Store 1: offset = 0, indexc = 0 (decoy)
+ // Flaw in StoreInfoCompare: this store with offset 0 and constant index
+ // 0 collides with Store 2 (offset 0, constant index 64) and causes Store
+ // 2 to be dropped from the ZoneSet, suppressing vectorization.
+ WASM_SIMD_STORE_MEM(WASM_I32V_1(0), WASM_LOCAL_GET(temp1)), WASM_ONE});
+
+ r.Call(0);
+}
+
#endif // V8_ENABLE_WASM_SIMD256_REVEC
#undef WASM_SIMD_CHECK_LANE_S
diff --git a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
index 0ed172b4642..05bf5ccbade 100644
--- a/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
+++ b/deps/v8/test/cctest/wasm/test-streaming-compilation.cc
@@ -231,7 +231,7 @@ class StreamTester {
}
// Compiled native module, valid after successful compile.
- Managed<NativeModule>::Ptr native_module() const {
+ CppGCManaged<NativeModule>::Ptr native_module() const {
return module_object()->native_module();
}
@@ -332,7 +332,7 @@ ZoneBuffer GetValidCompiledModuleBytes(v8::Isolate* isolate, Zone* zone,
tester.RunCompilerTasks();
CHECK(tester.IsPromiseFulfilled());
- Managed<NativeModule>::Ptr native_module = tester.native_module();
+ CppGCManaged<NativeModule>::Ptr native_module = tester.native_module();
CHECK_NOT_NULL(native_module);
i::Isolate* i_isolate = reinterpret_cast<i::Isolate*>(isolate);
@@ -1292,7 +1292,7 @@ STREAM_TEST(TestIncrementalCaching) {
CHECK(!thrower.error());
WasmCodeRefScope code_scope;
- Managed<NativeModule>::Ptr module = tester.native_module();
+ CppGCManaged<NativeModule>::Ptr module = tester.native_module();
CHECK(module->GetCode(0) == nullptr || module->GetCode(0)->is_liftoff());
CHECK(module->GetCode(1) == nullptr || module->GetCode(1)->is_liftoff());
CHECK(module->GetCode(2) == nullptr || module->GetCode(2)->is_liftoff());
@@ -1304,7 +1304,7 @@ STREAM_TEST(TestIncrementalCaching) {
size_t serialized_size;
{
WasmCodeRefScope code_scope;
- Managed<NativeModule>::Ptr module = tester.native_module();
+ CppGCManaged<NativeModule>::Ptr module = tester.native_module();
CHECK(!module->GetCode(0)->is_liftoff());
CHECK(module->GetCode(1) == nullptr || module->GetCode(1)->is_liftoff());
CHECK(module->GetCode(2) == nullptr || module->GetCode(2)->is_liftoff());
@@ -1318,7 +1318,7 @@ STREAM_TEST(TestIncrementalCaching) {
tester.RunCompilerTasks();
{
WasmCodeRefScope code_scope;
- Managed<NativeModule>::Ptr module = tester.native_module();
+ CppGCManaged<NativeModule>::Ptr module = tester.native_module();
CHECK(!module->GetCode(0)->is_liftoff());
CHECK(!module->GetCode(1)->is_liftoff());
CHECK(module->GetCode(2) == nullptr || module->GetCode(2)->is_liftoff());
diff --git a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
index d0caae48254..c7a2ce60ae5 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-breakpoints.cc
@@ -289,7 +289,7 @@ WASM_COMPILED_EXEC_TEST(WasmCollectPossibleBreakpoints) {
runner.Build({WASM_NOP, WASM_I32_ADD(WASM_ZERO, WASM_ONE)});
Tagged<WasmInstanceObject> instance = *runner.builder().instance_object();
- Managed<NativeModule>::Ptr native_module =
+ CppGCManaged<NativeModule>::Ptr native_module =
instance->module_object()->native_module();
std::vector<debug::Location> locations;
diff --git a/deps/v8/test/cctest/wasm/test-wasm-metrics.cc b/deps/v8/test/cctest/wasm/test-wasm-metrics.cc
index 5eff78ccb40..fc75c7cefa1 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-metrics.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-metrics.cc
@@ -182,7 +182,7 @@ class InstantiateResolver : public InstantiationResultResolver {
class CompileResolver : public CompilationResultResolver {
public:
CompileResolver(CompilationStatus* status, std::string* error_message,
- Isolate* isolate, Managed<NativeModule>::Ptr* native_module)
+ Isolate* isolate, CppGCManaged<NativeModule>::Ptr* native_module)
: status_(status),
error_message_(error_message),
isolate_(isolate),
@@ -211,7 +211,7 @@ class CompileResolver : public CompilationResultResolver {
CompilationStatus* const status_;
std::string* const error_message_;
Isolate* isolate_;
- Managed<NativeModule>::Ptr* const native_module_;
+ CppGCManaged<NativeModule>::Ptr* const native_module_;
};
} // namespace test
@@ -288,7 +288,7 @@ COMPILE_TEST(TestEventMetrics) {
auto enabled_features = WasmEnabledFeatures::FromIsolate(isolate);
test::CompilationStatus status = test::CompilationStatus::kPending;
std::string error_message;
- Managed<NativeModule>::Ptr native_module;
+ CppGCManaged<NativeModule>::Ptr native_module;
base::OwnedVector<const uint8_t> bytes = base::OwnedCopyOf(buffer);
GetWasmEngine()->AsyncCompile(
isolate, enabled_features, CompileTimeImports{},
diff --git a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
index 9c05e4152a3..eb365875823 100644
--- a/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
+++ b/deps/v8/test/cctest/wasm/test-wasm-serialization.cc
@@ -86,7 +86,7 @@ class WasmSerializationTest {
CHECK(Deserialize().ToHandle(&module_object));
{
DisallowGarbageCollection assume_no_gc;
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
base::Vector<const uint8_t> deserialized_module_wire_bytes =
native_module->wire_bytes();
@@ -292,7 +292,7 @@ UNINITIALIZED_TEST(CompiledWasmModulesTransfer) {
create_params.array_buffer_allocator = CcTest::array_buffer_allocator();
v8::Isolate* from_isolate = v8::Isolate::New(create_params);
std::vector<v8::CompiledWasmModule> store;
- Managed<NativeModule>::Ptr original_native_module;
+ CppGCManaged<NativeModule>::Ptr original_native_module;
{
v8::Isolate::Scope isolate_scope(from_isolate);
v8::HandleScope scope(from_isolate);
@@ -325,7 +325,7 @@ UNINITIALIZED_TEST(CompiledWasmModulesTransfer) {
CHECK(!transferred_module.IsEmpty());
DirectHandle<WasmModuleObject> module_object = Cast<WasmModuleObject>(
v8::Utils::OpenDirectHandle(*transferred_module.ToLocalChecked()));
- Managed<NativeModule>::Ptr transferred_native_module =
+ CppGCManaged<NativeModule>::Ptr transferred_native_module =
module_object->native_module();
CHECK_EQ(original_native_module, transferred_native_module);
}
@@ -343,7 +343,7 @@ TEST(TierDownAfterDeserialization) {
DirectHandle<WasmModuleObject> module_object;
CHECK(test.Deserialize().ToHandle(&module_object));
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
CHECK_EQ(3, native_module->module()->functions.size());
WasmCodeRefScope code_ref_scope;
@@ -381,7 +381,7 @@ TEST(SerializeLiftoffModuleFails) {
DirectHandle<WasmModuleObject> module_object =
maybe_module_object.ToHandleChecked();
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
WasmSerializer wasm_serializer(native_module.raw());
size_t buffer_size = wasm_serializer.GetSerializedNativeModuleSize();
@@ -402,7 +402,7 @@ TEST(SerializeTieringBudget) {
DirectHandle<WasmModuleObject> module_object;
CHECK(test.Deserialize().ToHandle(&module_object));
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
memcpy(native_module->tiering_budget_array(), mock_budget,
arraysize(mock_budget) * sizeof(uint32_t));
@@ -434,7 +434,7 @@ TEST(SerializeTieringBudget) {
wire_bytes_copy, compile_imports, {})
.ToHandle(&module_object));
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
for (size_t i = 0; i < arraysize(mock_budget); ++i) {
CHECK_EQ(mock_budget[i], native_module->tiering_budget_array()[i]);
@@ -538,7 +538,7 @@ TEST(DeserializeIndirectCallWithDifferentCanonicalId) {
CompileTimeImports{}, &thrower,
base::OwnedCopyOf(zone_buffer))
.ToHandleChecked();
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
weak_native_module = native_module.as_shared_ptr();
@@ -624,7 +624,7 @@ TEST(DeserializeIndirectCallWithDifferentCanonicalId) {
.ToHandleChecked();
// Check that the signature ID got canonicalized to index 1.
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const std::vector<CanonicalTypeIndex>& canonical_type_ids =
native_module->module()->isorecursive_canonical_type_ids;
diff --git a/deps/v8/test/common/types-fuzz.h b/deps/v8/test/common/types-fuzz.h
index e70a691960a..fdc16a49922 100644
--- a/deps/v8/test/common/types-fuzz.h
+++ b/deps/v8/test/common/types-fuzz.h
@@ -34,6 +34,7 @@
#include "src/handles/handles-inl.h"
#include "src/heap/factory.h"
#include "src/init/v8.h"
+#include "src/objects/object-conversions-inl.h"
namespace v8 {
namespace internal {
diff --git a/deps/v8/test/common/wasm/fuzzer-common.cc b/deps/v8/test/common/wasm/fuzzer-common.cc
index 8ec4ea43600..5ea6707ef64 100644
--- a/deps/v8/test/common/wasm/fuzzer-common.cc
+++ b/deps/v8/test/common/wasm/fuzzer-common.cc
@@ -35,7 +35,7 @@
#include "src/wasm/module-instantiate.h"
#include "src/wasm/string-builder-multiline.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
+#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -474,8 +474,9 @@ MaybeDirectHandle<WasmModuleObject> CompileReferenceModule(
constexpr base::Vector<const char> kNoSourceUrl;
DirectHandle<Script> script =
GetWasmEngine()->GetOrCreateScript(isolate, native_module, kNoSourceUrl);
- TypeCanonicalizer::PrepareForCanonicalTypeId(isolate,
- module->MaxCanonicalTypeIndex());
+ TypeCanonicalizer::PrepareForCanonicalTypeId(
+ isolate, module->MaxCanonicalTypeIndex(),
+ SharedFlag{module->has_shared_part});
return WasmModuleObject::New(isolate, std::move(native_module), script);
}
@@ -759,8 +760,8 @@ bool MemoriesMatch(Isolate* isolate, const WasmModule* module,
Tagged<WasmMemoryObject> ref_memory =
ref_instance_data->memory_object(memory_index);
- Managed<BackingStore>::Ptr store = memory->backing_store();
- Managed<BackingStore>::Ptr ref_store = ref_memory->backing_store();
+ CppGCManaged<BackingStore>::Ptr store = memory->backing_store();
+ CppGCManaged<BackingStore>::Ptr ref_store = ref_memory->backing_store();
size_t memory_size = store->byte_length();
size_t ref_memory_size = ref_store->byte_length();
@@ -893,9 +894,10 @@ bool TablesMatch(Isolate* isolate, const WasmModule* module,
// Tuple2 is used as placeholder in tables (see
// `WasmTableObject::SetFunctionTablePlaceholder`). They reference the
// instance and the function index; just check the stored function index.
- if (IsTuple2(*entry)) {
- if (IsTuple2(*ref_entry) && Cast<Tuple2>(*entry)->value2() ==
- Cast<Tuple2>(*ref_entry)->value2()) {
+ if (!IsWasmNull(*entry) && IsTuple2(*entry)) {
+ if (!IsWasmNull(*ref_entry) && IsTuple2(*ref_entry) &&
+ Cast<Tuple2>(*entry)->value2() ==
+ Cast<Tuple2>(*ref_entry)->value2()) {
continue;
}
} else {
@@ -930,7 +932,7 @@ int ExecuteAgainstReference(Isolate* isolate,
) {
HandleScope handle_scope(isolate);
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const WasmModule* module = native_module->module();
const base::Vector<const uint8_t> wire_bytes = native_module->wire_bytes();
@@ -1202,9 +1204,12 @@ void EnableExperimentalWasmFeatures(v8::Isolate* isolate) {
// Enable all staged features.
#define ENABLE_PRE_STAGED_AND_STAGED_FEATURES(feat, ...) \
v8_flags.wasm_##feat = true;
- FOREACH_WASM_PRE_STAGING_FEATURE_FLAG(
- ENABLE_PRE_STAGED_AND_STAGED_FEATURES)
- FOREACH_WASM_STAGING_FEATURE_FLAG(ENABLE_PRE_STAGED_AND_STAGED_FEATURES)
+ FOREACH_PRE_STAGED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE,
+ ENABLE_PRE_STAGED_AND_STAGED_FEATURES,
+ IGNORE_NON_WASM_FEATURE)
+ FOREACH_STAGED_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE,
+ ENABLE_PRE_STAGED_AND_STAGED_FEATURES,
+ IGNORE_NON_WASM_FEATURE)
#undef ENABLE_PRE_STAGED_AND_STAGED_FEATURES
// Enable non-staged experimental features or other experimental flags
diff --git a/deps/v8/test/common/wasm/fuzzer-common.h b/deps/v8/test/common/wasm/fuzzer-common.h
index 5802a209faa..5bdc449fa4f 100644
--- a/deps/v8/test/common/wasm/fuzzer-common.h
+++ b/deps/v8/test/common/wasm/fuzzer-common.h
@@ -10,7 +10,6 @@
#include <memory>
-#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-tracing.h"
diff --git a/deps/v8/test/common/wasm/wasm-run-utils.cc b/deps/v8/test/common/wasm/wasm-run-utils.cc
index d04ee8ffa2d..e7b753b7131 100644
--- a/deps/v8/test/common/wasm/wasm-run-utils.cc
+++ b/deps/v8/test/common/wasm/wasm-run-utils.cc
@@ -266,7 +266,8 @@ uint32_t TestingModuleBuilder::AddFunction(const FunctionSig* sig,
void TestingModuleBuilder::InitializeWrapperCache() {
TypeCanonicalizer::PrepareForCanonicalTypeId(
- isolate_, module_->MaxCanonicalTypeIndex());
+ isolate_, module_->MaxCanonicalTypeIndex(),
+ SharedFlag{module_->has_shared_part});
DirectHandle<FixedArray> maps = isolate_->factory()->NewFixedArray(
static_cast<int>(module_->types.size()));
for (uint32_t index = 0; index < module_->types.size(); index++) {
diff --git a/deps/v8/test/common/wasm/wasm-run-utils.h b/deps/v8/test/common/wasm/wasm-run-utils.h
index 77831ddc6fb..0c175edf2cb 100644
--- a/deps/v8/test/common/wasm/wasm-run-utils.h
+++ b/deps/v8/test/common/wasm/wasm-run-utils.h
@@ -19,6 +19,7 @@
#include "src/compiler/js-graph.h"
#include "src/compiler/node.h"
#include "src/compiler/wasm-compiler.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/trap-handler/trap-handler.h"
#include "src/wasm/canonical-types.h"
#include "src/wasm/function-body-decoder.h"
diff --git a/deps/v8/test/debugger/debug/debug-evaluate-closure.js b/deps/v8/test/debugger/debug/debug-evaluate-closure.js
index 5b8ad89c5d9..9d7189604f0 100644
--- a/deps/v8/test/debugger/debug/debug-evaluate-closure.js
+++ b/deps/v8/test/debugger/debug/debug-evaluate-closure.js
@@ -33,6 +33,8 @@ function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
assertEquals("goo", exec_state.frame(0).evaluate("goo").value());
+ assertEquals("goo", exec_state.frame(0).scope(1).evaluate("goo").value());
+ assertThrows(() => exec_state.frame(0).scope(1).evaluate("w").value());
exec_state.frame(0).evaluate("goo = 'goo foo'");
assertEquals("bar return", exec_state.frame(0).evaluate("bar()").value());
assertEquals("inner bar", exec_state.frame(0).evaluate("inner").value());
diff --git a/deps/v8/test/debugger/debug/debug-evaluate-locals.js b/deps/v8/test/debugger/debug/debug-evaluate-locals.js
index edc27e60bbf..4364b90e872 100644
--- a/deps/v8/test/debugger/debug/debug-evaluate-locals.js
+++ b/deps/v8/test/debugger/debug/debug-evaluate-locals.js
@@ -124,6 +124,9 @@ function listener(event, exec_state, event_data, data) {
assertEquals(6, exec_state.frame(2).evaluate('b').value());
assertEquals("function",
exec_state.frame(2).evaluate('typeof eval').value());
+ assertEquals(1,
+ exec_state.frame(0).scope(0).evaluate('a').value());
+ assertThrows(() => exec_state.frame(0).scope(1).evaluate('a').value());
assertEquals("foo",
exec_state.frame(0).evaluate('a = "foo"').value());
assertEquals("bar",
diff --git a/deps/v8/test/debugger/debug/debug-evaluate-nested-let.js b/deps/v8/test/debugger/debug/debug-evaluate-nested-let.js
index fb8c569f7b5..3f708fae854 100644
--- a/deps/v8/test/debugger/debug/debug-evaluate-nested-let.js
+++ b/deps/v8/test/debugger/debug/debug-evaluate-nested-let.js
@@ -35,6 +35,8 @@ function f() {
function listener(event, exec_state, event_data, data) {
if (event != Debug.DebugEvent.Break) return;
try {
+ assertEquals(2, exec_state.frame(0).scope(0).evaluate("a").value());
+ assertEquals(1, exec_state.frame(0).scope(1).evaluate("a").value());
exec_state.frame(0).evaluate("a = 3");
exec_state.frame(1).evaluate("a = 4");
assertThrows(() => exec_state.frame(0).evaluate("this = 2"));
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 a3b17b63e81..371012a0db8 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
@@ -182,6 +182,34 @@ listener_delegate = function(exec_state) {
(f5())()();
EndTest();
+BeginTest("Check evaluating on outer closure scopes with shadowing");
+function test_scopes_shadowing() {
+ let x = 'outer_x';
+ let y = 'outer_y';
+ () => [x, y]; // context allocate x and y in f7
+ return function g() {
+ let x = 'middle_x';
+ () => x; // context allocate x in g
+ return function h() {
+ let x = 'inner_x_stack'; // stack allocate x in h
+ debugger;
+ };
+ };
+}
+
+listener_delegate = function(exec_state) {
+ assertEquals('inner_x_stack', exec_state.frame(0).scope(0).evaluate("x").value());
+ assertEquals('outer_y', exec_state.frame(0).scope(0).evaluate("y").value());
+
+ assertEquals('middle_x', exec_state.frame(0).scope(1).evaluate("x").value());
+ assertEquals('outer_y', exec_state.frame(0).scope(1).evaluate("y").value());
+
+ assertEquals('outer_x', exec_state.frame(0).scope(2).evaluate("x").value());
+ assertEquals('outer_y', exec_state.frame(0).scope(2).evaluate("y").value());
+};
+(test_scopes_shadowing())()();
+EndTest();
+
BeginTest("Check that outer functions also get the correct block list calculated");
// This test is important once we reuse block list info. The block list for `g`
// needs to be correctly calculated already when we stop on break_position 1.
@@ -242,6 +270,23 @@ break_position = 2;
f7({});
EndTest();
+BeginTest("Check evaluating on outer closure scope with stack-allocated shadowed variable");
+var x = 'global_x';
+function test_outer_shadow() {
+ let x = 'outer_stack';
+ let closure_y = 'closure_y';
+ () => closure_y; // force context allocation for closure_y
+ return function inner() {
+ 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())();
+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 d16f8fbc038..8f4024f58d6 100644
--- a/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context.js
+++ b/deps/v8/test/debugger/debug/debug-evaluate-shadowed-context.js
@@ -178,6 +178,34 @@ listener_delegate = function(exec_state) {
(f5())()();
EndTest();
+BeginTest("Check evaluating on outer closure scopes with shadowing");
+function test_scopes_shadowing() {
+ let x = 'outer_x';
+ let y = 'outer_y';
+ () => [x, y]; // context allocate x and y in f7
+ return function g() {
+ let x = 'middle_x';
+ () => x; // context allocate x in g
+ return function h() {
+ let x = 'inner_x_stack'; // stack allocate x in h
+ debugger;
+ };
+ };
+}
+
+listener_delegate = function(exec_state) {
+ assertEquals('inner_x_stack', exec_state.frame(0).scope(0).evaluate("x").value());
+ assertEquals('outer_y', exec_state.frame(0).scope(0).evaluate("y").value());
+
+ assertEquals('middle_x', exec_state.frame(0).scope(1).evaluate("x").value());
+ assertEquals('outer_y', exec_state.frame(0).scope(1).evaluate("y").value());
+
+ assertEquals('outer_x', exec_state.frame(0).scope(2).evaluate("x").value());
+ assertEquals('outer_y', exec_state.frame(0).scope(2).evaluate("y").value());
+};
+(test_scopes_shadowing())()();
+EndTest();
+
BeginTest("Check that outer functions also get the correct block list calculated");
// This test is important once we reuse block list info. The block list for `g`
// needs to be correctly calculated already when we stop on break_position 1.
@@ -209,6 +237,23 @@ break_position = 2;
(f6())()();
EndTest();
+BeginTest("Check evaluating on outer closure scope with stack-allocated shadowed variable");
+var x = 'global_x';
+function test_outer_shadow() {
+ let x = 'outer_stack';
+ let closure_y = 'closure_y';
+ () => closure_y; // force context allocation for closure_y
+ return function inner() {
+ 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())();
+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-liveedit-1.js b/deps/v8/test/debugger/debug/debug-liveedit-1.js
deleted file mode 100644
index 65e4e691c28..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-1.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-eval("var something1 = 25; "
- + " function ChooseAnimal() { return 'Cat'; } "
- + " ChooseAnimal.Helper = function() { return 'Help!'; }");
-
-assertEquals("Cat", ChooseAnimal());
-
-var orig_animal = "Cat";
-var new_animal_patch = "Cap' + 'y' + 'bara";
-var new_source =
- Debug.scriptSource(ChooseAnimal).replace(orig_animal, new_animal_patch);
-
-%LiveEditPatchScript(ChooseAnimal, new_source);
-
-assertEquals("Capybara", ChooseAnimal());
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-2.js b/deps/v8/test/debugger/debug/debug-liveedit-2.js
deleted file mode 100644
index 72be61f05c8..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-2.js
+++ /dev/null
@@ -1,57 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-eval("function ChooseAnimal(p) {\n " +
- " if (p == 7) {\n" + // Use p
- " return;\n" +
- " }\n" +
- " return function Chooser() {\n" +
- " return 'Cat';\n" +
- " };\n" +
- "}\n");
-
-var old_closure = ChooseAnimal(19);
-
-assertEquals("Cat", old_closure());
-
-// We patch innermost function "Chooser".
-// However, this does not actually patch existing "Chooser" instances,
-// because old value of parameter "p" was not saved.
-// Instead it patches ChooseAnimal.
-%LiveEditPatchScript(
- ChooseAnimal, Debug.scriptSource(ChooseAnimal).replace("'Cat'", "'Capybara' + p"));
-
-var new_closure = ChooseAnimal(19);
-// New instance of closure is patched.
-assertEquals("Capybara19", new_closure());
-
-// Old instance of closure is not patched.
-assertEquals("Cat", old_closure());
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-3.js b/deps/v8/test/debugger/debug/debug-liveedit-3.js
deleted file mode 100644
index 28c26f5e2c2..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-3.js
+++ /dev/null
@@ -1,63 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// In this test case we edit a script so that techincally function text
-// hasen't been changed. However actually function became one level more nested
-// and must be recompiled because it uses variable from outer scope.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-var function_z_text =
-" function Z() {\n"
-+ " return 2 + p;\n"
-+ " }\n";
-
-eval(
-"function Factory(p) {\n"
-+ "return (\n"
-+ function_z_text
-+ ");\n"
-+ "}\n"
-);
-
-var z6 = Factory(6);
-assertEquals(8, z6());
-
-var new_source = Debug.scriptSource(Factory).replace(
- function_z_text,
- 'function Intermediate() {\nreturn (\n' + function_z_text + ')\n;\n}\n');
-
-%LiveEditPatchScript(Factory, new_source);
-
-assertEquals(8, z6());
-
-var z100 = Factory(100)();
-
-assertEquals(102, z100());
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-4.js b/deps/v8/test/debugger/debug/debug-liveedit-4.js
deleted file mode 100644
index 96944e7d2ef..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-4.js
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// In this test case we edit a script so that techincally function text
-// hasen't been changed. However actually function became one level more nested
-// and must be recompiled because it uses variable from outer scope.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-eval(
-"function TestFunction() {\n"
-+ " var a = 'a';\n"
-+ " var b = 'b';\n"
-+ " var c = 'c';\n"
-+ " function A() {\n"
-+ " return 2013;\n"
-+ " }\n"
-+ " function B() {\n"
-+ " return String([a, c]);\n"
-+ " }\n"
-+ " return B();\n"
-+ "}\n"
-);
-
-var res = TestFunction();
-print(res);
-assertEquals('a,c', res);
-
-var new_source = Debug.scriptSource(TestFunction).replace('2013', 'b');
-print("new source: " + new_source);
-
-%LiveEditPatchScript(TestFunction, new_source);
-
-var res = TestFunction();
-print(res);
-// This might be 'a,b' without a bug fixed.
-assertEquals('a,c', res);
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-arrow-function-at-start.js b/deps/v8/test/debugger/debug/debug-liveedit-arrow-function-at-start.js
deleted file mode 100644
index 36b7fde3e66..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-arrow-function-at-start.js
+++ /dev/null
@@ -1,13 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-// ()=>42 will have the same start and end position as the top-level script.
-var foo = eval("()=>{ return 42 }");
-assertEquals(42, foo());
-
-%LiveEditPatchScript(foo, "()=>{ return 13 }");
-
-assertEquals(13, foo());
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-check-stack.js b/deps/v8/test/debugger/debug/debug-liveedit-check-stack.js
deleted file mode 100644
index e63659e292a..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-check-stack.js
+++ /dev/null
@@ -1,142 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-unique_id = 1;
-
-function TestBase(name) {
- print("TestBase constructor: " + name);
-
- const original_source = '/* ' + unique_id + '*/\n' +
- '(function ChooseAnimal(callback) {\n ' +
- ' callback();\n' +
- ' return \'Cat\';\n' +
- '})\n';
- const updated_source = original_source.replace('\'Cat\'', '\'Capybara\'');
-
- this.ChooseAnimal = eval(original_source);
- // Prevents eval script caching.
- unique_id++;
-
- const func = this.ChooseAnimal;
-
- var got_exception = false;
- var successfully_changed = false;
-
- // Should be called from Debug context.
- this.ScriptChanger = () => {
- assertEquals(false, successfully_changed, "applying patch second time");
- %LiveEditPatchScript(func, updated_source);
- successfully_changed = true;
- };
-}
-
-function Noop() {}
-
-function WrapInCatcher(f, holder) {
- return function() {
- delete holder[0];
- try {
- f();
- } catch (e) {
- if (e.startsWith('LiveEdit failed')) {
- holder[0] = e;
- } else {
- throw e;
- }
- }
- };
-}
-
-function WrapInNativeCall(f) {
- return function() {
- return %Call(f, undefined);
- };
-}
-
-function ExecuteInDebugContext(f) {
- var result;
- var exception = null;
- Debug.setListener(function(event) {
- if (event == Debug.DebugEvent.Break) {
- try {
- result = f();
- } catch (e) {
- // Rethrow this exception later.
- exception = e;
- }
- }
- });
- debugger;
- Debug.setListener(null);
- if (exception !== null) throw exception;
- return result;
-}
-
-function WrapInDebuggerCall(f) {
- return function() {
- return ExecuteInDebugContext(f);
- };
-}
-
-function WrapInRestartProof(f) {
- var already_called = false;
- return function() {
- if (already_called) {
- return;
- }
- already_called = true;
- f();
- }
-}
-
-function WrapInConstructor(f) {
- return function() {
- return new function() {
- f();
- };
- }
-}
-
-
-// A series of tests. In each test we call ChooseAnimal function that calls
-// a callback that attempts to modify the function on the fly.
-
-test = new TestBase("First test ChooseAnimal without edit");
-assertEquals("Cat", test.ChooseAnimal(Noop));
-
-test = new TestBase("Test without function on stack");
-test.ScriptChanger();
-assertEquals("Capybara", test.ChooseAnimal(Noop));
-
-test = new TestBase("Test with C++ frame above ChooseAnimal frame");
-exception_holder = {};
-assertEquals("Cat", test.ChooseAnimal(WrapInNativeCall(WrapInDebuggerCall(WrapInCatcher(test.ScriptChanger, exception_holder)))));
-assertTrue(!!exception_holder[0]);
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-compile-error.js b/deps/v8/test/debugger/debug/debug-liveedit-compile-error.js
deleted file mode 100644
index decd1a20165..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-compile-error.js
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2012 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-eval("var something1 = 25; \n"
- + " function ChooseAnimal() { return 'Cat'; } \n"
- + " ChooseAnimal.Helper = function() { return 'Help!'; }\n");
-
-assertEquals("Cat", ChooseAnimal());
-
-var new_source =
- Debug.scriptSource(ChooseAnimal).replace('Cat', 'Cap\' + ) + \'bara');
-print('new source: ' + new_source);
-
-var caught_exception = null;
-try {
- %LiveEditPatchScript(ChooseAnimal, new_source);
-} catch (e) {
- caught_exception = e;
-}
-
-assertNotNull(caught_exception);
-assertEquals('LiveEdit failed: COMPILE_ERROR', caught_exception);
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-eval.js b/deps/v8/test/debugger/debug/debug-liveedit-eval.js
deleted file mode 100644
index c95421db370..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-eval.js
+++ /dev/null
@@ -1,23 +0,0 @@
-// Copyright 2025 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 --inspector-live-edit
-
-Debug = debug.Debug
-
-eval("var something1 = 25; "
- + "function do_eval(s) { return eval(`'${s}'`) };"
- + " function ChooseAnimal() { return do_eval('Cat'); } "
- + " ChooseAnimal.Helper = function() { return eval(\"'Help!\"); }");
-
-assertEquals("Cat", ChooseAnimal());
-
-var orig_animal = "Cat";
-var new_animal_patch = "Cap' + 'y' + 'bara";
-var old_source = Debug.scriptSource(ChooseAnimal);
-var new_source = old_source.replace(orig_animal, new_animal_patch);
-
-%LiveEditPatchScript(ChooseAnimal, new_source);
-
-assertEquals("Capybara", ChooseAnimal());
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-inline.js b/deps/v8/test/debugger/debug/debug-liveedit-inline.js
deleted file mode 100644
index 4fbd155a26f..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-inline.js
+++ /dev/null
@@ -1,27 +0,0 @@
-// Copyright 2017 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-eval("var something1 = 25; "
- + " function ChooseAnimal() { return 'Cat'; } "
- + " ChooseAnimal.Helper = function() { return 'Help!'; }");
-
-function foo() { return ChooseAnimal() }
-
-%PrepareFunctionForOptimization(foo);
-assertEquals("Cat", foo());
-%OptimizeFunctionOnNextCall(foo);
-
-foo();
-
-var new_source =
- Debug.scriptSource(ChooseAnimal).replace('Cat', "Cap' + 'y' + 'bara");
-print('new source: ' + new_source);
-
-%LiveEditPatchScript(ChooseAnimal, new_source);
-
-assertEquals("Capybara", foo());
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-literals.js b/deps/v8/test/debugger/debug/debug-liveedit-literals.js
deleted file mode 100644
index c391db6ccc2..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-literals.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-function Test(old_expression, new_expression) {
- // Generate several instances of function to test that we correctly fix
- // all functions in memory.
- var function_instance_number = 11;
- eval("var t1 =1;\n" +
- "ChooseAnimalArray = [];\n" +
- "for (var i = 0; i < function_instance_number; i++) {\n" +
- " ChooseAnimalArray.push(\n" +
- " function ChooseAnimal() {\n" +
- " return " + old_expression + ";\n" +
- " });\n" +
- "}\n" +
- "var t2 =1;\n");
-
- for (var i = 0; i < ChooseAnimalArray.length; i++) {
- assertEquals("Cat", ChooseAnimalArray[i]());
- }
-
- var new_source =
- Debug.scriptSource(ChooseAnimalArray[0]).replace(old_expression, new_expression);
- %LiveEditPatchScript(ChooseAnimalArray[0], new_source);
-
- for (var i = 0; i < ChooseAnimalArray.length; i++) {
- assertEquals("Capybara", ChooseAnimalArray[i]());
- }
-}
-
-// Check that old literal boilerplate was reset.
-Test("['Cat'][0]", "['Capybara'][0]");
-Test("['Cat'][0]", "{a:'Capybara'}.a");
-
-// No literals -> 1 literal.
-Test("'Cat'", "['Capybara'][0]");
-
-// No literals -> 2 literals.
-Test("'Cat'", "['Capy'][0] + {a:'bara'}.a");
-
-// 1 literal -> no literals.
-Test("['Cat'][0]", "'Capybara'");
-
-// 2 literals -> no literals.
-Test("['Ca'][0] + {a:'t'}.a", "'Capybara'");
-
-// No literals -> regexp.
-Test("'Cat'", "(/.A.Y.A.A/i).exec('Capybara')[0]");
-
-// Array literal -> regexp.
-Test("['Cat'][0]", "(/.A.Y.A.A/i).exec('Capybara')[0]");
-
-// Regexp -> object literal.
-Test("(/.A./i).exec('Cat')[0]", "{c:'Capybara'}.c");
-
-// No literals -> regexp.
-Test("'Cat'", "(/.A.Y.A.A/i).exec('Capybara')[0]");
-
-// Regexp -> no literals.
-Test("(/.A./i).exec('Cat')[0]", "'Capybara'");
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-newsource.js b/deps/v8/test/debugger/debug/debug-liveedit-newsource.js
deleted file mode 100644
index 0dd52f13023..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-newsource.js
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-
-eval("var something1 = 25; \n"
- + "var something2 = 2010; \n"
- + "// Array(); \n"
- + "function ChooseAnimal() {\n"
- + " return 'Cat';\n"
- + "} \n"
- + "function ChooseFurniture() {\n"
- + " return 'Table';\n"
- + "} \n"
- + "function ChooseNumber() { return 17; } \n"
- + "ChooseAnimal.Factory = function Factory() {\n"
- + " return function FactoryImpl(name) {\n"
- + " return 'Help ' + name;\n"
- + " }\n"
- + "}\n");
-
-assertEquals("Cat", ChooseAnimal());
-assertEquals(25, something1);
-
-var new_source = Debug.scriptSource(ChooseAnimal).replace("Cat", "Cap' + 'yb' + 'ara");
-var new_source = new_source.replace("25", "26");
-var new_source = new_source.replace("Help", "Hello");
-var new_source = new_source.replace("17", "18");
-// The call to array causes a change in the number of type feedback slots for
-// the script.
-//
-// TODO(mvstanton): For now, the inclusion of the Array() call at the top level
-// of the script causes us to visit a corner case, but I'd like to validate
-// correctness more explicitly.
-var new_source = new_source.replace("// Array", "Array");
-print("new source: " + new_source);
-
-%LiveEditPatchScript(ChooseAnimal, new_source);
-
-assertEquals("Capybara", ChooseAnimal());
-// Global variable do not get changed (without restarting script).
-assertEquals(25, something1);
-// We should support changes in oneliners.
-assertEquals(18, ChooseNumber());
-assertEquals("Hello Peter", ChooseAnimal.Factory()("Peter"));
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js b/deps/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js
deleted file mode 100644
index 0bdd5b4ebe8..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-patch-positions-replace.js
+++ /dev/null
@@ -1,76 +0,0 @@
-// Copyright 2010 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// Scenario: a function is being changed, which causes enclosing function to
-// have its positions patched; position changing requires new instance of Code
-// object to be introduced; the function happens to be on stack at this moment;
-// later it will resume over new instance of Code.
-// Before the change 2 rinfo are 22 characters away from each other. After the
-// change they are 114 characters away from each other. New instance of Code is
-// required when those numbers cross the border value of 64 (in any direction).
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-Debug = debug.Debug
-
-eval(
- "function BeingReplaced(changer, opt_x, opt_y) {\n" +
- " changer();\n" +
- " var res = new Object();\n" +
- " if (opt_x) { res.y = opt_y; }\n" +
- " res.a = (function() {})();\n" +
- " return res.a;\n" +
- "}"
-);
-
-function Changer() {
- // Line long enough to change rinfo encoding.
- var new_source =
- Debug.scriptSource(BeingReplaced).replace("{}", "{return 'Capybara';" +
- " " +
- "}");
- %LiveEditPatchScript(BeingReplaced, new_source);
-}
-
-function NoOp() {
-}
-
-function CallM(changer) {
- // We expect call IC here after several function runs.
- return BeingReplaced(changer);
-}
-
-// This several iterations should cause call IC for BeingReplaced call. This IC
-// will keep reference to code object of BeingReplaced function. This reference
-// should also be patched. Unfortunately, this is a manually checked fact (from
-// debugger or debug print) and doesn't work as an automatic test.
-CallM(NoOp);
-CallM(NoOp);
-CallM(NoOp);
-
-var res = CallM(Changer);
-assertEquals("Capybara", res);
diff --git a/deps/v8/test/debugger/debug/debug-liveedit-recursion.js b/deps/v8/test/debugger/debug/debug-liveedit-recursion.js
deleted file mode 100644
index ab326a30326..00000000000
--- a/deps/v8/test/debugger/debug/debug-liveedit-recursion.js
+++ /dev/null
@@ -1,42 +0,0 @@
-// Copyright 2018 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug;
-
-function test(i) {
- if (i == 3) {
- return (function* gen() { yield test(i - 1); })().next().value;
- } else if (i > 1) {
- return test(i - 1);
- } else {
- debugger;
- return 5;
- }
-}
-
-let patch = null, exception = null;
-
-Debug.setListener(listener);
-patch = ['return 5', 'return 3'];
-assertEquals(5, test(2)); // generator on stack
-assertEquals(exception,
- 'LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION');
-patch = ['return 3', 'return -1'];
-assertEquals(5, test(5)); // there is running generator
-assertEquals(exception,
- 'LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION');
-Debug.setListener(null);
-
-function listener(event) {
- if (event != Debug.DebugEvent.Break || !patch) return;
- try {
- %LiveEditPatchScript(test,
- Debug.scriptSource(test).replace(patch[0], patch[1]));
- } catch (e) {
- exception = e;
- }
- patch = null;
-}
diff --git a/deps/v8/test/debugger/debug/debug-modules-many-variables.mjs b/deps/v8/test/debugger/debug/debug-modules-many-variables.mjs
new file mode 100644
index 00000000000..d0ec5e7b475
--- /dev/null
+++ b/deps/v8/test/debugger/debug/debug-modules-many-variables.mjs
@@ -0,0 +1,162 @@
+// 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-turbofan
+
+// setVariableValue / scope inspection on a module scope with more module
+// variables than kScopeInfoMaxInlinedLocalNamesSize, so the debugger's
+// ScopeInfo::ModuleIndex lookups go through the module-variables hashtable.
+
+var Debug = debug.Debug;
+
+export let v0 = 0;
+export let v1 = 1;
+export let v2 = 2;
+export let v3 = 3;
+export let v4 = 4;
+export let v5 = 5;
+export let v6 = 6;
+export let v7 = 7;
+export let v8 = 8;
+export let v9 = 9;
+export let v10 = 10;
+export let v11 = 11;
+export let v12 = 12;
+export let v13 = 13;
+export let v14 = 14;
+export let v15 = 15;
+export let v16 = 16;
+export let v17 = 17;
+export let v18 = 18;
+export let v19 = 19;
+export let v20 = 20;
+export let v21 = 21;
+export let v22 = 22;
+export let v23 = 23;
+export let v24 = 24;
+export let v25 = 25;
+export let v26 = 26;
+export let v27 = 27;
+export let v28 = 28;
+export let v29 = 29;
+export let v30 = 30;
+export let v31 = 31;
+export let v32 = 32;
+export let v33 = 33;
+export let v34 = 34;
+export let v35 = 35;
+export let v36 = 36;
+export let v37 = 37;
+export let v38 = 38;
+export let v39 = 39;
+export let v40 = 40;
+export let v41 = 41;
+export let v42 = 42;
+export let v43 = 43;
+export let v44 = 44;
+export let v45 = 45;
+export let v46 = 46;
+export let v47 = 47;
+export let v48 = 48;
+export let v49 = 49;
+export let v50 = 50;
+export let v51 = 51;
+export let v52 = 52;
+export let v53 = 53;
+export let v54 = 54;
+export let v55 = 55;
+export let v56 = 56;
+export let v57 = 57;
+export let v58 = 58;
+export let v59 = 59;
+export let v60 = 60;
+export let v61 = 61;
+export let v62 = 62;
+export let v63 = 63;
+export let v64 = 64;
+export let v65 = 65;
+export let v66 = 66;
+export let v67 = 67;
+export let v68 = 68;
+export let v69 = 69;
+export let v70 = 70;
+export let v71 = 71;
+export let v72 = 72;
+export let v73 = 73;
+export let v74 = 74;
+export let v75 = 75;
+export let v76 = 76;
+export let v77 = 77;
+export let v78 = 78;
+export let v79 = 79;
+export let v80 = 80;
+export let v81 = 81;
+export let v82 = 82;
+export let v83 = 83;
+export let v84 = 84;
+export let v85 = 85;
+export let v86 = 86;
+export let v87 = 87;
+export let v88 = 88;
+export let v89 = 89;
+export let v90 = 90;
+export let v91 = 91;
+export let v92 = 92;
+export let v93 = 93;
+export let v94 = 94;
+export let v95 = 95;
+export let v96 = 96;
+export let v97 = 97;
+export let v98 = 98;
+export let v99 = 99;
+export let v100 = 100;
+export let v101 = 101;
+export let v102 = 102;
+export let v103 = 103;
+export let v104 = 104;
+export let v105 = 105;
+export let v106 = 106;
+export let v107 = 107;
+export let v108 = 108;
+export let v109 = 109;
+export let v110 = 110;
+export let v111 = 111;
+export let v112 = 112;
+export let v113 = 113;
+export let v114 = 114;
+export let v115 = 115;
+export let v116 = 116;
+export let v117 = 117;
+export let v118 = 118;
+export let v119 = 119;
+
+let notExported = 'a';
+
+{
+ let exception;
+ function listener(event, exec_state) {
+ if (event != Debug.DebugEvent.Break) return;
+ try {
+ let module_scope = exec_state.frame().scope(1);
+ assertEquals(debug.ScopeType.Module, module_scope.scopeType());
+ // Existing variables at various positions in the module_variables list.
+ module_scope.setVariableValue('v0', 1000);
+ module_scope.setVariableValue('v74', 1074);
+ module_scope.setVariableValue('v75', 1075);
+ module_scope.setVariableValue('v119', 2000);
+ module_scope.setVariableValue('notExported', 'b');
+ // Non-existing variable must throw.
+ assertThrows(() => module_scope.setVariableValue('spargel', 42));
+ } catch (e) { exception = e; }
+ }
+ Debug.setListener(listener);
+ debugger;
+ Debug.setListener(null);
+ assertEquals(undefined, exception);
+ assertEquals(1000, v0);
+ assertEquals(1074, v74);
+ assertEquals(1075, v75);
+ assertEquals(2000, v119);
+ assertEquals('b', notExported);
+ assertEquals(1, v1);
+}
diff --git a/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js b/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js
deleted file mode 100644
index 4a43c11b46e..00000000000
--- a/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-1.js
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Test that live-editing a frame that uses new.target fails.
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug
-var calls = 0;
-var exceptions = 0;
-var results = [];
-var replace_again;
-
-eval(`
- function LogNewTarget() {
- calls++;
- ReplaceOnce();
- results.push(true);
- results.push(new.target);
- }
-`);
-
-function Dummy() {}
-
-function ExecuteInDebugContext(f) {
- var result;
- var exception = null;
- Debug.setListener(function(event) {
- if (event == Debug.DebugEvent.Break) {
- try {
- result = f();
- } catch (e) {
- // Rethrow this exception later.
- exception = e;
- }
- }
- });
- debugger;
- Debug.setListener(null);
- if (exception !== null) throw exception;
- return result;
-}
-
-function Replace(fun, original, patch) {
- ExecuteInDebugContext(function() {
- try {
- %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
- } catch (e) {
- assertEquals(e, 'LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION');
- exceptions++;
- }
- });
-}
-
-function ReplaceOnce() {
- if (replace_again) {
- replace_again = false;
- Replace(LogNewTarget, "true", "false");
- }
-}
-
-function Revert() {
- Replace(LogNewTarget, "false", "true");
-}
-
-replace_again = true;
-ReplaceOnce();
-new LogNewTarget();
-Revert();
-assertEquals(1, calls);
-assertEquals(0, exceptions);
-assertEquals([false, LogNewTarget], results);
-
-replace_again = true;
-LogNewTarget();
-
-replace_again = true;
-new LogNewTarget();
-
-replace_again = true;
-Reflect.construct(LogNewTarget, [], Dummy);
-
-assertEquals(
- [false, LogNewTarget, true, undefined, true, LogNewTarget, true, Dummy],
- results);
-assertEquals(4, calls); // No restarts
-assertEquals(3, exceptions); // Replace failed.
diff --git a/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js b/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js
deleted file mode 100644
index 41399e3ff51..00000000000
--- a/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-2.js
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --allow-natives-syntax --inspector-live-edit
-// Test that live-editing a frame to introduce new.target fails.
-
-Debug = debug.Debug
-var calls = 0;
-var exceptions = 0;
-var results = [];
-var replace_again;
-
-eval(`
- function LogNewTarget() {
- calls++;
- ReplaceOnce();
- results.push(true);
- }
-`);
-
-function ExecuteInDebugContext(f) {
- var result;
- var exception = null;
- Debug.setListener(function(event) {
- if (event == Debug.DebugEvent.Break) {
- try {
- result = f();
- } catch (e) {
- // Rethrow this exception later.
- exception = e;
- }
- }
- });
- debugger;
- Debug.setListener(null);
- if (exception !== null) throw exception;
- return result;
-}
-
-function Replace(fun, original, patch) {
- ExecuteInDebugContext(function() {
- try {
- %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
- } catch (e) {
- assertEquals(e, 'LiveEdit failed: BLOCKED_BY_ACTIVE_FUNCTION');
- exceptions++;
- }
- });
-}
-
-function ReplaceOnce(x) {
- if (replace_again) {
- replace_again = false;
- Replace(LogNewTarget, "true", "new.target");
- }
-}
-
-function Revert() {
- Replace(LogNewTarget, "new.target", "true");
-}
-
-replace_again = true;
-ReplaceOnce();
-new LogNewTarget();
-Revert();
-assertEquals(1, calls);
-assertEquals(0, exceptions);
-assertEquals([LogNewTarget], results);
-
-replace_again = true;
-new LogNewTarget();
-assertEquals(2, calls); // No restarts
-assertEquals(1, exceptions); // Replace failed.
-assertEquals([LogNewTarget, true], results);
diff --git a/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js b/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js
deleted file mode 100644
index a6b776075f9..00000000000
--- a/deps/v8/test/debugger/debug/es6/debug-liveedit-new-target-3.js
+++ /dev/null
@@ -1,88 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Test that live-editing a frame above one that uses new.target succeeds.
-// Flags: --allow-natives-syntax --inspector-live-edit
-
-Debug = debug.Debug;
-var wrapper_calls = 0;
-var construct_calls = 0;
-var exceptions = 0;
-var results = [];
-var replace_again;
-
-eval(`
- function LogNewTarget(arg) {
- construct_calls++;
- results.push(new.target);
- }
- function Wrapper() {
- wrapper_calls++;
- ReplaceOnce();
- new LogNewTarget(true);
- }
-`);
-
-function ExecuteInDebugContext(f) {
- var result;
- var exception = null;
- Debug.setListener(function(event) {
- if (event == Debug.DebugEvent.Break) {
- try {
- result = f();
- } catch (e) {
- // Rethrow this exception later.
- exception = e;
- }
- }
- });
- debugger;
- Debug.setListener(null);
- if (exception !== null) throw exception;
- return result;
-}
-
-function Replace(fun, original, patch) {
- ExecuteInDebugContext(function() {
- var change_log = [];
- try {
- %LiveEditPatchScript(fun, Debug.scriptSource(fun).replace(original, patch));
- } catch (e) {
- exceptions++;
- }
- });
-}
-
-function ReplaceOnce(x) {
- if (replace_again) {
- replace_again = false;
- Replace(Wrapper, "true", "false");
- }
-}
-
-function Revert() {
- Replace(Wrapper, "false", "true");
-}
-
-replace_again = true;
-ReplaceOnce();
-Wrapper();
-Revert();
-assertEquals(1, construct_calls);
-assertEquals(1, wrapper_calls);
-assertEquals(0, exceptions); // Replace succeeds
-assertEquals([LogNewTarget], results);
-
-Wrapper();
-assertEquals(2, construct_calls);
-assertEquals(2, wrapper_calls);
-assertEquals(0, exceptions); // Replace succeeds
-assertEquals([LogNewTarget, LogNewTarget], results);
-
-replace_again = true;
-Wrapper();
-assertEquals(3, construct_calls);
-assertEquals(3, wrapper_calls);
-assertEquals(1, exceptions); // Replace failed
-assertEquals([LogNewTarget, LogNewTarget, LogNewTarget], results);
diff --git a/deps/v8/test/debugger/debug/futex-reentrant-wait.js b/deps/v8/test/debugger/debug/futex-reentrant-wait.js
new file mode 100644
index 00000000000..fc82beac534
--- /dev/null
+++ b/deps/v8/test/debugger/debug/futex-reentrant-wait.js
@@ -0,0 +1,35 @@
+// 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
+
+var Debug = debug.Debug;
+var exception = null;
+
+Debug.setListener(function (event, exec_state, event_data, data) {
+ if (event == Debug.DebugEvent.Break) {
+ try {
+ var sab2 = new SharedArrayBuffer(4);
+ var i32a2 = new Int32Array(sab2);
+ Atomics.wait(i32a2, 0, 0, 10);
+ } catch (e) {
+ exception = e;
+ }
+ }
+});
+
+let sab = new SharedArrayBuffer(4);
+let i32a = new Int32Array(sab);
+
+let timeout = {
+ valueOf: function() {
+ %ScheduleBreak();
+ return 10;
+ }
+};
+
+Atomics.wait(i32a, 0, 0, timeout);
+
+assertNotNull(exception);
+assertTrue(exception.message.includes("cannot be called in this context"));
diff --git a/deps/v8/test/debugger/debug/regress-debug-scopes-context-blocklist.js b/deps/v8/test/debugger/debug/regress-debug-scopes-context-blocklist.js
new file mode 100644
index 00000000000..54425333a3d
--- /dev/null
+++ b/deps/v8/test/debugger/debug/regress-debug-scopes-context-blocklist.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: --no-analyze-environment-liveness
+
+Debug = debug.Debug;
+
+let listener_delegate;
+let error = null;
+
+function listener(event, exec_state, event_data, data) {
+ try {
+ if (event == Debug.DebugEvent.Break) {
+ listener_delegate(exec_state);
+ }
+ } catch (e) {
+ error = e;
+ }
+}
+Debug.setListener(listener);
+
+var x = 'global_x';
+
+function outer() {
+ let y = 'y';
+ () => y; // force context allocation for outer
+
+ // intermediate scope, no context needed
+ function intermediate() {
+ let x = 'intermediate_x'; // stack variable
+
+ // innermost scope, paused here. No context needed.
+ function inner() {
+ debugger;
+ }
+ inner();
+ }
+
+ return intermediate;
+}
+
+let f = outer();
+
+listener_delegate = function(exec_state) {
+ // exec_state.frame(0).scope(1) is 'outer's closure scope.
+ // We evaluate 'x' inside 'outer's scope.
+ // It should return 'global_x' because 'outer' does not have an 'x'.
+ // But due to the defect, 'intermediate's stack variable 'x' leaks
+ // into 'outer's context blocklist, causing a ReferenceError.
+ let val;
+ try {
+ val = exec_state.frame(0).scope(1).evaluate('x').value();
+ } catch (e) {
+ throw new Error('Spurious error: ' + e.message);
+ }
+
+ if (val !== 'global_x') {
+ throw new Error('Expected global_x, got ' + val);
+ }
+};
+
+f();
+
+Debug.setListener(null);
+
+if (error) {
+ throw error;
+}
diff --git a/deps/v8/test/debugger/debugger.status b/deps/v8/test/debugger/debugger.status
index b442b73bc24..68d35bf4856 100644
--- a/deps/v8/test/debugger/debugger.status
+++ b/deps/v8/test/debugger/debugger.status
@@ -82,8 +82,6 @@
##############################################################################
['verify_predictable', {
- # https://crbug.com/v8/8147
- 'debug/debug-liveedit-*': [SKIP],
'debug/debug-set-variable-value': [SKIP],
# Rely on (blocking) concurrent compilation.
@@ -123,12 +121,6 @@
# Test uses a flag only available in debug mode
'debug/wasm/debug-enabled-tier-down-wasm-unsupported-liftoff': [SKIP],
}],
-##############################################################################
-['arch == s390x', {
-
- # Stack manipulations in LiveEdit is not implemented for this arch.
- 'debug/debug-liveedit-check-stack': [SKIP],
-}], # 'arch == s390x'
##############################################################################
# TODO(v8:7777): Change this once wasm is supported in jitless mode.
diff --git a/deps/v8/test/debugger/test-api.js b/deps/v8/test/debugger/test-api.js
index d2cf8fe09a3..4917c0ba200 100644
--- a/deps/v8/test/debugger/test-api.js
+++ b/deps/v8/test/debugger/test-api.js
@@ -383,6 +383,8 @@ class DebugWrapper {
scopeIndex : () => scope_index,
frameIndex : () => frame.callFrameId,
scopeObject : () => this.execStateScopeObject(scope.object),
+ evaluate : (expr, throw_on_side_effect) =>
+ this.evaluateOnCallFrame(frame, expr, throw_on_side_effect, scope_index),
setVariableValue :
(name, value) => this.setVariableValue(frame, scope_index,
name, value),
@@ -562,13 +564,14 @@ class DebugWrapper {
};
}
- evaluateOnCallFrame(frame, expr, throw_on_side_effect = false) {
+ evaluateOnCallFrame(frame, expr, throw_on_side_effect = false, scope_number = undefined) {
const frameid = frame.callFrameId;
const {msgid, msg} = this.createMessage(
"Debugger.evaluateOnCallFrame",
{ callFrameId : frameid,
expression : expr,
throwOnSideEffect : throw_on_side_effect,
+ scopeNumber : scope_number,
});
this.sendMessage(msg);
const reply = this.takeReplyChecked(msgid);
diff --git a/deps/v8/test/filecheck/filecheck.status b/deps/v8/test/filecheck/filecheck.status
index d5a23da9920..84b6b07dffe 100644
--- a/deps/v8/test/filecheck/filecheck.status
+++ b/deps/v8/test/filecheck/filecheck.status
@@ -42,6 +42,7 @@
['official_build', {
'wasm/crash/failed-type-assertion': [SKIP],
+ 'wasm/crash/invalid-wasm-code-space-size': [SKIP],
'wasm/crash/regress-481074858': [SKIP],
'wasm/regress-509312806': [SKIP],
}], # official_build
diff --git a/deps/v8/test/filecheck/wasm/crash/invalid-wasm-code-space-size.js b/deps/v8/test/filecheck/wasm/crash/invalid-wasm-code-space-size.js
new file mode 100644
index 00000000000..69af1bf9b60
--- /dev/null
+++ b/deps/v8/test/filecheck/wasm/crash/invalid-wasm-code-space-size.js
@@ -0,0 +1,6 @@
+// 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-max-code-space-size-mb=2000
+// CHECK: Fatal error with no security impact
diff --git a/deps/v8/test/filecheck/wasm/invalid-wasm-code-space-size-fuzzing.js b/deps/v8/test/filecheck/wasm/invalid-wasm-code-space-size-fuzzing.js
new file mode 100644
index 00000000000..ed843402ed2
--- /dev/null
+++ b/deps/v8/test/filecheck/wasm/invalid-wasm-code-space-size-fuzzing.js
@@ -0,0 +1,6 @@
+// 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-max-code-space-size-mb=2000 --fuzzing
+// CHECK: Warning: lowering flag --wasm-max-code-space-size-mb=2000 to --wasm-max-code-space-size-mb={{.*}}, larger values are unsupported
diff --git a/deps/v8/test/fuzzer/wasm/deopt.cc b/deps/v8/test/fuzzer/wasm/deopt.cc
index 50a028c20c6..962cabd4895 100644
--- a/deps/v8/test/fuzzer/wasm/deopt.cc
+++ b/deps/v8/test/fuzzer/wasm/deopt.cc
@@ -13,7 +13,6 @@
#include "src/wasm/fuzzing/random-module-generation.h"
#include "src/wasm/module-compiler.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-subtyping.h"
diff --git a/deps/v8/test/fuzzer/wasm/init-expr.cc b/deps/v8/test/fuzzer/wasm/init-expr.cc
index a32de30c620..cbeeb62c105 100644
--- a/deps/v8/test/fuzzer/wasm/init-expr.cc
+++ b/deps/v8/test/fuzzer/wasm/init-expr.cc
@@ -12,7 +12,6 @@
#include "src/wasm/compilation-environment-inl.h"
#include "src/wasm/fuzzing/random-module-generation.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-subtyping.h"
@@ -120,7 +119,7 @@ void FuzzIt(base::Vector<const uint8_t> data) {
DirectHandle<WasmModuleObject> module_object =
compiled_module.ToHandleChecked();
- Managed<wasm::NativeModule>::Ptr native_module =
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
module_object->native_module();
const WasmModule* module = native_module->module();
DirectHandle<WasmInstanceObject> instance =
diff --git a/deps/v8/test/fuzzer/wasm/interpreter/interpreter-diff.cc b/deps/v8/test/fuzzer/wasm/interpreter/interpreter-diff.cc
index 58ac99beeaa..da4d43aee65 100644
--- a/deps/v8/test/fuzzer/wasm/interpreter/interpreter-diff.cc
+++ b/deps/v8/test/fuzzer/wasm/interpreter/interpreter-diff.cc
@@ -13,7 +13,6 @@
#include "include/v8-local-handle.h"
#include "src/execution/isolate-inl.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
#include "src/wasm/wasm-module.h"
#include "test/common/wasm/fuzzer-common.h"
#include "test/common/wasm/wasm-module-runner.h"
diff --git a/deps/v8/test/fuzzer/wasm/interpreter/interpreter-fuzzer-common.cc b/deps/v8/test/fuzzer/wasm/interpreter/interpreter-fuzzer-common.cc
index 224c6661a1c..5a02b24f6d0 100644
--- a/deps/v8/test/fuzzer/wasm/interpreter/interpreter-fuzzer-common.cc
+++ b/deps/v8/test/fuzzer/wasm/interpreter/interpreter-fuzzer-common.cc
@@ -24,7 +24,6 @@
#include "src/wasm/interpreter/wasm-interpreter.h"
#include "src/wasm/module-instantiate.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
#include "src/wasm/wasm-module-builder.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
@@ -110,13 +109,18 @@ WasmInterpretationResult FastInterpretWasmModule(
wasm::WasmInterpreterThread* thread =
wasm::WasmInterpreterThread::GetCurrentInterpreterThread(isolate);
- DirectHandle<Tuple2> interpreter_object =
- v8::internal::WasmTrustedInstanceData::GetOrCreateInterpreterObject(
- instance);
+ DirectHandle<WasmTrustedInstanceData> trusted_data =
+ direct_handle(instance->trusted_data(isolate), isolate);
+ // SANDBOX SAFETY: the in-cage instance->trusted_data() handle is
+ // attacker-swappable, so re-validate that it still belongs to {instance}
+ // before using its interpreter handle. This preserves the check that the
+ // removed WasmTrustedInstanceData::GetOrCreateInterpreterObject performed.
+ SBXCHECK(trusted_data->has_instance_object() &&
+ trusted_data->instance_object() == *instance);
// Assume an instance can run in only one thread.
- DirectHandle<Managed<wasm::InterpreterHandle>> handle =
- wasm::GetOrCreateInterpreterHandle(isolate, interpreter_object);
+ DirectHandle<TrustedManaged<wasm::InterpreterHandle>> handle =
+ wasm::GetOrCreateInterpreterHandle(isolate, trusted_data);
for (const WasmValue& arg : args) {
if (arg.type().is_ref()) {
@@ -124,7 +128,7 @@ WasmInterpretationResult FastInterpretWasmModule(
CHECK(!IsNull(*arg.to_ref()));
}
}
- bool success = handle->ptr()->Execute(
+ bool success = handle->raw()->Execute(
thread, 0, static_cast<uint32_t>(function_index), args, rets);
// Returned values should not be the hole value.
@@ -174,7 +178,8 @@ Handle<JSFunction> GenerateJSFunction(Isolate* isolate) {
MaybeDirectHandle<WasmTableObject> GenerateWasmTable(
Isolate* isolate, DirectHandle<WasmModuleObject> module_object,
uint32_t table_index) {
- Managed<NativeModule>::Ptr native_module = module_object->native_module();
+ CppGCManaged<NativeModule>::Ptr native_module =
+ module_object->native_module();
const WasmTable& table = native_module->module()->tables[table_index];
uint32_t table_initial = 10;
@@ -221,7 +226,8 @@ Handle<JSObject> CreateImportObjectInternal(
for (size_t index = 0;
index < module_object->native_module()->module()->import_table.size();
++index) {
- Managed<NativeModule>::Ptr native_module = module_object->native_module();
+ CppGCManaged<NativeModule>::Ptr native_module =
+ module_object->native_module();
const WasmImport& import = native_module->module()->import_table[index];
Handle<String> module_name = ExtractUtf8StringFromModuleBytes(
@@ -278,9 +284,8 @@ Handle<JSObject> CreateImportObjectInternal(
const WasmGlobal& global =
native_module->module()->globals[import.index];
DirectHandle<WasmTrustedInstanceData> trusted_data =
- WasmTrustedInstanceData::New(
- isolate, module_object,
- module_object->native_module().as_shared_ptr());
+ WasmTrustedInstanceData::New(isolate, module_object,
+ native_module.as_shared_ptr());
MaybeDirectHandle<WasmGlobalObject> maybe_global_obj =
WasmGlobalObject::New(isolate, trusted_data,
MaybeHandle<WasmGlobalObject::BufferType>(),
@@ -372,9 +377,8 @@ std::vector<WasmValue> FastMakeDefaultInterpreterArguments(
}
case kS128: {
int64_t rand_num2 = mt_generator_64();
- const int64_t simd_value[2] = {rand_num, rand_num2};
- arguments[i] = WasmValue(reinterpret_cast<const uint8_t*>(simd_value),
- (CanonicalValueType)sig->GetParam(i));
+ Simd128 simd_value(Simd128::int64x2{rand_num, rand_num2});
+ arguments[i] = WasmValue(simd_value);
break;
}
case kRef:
@@ -473,10 +477,13 @@ int FastInterpretAndExecuteModules(
i::Isolate* isolate, DirectHandle<WasmModuleObject> module_object,
DirectHandle<WasmModuleObject> other_module_object,
std::mt19937_64 rand_generator) {
- if (module_object->native_module()->module()->start_function_index >= 0)
- return -1;
- if (other_module_object->native_module()->module()->start_function_index >= 0)
- return -1;
+ CppGCManaged<wasm::NativeModule>::Ptr native_module =
+ module_object->native_module();
+ CppGCManaged<wasm::NativeModule>::Ptr other_native_module =
+ other_module_object->native_module();
+ if (native_module->module()->start_function_index >= 0) return -1;
+ const WasmModule* other_module = other_native_module->module();
+ if (other_module->start_function_index >= 0) return -1;
HandleScope handle_scope(isolate); // Avoid leaking handles.
@@ -492,11 +499,8 @@ int FastInterpretAndExecuteModules(
Handle<JSObject> imports_obj =
CreateImportObjectInternal(isolate, module_object);
- for (size_t i = 0;
- i < other_module_object->native_module()->module()->export_table.size();
- ++i) {
- WasmExport exp =
- other_module_object->native_module()->module()->export_table[i];
+ for (size_t i = 0; i < other_module->export_table.size(); ++i) {
+ WasmExport exp = other_module->export_table[i];
if (exp.kind != kExternalFunction) continue;
diff --git a/deps/v8/test/fuzzer/wasm/interpreter/interpreter-init-expr.cc b/deps/v8/test/fuzzer/wasm/interpreter/interpreter-init-expr.cc
index b02266c0aaf..126180d57fa 100644
--- a/deps/v8/test/fuzzer/wasm/interpreter/interpreter-init-expr.cc
+++ b/deps/v8/test/fuzzer/wasm/interpreter/interpreter-init-expr.cc
@@ -12,7 +12,6 @@
#include "src/wasm/compilation-environment-inl.h"
#include "src/wasm/fuzzing/random-module-generation.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
#include "src/wasm/wasm-module.h"
#include "src/wasm/wasm-objects-inl.h"
#include "src/wasm/wasm-subtyping.h"
diff --git a/deps/v8/test/fuzzer/wasm/module.cc b/deps/v8/test/fuzzer/wasm/module.cc
index 35edfcd1f4c..01306b7f9e4 100644
--- a/deps/v8/test/fuzzer/wasm/module.cc
+++ b/deps/v8/test/fuzzer/wasm/module.cc
@@ -13,7 +13,6 @@
#include "include/v8-local-handle.h"
#include "src/execution/isolate-inl.h"
#include "src/wasm/wasm-engine.h"
-#include "src/wasm/wasm-feature-flags.h"
#include "src/wasm/wasm-module.h"
#include "test/common/wasm/fuzzer-common.h"
#include "test/common/wasm/wasm-module-runner.h"
diff --git a/deps/v8/test/fuzzer/wasm/streaming.cc b/deps/v8/test/fuzzer/wasm/streaming.cc
index 688817c2493..a5291afd28b 100644
--- a/deps/v8/test/fuzzer/wasm/streaming.cc
+++ b/deps/v8/test/fuzzer/wasm/streaming.cc
@@ -75,7 +75,7 @@ class TestResolver : public CompilationResultResolver {
bool done_ = false;
bool failed_ = false;
std::string error_message_;
- Managed<NativeModule>::Ptr native_module_;
+ CppGCManaged<NativeModule>::Ptr native_module_;
};
CompilationResult CompileStreaming(v8_fuzzer::FuzzerSupport* support,
diff --git a/deps/v8/test/inspector/cpu-profiler/untrusted-session-expected.txt b/deps/v8/test/inspector/cpu-profiler/untrusted-session-expected.txt
new file mode 100644
index 00000000000..eb29fc07d37
--- /dev/null
+++ b/deps/v8/test/inspector/cpu-profiler/untrusted-session-expected.txt
@@ -0,0 +1,3 @@
+Tests that Profiler domain is not available in untrusted session.
+console.profile in untrusted session did not crash.
+Error: Called non-existent method. 'Profiler.enable' wasn't found code: -32601
diff --git a/deps/v8/test/inspector/cpu-profiler/untrusted-session.js b/deps/v8/test/inspector/cpu-profiler/untrusted-session.js
new file mode 100644
index 00000000000..47c1b2c8d9d
--- /dev/null
+++ b/deps/v8/test/inspector/cpu-profiler/untrusted-session.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.
+
+InspectorTest.start(
+ 'Tests that Profiler domain is not available in untrusted session.');
+
+(async () => {
+ const contextGroup = new InspectorTest.ContextGroup();
+ const session = contextGroup.connect(/* isFullyTrusted */ false);
+ const {Protocol} = session;
+
+ await Protocol.Runtime.evaluate({
+ expression: 'console.profile("test"); console.profileEnd("test");'
+ });
+ InspectorTest.log('console.profile in untrusted session did not crash.');
+ await Protocol.Profiler.enable();
+
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/debugger/es6-module-liveedit-expected.txt b/deps/v8/test/inspector/debugger/es6-module-liveedit-expected.txt
deleted file mode 100644
index c02087d1cf6..00000000000
--- a/deps/v8/test/inspector/debugger/es6-module-liveedit-expected.txt
+++ /dev/null
@@ -1,15 +0,0 @@
-Checks liveedit with ES6 modules.
-console.log message from function before patching:
-{
- type : string
- value : module1
-}
-Debugger.setScriptSource result:
-{
- status : Ok
-}
-console.log message from function after patching:
-{
- type : string
- value : patched module1
-}
diff --git a/deps/v8/test/inspector/debugger/es6-module-liveedit.js b/deps/v8/test/inspector/debugger/es6-module-liveedit.js
deleted file mode 100644
index 97165098b3f..00000000000
--- a/deps/v8/test/inspector/debugger/es6-module-liveedit.js
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2017 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --inspector-live-edit
-
-const {session, contextGroup, Protocol} =
- InspectorTest.start('Checks liveedit with ES6 modules.');
-
-const moduleSource = `
-export function foo() {
- console.log('module1');
- return 42;
-}
-foo()`;
-
-const newModuleSource = `
-export function foo() {
- console.log('patched module1');
- return 42;
-}
-foo()`;
-
-const callFooSource = `
-import { foo } from 'module';
-foo();`;
-
-(async function test() {
- await Protocol.Runtime.enable();
- await Protocol.Debugger.enable();
- contextGroup.addModule(moduleSource, 'module');
- const [{ params: { scriptId } }, { params: { args }}] = [
- await Protocol.Debugger.onceScriptParsed(),
- await Protocol.Runtime.onceConsoleAPICalled()
- ];
- InspectorTest.log('console.log message from function before patching:')
- InspectorTest.logMessage(args[0]);
-
- const {result} = await Protocol.Debugger.setScriptSource({
- scriptId,
- scriptSource: newModuleSource
- });
- InspectorTest.log('Debugger.setScriptSource result:');
- InspectorTest.logMessage(result);
-
- contextGroup.addModule(callFooSource, 'callFoo');
- const { params: {args: patchedArgs } } =
- await Protocol.Runtime.onceConsoleAPICalled();
- InspectorTest.log('console.log message from function after patching:')
- InspectorTest.logMessage(patchedArgs[0]);
- InspectorTest.completeTest();
-})()
diff --git a/deps/v8/test/inspector/debugger/evaluate-on-call-frame-scopes-expected.txt b/deps/v8/test/inspector/debugger/evaluate-on-call-frame-scopes-expected.txt
new file mode 100644
index 00000000000..957e4a58c70
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/evaluate-on-call-frame-scopes-expected.txt
@@ -0,0 +1,34 @@
+Test for Debugger.evaluateOnCallFrame with scopeNumber
+
+Running test: testEvaluateOnScopes
+Paused with 4 scopes in scopeChain.
+Scope 0: local
+Scope 1: closure
+Scope 2: script
+Scope 3: global
+Eval "a" at scopeNumber=undefined:
+ Result: inner_stack
+Eval "a" at scopeNumber=0:
+ Result: inner_stack
+Eval "a" at scopeNumber=1:
+ Result: closure_outer
+Eval "closure_y" at scopeNumber=0:
+ Result: 20
+Eval "closure_y" at scopeNumber=1:
+ Result: 20
+Eval "x" at scopeNumber=0:
+ Result: 10
+Eval "x" at scopeNumber=1:
+ Exception: ReferenceError: x is not defined
+ at eval (eval at inner (test.js:10:11), <anonymous>:1:1)
+ at inner (test.js:22:11)
+ at outer (test.js:25:16)
+ at <anonymous>:1:1
+Eval "z" at scopeNumber=0:
+ Result: global_z
+Eval "z" at scopeNumber=1:
+ Result: global_z
+Eval "a" at scopeNumber=999:
+ Error: Could not find scope with given number
+Eval "a" at scopeNumber=-1:
+ Error: Could not find scope with given number
diff --git a/deps/v8/test/inspector/debugger/evaluate-on-call-frame-scopes.js b/deps/v8/test/inspector/debugger/evaluate-on-call-frame-scopes.js
new file mode 100644
index 00000000000..1994560d515
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/evaluate-on-call-frame-scopes.js
@@ -0,0 +1,65 @@
+// 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 {session, contextGroup, Protocol} =
+ InspectorTest.start(`Test for Debugger.evaluateOnCallFrame with scopeNumber`);
+
+Protocol.Debugger.enable();
+
+InspectorTest.runAsyncTestSuite([
+ async function testEvaluateOnScopes() {
+ contextGroup.addInlineScript(`
+ var z = 'global_z';
+ let script_a = 'script_outer';
+ function outer(y) {
+ let a = 'closure_outer';
+ let closure_y = y;
+ () => a;
+ function inner(x) {
+ let a = 'inner_stack';
+ debugger;
+ return x + closure_y + a;
+ }
+ return inner(10);
+ }
+ `, 'test.js');
+
+ Protocol.Runtime.evaluate({ expression: 'outer(20)' });
+ const { params: { callFrames: [ { callFrameId, scopeChain } ] } } =
+ await Protocol.Debugger.oncePaused();
+
+ InspectorTest.log(`Paused with ${scopeChain.length} scopes in scopeChain.`);
+ for (let i = 0; i < scopeChain.length; i++) {
+ InspectorTest.log(`Scope ${i}: ${scopeChain[i].type}`);
+ }
+
+ async function evaluateAndLog(expression, scopeNumber) {
+ const params = { callFrameId, expression };
+ if (scopeNumber !== undefined) params.scopeNumber = scopeNumber;
+ const response = await Protocol.Debugger.evaluateOnCallFrame(params);
+ InspectorTest.log(`Eval "${expression}" at scopeNumber=${scopeNumber}:`);
+ if (response.error) {
+ InspectorTest.log(` Error: ${response.error.message}`);
+ } else if (response.result.exceptionDetails) {
+ InspectorTest.log(` Exception: ${response.result.exceptionDetails.exception.description.split('\\n')[0]}`);
+ } else {
+ InspectorTest.log(` Result: ${response.result.result.value}`);
+ }
+ }
+
+ await evaluateAndLog('a', undefined); // Default scope 0
+ await evaluateAndLog('a', 0); // Scope 0 ('inner_stack')
+ await evaluateAndLog('a', 1); // Scope 1 ('closure_outer')
+ await evaluateAndLog('closure_y', 0); // Scope 0 (can see outer closure_y)
+ await evaluateAndLog('closure_y', 1); // Scope 1 (can see closure_y)
+ await evaluateAndLog('x', 0); // Scope 0 (10)
+ await evaluateAndLog('x', 1); // Scope 1 (should throw ReferenceError)
+ await evaluateAndLog('z', 0); // Scope 0 ('global_z')
+ await evaluateAndLog('z', 1); // Scope 1 ('global_z')
+ await evaluateAndLog('a', 999); // Invalid scopeNumber
+ await evaluateAndLog('a', -1); // Invalid scopeNumber
+
+ await Protocol.Debugger.resume();
+ }
+]);
diff --git a/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-async-expected.txt b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-async-expected.txt
new file mode 100644
index 00000000000..3850214edcd
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-async-expected.txt
@@ -0,0 +1,7 @@
+Tests for break on caught exception in async modules.
+paused on exception:
+{
+ type : string
+ uncaught : false
+ value : hello
+}
diff --git a/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-async.js b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-async.js
new file mode 100644
index 00000000000..2e7a4ae996f
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-async.js
@@ -0,0 +1,18 @@
+// 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 for break on caught exception in async modules.');
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setPauseOnExceptions({state: 'caught'});
+Protocol.Debugger.onPaused(({params: {data}}) => {
+ InspectorTest.log('paused on exception:');
+ InspectorTest.logMessage(data);
+ Protocol.Debugger.resume();
+});
+
+contextGroup.addModule('await 1; try { throw "hello"; } catch (e) {}', 'module.js');
+
+InspectorTest.waitForPendingTasks().then(() => InspectorTest.completeTest());
diff --git a/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-expected.txt b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-expected.txt
new file mode 100644
index 00000000000..4a89dc947d7
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module-expected.txt
@@ -0,0 +1,7 @@
+Tests for break on caught exception in modules.
+paused on exception:
+{
+ type : string
+ uncaught : false
+ value : hello
+}
diff --git a/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module.js b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module.js
new file mode 100644
index 00000000000..9f98f3a7e18
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-caught-exception-in-module.js
@@ -0,0 +1,18 @@
+// 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 for break on caught exception in modules.');
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setPauseOnExceptions({state: 'caught'});
+Protocol.Debugger.onPaused(({params: {data}}) => {
+ InspectorTest.log('paused on exception:');
+ InspectorTest.logMessage(data);
+ Protocol.Debugger.resume();
+});
+
+contextGroup.addModule('try { throw "hello"; } catch (e) {}', 'module.js');
+
+InspectorTest.waitForPendingTasks().then(() => InspectorTest.completeTest());
diff --git a/deps/v8/test/inspector/debugger/pause-on-exception-in-module-async-expected.txt b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-async-expected.txt
new file mode 100644
index 00000000000..7f953f02cf0
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-async-expected.txt
@@ -0,0 +1,7 @@
+Tests for break on uncaught exception in async modules.
+paused on exception:
+{
+ type : string
+ uncaught : true
+ value : hello
+}
diff --git a/deps/v8/test/inspector/debugger/pause-on-exception-in-module-async.js b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-async.js
new file mode 100644
index 00000000000..09c6ba2399e
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-async.js
@@ -0,0 +1,18 @@
+// 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 for break on uncaught exception in async modules.');
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
+Protocol.Debugger.onPaused(({params: {data}}) => {
+ InspectorTest.log('paused on exception:');
+ InspectorTest.logMessage(data);
+ Protocol.Debugger.resume();
+});
+
+contextGroup.addModule('await 1; throw "hello";', 'module.js');
+
+InspectorTest.waitForPendingTasks().then(() => InspectorTest.completeTest());
diff --git a/deps/v8/test/inspector/debugger/pause-on-exception-in-module-expected.txt b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-expected.txt
new file mode 100644
index 00000000000..4201c0ac37f
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-expected.txt
@@ -0,0 +1,7 @@
+Tests for break on exception in modules.
+paused on exception:
+{
+ type : string
+ uncaught : true
+ value : hello
+}
diff --git a/deps/v8/test/inspector/debugger/pause-on-exception-in-module-imported-expected.txt b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-imported-expected.txt
new file mode 100644
index 00000000000..99a50ffc5fe
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-imported-expected.txt
@@ -0,0 +1,7 @@
+Tests for break on uncaught exception in imported modules.
+paused on exception:
+{
+ type : string
+ uncaught : true
+ value : hello
+}
diff --git a/deps/v8/test/inspector/debugger/pause-on-exception-in-module-imported.js b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-imported.js
new file mode 100644
index 00000000000..3c4145aa4e7
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-exception-in-module-imported.js
@@ -0,0 +1,19 @@
+// 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 for break on uncaught exception in imported modules.');
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
+Protocol.Debugger.onPaused(({params: {data}}) => {
+ InspectorTest.log('paused on exception:');
+ InspectorTest.logMessage(data);
+ Protocol.Debugger.resume();
+});
+
+contextGroup.addModule('throw "hello";', 'module.js');
+contextGroup.addModule('import "./module.js";', 'importer.js');
+
+InspectorTest.waitForPendingTasks().then(() => InspectorTest.completeTest());
diff --git a/deps/v8/test/inspector/debugger/pause-on-exception-in-module.js b/deps/v8/test/inspector/debugger/pause-on-exception-in-module.js
new file mode 100644
index 00000000000..03feabb692f
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-exception-in-module.js
@@ -0,0 +1,18 @@
+// 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 for break on exception in modules.');
+
+Protocol.Debugger.enable();
+Protocol.Debugger.setPauseOnExceptions({state: 'uncaught'});
+Protocol.Debugger.onPaused(({params: {data}}) => {
+ InspectorTest.log('paused on exception:');
+ InspectorTest.logMessage(data);
+ Protocol.Debugger.resume();
+});
+
+contextGroup.addModule('throw "hello";', 'module.js');
+
+InspectorTest.waitForPendingTasks().then(() => InspectorTest.completeTest());
diff --git a/deps/v8/test/inspector/debugger/pause-on-oom-in-eval-expected.txt b/deps/v8/test/inspector/debugger/pause-on-oom-in-eval-expected.txt
new file mode 100644
index 00000000000..cddc096dbbf
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-oom-in-eval-expected.txt
@@ -0,0 +1,2 @@
+Tests that an OOM break triggered at the entry of a top-level strict eval pauses inside the eval
+reason: OOM
diff --git a/deps/v8/test/inspector/debugger/pause-on-oom-in-eval.js b/deps/v8/test/inspector/debugger/pause-on-oom-in-eval.js
new file mode 100644
index 00000000000..dbbfb202dde
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/pause-on-oom-in-eval.js
@@ -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.
+
+// Flags: --max-old-space-size=16
+
+const {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Tests that an OOM break triggered at the entry of a top-level strict ' +
+ 'eval pauses inside the eval');
+
+Protocol.Debugger.onPaused(async message => {
+ InspectorTest.log(`reason: ${message.params.reason}`);
+ await Protocol.Debugger.evaluateOnCallFrame({
+ callFrameId: message.params.callFrames[0].callFrameId,
+ expression: 'arr = []; stop = true;'
+ });
+ Protocol.Debugger.resume();
+});
+
+(async function test() {
+ await Protocol.Debugger.enable();
+ // The loop body only allocates before entering the eval, so the OOM
+ // interrupt requested by the near-heap-limit callback fires at the
+ // function-entry stack check of the eval, i.e. before the eval context is
+ // pushed. The eval is called from the top level of the script so that the
+ // current context is the script context, whose ScopeInfo shares its unique
+ // ID with the eval scope.
+ await Protocol.Runtime.evaluate({
+ expression: `
+ 'use strict';
+ let arr = [];
+ let stop = false;
+ while (!stop) {
+ arr.push(new Array(10000).fill(0));
+ eval('let x = 1; function inner() { return x; }');
+ }
+ //# sourceURL=test.js`
+ });
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/debugger/restart-frame/restart-osr-frame-expected.txt b/deps/v8/test/inspector/debugger/restart-frame/restart-osr-frame-expected.txt
new file mode 100644
index 00000000000..f36a1385cf7
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/restart-frame/restart-osr-frame-expected.txt
@@ -0,0 +1,18 @@
+Checks that restarting an OSR-optimized frame works.
+Paused at (after evaluation):
+function foo() {
+ #debugger;
+}
+
+Pause stack:
+ foo:2 (canBeRestarted = true)
+ osr_caller:9 (canBeRestarted = true)
+
+Restarting osr_caller frame...
+Restarting function "osr_caller" ...
+Paused at (after restart):
+function osr_caller() {
+ for (let i = #0; i < 1000; i++) {
+ if (i == 10) %OptimizeOsr();
+
+Resuming...
diff --git a/deps/v8/test/inspector/debugger/restart-frame/restart-osr-frame.js b/deps/v8/test/inspector/debugger/restart-frame/restart-osr-frame.js
new file mode 100644
index 00000000000..591d7fcb44c
--- /dev/null
+++ b/deps/v8/test/inspector/debugger/restart-frame/restart-osr-frame.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 --turbofan --no-maglev
+
+const {session, contextGroup, Protocol} =
+ InspectorTest.start('Checks that restarting an OSR-optimized frame works.');
+
+session.setupScriptMap();
+
+contextGroup.addScript(`
+function foo() {
+ debugger;
+}
+
+function osr_caller() {
+ for (let i = 0; i < 1000; i++) {
+ if (i == 10) %OptimizeOsr();
+ }
+ foo();
+}
+`, 0, 0, 'test.js');
+
+(async () => {
+ await Protocol.Debugger.enable();
+ await Protocol.Runtime.enable();
+
+ const { callFrames } = await InspectorTest.evaluateAndWaitForPause(
+ '%PrepareFunctionForOptimization(osr_caller); osr_caller();');
+
+ InspectorTest.log('Restarting osr_caller frame...');
+ await InspectorTest.restartFrameAndWaitForPause(callFrames, 1);
+
+ InspectorTest.log('Resuming...');
+ Protocol.Debugger.resume();
+ await Protocol.Debugger.oncePaused();
+ await Protocol.Debugger.resume();
+
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/debugger/set-breakpoint-after-liveedit-expected.txt b/deps/v8/test/inspector/debugger/set-breakpoint-after-liveedit-expected.txt
deleted file mode 100644
index 864e4bd5bf4..00000000000
--- a/deps/v8/test/inspector/debugger/set-breakpoint-after-liveedit-expected.txt
+++ /dev/null
@@ -1,17 +0,0 @@
-Breakpoint in liveedited script
-Update script source
-{
- status : Ok
-}
-Set breakpoint
-{
- actualLocation : {
- columnNumber : 0
- lineNumber : 3
- scriptId : <scriptId>
- }
- breakpointId : <breakpointId>
-}
-Call function foo and dump stack
-foo (:3:0)
-(anonymous) (:0:0)
diff --git a/deps/v8/test/inspector/debugger/set-breakpoint-after-liveedit.js b/deps/v8/test/inspector/debugger/set-breakpoint-after-liveedit.js
deleted file mode 100644
index 580527a26ba..00000000000
--- a/deps/v8/test/inspector/debugger/set-breakpoint-after-liveedit.js
+++ /dev/null
@@ -1,41 +0,0 @@
-// Copyright 2018 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --inspector-live-edit
-
-let {session, contextGroup, Protocol} =
- InspectorTest.start('Breakpoint in liveedited script');
-
-contextGroup.addScript(
-`function foo() {
-}
-var f = foo;`);
-
-const newSource = `function boo() {
-}
-function foo() {
-}
-f = foo;`;
-
-(async function test() {
- session.setupScriptMap();
- Protocol.Debugger.enable();
- const {params: {scriptId}} = await Protocol.Debugger.onceScriptParsed();
- InspectorTest.log('Update script source');
- let {result} = await Protocol.Debugger.setScriptSource(
- {scriptId, scriptSource: newSource})
- InspectorTest.logMessage(result);
- InspectorTest.log('Set breakpoint');
- ({result} = await Protocol.Debugger.setBreakpoint({location:{
- scriptId,
- lineNumber: 3,
- columnNumber: 0
- }}));
- InspectorTest.logMessage(result);
- InspectorTest.log('Call function foo and dump stack');
- Protocol.Runtime.evaluate({expression: 'foo()'});
- const {params:{callFrames}} = await Protocol.Debugger.oncePaused();
- session.logCallFrames(callFrames);
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-active-function-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-active-function-expected.txt
deleted file mode 100644
index bb5d1b621c1..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-active-function-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Checks that setScriptSource fails for editing functions that are below the top-most frame on the stack
-Paused at (before live edit):
-function foo(b) {
- #debugger;
- return b + 25;
-
-Debugger.setScriptSource result:
-{
- status : BlockedByActiveFunction
-}
-Evaluation result:
-{
- description : 33
- type : number
- value : 33
-}
diff --git a/deps/v8/test/inspector/debugger/set-script-source-active-function.js b/deps/v8/test/inspector/debugger/set-script-source-active-function.js
deleted file mode 100644
index 4636a08f72a..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-active-function.js
+++ /dev/null
@@ -1,45 +0,0 @@
-// Copyright 2022 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: --inspector-live-edit
-
-const {session, contextGroup, Protocol} = InspectorTest.start(
- 'Checks that setScriptSource fails for editing functions that are below the top-most frame on the stack');
-
-const originalScript = `
-function foo(b) {
- debugger;
- return b + 25;
-}
-function testExpression(a, b) {
- return a + foo(b);
-}`;
-
-contextGroup.addScript(originalScript);
-
-const replacementScript = originalScript.replace('a + foo(b)', 'a * foo(b)');
-
-session.setupScriptMap();
-
-(async () => {
- Protocol.Debugger.enable();
- const { params: { scriptId } } = await Protocol.Debugger.onceScriptParsed();
-
- const evaluatePromise = Protocol.Runtime.evaluate({ expression: 'testExpression(3, 5)' });
- let { params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused();
- InspectorTest.log('Paused at (before live edit):');
- await session.logSourceLocation(pausedCallFrames[0].location);
-
- const response = await Protocol.Debugger.setScriptSource({ scriptId, scriptSource: replacementScript, allowTopFrameEditing: true })
- InspectorTest.log('Debugger.setScriptSource result:');
- InspectorTest.logMessage(response.result);
-
- Protocol.Debugger.resume();
-
- const { result: { result } } = await evaluatePromise;
- InspectorTest.log('Evaluation result:');
- InspectorTest.logMessage(result);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-debug-evaluate-closure-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-debug-evaluate-closure-expected.txt
deleted file mode 100644
index c230516c662..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-debug-evaluate-closure-expected.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-Check that setScriptSource doesn't affect debug-evaluate block listing
-{
- className : ReferenceError
- description : ReferenceError: a is not defined at globalThis.foo (eval at i (:1:1), <anonymous>:1:27) at <anonymous>:1:12
- objectId : <objectId>
- subtype : error
- type : object
-}
-Debugger.setScriptSource: Ok
-{
- className : ReferenceError
- description : ReferenceError: a is not defined at globalThis.foo (eval at i (:1:1), <anonymous>:1:27) at <anonymous>:1:12
- objectId : <objectId>
- subtype : error
- type : object
-}
diff --git a/deps/v8/test/inspector/debugger/set-script-source-debug-evaluate-closure.js b/deps/v8/test/inspector/debugger/set-script-source-debug-evaluate-closure.js
deleted file mode 100644
index 3d631751356..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-debug-evaluate-closure.js
+++ /dev/null
@@ -1,66 +0,0 @@
-// Copyright 2020 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --inspector-live-edit
-
-const {session, contextGroup, Protocol} =
- InspectorTest.start('Check that setScriptSource doesn\'t affect debug-evaluate block listing');
-
-const script = `
-// INSERT NEWLINES HERE
-function f() {
- let a = 3; () => a; // context allocated.
- return function g() {
- let a = 42; // stack-allocated. Shadowing context-allocated from f.
- return function h() {
- // Give h a context.
- let x = 5; () => x;
- return function i() {
- debugger;
- };
- };
- };
-}
-(((f())())())();
-`;
-
-const updatedScript = script.replace('// INSERT NEWLINES HERE', '\n\n\n');
-
-(async function test() {
- await Protocol.Debugger.enable();
- await Protocol.Runtime.enable();
- const promise = Protocol.Debugger.oncePaused();
-
- contextGroup.addScript(script);
-
- const { params: { callFrames: [{ callFrameId, functionLocation: { scriptId } }] } } = await promise;
-
- // Create a closure that returns `a` and stash it on the global.
- await Protocol.Debugger.evaluateOnCallFrame({
- callFrameId,
- expression: `globalThis['foo'] = () => a;`
- });
- await Protocol.Debugger.resume();
-
- // Expect a ReferenceError.
- const { result: { result: result1 } } = await Protocol.Runtime.evaluate({
- expression: 'globalThis.foo();'
- });
- InspectorTest.logMessage(result1);
-
- // Move function 'h' but don't change it.
- const { result: { status } } = await Protocol.Debugger.setScriptSource({
- scriptId,
- scriptSource: updatedScript,
- });
- InspectorTest.log(`Debugger.setScriptSource: ${status}`);
-
- // Still expect a ReferenceError.
- const { result: { result: result2 } } = await Protocol.Runtime.evaluate({
- expression: 'globalThis.foo();'
- });
- InspectorTest.logMessage(result2);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-es-module-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-es-module-expected.txt
deleted file mode 100644
index 152643a9c59..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-es-module-expected.txt
+++ /dev/null
@@ -1,9 +0,0 @@
-Test that live editing the top-level function of an ES module does not work [crbug.com/1413447]
-Uncommenting the import line should fail:
-{
- status : BlockedByTopLevelEsModuleChange
-}
-Uncommenting the console.log line should work:
-{
- status : Ok
-}
diff --git a/deps/v8/test/inspector/debugger/set-script-source-es-module.js b/deps/v8/test/inspector/debugger/set-script-source-es-module.js
deleted file mode 100644
index b2a97c91ccb..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-es-module.js
+++ /dev/null
@@ -1,39 +0,0 @@
-// Copyright 2023 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: --inspector-live-edit
-
-const {session, contextGroup, Protocol} = InspectorTest.start(
- 'Test that live editing the top-level function of an ES module does not work [crbug.com/1413447]');
-
-const inputSnippet = `
-//$1 import {b} from "./b.js";
-
-export function foo() {
- console.log('foo');
-}
-
-export function bar() {
- //$2 console.log('bar');
-}
-`;
-
-(async () => {
- await Protocol.Debugger.enable();
-
- contextGroup.addModule(inputSnippet, 'a.js', 3, 8);
- const { params: { scriptId } } = await Protocol.Debugger.onceScriptParsed();
-
- InspectorTest.log('Uncommenting the import line should fail:');
- const changedTopLevelModule = inputSnippet.replace('//$1 ', '');
- const response1 = await Protocol.Debugger.setScriptSource({ scriptId, scriptSource: changedTopLevelModule });
- InspectorTest.logMessage(response1.result);
-
- InspectorTest.log('Uncommenting the console.log line should work:');
- const changedFunction = inputSnippet.replace('//$2 ', '');
- const response2 = await Protocol.Debugger.setScriptSource({ scriptId, scriptSource: changedFunction });
- InspectorTest.logMessage(response2.result);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-exception-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-exception-expected.txt
deleted file mode 100644
index 36dc66adfce..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-exception-expected.txt
+++ /dev/null
@@ -1,24 +0,0 @@
-Check that setScriptSource completes correctly when an exception is thrown.
-
-Running test: testIncorrectScriptId
-{
- error : {
- code : -32000
- message : No script with given id found
- }
- id : <messageId>
-}
-
-Running test: testSourceWithSyntaxError
-{
- id : <messageId>
- result : {
- exceptionDetails : {
- columnNumber : 11
- exceptionId : <exceptionId>
- lineNumber : 1
- text : Uncaught SyntaxError: Invalid or unexpected token
- }
- status : CompileError
- }
-}
diff --git a/deps/v8/test/inspector/debugger/set-script-source-exception.js b/deps/v8/test/inspector/debugger/set-script-source-exception.js
deleted file mode 100644
index 13a6391fa3e..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-exception.js
+++ /dev/null
@@ -1,28 +0,0 @@
-// Copyright 2017 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --inspector-live-edit
-
-let {session, contextGroup, Protocol} = InspectorTest.start(
- 'Check that setScriptSource completes correctly when an exception is' +
- ' thrown.');
-
-Protocol.Debugger.enable();
-
-InspectorTest.runAsyncTestSuite([
- async function testIncorrectScriptId() {
- InspectorTest.logMessage(await Protocol.Debugger.setScriptSource(
- {scriptId: '-1', scriptSource: '0'}));
- },
-
- async function testSourceWithSyntaxError() {
- contextGroup.addScript('function foo() {}');
- const {params} = await Protocol.Debugger.onceScriptParsed();
- const msg = await Protocol.Debugger.setScriptSource({
- scriptId: params.scriptId,
- scriptSource: 'function foo() {\n return a # b;\n}'
- });
- InspectorTest.logMessage(msg);
- }
-]);
diff --git a/deps/v8/test/inspector/debugger/set-script-source-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-expected.txt
index d52fc4ee98a..4dd4142ddd2 100644
--- a/deps/v8/test/inspector/debugger/set-script-source-expected.txt
+++ b/deps/v8/test/inspector/debugger/set-script-source-expected.txt
@@ -1,18 +1,5 @@
Tests Debugger.setScriptSource
-TestExpression(2,4) === 6
-Update current script source 'a + b' -> 'a * b'..
{
- status : Ok
+ code : -32000
+ message : setScriptSource functionality no longer available
}
-TestExpression(2,4) === 8
-Update current script source 'a * b' -> 'a # b'..
-{
- exceptionDetails : {
- columnNumber : 13
- exceptionId : <exceptionId>
- lineNumber : 1
- text : Uncaught SyntaxError: Invalid or unexpected token
- }
- status : CompileError
-}
-TestExpression(2,4) === 8
diff --git a/deps/v8/test/inspector/debugger/set-script-source-repl-mode-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-repl-mode-expected.txt
deleted file mode 100644
index ae06efb450e..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-repl-mode-expected.txt
+++ /dev/null
@@ -1,2 +0,0 @@
-Check that setScriptSource works with REPL mode
-Debugger.setScriptSource: Ok
diff --git a/deps/v8/test/inspector/debugger/set-script-source-repl-mode.js b/deps/v8/test/inspector/debugger/set-script-source-repl-mode.js
deleted file mode 100644
index 702d532a2ae..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-repl-mode.js
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2022 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: --inspector-live-edit --no-stress-incremental-marking
-
-const {session, contextGroup, Protocol} =
- InspectorTest.start('Check that setScriptSource works with REPL mode');
-
-const script = `
- function foo() { return 42; }
- const bar = foo();
-`;
-const changedScript = script.replace('const', 'let');
-
-(async function test() {
- await Protocol.Debugger.enable();
-
- Protocol.Runtime.evaluate({
- expression: script,
- replMode: true,
- });
- const { params: { scriptId } } = await Protocol.Debugger.onceScriptParsed();
-
- // Run the GC to make sure the script's generator (for the top-level async
- // function, which is async since this is repl mode) is able to die.
- await Protocol.HeapProfiler.collectGarbage();
-
- const { result: { status } } = await Protocol.Debugger.setScriptSource({
- scriptId,
- scriptSource: changedScript,
- });
- InspectorTest.log(`Debugger.setScriptSource: ${status}`);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-top-frame-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-top-frame-expected.txt
deleted file mode 100644
index 7a947593a10..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-top-frame-expected.txt
+++ /dev/null
@@ -1,30 +0,0 @@
-Checks that setScriptSource works for editing the top-most stack frame
-Paused at (before live edit):
-function testExpression(a, b) {
- #debugger;
- return a + b;
-
-Paused at (after live edit 1):
-function testExpression(a, b) {
- #return a * b;
-}
-
-Nested result 1: 15
-Paused at (after live edit 2):
-function testExpression(a, b, c, d, e, f, g, h) {
- #return a * b + String(h).length; // +"undefined".length
-}
-
-Nested result 2: 24
-Paused at (after live edit 3):
-function testExpression(a, b) {
- #return a * b + 3;
-}
-
-Nested result 3: 18
-Result:
-{
- description : 18
- type : number
- value : 18
-}
diff --git a/deps/v8/test/inspector/debugger/set-script-source-top-frame-with-additional-activations-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-top-frame-with-additional-activations-expected.txt
deleted file mode 100644
index d89e0523bd9..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-top-frame-with-additional-activations-expected.txt
+++ /dev/null
@@ -1,21 +0,0 @@
-Checks that setScriptSource fails when editing the top-most stack frame, but that function also has an activation further down the stack
-First pause at (before live edit):
-function testExpression(a, b) {
- #debugger;
- if (!a && !b) {
-
-Second pause at (before live edit):
-function testExpression(a, b) {
- #debugger;
- if (!a && !b) {
-
-Debugger.setScriptSource result:
-{
- status : BlockedByActiveFunction
-}
-Evaluation result:
-{
- description : 8
- type : number
- value : 8
-}
diff --git a/deps/v8/test/inspector/debugger/set-script-source-top-frame-with-additional-activations.js b/deps/v8/test/inspector/debugger/set-script-source-top-frame-with-additional-activations.js
deleted file mode 100644
index 24c11387b86..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-top-frame-with-additional-activations.js
+++ /dev/null
@@ -1,53 +0,0 @@
-// Copyright 2022 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: --inspector-live-edit
-
-const {session, contextGroup, Protocol} = InspectorTest.start(
- 'Checks that setScriptSource fails when editing the top-most stack frame, but that function also has an activation further down the stack');
-
-const script = `
-function callsTestExpression(a, b) {
- return testExpression(a, b);
-}
-
-function testExpression(a, b) {
- debugger;
- if (!a && !b) {
- return callsTestExpression(5, 3);
- }
- return a + b;
-}`;
-const replacementScript = script.replace('a + b', 'a * b');
-
-contextGroup.addScript(script);
-
-session.setupScriptMap();
-
-(async () => {
- Protocol.Debugger.enable();
- const { params: { scriptId } } = await Protocol.Debugger.onceScriptParsed();
-
- const evaluatePromise = Protocol.Runtime.evaluate({ expression: 'callsTestExpression()' });
- let { params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused();
- InspectorTest.log('First pause at (before live edit):');
- await session.logSourceLocation(pausedCallFrames[0].location);
-
- Protocol.Debugger.resume();
- ({ params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused());
- InspectorTest.log('Second pause at (before live edit):');
- await session.logSourceLocation(pausedCallFrames[0].location);
-
- const response = await Protocol.Debugger.setScriptSource({ scriptId, scriptSource: replacementScript, allowTopFrameEditing: true })
- InspectorTest.log('Debugger.setScriptSource result:');
- InspectorTest.logMessage(response.result);
-
- Protocol.Debugger.resume();
-
- const { result: { result } } = await evaluatePromise;
- InspectorTest.log('Evaluation result:');
- InspectorTest.logMessage(result);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-top-frame.js b/deps/v8/test/inspector/debugger/set-script-source-top-frame.js
deleted file mode 100644
index 060f1ed4927..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-top-frame.js
+++ /dev/null
@@ -1,70 +0,0 @@
-// Copyright 2022 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: --inspector-live-edit
-
-const {session, contextGroup, Protocol} = InspectorTest.start(
- 'Checks that setScriptSource works for editing the top-most stack frame');
-
-contextGroup.addScript(`
-function testExpression(a, b) {
- debugger;
- return a + b;
-}`);
-
-const replacementScript1 = `
-function testExpression(a, b) {
- return a * b;
-}`;
-
-const replacementScript2 = `
-function testExpression(a, b, c, d, e, f, g, h) {
- return a * b + String(h).length; // +"undefined".length
-}`;
-
-const replacementScript3 = `
-function testExpression(a, b) {
- return a * b + 3;
-}`;
-
-session.setupScriptMap();
-
-(async () => {
- Protocol.Debugger.enable();
- const { params: { scriptId } } = await Protocol.Debugger.onceScriptParsed();
-
- const evaluatePromise = Protocol.Runtime.evaluate({ expression: 'testExpression(3, 5)' });
- let { params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused();
- InspectorTest.log('Paused at (before live edit):');
- await session.logSourceLocation(pausedCallFrames[0].location);
-
- Protocol.Debugger.setScriptSource({ scriptId, scriptSource: replacementScript1, allowTopFrameEditing: true });
- ({ params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused());
- InspectorTest.log('Paused at (after live edit 1):');
- await session.logSourceLocation(pausedCallFrames[0].location, /* forceSourceRequest */ true);
- let { result: { result: r1 } } = await Protocol.Runtime.evaluate({ expression: 'testExpression(3, 5)' });
- InspectorTest.log('Nested result 1: ' + r1.value);
-
- Protocol.Debugger.setScriptSource({ scriptId, scriptSource: replacementScript2, allowTopFrameEditing: true });
- ({ params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused());
- InspectorTest.log('Paused at (after live edit 2):');
- await session.logSourceLocation(pausedCallFrames[0].location, /* forceSourceRequest */ true);
- let { result: { result: r2 } } = await Protocol.Runtime.evaluate({ expression: 'testExpression(3, 5)' });
- InspectorTest.log('Nested result 2: ' + r2.value);
-
- Protocol.Debugger.setScriptSource({ scriptId, scriptSource: replacementScript3, allowTopFrameEditing: true });
- ({ params: { callFrames: pausedCallFrames } } = await Protocol.Debugger.oncePaused());
- InspectorTest.log('Paused at (after live edit 3):');
- await session.logSourceLocation(pausedCallFrames[0].location, /* forceSourceRequest */ true);
- let { result: { result: r3 } } = await Protocol.Runtime.evaluate({ expression: 'testExpression(3, 5)' });
- InspectorTest.log('Nested result 3: ' + r3.value);
-
- Protocol.Debugger.resume();
-
- const { result: { result } } = await evaluatePromise;
- InspectorTest.log('Result:');
- InspectorTest.logMessage(result);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source-unchanged-expected.txt b/deps/v8/test/inspector/debugger/set-script-source-unchanged-expected.txt
deleted file mode 100644
index 13e3fbcf811..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-unchanged-expected.txt
+++ /dev/null
@@ -1 +0,0 @@
-Check that setScriptSource does not crash when source is unchanged
diff --git a/deps/v8/test/inspector/debugger/set-script-source-unchanged.js b/deps/v8/test/inspector/debugger/set-script-source-unchanged.js
deleted file mode 100644
index a161071c355..00000000000
--- a/deps/v8/test/inspector/debugger/set-script-source-unchanged.js
+++ /dev/null
@@ -1,18 +0,0 @@
-// Copyright 2020 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-// Flags: --inspector-live-edit
-
-let {session, contextGroup, Protocol} =
- InspectorTest.start('Check that setScriptSource does not crash when source is unchanged');
-
-let scriptSource = `function TestExpression() {}`;
-contextGroup.addScript(scriptSource);
-
-(async function test() {
- Protocol.Debugger.enable();
- const {params: {scriptId}} = await Protocol.Debugger.onceScriptParsed();
- await Protocol.Debugger.setScriptSource({scriptId, scriptSource});
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/debugger/set-script-source.js b/deps/v8/test/inspector/debugger/set-script-source.js
index 95702d567ef..c9a9a617275 100644
--- a/deps/v8/test/inspector/debugger/set-script-source.js
+++ b/deps/v8/test/inspector/debugger/set-script-source.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.
-// Flags: --inspector-live-edit
-
const {session, contextGroup, Protocol} =
InspectorTest.start('Tests Debugger.setScriptSource');
@@ -15,30 +13,8 @@ contextGroup.addScript(
(async function test() {
Protocol.Debugger.enable();
const {params: {scriptId}} = await Protocol.Debugger.onceScriptParsed();
- const {result: {result: {value}}} =
- await Protocol.Runtime.evaluate({expression: 'TestExpression(2, 4)'});
- InspectorTest.log(`TestExpression(2,4) === ${value}`);
- {
- const {result: {scriptSource}} =
- await Protocol.Debugger.getScriptSource({scriptId});
- InspectorTest.log(`Update current script source 'a + b' -> 'a * b'..`);
- const {result} = await Protocol.Debugger.setScriptSource(
- {scriptId, scriptSource: scriptSource.replace('a + b', 'a * b')})
- InspectorTest.logMessage(result);
- const {result: {result: {value}}} =
- await Protocol.Runtime.evaluate({expression: 'TestExpression(2, 4)'});
- InspectorTest.log(`TestExpression(2,4) === ${value}`);
- }
- {
- const {result: {scriptSource}} =
- await Protocol.Debugger.getScriptSource({scriptId});
- InspectorTest.log(`Update current script source 'a * b' -> 'a # b'..`);
- const {result} = await Protocol.Debugger.setScriptSource(
- {scriptId, scriptSource: scriptSource.replace('a * b', 'a # b')})
- InspectorTest.logMessage(result);
- const {result: {result: {value}}} =
- await Protocol.Runtime.evaluate({expression: 'TestExpression(2, 4)'});
- InspectorTest.log(`TestExpression(2,4) === ${value}`);
- }
+ const response = await Protocol.Debugger.setScriptSource(
+ {scriptId, scriptSource: 'function TestExpression(a, b) { return a * b; }'});
+ InspectorTest.logMessage(response.error);
InspectorTest.completeTest();
})();
diff --git a/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack-expected.txt b/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack-expected.txt
index 42e53007606..cbaa448b69c 100644
--- a/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack-expected.txt
+++ b/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack-expected.txt
@@ -7,4 +7,6 @@ Call tree size: 2
Call tree contains allocationChunk: true
Starting heap profiler with stack depth: 0
Expected error: Invalid stack depth
+Starting heap profiler with stack depth: 0.5
+Expected error: Invalid stack depth
Successfully finished
diff --git a/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack.js b/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack.js
index e7ba9418890..15a75ef72ed 100644
--- a/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack.js
+++ b/deps/v8/test/inspector/heap-profiler/sampling-heap-profiler-call-stack.js
@@ -35,6 +35,9 @@
// should fail with stackDepth=0
await captureProfilerWithDepth(0);
+ // should fail with stackDepth=0.5
+ await captureProfilerWithDepth(0.5);
+
InspectorTest.log('Successfully finished');
InspectorTest.completeTest();
diff --git a/deps/v8/test/inspector/inspector-test.cc b/deps/v8/test/inspector/inspector-test.cc
index f88dd685cb3..d655375be31 100644
--- a/deps/v8/test/inspector/inspector-test.cc
+++ b/deps/v8/test/inspector/inspector-test.cc
@@ -223,19 +223,19 @@ class UtilsExtension : public InspectorIsolateData::SetupGlobalTask {
static void CompileAndRunWithOrigin(
const v8::FunctionCallbackInfo<v8::Value>& info) {
- if (info.Length() != 6 || !info[0]->IsInt32() || !info[1]->IsString() ||
+ if (info.Length() != 7 || !info[0]->IsInt32() || !info[1]->IsString() ||
!info[2]->IsString() || !info[3]->IsInt32() || !info[4]->IsInt32() ||
- !info[5]->IsBoolean()) {
+ !info[5]->IsBoolean() || !info[6]->IsBoolean()) {
FATAL(
"Internal error: compileAndRunWithOrigin(context_group_id, source, "
- "name, line, column, is_module).");
+ "name, line, column, is_module, evaluate).");
}
-
backend_runner_->Append(std::make_unique<ExecuteStringTask>(
info.GetIsolate(), info[0].As<v8::Int32>()->Value(),
ToVector(info.GetIsolate(), info[1].As<v8::String>()),
info[2].As<v8::String>(), info[3].As<v8::Int32>(),
- info[4].As<v8::Int32>(), info[5].As<v8::Boolean>()));
+ info[4].As<v8::Int32>(), info[5].As<v8::Boolean>(),
+ info[6].As<v8::Boolean>()->Value()));
}
static void CompileAndRunWrapped(
diff --git a/deps/v8/test/inspector/inspector.status b/deps/v8/test/inspector/inspector.status
index 0e51b6e1700..4041d4a5052 100644
--- a/deps/v8/test/inspector/inspector.status
+++ b/deps/v8/test/inspector/inspector.status
@@ -26,7 +26,11 @@
# Tests that need to run sequentially (e.g. due to memory consumption).
'runtime/console-messages-limits': [PASS, SLOW, HEAVY],
'runtime/regression-732717': [PASS, HEAVY],
+
+ # Use-after-free regression tests, only meaningful under ASan.
'runtime/regress-520052954': [PASS, ['not asan', SKIP]],
+ 'runtime/regress-520052954-2': [PASS, ['not asan', SKIP]],
+ 'runtime/regress-520052954-3': [PASS, ['not asan', SKIP]],
}], # ALWAYS
##############################################################################
@@ -182,7 +186,6 @@
'debugger/script-on-after-compile': [SKIP],
'debugger/set-breakpoint-at-last-line': [SKIP],
'debugger/set-breakpoint-breaks-on-first-breakable-location': [SKIP],
- 'debugger/set-script-source-repl-mode': [SKIP],
'heap-profiler/collect-garbage' : [SKIP],
'runtime/context-destroyed-on-context-collected': [SKIP],
'runtime/evaluate-async': [SKIP],
diff --git a/deps/v8/test/inspector/isolate-data.cc b/deps/v8/test/inspector/isolate-data.cc
index c17f2d1c201..49a134bd35c 100644
--- a/deps/v8/test/inspector/isolate-data.cc
+++ b/deps/v8/test/inspector/isolate-data.cc
@@ -158,7 +158,8 @@ int InspectorIsolateData::GetContextGroupId(v8::Local<v8::Context> context) {
void InspectorIsolateData::RegisterModule(v8::Local<v8::Context> context,
std::vector<uint16_t> name,
- v8::ScriptCompiler::Source* source) {
+ v8::ScriptCompiler::Source* source,
+ bool evaluate) {
v8::Local<v8::Module> module;
if (!v8::ScriptCompiler::CompileModule(isolate(), source).ToLocal(&module)) {
return;
@@ -169,8 +170,10 @@ void InspectorIsolateData::RegisterModule(v8::Local<v8::Context> context,
.FromMaybe(false)) {
return;
}
- v8::Local<v8::Value> result;
- if (!module->Evaluate(context).ToLocal(&result)) return;
+ if (evaluate) {
+ v8::Local<v8::Value> result;
+ if (!module->Evaluate(context).ToLocal(&result)) return;
+ }
modules_[name] = v8::Global<v8::Module>(isolate_.get(), module);
}
@@ -519,6 +522,30 @@ void InspectorIsolateData::quitMessageLoopOnPause() {
void InspectorIsolateData::installAdditionalCommandLineAPI(
v8::Local<v8::Context> context, v8::Local<v8::Object> object) {
+ // PoC: mirror Blink's
+ // ThreadDebuggerCommonImpl::installAdditionalCommandLineAPI
+ // (third_party/blink/renderer/core/inspector/thread_debugger_common_impl.cc),
+ // which installs `monitorEvents` / `unmonitorEvents` as own properties on the
+ // commandLineAPI object via CreateFunctionPropertyWithData(...,
+ // kHasSideEffect). The function body is irrelevant; only the side effect type
+ // matters for the IsUnsafeCommandLineAPIFn check in v8-console.cc.
+ {
+ v8::Context::Scope context_scope(context);
+ auto noop = [](const v8::FunctionCallbackInfo<v8::Value>&) {};
+ v8::Local<v8::Function> fn =
+ v8::Function::New(context, noop, v8::Local<v8::Value>(), 0,
+ v8::ConstructorBehavior::kThrow,
+ v8::SideEffectType::kHasSideEffect)
+ .ToLocalChecked();
+ object
+ ->Set(context,
+ v8::String::NewFromUtf8Literal(isolate(), "monitorEvents"), fn)
+ .Check();
+ object
+ ->Set(context,
+ v8::String::NewFromUtf8Literal(isolate(), "unmonitorEvents"), fn)
+ .Check();
+ }
if (additional_console_api_.IsEmpty()) return;
CHECK_EQ(v8::Isolate::GetCurrent(), isolate());
v8::HandleScope handle_scope(isolate());
diff --git a/deps/v8/test/inspector/isolate-data.h b/deps/v8/test/inspector/isolate-data.h
index 8714af1bb19..7bc44d45979 100644
--- a/deps/v8/test/inspector/isolate-data.h
+++ b/deps/v8/test/inspector/isolate-data.h
@@ -62,9 +62,12 @@ class InspectorIsolateData : public v8_inspector::V8InspectorClient {
void ResetContextGroup(int context_group_id);
v8::Local<v8::Context> GetDefaultContext(int context_group_id);
int GetContextGroupId(v8::Local<v8::Context> context);
+ // Compiles and instantiates the module, and registers it under |name| so
+ // that it can be resolved as a dependency. |evaluate| is false for modules
+ // that must stay unevaluated, e.g. the target of an `import defer`.
void RegisterModule(v8::Local<v8::Context> context,
std::vector<uint16_t> name,
- v8::ScriptCompiler::Source* source);
+ v8::ScriptCompiler::Source* source, bool evaluate);
// Working with V8Inspector api.
std::optional<int> ConnectSession(
diff --git a/deps/v8/test/inspector/protocol-test.js b/deps/v8/test/inspector/protocol-test.js
index cb6ab9866a7..5f5bc0b8637 100644
--- a/deps/v8/test/inspector/protocol-test.js
+++ b/deps/v8/test/inspector/protocol-test.js
@@ -162,7 +162,7 @@ InspectorTest.ContextGroup = class {
}
addScript(string, lineOffset, columnOffset, url) {
- utils.compileAndRunWithOrigin(this.id, string, url || '', lineOffset || 0, columnOffset || 0, false);
+ utils.compileAndRunWithOrigin(this.id, string, url || '', lineOffset || 0, columnOffset || 0, false, true);
}
addInlineScript(string, url) {
@@ -172,7 +172,13 @@ InspectorTest.ContextGroup = class {
}
addModule(string, url, lineOffset, columnOffset) {
- utils.compileAndRunWithOrigin(this.id, string, url, lineOffset || 0, columnOffset || 0, true);
+ utils.compileAndRunWithOrigin(this.id, string, url, lineOffset || 0, columnOffset || 0, true, true);
+ }
+
+ // Registers a module so that it can be resolved as a dependency, but leaves
+ // it unevaluated. Used to set up the target of an `import defer`.
+ addModuleWithoutEvaluating(string, url, lineOffset, columnOffset) {
+ utils.compileAndRunWithOrigin(this.id, string, url, lineOffset || 0, columnOffset || 0, true, false);
}
loadScript(fileName) {
diff --git a/deps/v8/test/inspector/regress/regress-crbug-1195927-expected.txt b/deps/v8/test/inspector/regress/regress-crbug-1195927-expected.txt
deleted file mode 100644
index 197cc07e0a7..00000000000
--- a/deps/v8/test/inspector/regress/regress-crbug-1195927-expected.txt
+++ /dev/null
@@ -1,27 +0,0 @@
-Regression test for crbug.com/1195927
-
-Running test: test
-Debugger.setBreakpoint result:
-{
- actualLocation : {
- columnNumber : 2
- lineNumber : 2
- scriptId : <scriptId>
- }
- breakpointId : <breakpointId>
-}
-Debugger.paused call frames:
-foo (foo.js:2:2)
-(anonymous) (:0:0)
-Debugger.setScriptSource result:
-{
- status : BlockedByActiveFunction
-}
-foo(42) result:
-{
- result : {
- description : 43
- type : number
- value : 43
- }
-}
diff --git a/deps/v8/test/inspector/regress/regress-crbug-1195927.js b/deps/v8/test/inspector/regress/regress-crbug-1195927.js
deleted file mode 100644
index 761e2c06130..00000000000
--- a/deps/v8/test/inspector/regress/regress-crbug-1195927.js
+++ /dev/null
@@ -1,56 +0,0 @@
-// Copyright 2021 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: --inspector-live-edit
-
-const {session, contextGroup, Protocol} =
- InspectorTest.start('Regression test for crbug.com/1195927');
-
-const source = `
-function foo(x) {
- x = x + 1;
- return x;
-}
-`;
-
-const newSource = `
-function foo(x) {
- x = x + 2;
- return x;
-}
-`;
-
-InspectorTest.runAsyncTestSuite([
- async function test() {
- session.setupScriptMap();
- await Protocol.Runtime.enable();
- await Protocol.Debugger.enable();
- contextGroup.addScript(source, 0, 0, 'foo.js');
- const { params: { scriptId } } = await Protocol.Debugger.onceScriptParsed();
-
- let {result} = await Protocol.Debugger.setBreakpoint({location: {
- scriptId,
- lineNumber: 2,
- }});
- InspectorTest.log('Debugger.setBreakpoint result:');
- InspectorTest.logMessage(result);
-
- const callPromise = Protocol.Runtime.evaluate({expression: 'foo(42)'});
-
- let {params: {callFrames}} = await Protocol.Debugger.oncePaused();
- InspectorTest.log('Debugger.paused call frames:');
- session.logCallFrames(callFrames);
-
- ({result} = await Protocol.Debugger.setScriptSource({
- scriptId,
- scriptSource: newSource
- }));
- InspectorTest.log('Debugger.setScriptSource result:');
- InspectorTest.logMessage(result);
-
- ([, {result}] = await Promise.all([Protocol.Debugger.resume(), callPromise]));
- InspectorTest.log('foo(42) result:');
- InspectorTest.logMessage(result);
- }
-]);
diff --git a/deps/v8/test/inspector/regress/regress-crbug-1197392-expected.txt b/deps/v8/test/inspector/regress/regress-crbug-1197392-expected.txt
index e6e27f90949..5a3ed2d2d1d 100644
--- a/deps/v8/test/inspector/regress/regress-crbug-1197392-expected.txt
+++ b/deps/v8/test/inspector/regress/regress-crbug-1197392-expected.txt
@@ -8,3 +8,10 @@ Running test: testInvalidSamplingInterval
}
id : <messageId>
}
+{
+ error : {
+ code : -32000
+ message : Invalid sampling interval
+ }
+ id : <messageId>
+}
diff --git a/deps/v8/test/inspector/regress/regress-crbug-1197392.js b/deps/v8/test/inspector/regress/regress-crbug-1197392.js
index 572d35885a8..bfde791aebb 100644
--- a/deps/v8/test/inspector/regress/regress-crbug-1197392.js
+++ b/deps/v8/test/inspector/regress/regress-crbug-1197392.js
@@ -9,7 +9,9 @@ let {contextGroup, Protocol} = InspectorTest.start('Regression test for crbug.co
InspectorTest.runAsyncTestSuite([
async function testInvalidSamplingInterval() {
await Protocol.HeapProfiler.enable();
- const message = await Protocol.HeapProfiler.startSampling({samplingInterval: 0});
+ let message = await Protocol.HeapProfiler.startSampling({samplingInterval: 0});
+ InspectorTest.logMessage(message);
+ message = await Protocol.HeapProfiler.startSampling({samplingInterval: 0.5});
InspectorTest.logMessage(message);
await Protocol.HeapProfiler.disable();
}
diff --git a/deps/v8/test/inspector/regress/regress-crbug-1328453-expected.txt b/deps/v8/test/inspector/regress/regress-crbug-1328453-expected.txt
deleted file mode 100644
index 74a36834ce5..00000000000
--- a/deps/v8/test/inspector/regress/regress-crbug-1328453-expected.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-Don't crash when live editing an unused inner function [crbug.com/1328453]
-{
- id : <messageId>
- result : {
- status : Ok
- }
-}
diff --git a/deps/v8/test/inspector/regress/regress-crbug-1328453.js b/deps/v8/test/inspector/regress/regress-crbug-1328453.js
deleted file mode 100644
index 510629847b0..00000000000
--- a/deps/v8/test/inspector/regress/regress-crbug-1328453.js
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2022 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: --inspector-live-edit
-
-const {contextGroup, Protocol} = InspectorTest.start(
- 'Don\'t crash when live editing an unused inner function [crbug.com/1328453]');
-
-contextGroup.addScript(`
-function outerFn() {
- function innerFn() {
- console.log("aa"); // We'll edit the "aa".
- }
-}`);
-
-const updatedScript = `
-function outerFn() {
- function innerFn() {
- console.log("aabb");
- }
-}`;
-
-(async () => {
- Protocol.Debugger.enable();
- const { params: {scriptId} } = await Protocol.Debugger.onceScriptParsed();
-
- const response = await Protocol.Debugger.setScriptSource({ scriptId, scriptSource: updatedScript });
- InspectorTest.logMessage(response);
-
- InspectorTest.completeTest();
-})();
diff --git a/deps/v8/test/inspector/runtime/custom-preview-proxy-expected.txt b/deps/v8/test/inspector/runtime/custom-preview-proxy-expected.txt
new file mode 100644
index 00000000000..60cdf687027
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/custom-preview-proxy-expected.txt
@@ -0,0 +1,91 @@
+Checks that proxies in JSONML are rejected by custom formatters
+Test proxy child in header JSONML..
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught Proxy values are not allowed in JSONML
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+No customPreview generated
+Test proxy attributes in header JSONML..
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught Proxy values are not allowed in JSONML
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+No customPreview generated
+Test proxy array child masquerading as tag..
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught Proxy values are not allowed in JSONML
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+No customPreview generated
+Test proxy attributes in object tag..
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught Proxy values are not allowed in JSONML
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+No customPreview generated
+Test proxy child in body JSONML..
+customPreview: ["span",{},"Header ok"]
+{
+ method : Runtime.consoleAPICalled
+ params : {
+ args : [
+ [0] : {
+ type : string
+ value : Custom Formatter Failed: Uncaught Proxy values are not allowed in JSONML
+ }
+ ]
+ executionContextId : <executionContextId>
+ timestamp : <timestamp>
+ type : error
+ }
+}
+{
+ id : <messageId>
+ result : {
+ result : {
+ type : undefined
+ }
+ }
+}
+Test formatting a proxy object itself (allowed)..
+customPreview: ["span",{},"Proxy formatted: ","proxyObject"]
diff --git a/deps/v8/test/inspector/runtime/custom-preview-proxy.js b/deps/v8/test/inspector/runtime/custom-preview-proxy.js
new file mode 100644
index 00000000000..c525d848647
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/custom-preview-proxy.js
@@ -0,0 +1,115 @@
+// 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 { session, contextGroup, Protocol } =
+ InspectorTest.start('Checks that proxies in JSONML are rejected by custom formatters');
+
+(async function test() {
+ Protocol.Runtime.enable();
+ Protocol.Runtime.setCustomObjectFormatterEnabled({ enabled: true });
+ Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
+
+ InspectorTest.log('Test proxy child in header JSONML..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, 'Header with proxy child', new Proxy([], {})],
+ hasBody: () => false
+ }];
+ `
+ });
+ let result = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(result);
+
+ InspectorTest.log('Test proxy attributes in header JSONML..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', new Proxy({}, {}), 'Header with proxy attributes'],
+ hasBody: () => false
+ }];
+ `
+ });
+ result = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(result);
+
+ InspectorTest.log('Test proxy array child masquerading as tag..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, new Proxy(['object', {object: {}}], {})],
+ hasBody: () => false
+ }];
+ `
+ });
+ result = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(result);
+
+ InspectorTest.log('Test proxy attributes in object tag..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, ['object', new Proxy({object: {}}, {})]],
+ hasBody: () => false
+ }];
+ `
+ });
+ result = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ dumpCustomPreview(result);
+
+ InspectorTest.log('Test proxy child in body JSONML..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ this.devtoolsFormatters = [{
+ header: () => ['span', {}, 'Header ok'],
+ hasBody: () => true,
+ body: () => ['span', {}, 'Body with proxy child', new Proxy([], {})]
+ }];
+ `
+ });
+ result = await Protocol.Runtime.evaluate({ expression: '({})', generatePreview: true });
+ await dumpCustomPreviewWithBody(result);
+
+ InspectorTest.log('Test formatting a proxy object itself (allowed)..');
+ await Protocol.Runtime.evaluate({
+ expression: `
+ var targetProxy = new Proxy({name: 'proxyObject'}, {});
+ this.devtoolsFormatters = [{
+ header: (x) => x === targetProxy ? ['span', {}, 'Proxy formatted: ', x.name] : null,
+ hasBody: () => false
+ }];
+ `
+ });
+ result = await Protocol.Runtime.evaluate({ expression: 'targetProxy', generatePreview: true });
+ dumpCustomPreview(result);
+
+ 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/deep-serialization-errors-expected.txt b/deps/v8/test/inspector/runtime/deep-serialization-errors-expected.txt
new file mode 100644
index 00000000000..3d96a162a94
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/deep-serialization-errors-expected.txt
@@ -0,0 +1,106 @@
+RemoteObject.deepSerializedValueErrors
+
+Running test: ObjectThrowingGetter
+testing expression: ({ get foo() { throw new Error('getter error'); } })
+Runtime.evaluate
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+Runtime.callFunctionOn
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+
+Running test: ArrayThrowingGetter
+testing expression: (()=>{ const a = [1]; Object.defineProperty(a, '1', { get() { throw new Error('array element error'); }, enumerable: true }); return a; })()
+Runtime.evaluate
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+Runtime.callFunctionOn
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+
+Running test: NestedThrowingGetter
+testing expression: ({ a: { b: [ { get c() { throw new Error('nested error'); } } ] } })
+Runtime.evaluate
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+Runtime.callFunctionOn
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+
+Running test: SpecialCharacterKeyThrowingGetter
+testing expression: ({ 'invalid identifier!': { get ['another special']() { throw new Error('special key error'); } } })
+Runtime.evaluate
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+Runtime.callFunctionOn
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+
+Running test: NumericKeyThrowingGetter
+testing expression: ({ '0': { get ['1']() { throw new Error('numeric key error'); } } })
+Runtime.evaluate
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
+Runtime.callFunctionOn
+...no deepSerializedValue...
+{
+ error : {
+ code : -32000
+ message : exception during deep serialization
+ }
+ id : <messageId>
+}
diff --git a/deps/v8/test/inspector/runtime/deep-serialization-errors.js b/deps/v8/test/inspector/runtime/deep-serialization-errors.js
new file mode 100644
index 00000000000..f0f50a55ed9
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/deep-serialization-errors.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.
+
+const { session, contextGroup, Protocol } =
+ InspectorTest.start('RemoteObject.deepSerializedValueErrors');
+
+Protocol.Runtime.enable();
+Protocol.Runtime.onConsoleAPICalled(m => InspectorTest.logMessage(m));
+
+InspectorTest.runAsyncTestSuite([
+ async function ObjectThrowingGetter() {
+ await testExpression("({ get foo() { throw new Error('getter error'); } })");
+ },
+ async function ArrayThrowingGetter() {
+ await testExpression("(()=>{ const a = [1]; Object.defineProperty(a, '1', { get() { throw new Error('array element error'); }, enumerable: true }); return a; })()");
+ },
+ async function NestedThrowingGetter() {
+ await testExpression("({ a: { b: [ { get c() { throw new Error('nested error'); } } ] } })");
+ },
+ async function SpecialCharacterKeyThrowingGetter() {
+ await testExpression("({ 'invalid identifier!': { get ['another special']() { throw new Error('special key error'); } } })");
+ },
+ async function NumericKeyThrowingGetter() {
+ await testExpression("({ '0': { get ['1']() { throw new Error('numeric key error'); } } })");
+ }
+]);
+
+async function serializeViaEvaluate(expression) {
+ return await Protocol.Runtime.evaluate({
+ expression: "(" + expression + ")",
+ serializationOptions: { serialization: "deep" }
+ });
+}
+
+async function serializeViaCallFunctionOn(expression) {
+ const objectId = (await Protocol.Runtime.evaluate({
+ expression: "({})",
+ })).result.result.objectId;
+
+ return await Protocol.Runtime.callFunctionOn({
+ functionDeclaration: "()=>{return " + expression + "}",
+ objectId,
+ serializationOptions: { serialization: "deep" }
+ });
+}
+
+async function testExpression(expression) {
+ InspectorTest.logMessage("testing expression: " + expression);
+
+ InspectorTest.logMessage("Runtime.evaluate");
+ dumpResult(await serializeViaEvaluate(expression));
+ InspectorTest.logMessage("Runtime.callFunctionOn");
+ dumpResult(await serializeViaCallFunctionOn(expression));
+}
+
+function dumpResult(result) {
+ if (result?.result?.result?.deepSerializedValue) {
+ InspectorTest.logMessage(result.result.result.deepSerializedValue);
+ } else {
+ InspectorTest.log("...no deepSerializedValue...");
+ InspectorTest.logMessage(result);
+ }
+}
diff --git a/deps/v8/test/inspector/runtime/error-preview-sideeffects-expected.txt b/deps/v8/test/inspector/runtime/error-preview-sideeffects-expected.txt
index acac983aeb0..6e7595742f2 100644
--- a/deps/v8/test/inspector/runtime/error-preview-sideeffects-expected.txt
+++ b/deps/v8/test/inspector/runtime/error-preview-sideeffects-expected.txt
@@ -12,3 +12,15 @@ Running test: ErrorStackBoundBuiltin
stackCalledViaBoundApply : false
stackCalledViaBoundCall : false
}
+
+Running test: ErrorStackProxy
+{
+ stackCalledViaProxy : false
+}
+
+Running test: ErrorDescriptionProxy
+{
+ messageCalled : false
+ nameCalled : false
+ stackCalled : false
+}
diff --git a/deps/v8/test/inspector/runtime/error-preview-sideeffects.js b/deps/v8/test/inspector/runtime/error-preview-sideeffects.js
index ea640f45dfc..87221a9b522 100644
--- a/deps/v8/test/inspector/runtime/error-preview-sideeffects.js
+++ b/deps/v8/test/inspector/runtime/error-preview-sideeffects.js
@@ -86,6 +86,62 @@ function testLogErrorBoundBuiltin() {
return {stackCalledViaBoundCall, stackCalledViaBoundApply};
}
+function testLogErrorProxy() {
+ let stackCalledViaProxy = false;
+ {
+ const error = new Error();
+ Object.defineProperty(error, 'stack', {
+ configurable: true,
+ get: new Proxy(function() {}, {
+ apply: () => {
+ stackCalledViaProxy = true;
+ return 'value';
+ },
+ }),
+ });
+ console.log(error);
+ }
+
+ console.clear();
+
+ return {stackCalledViaProxy};
+}
+
+function testErrorDescriptionProxy() {
+ let nameCalled = false;
+ let messageCalled = false;
+ let stackCalled = false;
+ const error = new Error();
+ Object.defineProperty(error, 'name', {
+ configurable: true,
+ get: new Proxy(function() {}, {
+ apply: () => {
+ nameCalled = true;
+ return 'CustomError';
+ },
+ }),
+ });
+ Object.defineProperty(error, 'message', {
+ configurable: true,
+ get: new Proxy(function() {}, {
+ apply: () => {
+ messageCalled = true;
+ return 'CustomMessage';
+ },
+ }),
+ });
+ Object.defineProperty(error, 'stack', {
+ configurable: true,
+ get: new Proxy(function() {}, {
+ apply: () => {
+ stackCalled = true;
+ return 'value';
+ },
+ }),
+ });
+ return {error, getTrapsCalled: () => ({nameCalled, messageCalled, stackCalled})};
+}
+
//# sourceURL=test.js
`);
@@ -101,5 +157,23 @@ InspectorTest.runAsyncTestSuite([
const result = await Protocol.Runtime.evaluate({expression: 'testLogErrorBoundBuiltin()', returnByValue: true});
InspectorTest.logObject(result.result.result.value);
await Protocol.Runtime.disable();
+ },
+ async function ErrorStackProxy() {
+ await Protocol.Runtime.enable();
+ const result = await Protocol.Runtime.evaluate(
+ {expression: 'testLogErrorProxy()', returnByValue: true});
+ InspectorTest.logObject(result.result.result.value);
+ await Protocol.Runtime.disable();
+ },
+ async function ErrorDescriptionProxy() {
+ await Protocol.Runtime.enable();
+ await Protocol.Runtime.evaluate({
+ expression:
+ 'var { error, getTrapsCalled } = testErrorDescriptionProxy(); error'
+ });
+ const result = await Protocol.Runtime.evaluate(
+ {expression: 'getTrapsCalled()', returnByValue: true});
+ InspectorTest.logObject(result.result.result.value);
+ await Protocol.Runtime.disable();
}
]);
diff --git a/deps/v8/test/inspector/runtime/evaluate-side-effect-free-monitor-events-expected.txt b/deps/v8/test/inspector/runtime/evaluate-side-effect-free-monitor-events-expected.txt
new file mode 100644
index 00000000000..3c597a29813
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/evaluate-side-effect-free-monitor-events-expected.txt
@@ -0,0 +1,6 @@
+Embedder-installed command-line-API names bypass UnsafeCommandLineAPIFns
+[debug] -> THROWS: EvalError: Possible side-effect in debug-evaluate
+[$0] -> OK: type=undefined
+[monitorEvents] -> THROWS: EvalError: Possible side-effect in debug-evaluate
+[unmonitorEvents] -> THROWS: EvalError: Possible side-effect in debug-evaluate
+[typeof monitorEvents] -> THROWS: EvalError: Possible side-effect in debug-evaluate
diff --git a/deps/v8/test/inspector/runtime/evaluate-side-effect-free-monitor-events.js b/deps/v8/test/inspector/runtime/evaluate-side-effect-free-monitor-events.js
new file mode 100644
index 00000000000..1dbcac9921f
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/evaluate-side-effect-free-monitor-events.js
@@ -0,0 +1,60 @@
+// 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.
+
+// PoC: UnsafeCommandLineAPIFns deny-list does not cover embedder-installed
+// command-line-API names. Blink installs `monitorEvents` / `unmonitorEvents`
+// via V8InspectorClient::installAdditionalCommandLineAPI; CommandLineAPIScope
+// then exposes them on the global proxy with a kHasNoSideEffect getter, so
+// they survive throwOnSideEffect:true (DevTools eager-eval) -- the exact
+// threat the deny-list at v8-console.cc:1035-1042 is meant to prevent.
+//
+// Run with the patched inspector-test (see test-harness.patch), which makes
+// the test client's installAdditionalCommandLineAPI add `monitorEvents` to
+// the commandLineAPI object exactly as Blink does.
+
+const {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Embedder-installed command-line-API names bypass UnsafeCommandLineAPIFns');
+
+async function probe(expression) {
+ const {result} = await Protocol.Runtime.evaluate({
+ expression,
+ includeCommandLineAPI: true,
+ throwOnSideEffect: true,
+ replMode: true,
+ });
+ if (result.exceptionDetails) {
+ InspectorTest.log(
+ `[${expression}] -> THROWS: ` +
+ result.exceptionDetails.exception.description.split('\n')[0]);
+ } else {
+ InspectorTest.log(
+ `[${expression}] -> OK: type=${result.result.type}` +
+ (result.result.description ? ` desc="${result.result.description}"` :
+ ''));
+ }
+}
+
+(async () => {
+ // Control 1: a name in the V8 deny-list. Reading it under
+ // throwOnSideEffect:true must throw "Possible side-effect".
+ await probe('debug');
+
+ // Control 2: a V8-side name explicitly carved out of the deny-list.
+ await probe('$0');
+
+ // BUG: embedder-installed names. These are iterated by the same
+ // CommandLineAPIScope loop (v8-console.cc:1066) but, because they are not
+ // in the hard-coded deny-list, get a kHasNoSideEffect getter. Under the
+ // threat model documented at v8-console.cc:1035-1037, that lets a page
+ // stash the function reference during eager-eval. In Blink the stashed
+ // monitorEvents() then attaches a page-context listener to a same-process
+ // cross-origin Window without a BindingSecurity check.
+ await probe('monitorEvents');
+ await probe('unmonitorEvents');
+
+ // Show the function value is actually delivered (not just "no exception").
+ await probe('typeof monitorEvents');
+
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/import-defer-module-namespace-expected.txt b/deps/v8/test/inspector/runtime/import-defer-module-namespace-expected.txt
new file mode 100644
index 00000000000..5ace09a43d0
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/import-defer-module-namespace-expected.txt
@@ -0,0 +1,361 @@
+Checks that the inspector describes a deferred module namespace without evaluating the module. Until the module runs, the namespace reports no properties at all -- reading an export, or even establishing its enumerability, would evaluate the module -- and [[ModuleStatus]] describes it instead.
+globalThis.deferredEvaluated before inspecting: undefined
+
+RemoteObject with preview for the deferred namespace:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : linked
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
+globalThis.deferredEvaluated after building the preview: undefined
+
+The same description through Runtime.awaitPromise:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : linked
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
+globalThis.deferredEvaluated after Runtime.awaitPromise: undefined
+
+The same description through Runtime.runScript:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : linked
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
+globalThis.deferredEvaluated after Runtime.runScript: undefined
+
+Runtime.getProperties on the deferred namespace:
+{
+ id : <messageId>
+ result : {
+ internalProperties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ value : {
+ type : string
+ value : linked
+ }
+ }
+ ]
+ result : [
+ ]
+ }
+}
+globalThis.deferredEvaluated after Runtime.getProperties: undefined
+
+Forcing evaluation through Object.keys:
+{
+ id : <messageId>
+ result : {
+ result : {
+ type : string
+ value : constExport,fnExport,letExport
+ }
+ }
+}
+globalThis.deferredEvaluated after forcing evaluation: true
+
+RemoteObject with preview once evaluated:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : evaluated
+ }
+ [1] : {
+ name : constExport
+ type : number
+ value : 1
+ }
+ [2] : {
+ name : fnExport
+ type : function
+ value :
+ }
+ [3] : {
+ name : letExport
+ type : number
+ value : 2
+ }
+ [4] : {
+ name : Symbol(Symbol.toStringTag)
+ type : string
+ value : Deferred Module
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
+
+Runtime.getProperties once evaluated:
+{
+ id : <messageId>
+ result : {
+ internalProperties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ value : {
+ type : string
+ value : evaluated
+ }
+ }
+ ]
+ result : [
+ [0] : {
+ configurable : false
+ enumerable : true
+ isOwn : true
+ name : constExport
+ value : {
+ description : 1
+ type : number
+ value : 1
+ }
+ writable : true
+ }
+ [1] : {
+ configurable : false
+ enumerable : true
+ isOwn : true
+ name : fnExport
+ value : {
+ className : Function
+ description : function fnExport() {}
+ objectId : <objectId>
+ type : function
+ }
+ writable : true
+ }
+ [2] : {
+ configurable : false
+ enumerable : true
+ isOwn : true
+ name : letExport
+ value : {
+ description : 2
+ type : number
+ value : 2
+ }
+ writable : true
+ }
+ [3] : {
+ configurable : false
+ enumerable : false
+ isOwn : true
+ name : Symbol(Symbol.toStringTag)
+ symbol : {
+ description : Symbol(Symbol.toStringTag)
+ objectId : <objectId>
+ type : symbol
+ }
+ value : {
+ type : string
+ value : Deferred Module
+ }
+ writable : false
+ }
+ ]
+ }
+}
+
+A deferred namespace nested in another object:
+{
+ className : Object
+ description : Object
+ objectId : <objectId>
+ preview : {
+ description : Object
+ overflow : false
+ properties : [
+ [0] : {
+ name : deferredNs
+ subtype : deferredmodule
+ type : object
+ value : Deferred Module
+ }
+ ]
+ type : object
+ }
+ type : object
+}
+
+A module with no exports:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : linked
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
+globalThis.sideEffectOnlyEvaluated after building the preview: undefined
+
+Object.keys forces evaluation with no exports to read:
+{
+ id : <messageId>
+ result : {
+ result : {
+ type : string
+ value :
+ }
+ }
+}
+globalThis.sideEffectOnlyEvaluated after forcing evaluation: true
+
+A module whose body throws:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : linked
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
+
+Forcing evaluation of the throwing module:
+{
+ id : <messageId>
+ result : {
+ exceptionDetails : {
+ columnNumber : 28
+ exception : {
+ className : Error
+ description : Error: module body threw at throwing:2:7 at Object.keys (<anonymous>) at Deferred Module.<anonymous> (<anonymous>:1:29)
+ objectId : <objectId>
+ subtype : error
+ type : object
+ }
+ exceptionId : <exceptionId>
+ lineNumber : 0
+ scriptId : <scriptId>
+ stackTrace : {
+ callFrames : [
+ [0] : {
+ columnNumber : 6
+ functionName :
+ lineNumber : 1
+ scriptId : <scriptId>
+ url : throwing
+ }
+ [1] : {
+ columnNumber : 28
+ functionName :
+ lineNumber : 0
+ scriptId : <scriptId>
+ url :
+ }
+ ]
+ }
+ text : Uncaught
+ }
+ result : {
+ className : Error
+ description : Error: module body threw at throwing:2:7 at Object.keys (<anonymous>) at Deferred Module.<anonymous> (<anonymous>:1:29)
+ objectId : <objectId>
+ subtype : error
+ type : object
+ }
+ }
+}
+
+RemoteObject with preview after the module threw:
+{
+ className : Deferred Module
+ description : Deferred Module
+ objectId : <objectId>
+ preview : {
+ description : Deferred Module
+ overflow : false
+ properties : [
+ [0] : {
+ name : [[ModuleStatus]]
+ type : string
+ value : errored
+ }
+ ]
+ subtype : deferredmodule
+ type : object
+ }
+ subtype : deferredmodule
+ type : object
+}
diff --git a/deps/v8/test/inspector/runtime/import-defer-module-namespace-subtype-expected.txt b/deps/v8/test/inspector/runtime/import-defer-module-namespace-subtype-expected.txt
new file mode 100644
index 00000000000..80c834a0984
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/import-defer-module-namespace-subtype-expected.txt
@@ -0,0 +1,28 @@
+Checks that a deferred module namespace reports the "deferredmodule" subtype, and that no other object can claim it.
+
+Runtime.evaluate on the unevaluated deferred namespace:
+deferredNs: type=object subtype=deferredmodule className=Deferred Module
+deferredNs: [[ModuleStatus]]=linked
+
+The namespace as a property value of the global object:
+deferredNs: type=object subtype=deferredmodule className=Deferred Module
+plainNs: type=object subtype=undefined className=Module
+forged: type=object subtype=undefined className=Deferred Module
+
+Nested in another object's preview:
+deferredNs: type=object subtype=deferredmodule value=Deferred Module
+
+Forcing evaluation of the deferred module:
+{
+ id : <messageId>
+ result : {
+ result : {
+ type : string
+ value : constExport
+ }
+ }
+}
+
+The subtype survives evaluation:
+deferredNs: type=object subtype=deferredmodule className=Deferred Module
+deferredNs: [[ModuleStatus]]=evaluated
diff --git a/deps/v8/test/inspector/runtime/import-defer-module-namespace-subtype.js b/deps/v8/test/inspector/runtime/import-defer-module-namespace-subtype.js
new file mode 100644
index 00000000000..6490bfd7377
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/import-defer-module-namespace-subtype.js
@@ -0,0 +1,99 @@
+// 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-defer-import-eval
+
+const {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Checks that a deferred module namespace reports the "deferredmodule" ' +
+ 'subtype, and that no other object can claim it.');
+
+contextGroup.addModuleWithoutEvaluating(
+ `
+globalThis.deferredEvaluated = true;
+export const constExport = 1;
+`,
+ 'deferred');
+
+contextGroup.addModuleWithoutEvaluating(
+ `
+export const constExport = 1;
+`,
+ 'plain');
+
+contextGroup.addModule(
+ `
+import defer * as deferredNs from 'deferred';
+import * as plainNs from 'plain';
+globalThis.deferredNs = deferredNs;
+globalThis.plainNs = plainNs;
+globalThis.holder = {deferredNs};
+// An ordinary object dressed up as a deferred namespace: the class name and
+// the internal-looking property are both forgeable, the subtype is not.
+globalThis.forged = {
+ [Symbol.toStringTag]: 'Deferred Module',
+ '[[ModuleStatus]]': 'linked',
+};
+`,
+ 'main');
+
+async function evaluate(expression) {
+ const {result: {result}} =
+ await Protocol.Runtime.evaluate({expression, generatePreview: true});
+ return result;
+}
+
+function logSubtype(what, remoteObject) {
+ InspectorTest.log(`${what}: type=${remoteObject.type} subtype=${
+ remoteObject.subtype} className=${remoteObject.className}`);
+}
+
+async function logModuleStatus(what, objectId) {
+ const {result: {internalProperties}} =
+ await Protocol.Runtime.getProperties({objectId, ownProperties: true});
+ const status =
+ (internalProperties || []).find(p => p.name === '[[ModuleStatus]]');
+ InspectorTest.log(
+ `${what}: [[ModuleStatus]]=${status && status.value.value}`);
+}
+
+(async function test() {
+ await Protocol.Runtime.enable();
+ await InspectorTest.waitForPendingTasks();
+
+ InspectorTest.log('\nRuntime.evaluate on the unevaluated deferred namespace:');
+ const deferredNs = await evaluate('globalThis.deferredNs');
+ logSubtype('deferredNs', deferredNs);
+ await logModuleStatus('deferredNs', deferredNs.objectId);
+
+ InspectorTest.log(
+ '\nThe namespace as a property value of the global object:');
+ const {result: {result: globalProps}} = await Protocol.Runtime.evaluate(
+ {expression: 'globalThis', generatePreview: true});
+ const {result: {result: properties}} = await Protocol.Runtime.getProperties(
+ {objectId: globalProps.objectId, ownProperties: true});
+ for (const name of ['deferredNs', 'plainNs', 'forged']) {
+ logSubtype(name, properties.find(p => p.name === name).value);
+ }
+
+ InspectorTest.log('\nNested in another object\'s preview:');
+ const holder = await evaluate('globalThis.holder');
+ for (const property of holder.preview.properties) {
+ InspectorTest.log(`${property.name}: type=${property.type} subtype=${
+ property.subtype} value=${property.value}`);
+ }
+
+ InspectorTest.log('\nForcing evaluation of the deferred module:');
+ InspectorTest.logMessage(await Protocol.Runtime.callFunctionOn({
+ objectId: deferredNs.objectId,
+ functionDeclaration: 'function() { return Object.keys(this).join(","); }',
+ returnByValue: true,
+ }));
+
+ InspectorTest.log('\nThe subtype survives evaluation:');
+ const evaluatedNs = await evaluate('globalThis.deferredNs');
+ logSubtype('deferredNs', evaluatedNs);
+ await logModuleStatus('deferredNs', evaluatedNs.objectId);
+
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/import-defer-module-namespace.js b/deps/v8/test/inspector/runtime/import-defer-module-namespace.js
new file mode 100644
index 00000000000..41d9ccc7064
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/import-defer-module-namespace.js
@@ -0,0 +1,156 @@
+// 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-defer-import-eval
+
+const {session, contextGroup, Protocol} = InspectorTest.start(
+ 'Checks that the inspector describes a deferred module namespace without ' +
+ 'evaluating the module. Until the module runs, the namespace reports no ' +
+ 'properties at all -- reading an export, or even establishing its ' +
+ 'enumerability, would evaluate the module -- and [[ModuleStatus]] ' +
+ 'describes it instead.');
+
+contextGroup.addModuleWithoutEvaluating(
+ `
+globalThis.deferredEvaluated = true;
+export const constExport = 1;
+export let letExport = 2;
+export function fnExport() {}
+`,
+ 'deferred');
+
+contextGroup.addModuleWithoutEvaluating(
+ `
+throw new Error('module body threw');
+export const neverInitialized = 1;
+`,
+ 'throwing');
+
+// A side-effect-only module: it has no export whose read could force the
+// evaluation, so `Object.keys` is the only way to trigger it.
+contextGroup.addModuleWithoutEvaluating(
+ `
+globalThis.sideEffectOnlyEvaluated = true;
+`,
+ 'side-effect-only');
+
+contextGroup.addModule(
+ `
+import defer * as deferredNs from 'deferred';
+import defer * as throwingNs from 'throwing';
+import defer * as sideEffectOnlyNs from 'side-effect-only';
+globalThis.deferredNs = deferredNs;
+globalThis.throwingNs = throwingNs;
+globalThis.sideEffectOnlyNs = sideEffectOnlyNs;
+globalThis.holder = {deferredNs};
+`,
+ 'main');
+
+async function evaluateToString(expression) {
+ const {result: {result}} =
+ await Protocol.Runtime.evaluate({expression: `String(${expression})`});
+ return result.value;
+}
+
+async function logDeferredEvaluated(when) {
+ InspectorTest.log(
+ `globalThis.deferredEvaluated ${when}: ` +
+ await evaluateToString('globalThis.deferredEvaluated'));
+}
+
+async function namespaceWithPreview(expression) {
+ const {result: {result}} =
+ await Protocol.Runtime.evaluate({expression, generatePreview: true});
+ return result;
+}
+
+(async function test() {
+ await Protocol.Runtime.enable();
+ await InspectorTest.waitForPendingTasks();
+
+ await logDeferredEvaluated('before inspecting');
+
+ InspectorTest.log('\nRemoteObject with preview for the deferred namespace:');
+ const ns = await namespaceWithPreview('globalThis.deferredNs');
+ InspectorTest.logMessage(ns);
+ await logDeferredEvaluated('after building the preview');
+
+ // Every command that wraps a value with a preview must describe the
+ // namespace the same way, whether it is the value of an expression, the
+ // result a promise settles with, or the completion value of a script.
+ InspectorTest.log('\nThe same description through Runtime.awaitPromise:');
+ const {result: {result: promise}} = await Protocol.Runtime.evaluate(
+ {expression: 'Promise.resolve(globalThis.deferredNs)'});
+ const {result: {result: awaited}} = await Protocol.Runtime.awaitPromise(
+ {promiseObjectId: promise.objectId, generatePreview: true});
+ InspectorTest.logMessage(awaited);
+ await logDeferredEvaluated('after Runtime.awaitPromise');
+
+ InspectorTest.log('\nThe same description through Runtime.runScript:');
+ const {result: {scriptId}} = await Protocol.Runtime.compileScript({
+ expression: 'globalThis.deferredNs',
+ sourceURL: 'namespace.js',
+ persistScript: true,
+ });
+ const {result: {result: scriptResult}} =
+ await Protocol.Runtime.runScript({scriptId, generatePreview: true});
+ InspectorTest.logMessage(scriptResult);
+ await logDeferredEvaluated('after Runtime.runScript');
+
+ InspectorTest.log('\nRuntime.getProperties on the deferred namespace:');
+ InspectorTest.logMessage(await Protocol.Runtime.getProperties(
+ {objectId: ns.objectId, ownProperties: true, generatePreview: true}));
+ await logDeferredEvaluated('after Runtime.getProperties');
+
+ InspectorTest.log('\nForcing evaluation through Object.keys:');
+ InspectorTest.logMessage(await Protocol.Runtime.callFunctionOn({
+ objectId: ns.objectId,
+ functionDeclaration: 'function() { return Object.keys(this).join(","); }',
+ returnByValue: true,
+ }));
+ await logDeferredEvaluated('after forcing evaluation');
+
+ InspectorTest.log('\nRemoteObject with preview once evaluated:');
+ InspectorTest.logMessage(await namespaceWithPreview('globalThis.deferredNs'));
+
+ InspectorTest.log('\nRuntime.getProperties once evaluated:');
+ InspectorTest.logMessage(await Protocol.Runtime.getProperties(
+ {objectId: ns.objectId, ownProperties: true, generatePreview: true}));
+
+ InspectorTest.log('\nA deferred namespace nested in another object:');
+ InspectorTest.logMessage(await namespaceWithPreview('globalThis.holder'));
+
+ InspectorTest.log('\nA module with no exports:');
+ const sideEffectOnlyNs =
+ await namespaceWithPreview('globalThis.sideEffectOnlyNs');
+ InspectorTest.logMessage(sideEffectOnlyNs);
+ InspectorTest.log(
+ 'globalThis.sideEffectOnlyEvaluated after building the preview: ' +
+ await evaluateToString('globalThis.sideEffectOnlyEvaluated'));
+
+ InspectorTest.log('\nObject.keys forces evaluation with no exports to read:');
+ InspectorTest.logMessage(await Protocol.Runtime.callFunctionOn({
+ objectId: sideEffectOnlyNs.objectId,
+ functionDeclaration: 'function() { return Object.keys(this).join(","); }',
+ returnByValue: true,
+ }));
+ InspectorTest.log(
+ 'globalThis.sideEffectOnlyEvaluated after forcing evaluation: ' +
+ await evaluateToString('globalThis.sideEffectOnlyEvaluated'));
+
+ InspectorTest.log('\nA module whose body throws:');
+ const throwingNs = await namespaceWithPreview('globalThis.throwingNs');
+ InspectorTest.logMessage(throwingNs);
+ InspectorTest.log('\nForcing evaluation of the throwing module:');
+ InspectorTest.logMessage(await Protocol.Runtime.callFunctionOn({
+ objectId: throwingNs.objectId,
+ functionDeclaration: 'function() { return Object.keys(this).join(","); }',
+ returnByValue: true,
+ }));
+ InspectorTest.log('\nRemoteObject with preview after the module threw:');
+ InspectorTest.logMessage(
+ await namespaceWithPreview('globalThis.throwingNs'));
+
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/preview-sideeffects-expected.txt b/deps/v8/test/inspector/runtime/preview-sideeffects-expected.txt
index 0955d166877..2e31946380e 100644
--- a/deps/v8/test/inspector/runtime/preview-sideeffects-expected.txt
+++ b/deps/v8/test/inspector/runtime/preview-sideeffects-expected.txt
@@ -10,3 +10,8 @@ Running test: ObjectGetterBoundBuiltin
callBindCalled : false
reflectApplyCalled : false
}
+
+Running test: ObjectGetterCallableProxy
+{
+ proxyCalled : false
+}
diff --git a/deps/v8/test/inspector/runtime/preview-sideeffects.js b/deps/v8/test/inspector/runtime/preview-sideeffects.js
index 509c24e41bb..d1a08c0c9df 100644
--- a/deps/v8/test/inspector/runtime/preview-sideeffects.js
+++ b/deps/v8/test/inspector/runtime/preview-sideeffects.js
@@ -45,6 +45,24 @@ function testLogObjectBoundBuiltin() {
return {callBindCalled, reflectApplyCalled};
}
+function testLogObjectProxy() {
+ let proxyCalled = false;
+ const obj = {};
+ Object.defineProperty(obj, 'a', {
+ get: new Proxy(function() {}, {
+ apply: () => {
+ proxyCalled = true;
+ return 'value';
+ },
+ }),
+ });
+
+ console.log(obj);
+ console.clear();
+
+ return {proxyCalled};
+}
+
//# sourceURL=test.js
`);
@@ -60,5 +78,12 @@ InspectorTest.runAsyncTestSuite([
const result = await Protocol.Runtime.evaluate({expression: 'testLogObjectBoundBuiltin()', returnByValue: true});
InspectorTest.logObject(result.result.result.value);
await Protocol.Runtime.disable();
+ },
+ async function ObjectGetterCallableProxy() {
+ await Protocol.Runtime.enable();
+ const result = await Protocol.Runtime.evaluate(
+ {expression: 'testLogObjectProxy()', returnByValue: true});
+ InspectorTest.logObject(result.result.result.value);
+ await Protocol.Runtime.disable();
}
]);
diff --git a/deps/v8/test/inspector/runtime/regress-520052954-2-expected.txt b/deps/v8/test/inspector/runtime/regress-520052954-2-expected.txt
new file mode 100644
index 00000000000..92f96bbcb79
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-520052954-2-expected.txt
@@ -0,0 +1,4 @@
+Test session disconnect during console inspect.
+[controller] paused -> stock utils.disconnectSession(victim)
+[controller] victim freed; resuming nested loop
+Reached post-wait.
diff --git a/deps/v8/test/inspector/runtime/regress-520052954-2.js b/deps/v8/test/inspector/runtime/regress-520052954-2.js
new file mode 100644
index 00000000000..e3bdcdd841c
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-520052954-2.js
@@ -0,0 +1,63 @@
+// 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.
+
+InspectorTest.log('Test session disconnect during console inspect.');
+
+const contextGroup = new InspectorTest.ContextGroup();
+const victim = contextGroup.connect();
+const VP = victim.Protocol;
+
+const controller = contextGroup.connect();
+const CP = controller.Protocol;
+
+let freed = false;
+
+(async function test() {
+ await VP.Runtime.enable();
+ await VP.Debugger.enable();
+
+ await CP.Runtime.enable();
+ await CP.Debugger.enable();
+
+ const victimId = victim.id;
+
+ CP.Debugger.onPaused(async () => {
+ if (freed) { await CP.Debugger.resume(); return; }
+ freed = true;
+ InspectorTest.log('[controller] paused -> stock utils.disconnectSession(victim)');
+ utils.disconnectSession(victimId);
+ InspectorTest.log('[controller] victim freed; resuming nested loop');
+ await CP.Debugger.resume();
+ });
+
+ await VP.Runtime.evaluate({
+ expression: 'globalThis.savedInspect = inspect;',
+ includeCommandLineAPI: true,
+ });
+
+ await VP.Runtime.evaluate({
+ expression: `
+ let e = new Error();
+ delete e.name;
+ Object.defineProperty(Object.getPrototypeOf(e), 'name', {
+ get() {
+ debugger;
+ return '';
+ }
+ });
+ setTimeout(function() {
+ savedInspect(e);
+ }, 0);
+ `,
+ });
+
+ await CP.Runtime.evaluate({
+ expression: 'new Promise(r => setTimeout(r, 0))',
+ awaitPromise: true,
+ });
+
+ InspectorTest.log('Reached post-wait.');
+ InspectorTest._sessions.delete(victim);
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/regress-520052954-3-expected.txt b/deps/v8/test/inspector/runtime/regress-520052954-3-expected.txt
new file mode 100644
index 00000000000..2ab1ea465cb
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-520052954-3-expected.txt
@@ -0,0 +1,4 @@
+Test session disconnect during custom preview wrapping.
+[controller] paused -> stock utils.disconnectSession(victim)
+[controller] victim freed; resuming nested loop
+Reached post-wait.
diff --git a/deps/v8/test/inspector/runtime/regress-520052954-3.js b/deps/v8/test/inspector/runtime/regress-520052954-3.js
new file mode 100644
index 00000000000..c7f73f6bbac
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-520052954-3.js
@@ -0,0 +1,59 @@
+// 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.
+
+InspectorTest.log('Test session disconnect during custom preview wrapping.');
+
+const contextGroup = new InspectorTest.ContextGroup();
+const victim = contextGroup.connect();
+const VP = victim.Protocol;
+
+const controller = contextGroup.connect();
+const CP = controller.Protocol;
+
+let freed = false;
+
+(async function test() {
+ await VP.Runtime.enable();
+ await VP.Debugger.enable();
+ await VP.Runtime.setCustomObjectFormatterEnabled({enabled: true});
+
+ await CP.Runtime.enable();
+ await CP.Debugger.enable();
+
+ const victimId = victim.id;
+
+ CP.Debugger.onPaused(async () => {
+ if (freed) { await CP.Debugger.resume(); return; }
+ freed = true;
+ InspectorTest.log('[controller] paused -> stock utils.disconnectSession(victim)');
+ utils.disconnectSession(victimId);
+ InspectorTest.log('[controller] victim freed; resuming nested loop');
+ await CP.Debugger.resume();
+ });
+
+ await VP.Runtime.evaluate({
+ expression: `
+ globalThis.devtoolsFormatters = [{
+ header: function(obj, config) {
+ console.error("Inside formatter");
+ debugger;
+ return null;
+ },
+ hasBody: function() { return false; },
+ }];
+ setTimeout(function() {
+ console.log({a: 1});
+ }, 0);
+ `,
+ });
+
+ await CP.Runtime.evaluate({
+ expression: 'new Promise(r => setTimeout(r, 0))',
+ awaitPromise: true,
+ });
+
+ InspectorTest.log('Reached post-wait.');
+ InspectorTest._sessions.delete(victim);
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/regress-523442920-expected.txt b/deps/v8/test/inspector/runtime/regress-523442920-expected.txt
new file mode 100644
index 00000000000..ac306d27afb
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-523442920-expected.txt
@@ -0,0 +1,2 @@
+Tests that destroying context during inspect does not cause UAF (regress-523442920).
+Success (no crash).
diff --git a/deps/v8/test/inspector/runtime/regress-523442920.js b/deps/v8/test/inspector/runtime/regress-523442920.js
new file mode 100644
index 00000000000..d3442cde81a
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-523442920.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.
+
+let {session, contextGroup, Protocol} =
+ InspectorTest.start('Tests that destroying context during inspect does not cause UAF (regress-523442920).');
+
+(async function test() {
+ await Protocol.Runtime.enable();
+
+ // Capture CommandLineAPI inspect function.
+ await Protocol.Runtime.evaluate({
+ expression: 'globalThis.savedInspect = inspect;',
+ includeCommandLineAPI: true,
+ });
+
+ // Call savedInspect from page-level execution where no ContextScope is active.
+ contextGroup.addScript(`
+ let e = new Error();
+ delete e.name;
+ Object.defineProperty(Object.getPrototypeOf(e), 'name', {
+ get() {
+ inspector.fireContextDestroyed();
+ return '';
+ }
+ });
+ savedInspect(e);
+ `);
+
+ InspectorTest.log('Success (no crash).');
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/runtime/regress-custom-preview-uaf-expected.txt b/deps/v8/test/inspector/runtime/regress-custom-preview-uaf-expected.txt
new file mode 100644
index 00000000000..15f253ad16e
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-custom-preview-uaf-expected.txt
@@ -0,0 +1 @@
+Tests that destroying context during custom preview wrapping does not cause UAF.
diff --git a/deps/v8/test/inspector/runtime/regress-custom-preview-uaf.js b/deps/v8/test/inspector/runtime/regress-custom-preview-uaf.js
new file mode 100644
index 00000000000..6fe5f7c8bd9
--- /dev/null
+++ b/deps/v8/test/inspector/runtime/regress-custom-preview-uaf.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.
+
+let {session, contextGroup, Protocol} =
+ InspectorTest.start('Tests that destroying context during custom preview wrapping does not cause UAF.');
+
+(async function test() {
+ await Protocol.Runtime.enable();
+ await Protocol.Runtime.evaluate({
+ expression: `
+ globalThis.devtoolsFormatters = [{
+ header: function(obj) {
+ return ['div', {}, 'header'];
+ },
+ hasBody: function(obj) {
+ inspector.fireContextDestroyed();
+ return true;
+ },
+ body: function(obj) {
+ return ['div', {}, 'body'];
+ }
+ }];
+ `
+ });
+
+ await Protocol.Runtime.evaluate({
+ expression: '({a: 1})',
+ generatePreview: true
+ });
+
+ InspectorTest.completeTest();
+})();
diff --git a/deps/v8/test/inspector/tasks.cc b/deps/v8/test/inspector/tasks.cc
index cf3a262791f..fe891ddd6f0 100644
--- a/deps/v8/test/inspector/tasks.cc
+++ b/deps/v8/test/inspector/tasks.cc
@@ -128,7 +128,7 @@ void ExecuteStringTask::Run(InspectorIsolateData* data) {
v8::MaybeLocal<v8::Value> result;
result = script->Run(context);
} else {
- data->RegisterModule(context, name_, &scriptSource);
+ data->RegisterModule(context, name_, &scriptSource, evaluate_);
}
}
diff --git a/deps/v8/test/inspector/tasks.h b/deps/v8/test/inspector/tasks.h
index 600f7ccc5a3..1887aaca0ec 100644
--- a/deps/v8/test/inspector/tasks.h
+++ b/deps/v8/test/inspector/tasks.h
@@ -74,12 +74,13 @@ class ExecuteStringTask : public TaskRunner::Task {
v8::Local<v8::String> name,
v8::Local<v8::Integer> line_offset,
v8::Local<v8::Integer> column_offset,
- v8::Local<v8::Boolean> is_module)
+ v8::Local<v8::Boolean> is_module, bool evaluate = true)
: expression_(expression),
name_(ToVector(isolate, name)),
line_offset_(line_offset.As<v8::Int32>()->Value()),
column_offset_(column_offset.As<v8::Int32>()->Value()),
is_module_(is_module->Value()),
+ evaluate_(evaluate),
context_group_id_(context_group_id) {}
ExecuteStringTask(const std::string& expression, int context_group_id)
@@ -98,6 +99,7 @@ class ExecuteStringTask : public TaskRunner::Task {
int32_t line_offset_ = 0;
int32_t column_offset_ = 0;
bool is_module_ = false;
+ bool evaluate_ = true;
int context_group_id_;
};
diff --git a/deps/v8/test/intl/date-format/temporal-cjk-format.js b/deps/v8/test/intl/date-format/temporal-cjk-format.js
new file mode 100644
index 00000000000..14dd6f4a2cc
--- /dev/null
+++ b/deps/v8/test/intl/date-format/temporal-cjk-format.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.
+
+const kOptions = {
+ year: "numeric",
+ month: "long",
+ day: "numeric",
+ timeZone: "UTC"
+};
+const kDate = new Date(Date.UTC(2026, 7, 27, 12, 0, 0));
+const kInstant = Temporal.Instant.from("2026-08-27T12:00:00Z");
+const kPlainDate = Temporal.PlainDate.from("2026-08-27");
+
+function assertTemporalMatchesDate(locale, options) {
+ const formatter = new Intl.DateTimeFormat(locale, options);
+ const expected = formatter.format(kDate);
+ assertEquals(expected, formatter.format(kInstant));
+ assertEquals(expected, formatter.format(kPlainDate));
+}
+
+assertTemporalMatchesDate("ja-JP", kOptions);
+assertTemporalMatchesDate("zh-CN", kOptions);
+assertTemporalMatchesDate("zh-TW", kOptions);
+assertTemporalMatchesDate("ko-KR", kOptions);
+assertTemporalMatchesDate("en-US", kOptions);
+
+assertTemporalMatchesDate("ja-JP", {dateStyle: "long", timeZone: "UTC"});
+assertTemporalMatchesDate("zh-CN", {dateStyle: "long", timeZone: "UTC"});
+assertTemporalMatchesDate("ja-JP", {dateStyle: "full", timeZone: "UTC"});
diff --git a/deps/v8/test/intl/date-format/year-woy-field.js b/deps/v8/test/intl/date-format/year-woy-field.js
new file mode 100644
index 00000000000..92e9a1b97c7
--- /dev/null
+++ b/deps/v8/test/intl/date-format/year-woy-field.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.
+
+// Test DateTimeFormat with locale patterns using Week-of-Year Year ('Y')
+// such as Telugu with Buddhist calendar ("te-u-ca-buddhist").
+
+let dtf = new Intl.DateTimeFormat("te-u-ca-buddhist", {
+ year: "numeric",
+ month: "long"
+});
+
+// 1. Verify resolvedOptions includes 'year' property.
+let options = dtf.resolvedOptions();
+assertEquals("numeric", options.year);
+assertEquals("long", options.month);
+assertEquals("buddhist", options.calendar);
+
+// 2. Verify formatToParts does not crash and returns the year part.
+let parts = dtf.formatToParts(new Date(2026, 7, 31));
+assertTrue(parts.some(part => part.type === "year"));
+assertTrue(parts.some(part => part.type === "month"));
+
+// 3. Verify formatRangeToParts does not crash and includes the year part.
+let rangeParts = dtf.formatRangeToParts(new Date(2020, 0, 1), new Date(2021, 0, 1));
+assertTrue(rangeParts.some(part => part.type === "year"));
diff --git a/deps/v8/test/intl/intl.status b/deps/v8/test/intl/intl.status
index 8fee80a5594..68d825812f7 100644
--- a/deps/v8/test/intl/intl.status
+++ b/deps/v8/test/intl/intl.status
@@ -110,4 +110,9 @@
'collator/default-locale': [FAIL],
}], # msan
+['variant == google3', {
+ # Needs temporal:
+ 'date-format/temporal-cjk-format': [SKIP],
+}], # variant == google3
+
]
diff --git a/deps/v8/test/message/fail/d8-trace-config-invalid.bad-json b/deps/v8/test/message/fail/d8-trace-config-invalid.bad-json
new file mode 100644
index 00000000000..e41fb3fb812
--- /dev/null
+++ b/deps/v8/test/message/fail/d8-trace-config-invalid.bad-json
@@ -0,0 +1 @@
+{ invalid_json
diff --git a/deps/v8/test/message/fail/d8-trace-config-invalid.js b/deps/v8/test/message/fail/d8-trace-config-invalid.js
new file mode 100644
index 00000000000..9f3b93bb0a8
--- /dev/null
+++ b/deps/v8/test/message/fail/d8-trace-config-invalid.js
@@ -0,0 +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: --enable-tracing
+// Flags: --trace-config=test/message/fail/d8-trace-config-invalid.bad-json
+// Resources: test/message/fail/d8-trace-config-invalid.bad-json
diff --git a/deps/v8/test/message/fail/d8-trace-config-invalid.out b/deps/v8/test/message/fail/d8-trace-config-invalid.out
new file mode 100644
index 00000000000..774c914bcd0
--- /dev/null
+++ b/deps/v8/test/message/fail/d8-trace-config-invalid.out
@@ -0,0 +1,6 @@
+Failed to parse trace config.
+
+undefined:1: SyntaxError: Expected property name or '}' in JSON at position 2 (line 1 column 3)
+{ invalid_json
+ ^
+SyntaxError: Expected property name or '}' in JSON at position 2 (line 1 column 3)
diff --git a/deps/v8/test/message/fail/d8-trace-config-missing.js b/deps/v8/test/message/fail/d8-trace-config-missing.js
new file mode 100644
index 00000000000..394649952b2
--- /dev/null
+++ b/deps/v8/test/message/fail/d8-trace-config-missing.js
@@ -0,0 +1,5 @@
+// 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: --enable-tracing --trace-config=test/message/fail/non_existent_file.json
diff --git a/deps/v8/test/message/fail/d8-trace-config-missing.out b/deps/v8/test/message/fail/d8-trace-config-missing.out
new file mode 100644
index 00000000000..221efab51f6
--- /dev/null
+++ b/deps/v8/test/message/fail/d8-trace-config-missing.out
@@ -0,0 +1 @@
+Failed to read trace config from 'test/message/fail/non_existent_file.json'
diff --git a/deps/v8/test/message/fail/modules-import-redeclare4.mjs b/deps/v8/test/message/fail/modules-import-redeclare4.mjs
new file mode 100644
index 00000000000..70b89498d5a
--- /dev/null
+++ b/deps/v8/test/message/fail/modules-import-redeclare4.mjs
@@ -0,0 +1,6 @@
+// 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.
+
+import * as foo from "modules-import-redeclare1.mjs";
+import * as foo from "modules-import-redeclare1.mjs";
diff --git a/deps/v8/test/message/fail/modules-import-redeclare4.out b/deps/v8/test/message/fail/modules-import-redeclare4.out
new file mode 100644
index 00000000000..f0e69d778a8
--- /dev/null
+++ b/deps/v8/test/message/fail/modules-import-redeclare4.out
@@ -0,0 +1,5 @@
+*%(basename)s:6: SyntaxError: Identifier 'foo' has already been declared
+import * as foo from "modules-import-redeclare1.mjs";
+^^^^^^^^^^^^^^^
+SyntaxError: Identifier 'foo' has already been declared
+
diff --git a/deps/v8/test/message/message.status b/deps/v8/test/message/message.status
index 190896f16d5..2b5d7e52ef4 100644
--- a/deps/v8/test/message/message.status
+++ b/deps/v8/test/message/message.status
@@ -40,6 +40,14 @@
'fail/map-grow-failed': [PASS, HEAVY],
'fail/set-grow-failed': [PASS, HEAVY],
'wasm-trace-memory64*': [PASS, HEAVY],
+
+ ##############################################################################
+ # Behavioural differences between Maglev and Turbofan when the former is used
+ # for OptimizeFunctionOnNextCall or as a frontend for Turboshaft.
+ #
+ # Maglev doesn't support inlining of Wasm code.
+ 'wasm-inlining-into-js': [SKIP],
+
}], # ALWAYS
# Skip Liftoff tests on platforms that don't support Liftoff.
@@ -147,14 +155,6 @@
'wasm-trace-memory64-liftoff': [SKIP],
}], # 'arch in (ia32, arm, riscv32)'
-##############################################################################
-# Behavioural differences between Maglev and Turbofan when the former is used
-# for OptimizeFunctionOnNextCall or as a frontend for Turboshaft.
-['variant in (stress_maglev, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future)', {
- # Maglev doesn't support inlining of Wasm code.
- 'wasm-inlining-into-js': [FAIL],
-}], # variant in (stress_maglev, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev_future, stress_turbolev_future)
-
##############################################################################
# The output for Turbolev wrapper inlining tests can be different with these
# variants.
diff --git a/deps/v8/test/message/wasm-trace-deopt-32.out b/deps/v8/test/message/wasm-trace-deopt-32.out
index 7889a15da7c..d31cb730978 100644
--- a/deps/v8/test/message/wasm-trace-deopt-32.out
+++ b/deps/v8/test/message/wasm-trace-deopt-32.out
@@ -9,7 +9,7 @@
6: (wasm float literal 3.200000)
7: (wasm double literal 6.400000)
8: 28 51 00 00 00 00 00 00 28 51 00 00 00 00 00 00 ; * (Simd128)
- 9: {ADDRESS} ; * {ADDRESS} <Other heap object (WASM_NULL_TYPE)>
+ 9: {ADDRESS} ; * {ADDRESS} WasmNull
10: 2 ; *(int32)*
11: 3 ; *(int32)*
12: {ADDRESS} ; * {ADDRESS} <Other heap object (WASM_FUNC_REF_TYPE)>
diff --git a/deps/v8/test/message/wasm-trace-deopt-64.out b/deps/v8/test/message/wasm-trace-deopt-64.out
index 28e677a4c4e..11cd22d20d8 100644
--- a/deps/v8/test/message/wasm-trace-deopt-64.out
+++ b/deps/v8/test/message/wasm-trace-deopt-64.out
@@ -8,7 +8,7 @@
5: (wasm float literal 3.200000)
6: (wasm double literal 6.400000)
7: 28 51 00 00 00 00 00 00 28 51 00 00 00 00 00 00 ; * (Simd128)
- 8: {ADDRESS} ; * {ADDRESS} <Other heap object (WASM_NULL_TYPE)>
+ 8: {ADDRESS} ; * {ADDRESS} WasmNull
9: 2 ; * (int32)
10: 3 ; * (int32)
11: {ADDRESS} ; * {ADDRESS} <Other heap object (WASM_FUNC_REF_TYPE)>
diff --git a/deps/v8/test/mjsunit/additive-safe-int-feedback.js b/deps/v8/test/mjsunit/additive-safe-int-feedback.js
index d5cad84317c..3eb261750b6 100644
--- a/deps/v8/test/mjsunit/additive-safe-int-feedback.js
+++ b/deps/v8/test/mjsunit/additive-safe-int-feedback.js
@@ -3,329 +3,89 @@
// found in the LICENSE file.
// Flags: --allow-natives-syntax --additive-safe-int-feedback
-// Flags: --turbofan
+// Flags: --turbolev --turbolev-additive-safe-int-feedback
-const maxAdditiveSafeInteger = 2251799813685247; // 2^52 - 1
-const minAdditiveSafeInteger = - 2251799813685248; // - 2^51
+const maxAdditiveSafeInteger = 1125899906842623; // 2^50 - 1
+const minAdditiveSafeInteger = - 1125899906842624; // - 2^50
-// If one of the inputs is a constant in the additive safe range,
-// we can use AdditiveSafeInteger.
-(function() {
- function foo(a) {
- return a + 1;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertEquals(1231234567891, foo(1231234567890));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertOptimized(foo);
-
- // We don't deopt in the maximum value.
- assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 1));
- assertOptimized(foo);
- // Nor in the minimum.
- assertEquals(minAdditiveSafeInteger + 1, foo(minAdditiveSafeInteger));
- assertOptimized(foo);
-
- // We deopt if we overflow!
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertOptimized(foo);
-
- // This time we don't overflow, since we use
- // Float64Add.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(2.5, foo(1.5));
- assertOptimized(foo);
-})();
+// Turbolev only emits a speculative additive-safe-integer add when the result
+// is truncated to word32 (the final `| 0` case); non-truncated adds use
+// Float64. That is slightly weaker than the TurboFan lowering was, so the
+// non-truncated cases below only check value correctness.
-// Deopt if input is a double.
+// a + <constant>.
(function() {
- function foo(a) {
- return a + 1;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertEquals(1231234567891, foo(1231234567890));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertOptimized(foo);
-
- // Deopt if input is a double.
- assertEquals(2.5, foo(1.5));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertOptimized(foo);
-
- // Don't deopt with doubles anymore.
- assertEquals(2.5, foo(1.5));
- assertOptimized(foo);
+ function foo(a) { return a + 1; }
+ %PrepareFunctionForOptimization(foo);
+ foo(1231234567890);
+ foo(1231234567890);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1231234567891, foo(1231234567890));
+ assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 1));
+ assertEquals(minAdditiveSafeInteger + 1, foo(minAdditiveSafeInteger));
+ assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger)); // Overflow.
+ assertEquals(2.5, foo(1.5)); // Double.
+ assertEquals(1, foo(-0)); // Minus zero.
})();
-// If we don't know statically that one of the inputs is
-// in the additive safe range, we fallback to float64 add.
+// a + b, neither operand statically in the safe range.
(function() {
- function foo(a, b) {
- return a + b;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567891, foo(1231234567890, 1));
- assertEquals(1231234567891, foo(1231234567890, 1));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // We don't deopt in overflow because neither input is statically known
- // to be in the AdditiveSafeInteger range, so we fell back to Float64.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(2.5, foo(1.5, 1));
- assertOptimized(foo);
+ function foo(a, b) { return a + b; }
+ %PrepareFunctionForOptimization(foo);
+ foo(1231234567890, 1);
+ foo(1231234567890, 1);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1231234567891, foo(1231234567890, 1));
+ assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
+ assertEquals(2.5, foo(1.5, 1));
})();
-// We deopt in minus zero.
+// a + (b | 0), truncated operand.
(function() {
- function foo(a) {
- return a + 1;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertEquals(1231234567891, foo(1231234567890));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertOptimized(foo);
-
- // TODO(victorgomes): If we know one of the inputs is
- // definitely not minus zero, we could avoid deopting here.
- assertEquals(1, foo(-0));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(2.5, foo(1.5));
- assertOptimized(foo);
+ function foo(a, b) { return a + (b | 0); }
+ %PrepareFunctionForOptimization(foo);
+ foo(1231234567890, 1);
+ foo(1231234567890, 1);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1231234567891, foo(1231234567890, 1));
+ assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
+ assertEquals(2.5, foo(1.5, 1));
})();
-// Optimize to AdditiveSafeInteger if one of the inputs is truncated, since it is
-// in the safe integer range.
+// Chained adds.
(function() {
- function foo(a, b) {
- return a + (b | 0);
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567891, foo(1231234567890, 1));
- assertEquals(1231234567891, foo(1231234567890, 1));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // We don't deopt in the maximum value.
- assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 1, 1));
- assertOptimized(foo);
- // Nor in the minimum.
- assertEquals(minAdditiveSafeInteger + 1, foo(minAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // We deopt if we overflow!
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // This time we don't overflow, since we use
- // Float64Add.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(2.5, foo(1.5, 1));
- assertOptimized(foo);
+ function foo(a, b) { return 1 + a + b; }
+ %PrepareFunctionForOptimization(foo);
+ foo(1231234567890, 1);
+ foo(1231234567890, 1);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1231234567892, foo(1231234567890, 1));
+ assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
+ assertEquals(3.5, foo(1.5, 1));
})();
-// We do not optimize when the result is pass to another add. We would need
-// to propagate the type of the optimized add, which we don't do anymore.
(function() {
- function foo(a, b) {
- return 1 + a + b;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertEquals(1231234567892, foo(1231234567890, 1));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // We don't deopt in the maximum value.
- assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 2, 1));
- assertOptimized(foo);
- // Nor in the minimum.
- assertEquals(minAdditiveSafeInteger + 2, foo(minAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Nor when we overflow the second add.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
- assertOptimized(foo);
-
- // But we can still deopt the first add.
- assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // This time no deopts.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
- assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(3.5, foo(1.5, 1));
- assertOptimized(foo);
-})();
-
-// Same as above. Don't optimize the second add.
-(function() {
- function foo(a, b) {
- return a + 1 + b;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertEquals(1231234567892, foo(1231234567890, 1));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // We don't deopt in the maximum value.
- assertEquals(maxAdditiveSafeInteger, foo(maxAdditiveSafeInteger - 2, 1));
- assertOptimized(foo);
- // Nor in the minimum.
- assertEquals(minAdditiveSafeInteger + 2, foo(minAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Nor when we overflow the second add.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
- assertOptimized(foo);
-
- // But we can still deopt the first add.
- assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // This time no deopts.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
- assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(3.5, foo(1.5, 1));
- assertOptimized(foo);
-})();
-
-// Since add is not an associative operation in JS, unfortunately, we don't
-// optimize the first add.
-(function() {
- function foo(a, b) {
- return a + b + 1;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertEquals(1231234567892, foo(1231234567890, 1));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // Overflow the second add to ensure that we optimize with additive safe int add.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567892, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // This time we don't overflow, since we use Float64Add.
- assertEquals(maxAdditiveSafeInteger + 1, foo(maxAdditiveSafeInteger - 1, 1));
- assertOptimized(foo);
-
- // And we cannot deopt by overflowing the first one, which has fallen
- // back to Float64 since neither side is statically known to be in the
- // AdditiveSafeInteger range.
- assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
- assertOptimized(foo);
-
- // Don't deopt with doubles.
- assertEquals(3.5, foo(1.5, 1));
- assertOptimized(foo);
+ function foo(a, b) { return a + b + 1; }
+ %PrepareFunctionForOptimization(foo);
+ foo(1231234567890, 1);
+ foo(1231234567890, 1);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1231234567892, foo(1231234567890, 1));
+ assertEquals(maxAdditiveSafeInteger + 2, foo(maxAdditiveSafeInteger, 1));
+ assertEquals(3.5, foo(1.5, 1));
})();
-// Don't need to deopt in overflow if we are truncating the result.
+// (a + <constant>) | 0: the truncated result *is* lowered to a speculative
+// additive-safe-integer (Int32) add. Overflow wraps mod 2^32.
(function() {
- function foo(a) {
- return a + 1 | 0;
- }
-
- %PrepareFunctionForOptimization(foo);
- assertEquals(1231234567891 | 0, foo(1231234567890, 1));
- assertEquals(1231234567891 | 0, foo(1231234567890, 1));
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891 | 0, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // We don't deopt in the maximum value.
- assertEquals(maxAdditiveSafeInteger | 0, foo(maxAdditiveSafeInteger - 1));
- assertOptimized(foo);
- // Nor in the minimum.
- assertEquals(minAdditiveSafeInteger + 1 | 0, foo(minAdditiveSafeInteger));
- assertOptimized(foo);
-
- // We don't deopt in overflow!
- assertEquals(maxAdditiveSafeInteger + 1 | 0, foo(maxAdditiveSafeInteger));
- assertOptimized(foo);
-
- // Deopt with doubles.
- assertEquals(2, foo(1.5));
- assertUnoptimized(foo);
-
- // Optimize again.
- %OptimizeFunctionOnNextCall(foo);
- assertEquals(1231234567891 | 0, foo(1231234567890, 1));
- assertOptimized(foo);
-
- // Don't deopt with doubles anymore.
- assertEquals(2, foo(1.5, 1));
- assertOptimized(foo);
+ function foo(a) { return a + 1 | 0; }
+ %PrepareFunctionForOptimization(foo);
+ foo(1231234567890);
+ foo(1231234567890);
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(1231234567891 | 0, foo(1231234567890));
+ assertEquals(maxAdditiveSafeInteger | 0, foo(maxAdditiveSafeInteger - 1));
+ assertEquals(minAdditiveSafeInteger + 1 | 0, foo(minAdditiveSafeInteger));
+ assertEquals(maxAdditiveSafeInteger + 1 | 0, foo(maxAdditiveSafeInteger)); // Overflow.
+ assertEquals(2, foo(1.5)); // Double.
})();
diff --git a/deps/v8/test/mjsunit/array-indexof-dictionary-elements.js b/deps/v8/test/mjsunit/array-indexof-dictionary-elements.js
new file mode 100644
index 00000000000..332a2367dea
--- /dev/null
+++ b/deps/v8/test/mjsunit/array-indexof-dictionary-elements.js
@@ -0,0 +1,84 @@
+// 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
+
+// Array.prototype.indexOf on dictionary-elements receivers takes a fast path
+// that iterates the backing NumberDictionary's entries instead of probing
+// every index up to length. These tests pin down its observable semantics.
+
+function makeDictionaryArray() {
+ const a = [];
+ a[0] = 'a';
+ a[10] = 'b';
+ a[1000] = 'c';
+ a[500000] = 'b';
+ a[1000000] = 'd';
+ assertTrue(%HasDictionaryElements(a));
+ return a;
+}
+
+// Returns the smallest matching index even though dictionary iteration
+// order is arbitrary ('b' is present at 10 and 500000).
+(function testSmallestIndexWins() {
+ const a = makeDictionaryArray();
+ assertEquals(10, a.indexOf('b'));
+ assertEquals(0, a.indexOf('a'));
+ assertEquals(1000000, a.indexOf('d'));
+ assertEquals(-1, a.indexOf('z'));
+})();
+
+// fromIndex excludes entries below it.
+(function testFromIndex() {
+ const a = makeDictionaryArray();
+ assertEquals(10, a.indexOf('b', 10));
+ assertEquals(500000, a.indexOf('b', 11));
+ assertEquals(-1, a.indexOf('a', 1));
+ // Negative fromIndex is relative to length.
+ assertEquals(1000000, a.indexOf('d', -1));
+ assertEquals(-1, a.indexOf('a', -1));
+})();
+
+// Holes are skipped: searching undefined only matches explicit undefined.
+(function testUndefinedSearch() {
+ const a = makeDictionaryArray();
+ assertEquals(-1, a.indexOf(undefined));
+ a[700000] = undefined;
+ assertTrue(%HasDictionaryElements(a));
+ assertEquals(700000, a.indexOf(undefined));
+})();
+
+// Strict equality semantics: NaN is never found, +0 matches -0.
+(function testStrictEquals() {
+ const a = [];
+ a[100000] = NaN;
+ a[200000] = -0;
+ assertTrue(%HasDictionaryElements(a));
+ assertEquals(-1, a.indexOf(NaN));
+ assertEquals(200000, a.indexOf(0));
+})();
+
+// An accessor element forces the ordered slow path: getters run in index
+// order and their values are observed.
+(function testAccessorBailout() {
+ const a = [];
+ a[100000] = 'x';
+ const log = [];
+ Object.defineProperty(a, 50000, {
+ get() {
+ log.push(50000);
+ return 'y';
+ },
+ });
+ Object.defineProperty(a, 60000, {
+ get() {
+ log.push(60000);
+ return 'x';
+ },
+ });
+ assertTrue(%HasDictionaryElements(a));
+ assertEquals(60000, a.indexOf('x'));
+ assertEquals([50000, 60000], log);
+ assertEquals(50000, a.indexOf('y'));
+})();
diff --git a/deps/v8/test/mjsunit/array-lastindexof-fast.js b/deps/v8/test/mjsunit/array-lastindexof-fast.js
new file mode 100644
index 00000000000..a33bfc4b213
--- /dev/null
+++ b/deps/v8/test/mjsunit/array-lastindexof-fast.js
@@ -0,0 +1,153 @@
+// 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
+
+// Fast-path lastIndexOf: elements-kind × search-type combinations, including
+// fromIndex -1 and searches that must return -1.
+
+function assertPackedSmi(arr) {
+ assertTrue(%HasSmiElements(arr));
+ assertFalse(%HasHoleyElements(arr));
+}
+
+function assertHoleySmi(arr) {
+ assertTrue(%HasSmiElements(arr));
+ assertTrue(%HasHoleyElements(arr));
+}
+
+function assertPackedDouble(arr) {
+ assertTrue(%HasDoubleElements(arr));
+ assertFalse(%HasHoleyElements(arr));
+}
+
+function assertHoleyDouble(arr) {
+ assertTrue(%HasDoubleElements(arr));
+ assertTrue(%HasHoleyElements(arr));
+}
+
+function assertPackedObject(arr) {
+ assertTrue(%HasObjectElements(arr));
+ assertFalse(%HasHoleyElements(arr));
+}
+
+function assertHoleyObject(arr) {
+ assertTrue(%HasObjectElements(arr));
+ assertTrue(%HasHoleyElements(arr));
+}
+
+(function packedSmi() {
+ var a = [1, 2, -1, 0, 2];
+ assertPackedSmi(a);
+
+ assertEquals(4, a.lastIndexOf(2));
+ assertEquals(4, a.lastIndexOf(2, -1));
+ assertEquals(1, a.lastIndexOf(2, -2));
+ assertEquals(2, a.lastIndexOf(-1));
+ assertEquals(2, a.lastIndexOf(-1, -1));
+ assertEquals(3, a.lastIndexOf(0));
+ assertEquals(3, a.lastIndexOf(-0));
+ assertEquals(-1, a.lastIndexOf(3));
+ assertEquals(-1, a.lastIndexOf(NaN));
+ assertEquals(-1, a.lastIndexOf(1.5));
+ assertEquals(-1, a.lastIndexOf(undefined));
+ assertEquals(-1, a.lastIndexOf('2'));
+ assertEquals(-1, a.lastIndexOf(true));
+ assertEquals(-1, [].lastIndexOf(-1));
+})();
+
+(function holeySmi() {
+ var a = [1, , -1, 0, 2];
+ assertHoleySmi(a);
+
+ assertEquals(4, a.lastIndexOf(2, -1));
+ assertEquals(2, a.lastIndexOf(-1));
+ assertEquals(-1, a.lastIndexOf(undefined));
+ assertEquals(-1, a.lastIndexOf(NaN));
+ assertEquals(-1, a.lastIndexOf('1'));
+})();
+
+(function packedDouble() {
+ var a = [1.5, 2, -1, 0, 2.5, NaN];
+ assertPackedDouble(a);
+
+ assertEquals(4, a.lastIndexOf(2.5));
+ assertEquals(4, a.lastIndexOf(2.5, -1));
+ assertEquals(1, a.lastIndexOf(2));
+ assertEquals(2, a.lastIndexOf(-1));
+ assertEquals(2, a.lastIndexOf(-1, -1));
+ assertEquals(3, a.lastIndexOf(0));
+ assertEquals(3, a.lastIndexOf(-0));
+ assertEquals(0, a.lastIndexOf(1.5));
+ assertEquals(-1, a.lastIndexOf(NaN));
+ assertEquals(-1, a.lastIndexOf(undefined));
+ assertEquals(-1, a.lastIndexOf('2'));
+ assertEquals(-1, a.lastIndexOf(true));
+ assertEquals(-1, a.lastIndexOf({}));
+})();
+
+(function holeyDouble() {
+ var a = [1.5, , -1, 0, 2.5];
+ assertHoleyDouble(a);
+
+ assertEquals(4, a.lastIndexOf(2.5, -1));
+ assertEquals(2, a.lastIndexOf(-1));
+ assertEquals(-1, a.lastIndexOf(undefined));
+ assertEquals(-1, a.lastIndexOf(NaN));
+ assertEquals(-1, a.lastIndexOf('1.5'));
+})();
+
+(function holeyDoubleUndefined() {
+ var a = [1.5, 2.5, 3.5];
+ a[1] = undefined;
+ if (%IsUndefinedDoubleEnabled()) {
+ assertHoleyDouble(a);
+ } else {
+ assertTrue(%HasObjectElements(a));
+ }
+ assertEquals(1, a.lastIndexOf(undefined));
+ assertEquals(1, a.lastIndexOf(undefined, -1));
+ assertEquals(-1, a.lastIndexOf(undefined, 0));
+ assertEquals(-1, a.lastIndexOf(NaN));
+})();
+
+(function packedObject() {
+ var o = {};
+ var a = [1, 'x', 1.5, -1, o, 'x', 0];
+ assertPackedObject(a);
+
+ assertEquals(5, a.lastIndexOf('x'));
+ assertEquals(5, a.lastIndexOf('x', -1));
+ assertEquals(5, a.lastIndexOf('x', -2));
+ assertEquals(3, a.lastIndexOf(-1));
+ assertEquals(0, a.lastIndexOf(1));
+ assertEquals(2, a.lastIndexOf(1.5));
+ assertEquals(6, a.lastIndexOf(0));
+ assertEquals(6, a.lastIndexOf(-0));
+ assertEquals(4, a.lastIndexOf(o));
+ assertEquals(-1, a.lastIndexOf({}));
+ assertEquals(-1, a.lastIndexOf(NaN));
+ assertEquals(-1, a.lastIndexOf(undefined));
+ assertEquals(-1, a.lastIndexOf(true));
+})();
+
+(function holeyObject() {
+ var a = [1, , 'x', -1, undefined];
+ assertHoleyObject(a);
+
+ assertEquals(3, a.lastIndexOf(-1, -1));
+ assertEquals(2, a.lastIndexOf('x'));
+ assertEquals(4, a.lastIndexOf(undefined));
+ assertEquals(-1, a.lastIndexOf(NaN));
+})();
+
+(function mixedNumberObject() {
+ // PACKED_ELEMENTS holding both Smi and HeapNumber.
+ var a = [1, 'x', 2.5, 2];
+ assertPackedObject(a);
+ assertEquals(3, a.lastIndexOf(2));
+ assertEquals(2, a.lastIndexOf(2.5));
+ assertEquals(0, a.lastIndexOf(1));
+ assertEquals(-1, a.lastIndexOf(-1));
+})();
diff --git a/deps/v8/test/mjsunit/array-reduce.js b/deps/v8/test/mjsunit/array-reduce.js
index 4d6293e4d93..178800c89c9 100644
--- a/deps/v8/test/mjsunit/array-reduce.js
+++ b/deps/v8/test/mjsunit/array-reduce.js
@@ -718,6 +718,7 @@ assertEquals(undefined, arr.reduceRight(function(val) { return val }));
})();
(function ReduceCatch() {
+ let array = [1, 2, 3];
let f = (a,current) => {
return a + current;
};
@@ -1050,6 +1051,7 @@ assertEquals(undefined, arr.reduceRight(function(val) { return val }));
})();
(function ReduceCatch() {
+ let array = [1, 2, 3];
let f = (a,current) => {
return a + current;
};
diff --git a/deps/v8/test/mjsunit/baseline/test-osr-maglev-tf.js b/deps/v8/test/mjsunit/baseline/test-osr-maglev-tf.js
index 666d28912b4..28eeb5e07a6 100644
--- a/deps/v8/test/mjsunit/baseline/test-osr-maglev-tf.js
+++ b/deps/v8/test/mjsunit/baseline/test-osr-maglev-tf.js
@@ -4,7 +4,7 @@
// Flags: --allow-natives-syntax --sparkplug --no-always-sparkplug --use-osr
// Flags: --turbofan --deopt-every-n-times=0
-// Flags: --maglev --maglev-osr --osr-from-maglev
+// Flags: --maglev --maglev-osr
// Flags: --concurrent-recompilation
function isExecutingBaseline(func) {
diff --git a/deps/v8/test/mjsunit/compiler/dataview-deopt.js b/deps/v8/test/mjsunit/compiler/dataview-deopt.js
index 18c2384ea87..a5e4d68c015 100644
--- a/deps/v8/test/mjsunit/compiler/dataview-deopt.js
+++ b/deps/v8/test/mjsunit/compiler/dataview-deopt.js
@@ -58,3 +58,17 @@ warmupWrite(writeUint8);
assertOptimized(writeUint8);
writeUint8(1.5, 0); // Doesn't deopt.
assertOptimized(writeUint8);
+
+function writeUint32(offset, value) {
+ dataview.setUint32(offset, value);
+}
+
+warmupWrite(writeUint32);
+assertOptimized(writeUint32);
+writeUint32(0.5, 0); // Deopts.
+assertUnoptimized(writeUint32);
+
+warmupWrite(writeUint32);
+assertOptimized(writeUint32);
+writeUint32(1.5, 0); // Doesn't deopt.
+assertOptimized(writeUint32);
diff --git a/deps/v8/test/mjsunit/compiler/dataview-get.js b/deps/v8/test/mjsunit/compiler/dataview-get.js
index 81f254e5311..8d094e84cfe 100644
--- a/deps/v8/test/mjsunit/compiler/dataview-get.js
+++ b/deps/v8/test/mjsunit/compiler/dataview-get.js
@@ -104,6 +104,12 @@ warmup(readUint16);
assertOptimized(readUint16);
assertEquals(0xabcd, readUint16(8));
assertEquals(0xcdab, readUint16(8, true));
+dataview.setUint16(8, 0x1234);
+assertEquals(0x1234, readUint16(8));
+assertEquals(0x3412, readUint16(8, true));
+dataview.setUint16(8, 0x8000);
+assertEquals(0x8000, readUint16(8));
+assertEquals(0x0080, readUint16(8, true));
// TurboFan valid getInt16.
let b1 = -0x1234;
diff --git a/deps/v8/test/mjsunit/compiler/dataview-set.js b/deps/v8/test/mjsunit/compiler/dataview-set.js
index 60023f3a1f7..e027e7fee04 100644
--- a/deps/v8/test/mjsunit/compiler/dataview-set.js
+++ b/deps/v8/test/mjsunit/compiler/dataview-set.js
@@ -99,6 +99,8 @@ writeUint32(0, 0xdeadbeef);
assertEquals(0xdeadbeef, dataview.getUint32(0));
writeUint32(0, 0xefbeadde, true);
assertEquals(0xdeadbeef, dataview.getUint32(0));
+writeUint32(0, -1);
+assertEquals(0xffffffff, dataview.getUint32(0));
// TurboFan valid setInt32.
warmup(writeInt32);
diff --git a/deps/v8/test/mjsunit/compiler/no-stack-checks.js b/deps/v8/test/mjsunit/compiler/no-stack-checks.js
new file mode 100644
index 00000000000..530433d652a
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/no-stack-checks.js
@@ -0,0 +1,54 @@
+// 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-stack-checks --allow-natives-syntax --turbofan
+
+// Test Turbofan loop and function entry with --no-stack-checks.
+function test_tf(o) {
+ for (let i = 0; i < 2; ++i) {
+ o.x = i;
+ }
+ return o.x;
+}
+
+%PrepareFunctionForOptimization(test_tf);
+let obj1 = { x: 0 };
+assertEquals(1, test_tf(obj1));
+assertEquals(1, test_tf(obj1));
+%OptimizeFunctionOnNextCall(test_tf);
+assertEquals(1, test_tf(obj1));
+assertOptimized(test_tf);
+
+// Test Maglev loop and function entry with --no-stack-checks.
+function test_maglev(n) {
+ let s = 0;
+ for (let i = 0; i < n; ++i) {
+ s += i;
+ }
+ return s;
+}
+
+%PrepareFunctionForOptimization(test_maglev);
+assertEquals(45, test_maglev(10));
+assertEquals(45, test_maglev(10));
+%OptimizeMaglevOnNextCall(test_maglev);
+assertEquals(45, test_maglev(10));
+
+// Test nested loops without stack checks.
+function test_nested_loops(n) {
+ let count = 0;
+ for (let i = 0; i < n; ++i) {
+ for (let j = 0; j < 3; ++j) {
+ count += j;
+ }
+ }
+ return count;
+}
+
+%PrepareFunctionForOptimization(test_nested_loops);
+assertEquals(30, test_nested_loops(10));
+assertEquals(30, test_nested_loops(10));
+%OptimizeFunctionOnNextCall(test_nested_loops);
+assertEquals(30, test_nested_loops(10));
+assertOptimized(test_nested_loops);
diff --git a/deps/v8/test/mjsunit/compiler/regress-542923494.js b/deps/v8/test/mjsunit/compiler/regress-542923494.js
new file mode 100644
index 00000000000..b8f83dc6284
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/regress-542923494.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 --concurrent-recompilation
+// Flags: --concurrent-recompilation-delay=50
+
+// A function whose .prototype is a primitive keeps its initial map in a Tuple2
+// instead of directly in prototype_or_initial_map. Installing the initial map
+// mutates that already-published tuple, while a background compilation can
+// reach the same map by reading the function out of a context slot and
+// following the tuple (JSFunctionData::Cache).
+
+(function() {
+ function Goo() {}
+ Goo.prototype = 42;
+
+ function opt() { return Goo; }
+
+ %PrepareFunctionForOptimization(opt);
+ opt();
+ %OptimizeFunctionOnNextCall(opt, "concurrent");
+ // Queues the background job. The recompilation delay keeps it from running
+ // until the initial map below has been installed.
+ opt();
+
+ new Goo();
+
+ %WaitForBackgroundOptimization();
+ assertSame(Goo, opt());
+})();
diff --git a/deps/v8/test/mjsunit/compiler/script-context-const-load.js b/deps/v8/test/mjsunit/compiler/script-context-const-load.js
new file mode 100644
index 00000000000..2fb84599a49
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/script-context-const-load.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 --bundle --turbofan
+
+// JS_BUNDLE_SCRIPT
+const scriptConst = 42;
+
+// JS_BUNDLE_SCRIPT
+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);
diff --git a/deps/v8/test/mjsunit/compiler/script-context-let-load.js b/deps/v8/test/mjsunit/compiler/script-context-let-load.js
new file mode 100644
index 00000000000..8b1aefc1a1d
--- /dev/null
+++ b/deps/v8/test/mjsunit/compiler/script-context-let-load.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 --bundle --turbofan
+
+// JS_BUNDLE_SCRIPT
+let scriptLet = 42;
+
+// JS_BUNDLE_SCRIPT
+function createClosure() {
+ return function foo() {
+ %TurbofanStaticAssert(scriptLet == 42);
+ return scriptLet;
+ };
+}
+
+// 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);
diff --git a/deps/v8/test/mjsunit/console.js b/deps/v8/test/mjsunit/console.js
index f78afc69dd5..cfba6666ce2 100644
--- a/deps/v8/test/mjsunit/console.js
+++ b/deps/v8/test/mjsunit/console.js
@@ -8,6 +8,14 @@ assertThrows(() => console.assert(false), Error);
assertThrows(() => console.assert(""), Error);
assertThrows(() => console.assert(0), Error);
+class CustomError extends Error {}
+assertThrows(() => console.assert(false, {
+ toString() { throw new CustomError(); }
+}), CustomError);
+assertThrows(() => console.assert(false, "prefix", {
+ toString() { throw new CustomError(); }
+}), CustomError);
+
let args = ["", {}, [], this, Array, 1, 1.4, true, false];
console.log(...args);
@@ -22,6 +30,22 @@ console.timeEnd();
console.time("a");
console.timeEnd("a");
+assertThrows(() => console.time({
+ toString() { throw new CustomError(); }
+}), CustomError);
+
+assertThrows(() => console.timeEnd({
+ toString() { throw new CustomError(); }
+}), CustomError);
+
+assertThrows(() => console.timeLog({
+ toString() { throw new CustomError(); }
+}), CustomError);
+
+assertThrows(() => console.timeStamp({
+ toString() { throw new CustomError(); }
+}), CustomError);
+
console.timeStamp();
args.forEach(each => console.timeStamp(each));
diff --git a/deps/v8/test/mjsunit/const-tracking-let-wont-prevent-osr-to-turbofan.js b/deps/v8/test/mjsunit/const-tracking-let-wont-prevent-osr-to-turbofan.js
index 901ed58bc6b..ffe800237b9 100644
--- a/deps/v8/test/mjsunit/const-tracking-let-wont-prevent-osr-to-turbofan.js
+++ b/deps/v8/test/mjsunit/const-tracking-let-wont-prevent-osr-to-turbofan.js
@@ -6,8 +6,7 @@
// Flags: --turbofan --maglev --no-stress-maglev
// Flags: --sparkplug --no-always-sparkplug
// Flags: --no-baseline-batch-compilation --use-osr
-// Flags: --osr-from-maglev --concurrent-osr --concurrent-recompilation
-// Flags: --always-osr-from-maglev
+// Flags: --concurrent-osr --concurrent-recompilation
let a = 0;
var keep_going = 100000; // A counter to avoid test hangs on failure.
diff --git a/deps/v8/test/mjsunit/cross-realm-callsite.js b/deps/v8/test/mjsunit/cross-realm-callsite.js
new file mode 100644
index 00000000000..6008e6d9d35
--- /dev/null
+++ b/deps/v8/test/mjsunit/cross-realm-callsite.js
@@ -0,0 +1,72 @@
+// 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 testCallSiteCrossRealmCapabilityFilter() {
+ Error.stackTraceLimit = 20;
+
+ let capturedSites = null;
+ Error.prepareStackTrace = (_error, callSites) => {
+ capturedSites = callSites;
+ return callSites;
+ };
+
+ const realm1 = Realm.create();
+ const captureInRealm1 = Realm.eval(realm1, `
+ (() => {
+ globalThis.realm1Receiver = {};
+
+ function realm1Function(target) {
+ Error.captureStackTrace(target);
+ }
+
+ return function(target) {
+ realm1Function.call(globalThis.realm1Receiver, target);
+ };
+ })()
+ `);
+
+ const target = {};
+ captureInRealm1(target);
+ void target.stack;
+
+ assertTrue(Array.isArray(capturedSites));
+ assertTrue(capturedSites.length > 0);
+
+ // All frames from realm1 must have their function, receiver,
+ // and function name filtered out when accessed by the main realm.
+ for (const site of capturedSites) {
+ assertEquals(undefined, site.getFunction());
+ assertEquals(undefined, site.getThis());
+ assertEquals(null, site.getFunctionName());
+ }
+})();
+
+(function testCallSiteSameRealmAccessAllowed() {
+ const realm1 = Realm.create();
+
+ const realm1Check = Realm.eval(realm1, `
+ (() => {
+ globalThis.sloppyReceiver = {};
+ let site = null;
+ Error.prepareStackTrace = (e, sites) => {
+ site = sites.find(s => s.getFunctionName() === 'sloppyMethod');
+ return sites;
+ };
+
+ (function sloppyMethod() {
+ const err = new Error();
+ void err.stack;
+ }).call(globalThis.sloppyReceiver);
+
+ return {
+ hasFunctionName: site.getFunctionName() === 'sloppyMethod',
+ hasFunction: typeof site.getFunction() === 'function',
+ hasThis: site.getThis() === globalThis.sloppyReceiver,
+ };
+ })()
+ `);
+ assertTrue(realm1Check.hasFunctionName);
+ assertTrue(realm1Check.hasFunction);
+ assertTrue(realm1Check.hasThis);
+})();
diff --git a/deps/v8/test/mjsunit/d8/d8-code-cache-import.js b/deps/v8/test/mjsunit/d8/d8-code-cache-import.js
new file mode 100644
index 00000000000..383db67b152
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-code-cache-import.js
@@ -0,0 +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: --cache=code
+
+import('./d8-code-cache-import.js');
diff --git a/deps/v8/test/mjsunit/d8/d8-code-cache-module-after-execute.mjs b/deps/v8/test/mjsunit/d8/d8-code-cache-module-after-execute.mjs
new file mode 100644
index 00000000000..95879ac3bb8
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-code-cache-module-after-execute.mjs
@@ -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: --cache=after-execute
+
+import { helper } from './d8-code-cache-module-dep.mjs';
+
+function compute(a, b) {
+ return helper(a) + b;
+}
+
+if (compute(10, 5) !== 25) {
+ throw new Error("Unexpected compute result");
+}
+
+export const val = compute(2, 3);
+
+import(import.meta.url).then(ns => {
+ if (ns.val !== 7) {
+ throw new Error("Unexpected exported value");
+ }
+});
diff --git a/deps/v8/test/mjsunit/d8/d8-code-cache-module-compile-only.mjs b/deps/v8/test/mjsunit/d8/d8-code-cache-module-compile-only.mjs
new file mode 100644
index 00000000000..4bd88c5f655
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-code-cache-module-compile-only.mjs
@@ -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.
+
+// Flags: --cache=code --compile-only
+
+import { helper } from './d8-code-cache-module-dep.mjs';
+
+export const x = 1;
+
+// If this module is executed, it will throw and fail the test.
+throw new Error("Module should only be compiled, not executed");
diff --git a/deps/v8/test/mjsunit/d8/d8-code-cache-module-dep.mjs b/deps/v8/test/mjsunit/d8/d8-code-cache-module-dep.mjs
new file mode 100644
index 00000000000..fd044b3fac9
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-code-cache-module-dep.mjs
@@ -0,0 +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.
+
+export function helper(x) {
+ return x * 2;
+}
diff --git a/deps/v8/test/mjsunit/d8/d8-code-cache-module-import.mjs b/deps/v8/test/mjsunit/d8/d8-code-cache-module-import.mjs
new file mode 100644
index 00000000000..40e7a6a5f81
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-code-cache-module-import.mjs
@@ -0,0 +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: --cache=code
+
+import(import.meta.url);
diff --git a/deps/v8/test/mjsunit/d8/d8-code-cache-module.mjs b/deps/v8/test/mjsunit/d8/d8-code-cache-module.mjs
new file mode 100644
index 00000000000..3a9928df85c
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-code-cache-module.mjs
@@ -0,0 +1,19 @@
+// 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: --cache=code
+
+import { helper } from './d8-code-cache-module-dep.mjs';
+
+if (helper(21) !== 42) {
+ throw new Error("Unexpected helper result");
+}
+
+export const value = 123;
+
+import(import.meta.url).then(ns => {
+ if (ns.value !== 123) {
+ throw new Error("Unexpected exported value");
+ }
+});
diff --git a/deps/v8/test/mjsunit/d8/d8-console-assert-terminate.js b/deps/v8/test/mjsunit/d8/d8-console-assert-terminate.js
new file mode 100644
index 00000000000..adf7e79580c
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-console-assert-terminate.js
@@ -0,0 +1,11 @@
+// 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: --strict-termination-checks
+
+console.assert(false, {
+ toString() {
+ d8.terminateNow();
+ }
+});
diff --git a/deps/v8/test/mjsunit/d8/d8-inspector-shutdown-pending-evaluate.js b/deps/v8/test/mjsunit/d8/d8-inspector-shutdown-pending-evaluate.js
new file mode 100644
index 00000000000..0788bd7c46e
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-inspector-shutdown-pending-evaluate.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: --enable-inspector
+
+// Verify that an unresolved asynchronous evaluation does not cause a
+// use-after-free during d8 isolate and inspector session teardown.
+send(JSON.stringify({
+ id: 1,
+ method: 'Runtime.evaluate',
+ params: {
+ expression: 'new Promise(() => {})',
+ awaitPromise: true
+ }
+}));
diff --git a/deps/v8/test/mjsunit/d8/d8-test-access-check.js b/deps/v8/test/mjsunit/d8/d8-test-access-check.js
new file mode 100644
index 00000000000..88869ef96bc
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-test-access-check.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.
+
+// 1. Allowed access.
+{
+ let obj = d8.test.createAccessCheckedObject(true);
+ obj.a = 42;
+ assertEquals(42, obj.a);
+
+ // 2. Denied access throws TypeError.
+ d8.test.setAccessPolicy(obj, false);
+ assertThrows(() => obj.a, TypeError);
+
+ // 3. Restore access.
+ d8.test.setAccessPolicy(obj, true);
+ assertEquals(42, obj.a);
+}
+
+// 4. "same-context" policy.
+{
+ let obj = d8.test.createAccessCheckedObject("same-context");
+ obj.a = 42;
+ assertEquals(42, obj.a);
+
+ let realm = Realm.create();
+ Realm.shared = obj;
+ let otherTypeError = Realm.eval(realm, "TypeError");
+ assertThrows(() => Realm.eval(realm, "Realm.shared.a"), otherTypeError);
+
+ d8.test.setAccessPolicy(obj, true);
+ assertEquals(42, Realm.eval(realm, "Realm.shared.a"));
+}
+
+// 5. "security-token" policy.
+{
+ let obj = d8.test.createAccessCheckedObject("security-token");
+ obj.a = 42;
+ assertEquals(42, obj.a);
+
+ let realm = Realm.create();
+ Realm.shared = obj;
+ let otherTypeError = Realm.eval(realm, "TypeError");
+ assertThrows(() => Realm.eval(realm, "Realm.shared.a"), otherTypeError);
+
+ let sameTokenRealm = Realm.createAllowCrossRealmAccess();
+ assertEquals(42, Realm.eval(sameTokenRealm, "Realm.shared.a"));
+
+ d8.test.setAccessPolicy(obj, true);
+ assertEquals(42, Realm.eval(realm, "Realm.shared.a"));
+}
+
+// 6. Input validation.
+assertThrows(() => d8.test.createAccessCheckedObject(), Error);
+assertThrows(() => d8.test.createAccessCheckedObject(123), Error);
+assertThrows(() => d8.test.createAccessCheckedObject("bad"), Error);
+assertThrows(() => d8.test.createAccessCheckedObject({}), Error);
+assertThrows(() => d8.test.createAccessCheckedObject(() => true), Error);
+
+let obj = d8.test.createAccessCheckedObject(true);
+assertThrows(() => d8.test.setAccessPolicy(obj, "bad"), Error);
+assertThrows(() => d8.test.setAccessPolicy(obj, 123), Error);
+assertThrows(() => d8.test.setAccessPolicy({}, true), Error);
+assertThrows(() => d8.test.setAccessPolicy(123, true), Error);
diff --git a/deps/v8/test/mjsunit/d8/d8-test-interceptor.js b/deps/v8/test/mjsunit/d8/d8-test-interceptor.js
new file mode 100644
index 00000000000..db24ad80d20
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-test-interceptor.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.
+
+// 1. Basic property interception.
+{
+ let interceptedProp = null;
+ let obj = d8.test.createInterceptorObject((prop) => {
+ interceptedProp = prop;
+ return 123;
+ });
+ assertEquals(123, obj.foo);
+ assertEquals("foo", interceptedProp);
+ assertEquals(123, obj.bar);
+ assertEquals("bar", interceptedProp);
+}
+
+// 2. Intercepting symbol properties.
+{
+ let s = Symbol("test");
+ let interceptedProp = null;
+ let obj = d8.test.createInterceptorObject((prop) => {
+ interceptedProp = prop;
+ return "symbol-value";
+ });
+ assertEquals("symbol-value", obj[s]);
+ assertEquals(s, interceptedProp);
+}
+
+// 3. Exception in interceptor callback propagates.
+{
+ let obj = d8.test.createInterceptorObject(() => {
+ throw new Error("interceptor-error");
+ });
+ assertThrows(() => obj.foo, Error, "interceptor-error");
+}
+
+// 4. Input validation.
+assertThrows(() => d8.test.createInterceptorObject(), Error);
+assertThrows(() => d8.test.createInterceptorObject(123), Error);
+assertThrows(() => d8.test.createInterceptorObject("bad"), Error);
+assertThrows(() => d8.test.createInterceptorObject({}), 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
new file mode 100644
index 00000000000..d3fac5f37c8
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-test-special-object.js
@@ -0,0 +1,53 @@
+// 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/d8/d8-tostring-errors.js b/deps/v8/test/mjsunit/d8/d8-tostring-errors.js
new file mode 100644
index 00000000000..b2b44eae02c
--- /dev/null
+++ b/deps/v8/test/mjsunit/d8/d8-tostring-errors.js
@@ -0,0 +1,54 @@
+// 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: --enable-os-system
+
+class CustomError extends Error {}
+const throwingObj = {
+ toString() { throw new CustomError(); }
+};
+
+// D8 core file and execution operations
+assertThrows(() => read(throwingObj), CustomError);
+assertThrows(() => read("nonexistent", throwingObj), CustomError);
+assertThrows(() => readbuffer(throwingObj), CustomError);
+assertThrows(() => load(throwingObj), CustomError);
+assertThrows(() => write(throwingObj, "test"), CustomError);
+assertThrows(() => writeFile(throwingObj, "test"), CustomError);
+assertThrows(() => writeFile(throwingObj, new Uint8Array([1, 2, 3])), CustomError);
+
+// D8 file object
+if (typeof d8 !== 'undefined' && d8.file) {
+ assertThrows(() => d8.file.exists(throwingObj), CustomError);
+}
+
+// OS builtins
+if (typeof os !== 'undefined') {
+ if (os.chdir) {
+ assertThrows(() => os.chdir(throwingObj), CustomError);
+ }
+ if (os.mkdirp) {
+ assertThrows(() => os.mkdirp(throwingObj), CustomError);
+ }
+ if (os.rmdir) {
+ assertThrows(() => os.rmdir(throwingObj), CustomError);
+ }
+ if (os.setenv) {
+ assertThrows(() => os.setenv(throwingObj, "value"), CustomError);
+ assertThrows(() => os.setenv("key", throwingObj), CustomError);
+ }
+ if (os.unsetenv) {
+ assertThrows(() => os.unsetenv(throwingObj), CustomError);
+ }
+ if (os.system) {
+ assertThrows(() => os.system(throwingObj), CustomError);
+ assertThrows(() => os.system("echo", [throwingObj]), CustomError);
+ let throwingArray = [];
+ Object.defineProperty(throwingArray, 0, {
+ get() { throw new CustomError(); }
+ });
+ throwingArray.length = 1;
+ assertThrows(() => os.system("echo", throwingArray), CustomError);
+ }
+}
diff --git a/deps/v8/test/mjsunit/debug-osr-debug-break.js b/deps/v8/test/mjsunit/debug-osr-debug-break.js
new file mode 100644
index 00000000000..bd65449ae0d
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-osr-debug-break.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 --enable-inspector --turbofan --no-maglev
+
+let msgId = 1;
+function cmd(method, params) {
+ return JSON.stringify({id: msgId++, method: method, params: params || {}});
+}
+
+function receive(msg) {
+ let obj = JSON.parse(msg);
+ if (obj.method === "Debugger.paused") {
+ send(cmd("Debugger.resume"));
+ }
+}
+
+let top_frame_status_after_break = -1;
+function check_deopt() {
+ eval("");
+ top_frame_status_after_break = %GetOptimizationStatus(osr_top);
+}
+%NeverOptimizeFunction(check_deopt);
+
+function osr_top() {
+ for (let i = 0; i < 20; i++) {
+ if (i === 10) {
+ %OptimizeOsr();
+ }
+ }
+ debugger;
+ check_deopt();
+}
+
+send(cmd("Debugger.enable"));
+%PrepareFunctionForOptimization(osr_top);
+osr_top();
+
+// kTopmostFrameIsTurboFanned is bit 11 (1 << 11 = 2048) of GetOptimizationStatus
+const kTopmostFrameIsTurboFanned = 1 << 11;
+const isTopFrameTurboFanned = (top_frame_status_after_break & kTopmostFrameIsTurboFanned) !== 0;
+
+assertFalse(isTopFrameTurboFanned, "OSR topmost frame should be deoptimized after debugger break");
diff --git a/deps/v8/test/mjsunit/debug-osr-step-in-blackboxed.js b/deps/v8/test/mjsunit/debug-osr-step-in-blackboxed.js
new file mode 100644
index 00000000000..628647308a0
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-osr-step-in-blackboxed.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 --enable-inspector --turbofan --no-maglev
+
+let msgId = 1;
+function cmd(method, params) { return JSON.stringify({id: msgId++, method: method, params: params || {}}); }
+
+let paused_locations = [];
+
+function receive(msg) {
+ let obj = JSON.parse(msg);
+ if (obj.method === "Debugger.paused") {
+ let fnName = obj.params.callFrames[0].functionName;
+ paused_locations.push(fnName);
+ if (fnName === "callee") {
+ send(cmd("Debugger.stepInto"));
+ } else {
+ send(cmd("Debugger.resume"));
+ }
+ }
+}
+
+function target() {
+ return 1;
+}
+
+function callee() {
+ eval("");
+ debugger;
+}
+%NeverOptimizeFunction(callee);
+
+eval(`
+function osr_caller(osr) {
+ for (let i = 0; i < 20; i++) {
+ if (osr && i === 10) %OptimizeOsr();
+ }
+ callee();
+ target();
+}
+//# sourceURL=osr_caller.js
+`);
+
+// Gather feedback for inlining
+%PrepareFunctionForOptimization(target);
+callee();
+target();
+callee();
+target();
+
+%PrepareFunctionForOptimization(osr_caller);
+osr_caller(false);
+osr_caller(false);
+
+send(cmd("Debugger.enable"));
+// Blackbox osr_caller so FloodWithOneShot is skipped, exposing the bug in PrepareStep
+send(cmd("Debugger.setBlackboxPatterns", { patterns: ["osr_caller\\.js"] }));
+
+paused_locations = [];
+osr_caller(true);
+
+assertTrue(paused_locations.includes("target"), "BUG: target was not stepped into across blackboxed OSR caller");
diff --git a/deps/v8/test/mjsunit/debug-osr-step-on-throw-blackboxed.js b/deps/v8/test/mjsunit/debug-osr-step-on-throw-blackboxed.js
new file mode 100644
index 00000000000..a8c83800d62
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-osr-step-on-throw-blackboxed.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: --allow-natives-syntax --enable-inspector --turbofan --no-maglev
+
+let msgId = 1;
+function cmd(method, params) { return JSON.stringify({id: msgId++, method: method, params: params || {}}); }
+
+let paused_locations = [];
+
+function receive(msg) {
+ let obj = JSON.parse(msg);
+ if (obj.method === "Debugger.paused") {
+ let fnName = obj.params.callFrames[0].functionName;
+ paused_locations.push(fnName);
+ if (fnName === "thrower") {
+ send(cmd("Debugger.stepInto"));
+ } else {
+ send(cmd("Debugger.resume"));
+ }
+ }
+}
+
+function target() {
+ return 1;
+}
+
+function thrower() {
+ eval("");
+ debugger;
+ throw new Error("test");
+}
+%NeverOptimizeFunction(thrower);
+
+eval(`
+function osr_caller(osr) {
+ for (let i = 0; i < 20; i++) {
+ if (osr && i === 10) %OptimizeOsr();
+ }
+ try { thrower(); } catch (e) { target(); }
+}
+//# sourceURL=osr_caller.js
+`);
+
+// Gather feedback for inlining
+%PrepareFunctionForOptimization(target);
+try { thrower(); } catch(e) { target(); }
+try { thrower(); } catch(e) { target(); }
+
+%PrepareFunctionForOptimization(osr_caller);
+osr_caller(false);
+osr_caller(false);
+
+send(cmd("Debugger.enable"));
+// Blackbox osr_caller so FloodWithOneShot is skipped, exposing the bug in PrepareStepOnThrow
+send(cmd("Debugger.setBlackboxPatterns", { patterns: ["osr_caller\\.js"] }));
+
+paused_locations = [];
+osr_caller(true);
+
+assertTrue(paused_locations.includes("target"), "BUG: target was not stepped into across blackboxed OSR caller");
diff --git a/deps/v8/test/mjsunit/debug-osr-step-on-throw.js b/deps/v8/test/mjsunit/debug-osr-step-on-throw.js
new file mode 100644
index 00000000000..de09c11931b
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-osr-step-on-throw.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: --allow-natives-syntax --enable-inspector --turbofan --no-maglev
+
+let msgId = 1;
+function cmd(method, params) {
+ return JSON.stringify({id: msgId++, method: method, params: params || {}});
+}
+
+let paused_locations = [];
+
+function receive(msg) {
+ let obj = JSON.parse(msg);
+ if (obj.method === "Debugger.paused") {
+ let fnName = obj.params.callFrames[0].functionName;
+ paused_locations.push(fnName);
+ if (fnName !== "caught_target") {
+ send(cmd("Debugger.stepInto"));
+ } else {
+ send(cmd("Debugger.resume"));
+ }
+ }
+}
+
+function caught_target() {
+ eval("");
+ // Should step into here after exception unwinds to catch handler in osr_caller()
+}
+
+function thrower() {
+ eval("");
+ debugger;
+ throw new Error("test");
+}
+
+%NeverOptimizeFunction(thrower);
+%NeverOptimizeFunction(caught_target);
+
+function osr_caller() {
+ for (let i = 0; i < 20; i++) {
+ if (i === 10) {
+ %OptimizeOsr();
+ }
+ }
+ try {
+ thrower();
+ } catch (e) {
+ caught_target();
+ }
+}
+
+send(cmd("Debugger.enable"));
+%PrepareFunctionForOptimization(osr_caller);
+osr_caller();
+
+assertEquals(["thrower", "thrower", "osr_caller", "caught_target"], paused_locations);
diff --git a/deps/v8/test/mjsunit/debug-osr-step-out.js b/deps/v8/test/mjsunit/debug-osr-step-out.js
new file mode 100644
index 00000000000..9044d75fc43
--- /dev/null
+++ b/deps/v8/test/mjsunit/debug-osr-step-out.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 --enable-inspector --turbofan --no-maglev
+
+let msgId = 1;
+function cmd(method, params) {
+ return JSON.stringify({id: msgId++, method: method, params: params || {}});
+}
+
+let paused_locations = [];
+function receive(msg) {
+ let obj = JSON.parse(msg);
+ if (obj.method === "Debugger.paused") {
+ let fnName = obj.params.callFrames[0].functionName;
+ paused_locations.push(fnName);
+ if (fnName === "foo") {
+ send(cmd("Debugger.stepOut"));
+ } else if (fnName === "osr_caller") {
+ send(cmd("Debugger.stepInto"));
+ } else {
+ send(cmd("Debugger.resume"));
+ }
+ }
+}
+
+function bar() {
+ // Should pause here when stepping out of foo() from osr_caller()
+}
+%NeverOptimizeFunction(bar);
+
+function foo() {
+ debugger;
+}
+%NeverOptimizeFunction(foo);
+
+function osr_caller() {
+ for (let i = 0; i < 20; i++) {
+ if (i === 10) {
+ %OptimizeOsr();
+ }
+ }
+ foo();
+ bar();
+}
+
+send(cmd("Debugger.enable"));
+%PrepareFunctionForOptimization(osr_caller);
+osr_caller();
+
+assertEquals(["foo", "osr_caller", "bar"], paused_locations);
diff --git a/deps/v8/test/mjsunit/es6/iterator-prototype.js b/deps/v8/test/mjsunit/es6/iterator-prototype.js
index 1bb60c6e366..958192fb38f 100644
--- a/deps/v8/test/mjsunit/es6/iterator-prototype.js
+++ b/deps/v8/test/mjsunit/es6/iterator-prototype.js
@@ -8,7 +8,7 @@ var iteratorPrototype = arrayIteratorPrototype.__proto__;
assertSame(Object.prototype, Object.getPrototypeOf(iteratorPrototype));
assertTrue(Object.isExtensible(iteratorPrototype));
-assertSame(12, Object.getOwnPropertyNames(iteratorPrototype).length);
+assertSame(14, Object.getOwnPropertyNames(iteratorPrototype).length);
assertSame(3, Object.getOwnPropertySymbols(iteratorPrototype).length);
assertSame(Symbol.iterator,
Object.getOwnPropertySymbols(iteratorPrototype)[0]);
diff --git a/deps/v8/test/mjsunit/frozen-array-reduce.js b/deps/v8/test/mjsunit/frozen-array-reduce.js
index 26fbebc101a..b0596a4bf34 100644
--- a/deps/v8/test/mjsunit/frozen-array-reduce.js
+++ b/deps/v8/test/mjsunit/frozen-array-reduce.js
@@ -704,6 +704,7 @@ assertEquals(undefined, Object.freeze(arr).reduceRight(function(val) { return va
})();
(function ReduceCatch() {
+ let array = [1, '2', 3];
let f = (a,current) => {
return a + current;
};
@@ -1063,6 +1064,7 @@ assertEquals(undefined, Object.freeze(arr).reduceRight(function(val) { return va
})();
(function ReduceCatch() {
+ let array = [1, '2', 3];
let f = (a,current) => {
return a + Number(current);
};
diff --git a/deps/v8/test/mjsunit/get-current-frame-optimization-status-02.js b/deps/v8/test/mjsunit/get-current-frame-optimization-status-02.js
index f69991555bb..37d8ae49671 100644
--- a/deps/v8/test/mjsunit/get-current-frame-optimization-status-02.js
+++ b/deps/v8/test/mjsunit/get-current-frame-optimization-status-02.js
@@ -4,6 +4,7 @@
// Flags: --sparkplug --no-always-sparkplug --maglev --turbofan
// Flags: --allow-natives-syntax --concurrent-recompilation
+// Flags: --osr-from-maglev=4
// Note: OSR from Maglev to Turbofan requires --concurrent-recompilation.
diff --git a/deps/v8/test/mjsunit/harmony/async-iterator-prototype-async-dispose.js b/deps/v8/test/mjsunit/harmony/async-iterator-prototype-async-dispose.js
new file mode 100644
index 00000000000..5ad19755d5e
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/async-iterator-prototype-async-dispose.js
@@ -0,0 +1,25 @@
+// 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-explicit-resource-management
+
+(async function testAsyncIteratorPrototypeAsyncDisposeArgCount() {
+ async function* generator() {}
+ const AsyncIteratorPrototype =
+ Object.getPrototypeOf(Object.getPrototypeOf(generator.prototype));
+
+ const iter = Object.create(AsyncIteratorPrototype);
+ let returnCalled = false;
+ let argumentCount = -1;
+
+ iter.return = async function() {
+ argumentCount = arguments.length;
+ returnCalled = true;
+ return { done: true };
+ };
+
+ await iter[Symbol.asyncDispose]();
+ assertTrue(returnCalled);
+ assertEquals(0, argumentCount);
+})();
diff --git a/deps/v8/test/mjsunit/harmony/base64-from-hex-long-inputs.js b/deps/v8/test/mjsunit/harmony/base64-from-hex-long-inputs.js
index 6e5df915a42..0ef7ddd604b 100644
--- a/deps/v8/test/mjsunit/harmony/base64-from-hex-long-inputs.js
+++ b/deps/v8/test/mjsunit/harmony/base64-from-hex-long-inputs.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-externalize-string --js-base-64
+// Flags: --expose-externalize-string
(function TestBase64FromHexWithLongInputs() {
var arr_32 = Uint8Array.fromHex('666f6F6261726172666f6f62617261ff');
diff --git a/deps/v8/test/mjsunit/harmony/base64-from-hex-with-two-byte-strings.js b/deps/v8/test/mjsunit/harmony/base64-from-hex-with-two-byte-strings.js
index 79ddbdcf515..411fe393444 100644
--- a/deps/v8/test/mjsunit/harmony/base64-from-hex-with-two-byte-strings.js
+++ b/deps/v8/test/mjsunit/harmony/base64-from-hex-with-two-byte-strings.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-externalize-string --js-base-64
+// Flags: --expose-externalize-string
(function TestBase64FromHexWithTwByteStrings() {
var twoByteString = createExternalizableTwoByteString('666f6f626172');
diff --git a/deps/v8/test/mjsunit/harmony/base64-from-to-base64-null-option.js b/deps/v8/test/mjsunit/harmony/base64-from-to-base64-null-option.js
index 4b4b64db773..8a97cd45f82 100644
--- a/deps/v8/test/mjsunit/harmony/base64-from-to-base64-null-option.js
+++ b/deps/v8/test/mjsunit/harmony/base64-from-to-base64-null-option.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.
-// Flags: --js-base-64
-
(function TestBase64FromToBase64WithNullOption() {
assertThrows(() => Uint8Array.fromBase64('Zm9vYmE', null), TypeError);
diff --git a/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-fill-with-maximum-value.js b/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-fill-with-maximum-value.js
index fb6e6a5270c..8f182a2d0dc 100644
--- a/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-fill-with-maximum-value.js
+++ b/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-fill-with-maximum-value.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.
-// Flags: --js-base-64
-
(function TestBase64PrototypeToHexWithFillMaximumInInputs() {
for (let i = 0; i < 100; ++i) {
assertEquals(new Uint8Array(i).fill(255).toHex(), 'ff'.repeat(i));
diff --git a/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-long-inputs.js b/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-long-inputs.js
index b532d301b63..91c65da7a78 100644
--- a/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-long-inputs.js
+++ b/deps/v8/test/mjsunit/harmony/base64-prototype-to-hex-long-inputs.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.
-// Flags: --js-base-64
-
(function TestBase64PrototypeToHexWithLongInputs() {
assertEquals(
(new Uint8Array([102, 111, 111, 98, 97, 114, 111, 111])).toHex(),
diff --git a/deps/v8/test/mjsunit/harmony/bigint/mod-fold.js b/deps/v8/test/mjsunit/harmony/bigint/mod-fold.js
new file mode 100644
index 00000000000..9a9b0576fa8
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/bigint/mod-fold.js
@@ -0,0 +1,216 @@
+// 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
+
+// Coverage for the fold fast path in {CachedMod}.
+//
+// {CachedMod_MakeInverse} divides T = 2^(n * kDigitBits) by the n-digit
+// divisor B and arms {cached_mod_fold_factor_} with the remainder C when
+// T = q * B + C has a single-digit C and q <= kMaxFoldQuotient. A nonzero
+// factor makes {CachedMod} run {CachedModFold} instead of multiplying by the
+// cached inverse. Zero is the not-armed sentinel, so a power of two, which
+// divides T exactly, can never arm the fold.
+//
+// Whether a divisor qualifies depends on kDigitBits, so the cases below are
+// built from the running target's actual digit width rather than from both
+// candidate widths.
+
+const kDigitBits = %Is64Bit() ? 64 : 32;
+
+// The cache arms after kCachingThreshold = 100 consecutive uses of one
+// divisor, so every case runs past that to cover the pre- and post-arming
+// paths.
+const kIterationsUntilCached = 105;
+
+// Reference modulo. Division and multiplication have no cached-divisor path of
+// their own (the cache is only consulted from
+// MutableBigInt_AbsoluteModAndCanonicalize), so this does not go through the
+// code under test.
+function refMod(a, b) {
+ return a - (a / b) * b;
+}
+
+// The mod in this loop is loop-invariant, so once the helper tiers up most
+// iterations are eliminated and never reach the runtime, leaving most cases
+// short of the arming threshold.
+%NeverOptimizeFunction(checkRepeated);
+function checkRepeated(divisor, dividend) {
+ const expected = refMod(dividend, divisor);
+ for (let i = 0; i < kIterationsUntilCached; i++) {
+ assertEquals(expected, dividend % divisor);
+ }
+}
+
+// {CachedMod} is only reached for dividends of at most 2n digits; wider ones
+// are rejected by the length check in the caller and fall through to
+// ModuloLarge. Sweep both sides of the split at n digits.
+function checkAllDividendSizes(divisor, n) {
+ for (let size = n; size <= 2 * n; size++) {
+ const top = 1n << BigInt(size * kDigitBits);
+ for (const dividend of [top - 1n, top - 12345n, top >> 1n,
+ (top >> 1n) | 1n]) {
+ checkRepeated(divisor, dividend);
+ }
+ }
+}
+
+// Pseudo-Mersenne divisors 2^k - c. A small c keeps C single-digit and q at 1
+// or 2, which is what the fold path is for.
+//
+// The fold factor and the cached inverse are single slots belonging to
+// whichever divisor is armed, so a stale one would show up right after a
+// switch. Every case here switches divisors, and each gets the arming
+// threshold to itself, so the sweeps below cover that on their own: 34
+// switches between two armed divisors with different C, plus 7 transitions
+// between the fold and the inverse.
+for (const n of [2, 3, 4, 5, 6, 8]) {
+ const bits = n * kDigitBits;
+ for (const c of [1n, 19n, 977n, 4294968273n]) {
+ checkAllDividendSizes((1n << BigInt(bits)) - c, n);
+ }
+ // B need not fill its top digit. T is taken at the next whole digit boundary
+ // at or above B, so a B whose top bit is clear gets C scaled up accordingly:
+ // 2^255 - 19 spans the same 4 digits as 2^256 - c at a 64-bit width, and
+ // yields q = 2, C = 38.
+ checkAllDividendSizes((1n << BigInt(bits - 1)) - 19n, n);
+}
+
+// The moduli this path exists for. The first three arm the fold; 2^521 - 1
+// does not, because its 521 bits sit in a 9-digit span (at a 64-bit width)
+// whose q is 2^55.
+const ed25519P = (1n << 255n) - 19n;
+const secp256k1P = (1n << 256n) - (1n << 32n) - 977n;
+const mersenne127 = (1n << 127n) - 1n;
+const mersenne521 = (1n << 521n) - 1n;
+for (const p of [ed25519P, secp256k1P, mersenne127, mersenne521]) {
+ checkRepeated(p, p - 1n);
+ checkRepeated(p, p);
+ checkRepeated(p, p + 1n);
+ checkRepeated(p, p * 2n - 1n);
+ checkRepeated(p, p * p - 1n);
+ let x = 123456789n;
+ for (let i = 0; i < 200; i++) {
+ // Reduce the unreduced square rather than the previous result: x is
+ // already below p by construction, so checking it against refMod(x, p)
+ // would compare it against itself.
+ const square = x * x;
+ x = square % p;
+ assertEquals(refMod(square, p), x);
+ }
+}
+
+// The two halves of the gate in {CachedMod_MakeInverse} do different jobs, so
+// cover each independently.
+//
+// q bounds the corrective loop at the end of {CachedModFold} and is capped at
+// kMaxFoldQuotient = 4. Divisors built from T = q * B + C with single-digit C:
+// 2^256 = 3 * ((2^256 - 4) / 3) + 4 q = 3, admitted
+// 2^256 = 4 * (2^254 - 1) + 4 q = 4, the largest admitted
+// 2^256 = 5 * ((2^256 - 1) / 5) + 1 q = 5, rejected, uses the inverse
+const n256 = 256 / kDigitBits;
+checkAllDividendSizes(((1n << 256n) - 4n) / 3n, n256);
+checkAllDividendSizes((1n << 254n) - 1n, n256);
+checkAllDividendSizes(((1n << 256n) - 1n) / 5n, n256);
+
+// C fitting one digit is the other half of the gate, and it is what keeps each
+// fold column a single multiply. 2^128 = 4 * (2^126 - 2^62 + 1) + (2^64 - 4)
+// has q = 4 and a C just under a 64-bit digit, so it is admitted at a 64-bit
+// width and rejected at a 32-bit one, where the same C spans two digits.
+checkAllDividendSizes((1n << 126n) - (1n << 62n) + 1n, 128 / kDigitBits);
+
+// C at the very top of a digit: 2^128 = 1 * (2^128 - 2^64 + 1) + (2^64 - 1)
+// arms with C == ~digit_t{0}, the largest factor the fold can see. Each column
+// then sums to exactly D^2 - 1, the tight end of the bound {CachedModFold}
+// relies on for its carry to stay single-digit.
+checkAllDividendSizes((1n << 128n) - (1n << 64n) + 1n, 128 / kDigitBits);
+
+// A C spanning exactly two digits with q = 1, which pins the C half of the
+// gate on its own: every other rejected divisor here is rejected on q too, and
+// admitting this one would fold with a factor truncated to C's low digit.
+// 2^256 = 1 * B + C with B = 2^256 - 2^64 - 1 gives C = 2^64 + 1.
+//
+// Not checkAllDividendSizes: its dividends below the divisor return early
+// without reaching the cached path, breaking the run the arming counter needs.
+{
+ const twoDigitFactorP = (1n << 256n) - (1n << 64n) - 1n;
+ checkRepeated(twoDigitFactorP, twoDigitFactorP * 3n + 12345n);
+ checkRepeated(twoDigitFactorP, twoDigitFactorP * twoDigitFactorP - 1n);
+}
+
+// Dividends that leave the fold with a nonzero carry out while the low n
+// digits are already below B, so comparing R against B alone would stop the
+// corrective loop one subtraction early. Each is solved for rather than
+// sampled: it puts the first fold at exactly R = D^n - 1 with a carry of 1,
+// which random dividends essentially never produce.
+{
+ // 2^255 - 19 at n = 4 (64-bit digits) or n = 8 (32-bit).
+ const forEd25519P =
+ 352837050787963081567737499952785424407351732120852457308514774834783263949486697425160875523482044389225082438360059208781376754060895394392327283802089n;
+ checkRepeated(ed25519P, forEd25519P);
+ // 2^127 - 1 at n = 2 or n = 4.
+ const forMersenne127 =
+ 57896044618658097711785492504343953926975274699741220483192166611388333031423n;
+ checkRepeated(mersenne127, forMersenne127);
+}
+
+// Negative divisors and dividends reach the same paths; only the result's sign
+// differs. The fold itself is sign-agnostic, so one case each is enough.
+checkRepeated(-ed25519P, ed25519P * ed25519P - 1n);
+checkRepeated(ed25519P, -(ed25519P * 2n + 12345n));
+
+// Divisors that must keep using the inverse: standard curve moduli whose C
+// spans more than one digit at either width.
+const kNonQualifying = [
+ // ed25519 group order.
+ (1n << 252n) + 27742317777372353535851937790883648493n,
+ // secp256k1 group order.
+ 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141n,
+ // NIST P-256 and P-384.
+ (1n << 256n) - (1n << 224n) + (1n << 192n) + (1n << 96n) - 1n,
+ (1n << 384n) - (1n << 128n) - (1n << 96n) + (1n << 32n) - 1n,
+ // bls12-381 base field.
+ 0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaabn,
+];
+for (const m of kNonQualifying) {
+ checkRepeated(m, m - 1n);
+ checkRepeated(m, m * m - 1n);
+ checkRepeated(m, (m << 1n) + 12345n);
+}
+
+// Powers of two divide T exactly, so C is 0, which is also the not-armed
+// sentinel. They must stay on the inverse path and stay correct.
+for (const bits of [128n, 192n, 256n, 320n]) {
+ const divisor = 1n << bits;
+ checkRepeated(divisor, divisor - 1n);
+ checkRepeated(divisor, divisor * divisor - 1n);
+ checkRepeated(divisor, (divisor << 1n) | 1n);
+}
+
+// An exact multiple folds to all-zero digits, the one fold result that
+// {Canonicalize} has to trim all the way down to 0n.
+for (const p of [ed25519P, secp256k1P, (1n << 640n) - 19n]) {
+ checkRepeated(p, p * 4n);
+ checkRepeated(p, -(p * 4n));
+}
+
+// kMaxCachedModDivisorSize = 32 digits caps what the cache accepts at all,
+// which is 2048 bits on a 64-bit digit and 1024 on a 32-bit one. Straddle both
+// so the larger divisor is uncacheable at either width, while the smaller
+// still folds.
+for (const bits of [1024n, 2048n, 2112n]) {
+ const divisor = (1n << bits) - 19n;
+ checkRepeated(divisor, divisor - 1n);
+ checkRepeated(divisor, divisor * 3n);
+ checkRepeated(divisor, divisor * divisor - 1n);
+}
+
+// Dividends wider than 2n digits skip the cached path entirely via the length
+// check in the caller, whether or not a factor is armed.
+{
+ const p = ed25519P;
+ checkRepeated(p, p * 3n);
+ const wide = (1n << 1200n) - 1n;
+ assertEquals(refMod(wide, p), wide % p);
+}
diff --git a/deps/v8/test/mjsunit/harmony/iterator-includes.js b/deps/v8/test/mjsunit/harmony/iterator-includes.js
index 41c3ca593f7..e7080e937f0 100644
--- a/deps/v8/test/mjsunit/harmony/iterator-includes.js
+++ b/deps/v8/test/mjsunit/harmony/iterator-includes.js
@@ -40,26 +40,35 @@
assertFalse(returnCalled);
})();
-/*
-// The following test is currently disabled because it relies on normative
-// spec changes (PR 3776) that have not yet been merged into the
-// iterator-includes proposal. It is kept here for future reference.
+(function TestIncludesSkippedElementsValidation() {
+ let closed = false;
+ function createClosable() {
+ closed = false;
+ return {
+ __proto__: Iterator.prototype,
+ get next() {
+ throw new Error('next should not be called');
+ },
+ return() {
+ closed = true;
+ return {};
+ },
+ };
+ }
-(function TestsForPR3776() {
- function* gen() { yield 42; yield 43; }
- const iter = gen();
+ assertThrows(() => createClosable().includes(42, -1), RangeError);
+ assertTrue(closed);
- // Non-integers should be truncated.
- assertTrue(gen().includes(43, 1.5));
- assertFalse(gen().includes(42, 1.5));
+ assertThrows(() => createClosable().includes(42, Number.MAX_SAFE_INTEGER + 1), RangeError);
+ assertTrue(closed);
- // Negative should throw RangeError.
- assertThrows(() => iter.includes(42, -1), RangeError);
+ assertThrows(() => createClosable().includes(42, 'invalid'), TypeError);
+ assertTrue(closed);
- // Large values > 2^53 - 1 should throw RangeError.
- assertThrows(() => iter.includes(42, 2 ** 53), RangeError);
+ assertThrows(() => createClosable().includes(42, NaN), TypeError);
+ assertTrue(closed);
- // NaN skippedElements should throw RangeError.
- assertThrows(() => iter.includes(42, NaN), RangeError);
+ // Infinity is allowed and skips all elements without throwing.
+ function* gen() { yield 42; yield 43; }
+ assertFalse(gen().includes(42, Infinity));
})();
-*/
diff --git a/deps/v8/test/mjsunit/harmony/iterator-zip-keyed.js b/deps/v8/test/mjsunit/harmony/iterator-zip-keyed.js
index cbf5d50c3a0..3970580c43c 100644
--- a/deps/v8/test/mjsunit/harmony/iterator-zip-keyed.js
+++ b/deps/v8/test/mjsunit/harmony/iterator-zip-keyed.js
@@ -245,3 +245,39 @@
Iterator.zipKeyed(iterables, options);
}, Error);
})();
+
+(function RegressionTestOnExceptionDuringNext() {
+ const thrower = {
+ next() {
+ throw new Error('Oops');
+ }
+ };
+
+ const zippedKeyed = Iterator.zipKeyed({a: thrower});
+
+ assertThrows(() => zippedKeyed.next(), Error, 'Oops');
+
+ const resultKeyed = zippedKeyed.next();
+ assertEquals(undefined, resultKeyed.value);
+ assertEquals(true, resultKeyed.done);
+})();
+
+(function RegressionTestOnExceptionDuringNextStrict() {
+ const iter1 = (function*() {
+ yield 1;
+ })();
+
+ const iter2 = (function*() {
+ yield 1;
+ throw new Error('Oops');
+ })();
+
+ const zippedKeyed = Iterator.zipKeyed({a: iter1, b: iter2}, {mode: 'strict'});
+ zippedKeyed.next(); // { a: 1, b: 1 }
+ assertThrows(
+ () => zippedKeyed.next(), Error, 'Oops'); // iter1 done, iter2 throws
+
+ const resultKeyed = zippedKeyed.next();
+ assertEquals(undefined, resultKeyed.value);
+ assertEquals(true, resultKeyed.done);
+})();
diff --git a/deps/v8/test/mjsunit/harmony/iterator-zip.js b/deps/v8/test/mjsunit/harmony/iterator-zip.js
index bb5f0652f8e..b28fa43681f 100644
--- a/deps/v8/test/mjsunit/harmony/iterator-zip.js
+++ b/deps/v8/test/mjsunit/harmony/iterator-zip.js
@@ -203,3 +203,38 @@
const options = { mode: 'longest', padding };
assertThrows(() => Iterator.zip(manyIterables, options), Error);
})();
+
+(function RegressionTestOnExceptionDuringNext() {
+ const thrower = {
+ next() {
+ throw new Error('Oops');
+ }
+ };
+
+ const zipped = Iterator.zip([thrower]);
+
+ assertThrows(() => zipped.next(), Error, 'Oops');
+
+ const result = zipped.next();
+ assertEquals(undefined, result.value);
+ assertEquals(true, result.done);
+})();
+
+(function RegressionTestOnExceptionDuringNextStrict() {
+ const iter1 = (function*() {
+ yield 1;
+ })();
+
+ const iter2 = (function*() {
+ yield 1;
+ throw new Error('Oops');
+ })();
+
+ const zipped = Iterator.zip([iter1, iter2], {mode: 'strict'});
+ zipped.next(); // [1, 1]
+ assertThrows(() => zipped.next(), Error, 'Oops'); // iter1 done, iter2 throws
+
+ const result = zipped.next();
+ assertEquals(undefined, result.value);
+ assertEquals(true, result.done);
+})();
diff --git a/deps/v8/test/mjsunit/harmony/modules-import-attributes-text.mjs b/deps/v8/test/mjsunit/harmony/modules-import-attributes-text.mjs
index 182871b4498..98fc7237d48 100644
--- a/deps/v8/test/mjsunit/harmony/modules-import-attributes-text.mjs
+++ b/deps/v8/test/mjsunit/harmony/modules-import-attributes-text.mjs
@@ -2,9 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --js-import-text
-
-
import text from 'modules-skip-1.txt' with { type: 'text' };
assertEquals("Hello, import text!\n", text);
diff --git a/deps/v8/test/mjsunit/harmony/modules-import-defer-get-private-member.mjs b/deps/v8/test/mjsunit/harmony/modules-import-defer-get-private-member.mjs
new file mode 100644
index 00000000000..f711807d8e4
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/modules-import-defer-get-private-member.mjs
@@ -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: --js-defer-import-eval --allow-natives-syntax
+
+globalThis.eval_list = [];
+
+import defer * as ns from './modules-skip-import-defer-1.mjs';
+
+assertEquals(0, globalThis.eval_list.length);
+
+// Collecting private names is what the inspector does when it computes the
+// internal properties of an object. It must not trigger the evaluation of the
+// deferred module, since the inspector runs it while JavaScript execution is
+// disallowed.
+assertThrows(() => %GetPrivateMember(ns, 'field'), Error);
+
+assertEquals(0, globalThis.eval_list.length);
+
+// Regular key collection still triggers the evaluation.
+assertArrayEquals(['foo'], Object.keys(ns));
+assertArrayEquals(['defer-1'], globalThis.eval_list);
diff --git a/deps/v8/test/mjsunit/harmony/modules-import-defer-own-property-keys-no-exports.mjs b/deps/v8/test/mjsunit/harmony/modules-import-defer-own-property-keys-no-exports.mjs
new file mode 100644
index 00000000000..3694f5fc31d
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/modules-import-defer-own-property-keys-no-exports.mjs
@@ -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: --js-defer-import-eval
+
+globalThis.eval_list = [];
+
+import defer * as ns from './modules-skip-import-defer-no-exports.mjs';
+
+assertEquals(0, globalThis.eval_list.length);
+
+// A side-effect-only module has no export to read, so [[OwnPropertyKeys]] is
+// the a way to force its evaluation.
+assertArrayEquals([], Object.keys(ns));
+
+assertArrayEquals(['defer-no-exports'], globalThis.eval_list);
diff --git a/deps/v8/test/mjsunit/harmony/modules-import-defer-sync-eval-async-cycle.js b/deps/v8/test/mjsunit/harmony/modules-import-defer-sync-eval-async-cycle.js
new file mode 100644
index 00000000000..c524d2adbe3
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/modules-import-defer-sync-eval-async-cycle.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: --js-defer-import-eval --bundle
+
+// Regression test for crbug.com/525234471: touching a deferred namespace whose
+// dependency belongs to an async cycle (A <-> B, with top-level await) used to
+// consider only the individual module's status when deciding whether the graph
+// is ready for synchronous evaluation. B could already be kEvaluated while its
+// cycle root A was still kEvaluatingAsync, so evaluating D synchronously
+// produced a pending (not fulfilled) evaluation promise and crashed in
+// JSDeferredModuleNamespace::EvaluateModuleSync[1]. The whole strongly-connected
+// component must be settled before the deferred module is evaluated.
+// [1] - https://github.com/tc39/proposal-defer-import-eval/issues/84
+
+// JS_BUNDLE_MODULE:setup.mjs
+export const p = Promise.withResolvers();
+
+// promises used to signal start of evaluation for A
+export const pA_start = Promise.withResolvers();
+
+// JS_BUNDLE_MODULE:resolve-p.mjs
+import {p} from "setup.mjs";
+
+p.resolve();
+
+// JS_BUNDLE_MODULE:A.mjs
+import {p, pA_start} from "setup.mjs";
+import "./B.mjs";
+
+pA_start.resolve(); // It signals start of A's evaluation
+globalThis.evaluationOrder.push("A-before-await");
+await p;
+globalThis.evaluationOrder.push("A-after-await");
+
+// JS_BUNDLE_MODULE:B.mjs
+import "./A.mjs";
+
+globalThis.evaluationOrder.push("B");
+
+// JS_BUNDLE_MODULE:D.mjs
+import "./B.mjs";
+globalThis.evaluationOrder.push("D");
+
+// JS_BUNDLE_MODULE:C.mjs
+import "Middle.mjs";
+import "resolve-p.mjs"; // It signals that p is resolved to unblock Middle.mjs
+
+// JS_BUNDLE_MODULE:Middle.mjs
+import defer * as nsD from "./D.mjs";
+// This should execute only after `D`'s async deps (i.e `A`) is evaluated.
+globalThis.evaluationOrder.push("Middle-before-nsD.z");
+nsD.z;
+globalThis.evaluationOrder.push("Middle-after-nsD.z");
+
+// JS_BUNDLE_MODULE_ENTRYPOINT:entry.mjs
+import {pA_start} from "setup.mjs";
+globalThis.evaluationOrder = [];
+
+const pA = import("./A.mjs");
+await pA_start.promise;
+// This is to force that Middle.mjs will evaluate after A.
+const pC = import("./C.mjs");
+await Promise.all([pA, pC]);
+
+// The async cycle {A, B} must be fully settled ("A-after-await") before
+// nsD.z forces the synchronous evaluation of the deferred module D.
+assertEquals([
+ "B",
+ "A-before-await",
+ "A-after-await",
+ "Middle-before-nsD.z",
+ "D",
+ "Middle-after-nsD.z",
+], globalThis.evaluationOrder);
diff --git a/deps/v8/test/mjsunit/harmony/modules-import-defer-throws-in-api-callback.mjs b/deps/v8/test/mjsunit/harmony/modules-import-defer-throws-in-api-callback.mjs
new file mode 100644
index 00000000000..123c1f8e3ee
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/modules-import-defer-throws-in-api-callback.mjs
@@ -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: --js-defer-import-eval
+
+// Evaluating a deferred module from inside an embedder API callback must not
+// leave the module's exception pending on the isolate while the top-level
+// capability is rejected.
+//
+// `print` is a d8 API callback, so calling it leaves an API callback frame on
+// the stack. Stringifying the namespace looks up `toString`, which evaluates
+// the deferred module; the module throws, rejecting its top-level capability.
+// That rejection has no handler, so V8 calls out to the host's rejection hook,
+// and d8's hook builds an Error to get a stack trace -- which has to summarize
+// the still-live API callback frame. Summarizing it instantiates the callback's
+// FunctionTemplate, and ApiNatives' InvokeScope reports whatever exception is
+// pending on the isolate. With the module's exception still pending there, that
+// happens inside a DisallowExceptions scope and hits a DCHECK.
+
+globalThis.eval_list = [];
+
+import defer * as ns from './modules-skip-import-defer-throws-primitive.mjs';
+
+assertEquals(0, globalThis.eval_list.length);
+
+// Stringifying the namespace inside the API callback evaluates the module,
+// which throws. `print` writes nothing, because ToString runs first.
+assertThrowsEquals(() => print(ns), 123);
+
+assertArrayEquals(['defer-throws-primitive'], globalThis.eval_list);
+
+// The module is errored: further access rethrows the same value, and does not
+// evaluate the module a second time.
+assertThrowsEquals(() => ns.foo, 123);
+assertArrayEquals(['defer-throws-primitive'], globalThis.eval_list);
diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-import-defer-no-exports.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-import-defer-no-exports.mjs
new file mode 100644
index 00000000000..c8f6333f305
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/modules-skip-import-defer-no-exports.mjs
@@ -0,0 +1,8 @@
+// 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.
+
+if (!globalThis.eval_list) {
+ globalThis.eval_list = [];
+}
+globalThis.eval_list.push('defer-no-exports');
diff --git a/deps/v8/test/mjsunit/harmony/modules-skip-import-defer-throws-primitive.mjs b/deps/v8/test/mjsunit/harmony/modules-skip-import-defer-throws-primitive.mjs
new file mode 100644
index 00000000000..13593b4054a
--- /dev/null
+++ b/deps/v8/test/mjsunit/harmony/modules-skip-import-defer-throws-primitive.mjs
@@ -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.
+
+if (!globalThis.eval_list) {
+ globalThis.eval_list = [];
+}
+globalThis.eval_list.push('defer-throws-primitive');
+
+// Throwing a primitive rather than an Error matters: d8's promise-rejection
+// hook only fabricates an Error (and so only walks the stack) when the
+// rejection value is not already a native Error.
+throw 123;
+
+export const foo = 42;
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-416166113.js b/deps/v8/test/mjsunit/harmony/regress/regress-416166113.js
index 41f680a295e..642fb33ba21 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-416166113.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-416166113.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: --js-base-64 --stress-scavenger-conservative-object-pinning-random
+// Flags: --stress-scavenger-conservative-object-pinning-random
for (let i = 0; i < 25; i++) {
for (let j = 0; j < 5; j++) {
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-416302802.js b/deps/v8/test/mjsunit/harmony/regress/regress-416302802.js
index 7e4b1f12006..af9f04e8067 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-416302802.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-416302802.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.
-// Flags: --js-base-64
-
const shared_array_buffer = new SharedArrayBuffer();
const uint8_array = new Uint8Array(shared_array_buffer);
const from_hex_result = uint8_array.setFromHex('666f6f626172');
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-418804470.js b/deps/v8/test/mjsunit/harmony/regress/regress-418804470.js
index ef7c4fc8c0f..1c71db6d02a 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-418804470.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-418804470.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.
-// Flags: --js-base-64
-
const shared_array_buffer = new SharedArrayBuffer(1.5);
const uint8_array = new Uint8Array(shared_array_buffer);
const from_hex_result = uint8_array.setFromHex('666f6f626172');
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-421227542.js b/deps/v8/test/mjsunit/harmony/regress/regress-421227542.js
index 66dbd6eafd6..67068c2d7e0 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-421227542.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-421227542.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: --js-base-64 --minor-ms
+// Flags: --minor-ms
function test() {
try {
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-499254994.js b/deps/v8/test/mjsunit/harmony/regress/regress-499254994.js
index 69891b0ffa9..707b5088106 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-499254994.js
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-499254994.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.
-// Flags: --js-explicit-resource-management
-
(function testSyncUsing() {
for (let iterations = 0; iterations <= 3; iterations++) {
let disposeCount = 0;
diff --git a/deps/v8/test/mjsunit/harmony/regress/regress-499254996.mjs b/deps/v8/test/mjsunit/harmony/regress/regress-499254996.mjs
index 2993a65d3c5..2c8ef16611e 100644
--- a/deps/v8/test/mjsunit/harmony/regress/regress-499254996.mjs
+++ b/deps/v8/test/mjsunit/harmony/regress/regress-499254996.mjs
@@ -2,8 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-// Flags: --js-explicit-resource-management
-
// Test 1: exported `using` variable (should be immutable)
const resource1 = {
value: 42,
diff --git a/deps/v8/test/mjsunit/harmony/uint8-array-set-from-base64-on-shared-array-buffer.js b/deps/v8/test/mjsunit/harmony/uint8-array-set-from-base64-on-shared-array-buffer.js
index 96a0be7a9d9..d2d26a6eb0e 100644
--- a/deps/v8/test/mjsunit/harmony/uint8-array-set-from-base64-on-shared-array-buffer.js
+++ b/deps/v8/test/mjsunit/harmony/uint8-array-set-from-base64-on-shared-array-buffer.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: --js-base-64 --allow-natives-syntax
+// Flags: --allow-natives-syntax
const workerScript = `
onmessage = function(event) {
diff --git a/deps/v8/test/mjsunit/harmony/uint8-array-set-from-hex-on-shared-array-buffer.js b/deps/v8/test/mjsunit/harmony/uint8-array-set-from-hex-on-shared-array-buffer.js
index 570e7be269d..0769b9c9cf9 100644
--- a/deps/v8/test/mjsunit/harmony/uint8-array-set-from-hex-on-shared-array-buffer.js
+++ b/deps/v8/test/mjsunit/harmony/uint8-array-set-from-hex-on-shared-array-buffer.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: --js-base-64 --allow-natives-syntax
+// Flags: --allow-natives-syntax
const workerScript = `
onmessage = function(event) {
diff --git a/deps/v8/test/mjsunit/harmony/uint8-array-to-base64-on-shared-array-buffer.js b/deps/v8/test/mjsunit/harmony/uint8-array-to-base64-on-shared-array-buffer.js
index c3fdb76ee8e..581e5e2f95b 100644
--- a/deps/v8/test/mjsunit/harmony/uint8-array-to-base64-on-shared-array-buffer.js
+++ b/deps/v8/test/mjsunit/harmony/uint8-array-to-base64-on-shared-array-buffer.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: --js-base-64 --allow-natives-syntax
+// Flags: --allow-natives-syntax
const workerScript = `
onmessage = function(event) {
diff --git a/deps/v8/test/mjsunit/harmony/uint8-array-to-hex-on-shared-array-buffer.js b/deps/v8/test/mjsunit/harmony/uint8-array-to-hex-on-shared-array-buffer.js
index f2a22b0ea31..8e07e5ad0b3 100644
--- a/deps/v8/test/mjsunit/harmony/uint8-array-to-hex-on-shared-array-buffer.js
+++ b/deps/v8/test/mjsunit/harmony/uint8-array-to-hex-on-shared-array-buffer.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: --js-base-64 --allow-natives-syntax
+// Flags: --allow-natives-syntax
const workerScript = `
onmessage = function(event) {
diff --git a/deps/v8/test/mjsunit/harmony/uint8array-base64-immutable.js b/deps/v8/test/mjsunit/harmony/uint8array-base64-immutable.js
index ed19d3ef4e7..0203d8f69f2 100644
--- a/deps/v8/test/mjsunit/harmony/uint8array-base64-immutable.js
+++ b/deps/v8/test/mjsunit/harmony/uint8array-base64-immutable.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: --js-base-64 --js-immutable-arraybuffer
+// Flags: --js-immutable-arraybuffer
const ab = new ArrayBuffer(10);
const immutable_ab = ab.transferToImmutable();
diff --git a/deps/v8/test/mjsunit/homomorphic-array-smi.js b/deps/v8/test/mjsunit/homomorphic-array-smi.js
index 7fec7dd13ed..46bc71374e2 100644
--- a/deps/v8/test/mjsunit/homomorphic-array-smi.js
+++ b/deps/v8/test/mjsunit/homomorphic-array-smi.js
@@ -8,27 +8,19 @@ function load_length(a) {
return a.length;
}
-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();
+const arrays = [];
+for (let i = 0; i < 11; i++) {
+ const A = class extends Array {};
+ arrays.push(new A());
+}
%PrepareFunctionForOptimization(load_length);
-// Warm up with all 5 maps
+// Warm up with all 11 maps
for (let i = 0; i < 20; i++) {
- load_length(a1);
- load_length(a2);
- load_length(a3);
- load_length(a4);
- load_length(a5);
+ for (const a of arrays) {
+ load_length(a);
+ }
}
// Assert that the feedback is homomorphic
@@ -42,11 +34,9 @@ if (fb !== undefined) {
%OptimizeFunctionOnNextCall(load_length);
// Test return values for arrays
-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));
+for (const a of arrays) {
+ assertEquals(0, load_length(a));
+}
assertOptimized(load_length);
diff --git a/deps/v8/test/mjsunit/homomorphic-ic.js b/deps/v8/test/mjsunit/homomorphic-ic.js
index d3d80d4e10e..f904d091cf5 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 < 10; i++) {
+for (let i = 0; i < 11; 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 < 10; i++) {
// Warm up
%PrepareFunctionForOptimization(load);
-for (let i = 0; i < 10; i++) {
+for (let i = 0; i < 11; i++) {
load(objects[i]);
}
@@ -35,7 +35,7 @@ load(objects[0]);
assertOptimized(load);
// Check result
-for (let i = 0; i < 10; i++) {
+for (let i = 0; i < 11; 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
new file mode 100644
index 00000000000..33f789ab9c4
--- /dev/null
+++ b/deps/v8/test/mjsunit/lower_limits_mode/regress/regress-561323344.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.
+
+// Flags: --allow-natives-syntax --experimental-wasm-stringref
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+(function testStringToLowerCaseIntl() {
+ if (typeof Intl === 'undefined') return;
+
+ const builder = new WasmModuleBuilder();
+ const sig_w_w = makeSig([kWasmStringRef], [kWasmStringRef]);
+ const toLowerCase = builder.addImport("m", "toLowerCase", sig_w_w);
+ builder.addFunction('main', makeSig([kWasmStringRef], []))
+ .addBody([
+ kExprLocalGet, 0,
+ kExprCallFunction, toLowerCase,
+ kExprDrop,
+ ])
+ .exportFunc();
+
+ const func = Function.prototype.call.bind(String.prototype.toLowerCase);
+ const instance = builder.instantiate({ m: { toLowerCase: func } });
+
+ // In lower limits mode, %StringMaxLength() is 1<<20 = 1048576.
+ // U+0130 lowercases to two characters ('i\u0307'), doubling the length and
+ // exceeding String::kMaxLength, throwing RangeError.
+ const len = Math.floor(%StringMaxLength() / 2) + 1;
+ const huge_string = "\u0130".repeat(len);
+
+ assertThrows(() => instance.exports.main(huge_string), RangeError,
+ /Invalid string length/);
+})();
+
+(function testIntToString() {
+ const builder = new WasmModuleBuilder();
+ const sig_w_ii = makeSig([kWasmI32, kWasmI32], [kWasmStringRef]);
+ const intToString = builder.addImport("m", "intToString", sig_w_ii);
+ builder.addFunction('main', makeSig([kWasmI32, kWasmI32], []))
+ .addBody([
+ kExprLocalGet, 0,
+ kExprLocalGet, 1,
+ kExprCallFunction, intToString,
+ kExprDrop,
+ ])
+ .exportFunc();
+
+ const func = Function.prototype.call.bind(Number.prototype.toString);
+ const instance = builder.instantiate({ m: { intToString: func } });
+
+ // Radix must be between 2 and 36; 100 throws RangeError.
+ assertThrows(() => instance.exports.main(42, 100), RangeError,
+ /toString\(\) radix argument must be between 2 and 36/);
+})();
diff --git a/deps/v8/test/mjsunit/maglev/call-with-spread-jsarray.js b/deps/v8/test/mjsunit/maglev/call-with-spread-jsarray.js
new file mode 100644
index 00000000000..a1c4c7a2b0d
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/call-with-spread-jsarray.js
@@ -0,0 +1,259 @@
+// 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 1: Spreading new Array() (empty capacity 4, length 0) and new Array(2)
+// (holey).
+(function() {
+function target(...rest) {
+ return rest.length;
+}
+function f_empty() {
+ const a = new Array();
+ return target(...a);
+}
+function f_holey() {
+ const a = new Array(2);
+ return target(...a);
+}
+
+%PrepareFunctionForOptimization(target);
+for (let [f, expected] of [[f_empty, 0], [f_holey, 2]]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals(expected, f());
+ assertEquals(expected, f());
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f());
+ assertOptimized(f);
+}
+})();
+
+// Test 2: Spreading holey array literals (double InlinedAllocation & tagged COW
+// FixedArray).
+(function() {
+function target(a, b, c) {
+ return '' + a + '|' + b + '|' + c;
+}
+function f_double() {
+ return target(...[1.5, , 2.5]);
+}
+function f_tagged() {
+ return target(...['x', , 'z']);
+}
+
+%PrepareFunctionForOptimization(target);
+for (let [f, expected] of [
+ [f_double, '1.5|undefined|2.5'], [f_tagged, 'x|undefined|z']]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals(expected, f());
+ assertEquals(expected, f());
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f());
+ assertOptimized(f);
+}
+})();
+
+// Test 3: Spreading rest parameters and arguments objects (emits
+// CallForwardVarargs).
+(function() {
+function outer(a, b, c) {
+ return '' + a + '|' + b + '|' + c;
+}
+function mid_rest(...rest) {
+ return outer(...rest);
+}
+function mid_args() {
+ return outer(...arguments);
+}
+
+%PrepareFunctionForOptimization(outer);
+for (let f of [mid_rest, mid_args]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals('1|2|3', f(1, 2, 3));
+ assertEquals('1|2|3', f(1, 2, 3));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals('1|2|3', f(1, 2, 3));
+ assertOptimized(f);
+}
+})();
+
+// Test 4: Construct with spread over empty, holey, and tagged arrays.
+(function() {
+class Target {
+ constructor(a, b, c) {
+ this.res = '' + a + '|' + b + '|' + c;
+ }
+}
+function f_empty() {
+ return new Target(...new Array());
+}
+function f_double() {
+ return new Target(...[1.5, , 2.5]);
+}
+function f_tagged() {
+ return new Target(...['x', , 'z']);
+}
+function f_holey() {
+ return new Target(...new Array(2));
+}
+
+%PrepareFunctionForOptimization(Target);
+for (let [f, expected] of [
+ [f_empty, 'undefined|undefined|undefined'],
+ [f_double, '1.5|undefined|2.5'],
+ [f_tagged, 'x|undefined|z'],
+ [f_holey, 'undefined|undefined|undefined'],
+]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals(expected, f().res);
+ assertEquals(expected, f().res);
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f().res);
+ assertOptimized(f);
+}
+})();
+
+// Test 5: Call with array-like (apply) over packed and holey arrays.
+(function() {
+function target(a, b, c) {
+ return '' + a + '|' + b + '|' + c;
+}
+function f_packed() {
+ return target.apply(null, [10, 20, 30]);
+}
+function f_double() {
+ return target.apply(null, [1.5, , 2.5]);
+}
+function f_tagged() {
+ return target.apply(null, ['x', , 'z']);
+}
+function f_holey() {
+ return target.apply(null, new Array(2));
+}
+
+%PrepareFunctionForOptimization(target);
+for (let [f, expected] of [
+ [f_packed, '10|20|30'],
+ [f_double, '1.5|undefined|2.5'],
+ [f_tagged, 'x|undefined|z'],
+ [f_holey, 'undefined|undefined|undefined'],
+]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals(expected, f());
+ assertEquals(expected, f());
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f());
+ assertOptimized(f);
+}
+})();
+
+// Test 6: Arity threshold (32 unpacks & inlines, 33 bails to generic call).
+(function() {
+function target(...rest) {
+ return rest.length;
+}
+
+function spread32() {
+ return target(
+ ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31]);
+}
+function spread33() {
+ return target(
+ ...[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32]);
+}
+function apply32() {
+ return target.apply(
+ null, [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15,
+ 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
+ ]);
+}
+function apply33() {
+ return target.apply(
+ null, [
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32
+ ]);
+}
+
+%PrepareFunctionForOptimization(target);
+for (let [f, expected] of [
+ [spread32, 32],
+ [spread33, 33],
+ [apply32, 32],
+ [apply33, 33],
+]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals(expected, f());
+ assertEquals(expected, f());
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f());
+ assertOptimized(f);
+}
+})();
+
+// Test 7: Spreading new Array(undefined, numbers...) (holey double elements).
+(function() {
+function target(a, b, c) {
+ return '' + a + '|' + b + '|' + c;
+}
+class Target {
+ constructor(a, b, c) {
+ this.res = '' + a + '|' + b + '|' + c;
+ }
+}
+
+function f_spread() {
+ const a = new Array(undefined, 1.5, 2.5);
+ return target(...a);
+}
+function f_apply() {
+ const a = new Array(undefined, 1.5, 2.5);
+ return target.apply(null, a);
+}
+function f_construct() {
+ const a = new Array(undefined, 1.5, 2.5);
+ return new Target(...a);
+}
+function f_reflect() {
+ const a = new Array(undefined, 1.5, 2.5);
+ return Reflect.apply(target, null, a);
+}
+function f_deopt() {
+ const a = new Array(undefined, 1.5);
+ return (function(x) { return [x].join(','); })(...a);
+}
+
+%PrepareFunctionForOptimization(target);
+%PrepareFunctionForOptimization(Target);
+for (let [f, expected] of [
+ [f_spread, 'undefined|1.5|2.5'],
+ [f_apply, 'undefined|1.5|2.5'],
+ [f_reflect, 'undefined|1.5|2.5'],
+]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals(expected, f());
+ assertEquals(expected, f());
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(expected, f());
+ assertOptimized(f);
+}
+
+%PrepareFunctionForOptimization(f_construct);
+assertEquals('undefined|1.5|2.5', f_construct().res);
+assertEquals('undefined|1.5|2.5', f_construct().res);
+%OptimizeMaglevOnNextCall(f_construct);
+assertEquals('undefined|1.5|2.5', f_construct().res);
+assertOptimized(f_construct);
+
+%PrepareFunctionForOptimization(f_deopt);
+assertEquals('', f_deopt());
+assertEquals('', f_deopt());
+%OptimizeMaglevOnNextCall(f_deopt);
+assertEquals('', f_deopt());
+assertOptimized(f_deopt);
+})();
diff --git a/deps/v8/test/mjsunit/maglev/call-with-spread-object-tracking.js b/deps/v8/test/mjsunit/maglev/call-with-spread-object-tracking.js
new file mode 100644
index 00000000000..d104aa1d565
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/call-with-spread-object-tracking.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 --maglev --maglev-object-tracking
+
+// Spreading arguments object with mutated length (non-inlined & inlined).
+(function() {
+function target(a, b, c) {
+ return '' + a + '|' + b + '|' + c;
+}
+
+function non_inlined(a, b, c) {
+ 'use strict';
+ arguments.length = 1;
+ return target(...arguments);
+}
+
+function mid(a, b, c) {
+ 'use strict';
+ arguments.length = 1;
+ return target(...arguments);
+}
+function inlined(a, b, c) {
+ return mid(a, b, c);
+}
+
+%PrepareFunctionForOptimization(target);
+%PrepareFunctionForOptimization(mid);
+for (let f of [non_inlined, inlined]) {
+ %PrepareFunctionForOptimization(f);
+ assertEquals('1|undefined|undefined', f(1, 2, 3));
+ assertEquals('1|undefined|undefined', f(1, 2, 3));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals('1|undefined|undefined', f(1, 2, 3));
+ assertOptimized(f);
+}
+})();
diff --git a/deps/v8/test/mjsunit/maglev/check-int32-is-smi.js b/deps/v8/test/mjsunit/maglev/check-int32-is-smi.js
new file mode 100644
index 00000000000..efc2bb023a2
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/check-int32-is-smi.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 --maglev --no-turbofan
+// Flags: --no-optimize-maglev-optimizes-to-turbofan
+
+function f(a, c, b) {
+ let bitwise = a | c;
+ let phi = b ? bitwise : 42;
+
+ // Smi feedback for ToNumber makes phi untagging insert CheckInt32IsSmi for
+ // the Int32 phi. The check must ignore the high 32 bits and only validate the
+ // Int32 payload.
+ let number = +phi;
+ if (phi < 100) return number;
+ return 0;
+}
+
+%PrepareFunctionForOptimization(f);
+assertEquals(42, f(0, -1, false));
+assertEquals(-1, f(0, -1, true));
+assertEquals(42, f(0, -1, false));
+assertEquals(-1, f(0, -1, true));
+
+%OptimizeMaglevOnNextCall(f);
+assertEquals(42, f(0, -1, false));
+assertTrue(isMaglevved(f));
+
+assertEquals(-1, f(0, -1, true));
+assertTrue(isMaglevved(f));
diff --git a/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js b/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js
new file mode 100644
index 00000000000..a1119434997
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/collection-iterator-next-inlined.js
@@ -0,0 +1,96 @@
+// 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 --no-stress-maglev
+
+function freshMap(n) {
+ const m = new Map();
+ for (let i = 0; i < n; i++) m.set(`k${i}`, i);
+ return m;
+}
+
+function freshSet(n) {
+ const s = new Set();
+ for (let i = 0; i < n; i++) s.add(`e${i}`);
+ return s;
+}
+
+function iterMap(m) {
+ let n = 0;
+ for (const [k, v] of m) n++;
+ return n;
+}
+
+function iterMapKeys(m) {
+ let n = 0;
+ for (const k of m.keys()) n++;
+ return n;
+}
+
+function iterMapValues(m) {
+ let n = 0;
+ for (const v of m.values()) n++;
+ return n;
+}
+
+function iterSet(s) {
+ let n = 0;
+ for (const v of s) n++;
+ return n;
+}
+
+function iterSetEntries(s) {
+ let n = 0;
+ for (const [a, b] of s.entries()) n++;
+ return n;
+}
+
+// The kind is unknown at the resume merge, so this takes the dynamic dispatch.
+function* genIterMap(m) {
+ for (const [k, v] of m) yield k;
+}
+
+function drainGenIterMap(m) {
+ let n = 0;
+ for (const x of genIterMap(m)) n++;
+ return n;
+}
+
+const fns = [
+ [iterMap, () => freshMap(9)],
+ [iterMapKeys, () => freshMap(9)],
+ [iterMapValues, () => freshMap(9)],
+ [iterSet, () => freshSet(9)],
+ [iterSetEntries, () => freshSet(9)],
+ [drainGenIterMap, () => freshMap(9)],
+];
+
+for (const [fn, makeArg] of fns) {
+ %PrepareFunctionForOptimization(fn);
+ assertEquals(9, fn(makeArg()));
+ assertEquals(9, fn(makeArg()));
+ %OptimizeMaglevOnNextCall(fn);
+ assertEquals(9, fn(makeArg()));
+ assertEquals(9, fn(makeArg()));
+ assertTrue(isMaglevved(fn), fn.name);
+}
+
+// A polymorphic iteration kind stays on the dynamic dispatch instead of
+// deoptimizing once per kind.
+function step(it) {
+ return it.next().value;
+}
+
+{
+ const m = new Map([[1, 10]]);
+ %PrepareFunctionForOptimization(step);
+ step(m.entries());
+ step(m.keys());
+ step(m.values());
+ %OptimizeMaglevOnNextCall(step);
+ step(m.entries());
+ step(m.keys());
+ step(m.values());
+ assertTrue(isMaglevved(step));
+}
diff --git a/deps/v8/test/mjsunit/maglev/collection-iterator-next.js b/deps/v8/test/mjsunit/maglev/collection-iterator-next.js
new file mode 100644
index 00000000000..a7599f0d460
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/collection-iterator-next.js
@@ -0,0 +1,357 @@
+// 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
+
+function freshMap(n) {
+ const m = new Map();
+ for (let i = 0; i < n; i++) m.set(`k${i}`, i);
+ return m;
+}
+
+function freshSet(n) {
+ const s = new Set();
+ for (let i = 0; i < n; i++) s.add(`e${i}`);
+ return s;
+}
+
+// Static-maps path: the iterator's map is known at the next() call site.
+function iterMap(m) {
+ const out = [];
+ for (const [k, v] of m) out.push(k, v);
+ return out;
+}
+
+function iterMapKeys(m) {
+ const out = [];
+ for (const k of m.keys()) out.push(k);
+ return out;
+}
+
+function iterMapValues(m) {
+ const out = [];
+ for (const v of m.values()) out.push(v);
+ return out;
+}
+
+function iterSet(s) {
+ const out = [];
+ for (const v of s) out.push(v);
+ return out;
+}
+
+function iterSetEntries(s) {
+ const out = [];
+ for (const [a, b] of s.entries()) out.push(a, b);
+ return out;
+}
+
+// Deleting while iterating shrinks the table mid-iteration and exercises
+// the obsolete-table healing path.
+function iterMapWithDeletes(m) {
+ const out = [];
+ for (const [k] of m) {
+ out.push(k);
+ m.delete(k);
+ }
+ return out;
+}
+
+// Adding while iterating grows/rehashes the table.
+function iterMapWithAdds(m, n) {
+ const out = [];
+ let added = 0;
+ for (const [k] of m) {
+ out.push(k);
+ if (added < n) m.set(`x${added++}`, added);
+ }
+ return out;
+}
+
+// Dynamic-kind path: inside a generator the iterator's map is unknown at
+// the resume merge, so the kind is dispatched on the map at runtime.
+function* genIterMap(m) {
+ for (const [k, v] of m) yield `${k}:${v}`;
+}
+
+function drainGenIterMap(m) {
+ const out = [];
+ for (const x of genIterMap(m)) out.push(x);
+ return out;
+}
+
+const expected = {
+ map: iterMap(freshMap(9)),
+ keys: iterMapKeys(freshMap(9)),
+ values: iterMapValues(freshMap(9)),
+ set: iterSet(freshSet(9)),
+ setEntries: iterSetEntries(freshSet(9)),
+ deletes: iterMapWithDeletes(freshMap(20)),
+ adds: iterMapWithAdds(freshMap(5), 8),
+ gen: drainGenIterMap(freshMap(9)),
+};
+
+const fns = [
+ [iterMap, () => [freshMap(9)], expected.map],
+ [iterMapKeys, () => [freshMap(9)], expected.keys],
+ [iterMapValues, () => [freshMap(9)], expected.values],
+ [iterSet, () => [freshSet(9)], expected.set],
+ [iterSetEntries, () => [freshSet(9)], expected.setEntries],
+ [iterMapWithDeletes, () => [freshMap(20)], expected.deletes],
+ [iterMapWithAdds, () => [freshMap(5), 8], expected.adds],
+ [drainGenIterMap, () => [freshMap(9)], expected.gen],
+];
+
+for (const [fn, makeArgs, want] of fns) {
+ %PrepareFunctionForOptimization(fn);
+ assertEquals(want, fn(...makeArgs()));
+ assertEquals(want, fn(...makeArgs()));
+ %OptimizeMaglevOnNextCall(fn);
+ assertEquals(want, fn(...makeArgs()));
+ assertEquals(want, fn(...makeArgs()));
+}
+
+// An exhausted iterator stays exhausted and keeps returning done.
+const it = freshMap(3).entries();
+while (!it.next().done) {
+}
+assertTrue(it.next().done);
+assertEquals(undefined, it.next().value);
+
+// A polymorphic site sees more than one iteration kind; each iterator must
+// keep the value shape of its own kind.
+function step(it) {
+ return it.next().value;
+}
+
+{
+ const m = new Map([[1, 10], [2, 20]]);
+ %PrepareFunctionForOptimization(step);
+ assertEquals([1, 10], step(m.entries()));
+ assertEquals(1, step(m.keys()));
+ assertEquals(10, step(m.values()));
+ %OptimizeMaglevOnNextCall(step);
+ assertEquals([1, 10], step(m.entries()));
+ assertEquals(1, step(m.keys()));
+ assertEquals(10, step(m.values()));
+}
+
+// Mutating the collection while an iterator is live obsoletes its table:
+// next() has to transition to the successor table. Growing, clearing and
+// shrinking all take that path.
+function drainKeys(it) {
+ const out = [];
+ let r;
+ while (!(r = it.next()).done) out.push(r.value[0]);
+ return out;
+}
+
+function growDuringIteration() {
+ const m = new Map();
+ for (let i = 0; i < 4; i++) m.set(i, i * 10);
+ const it = m.entries();
+ it.next();
+ for (let i = 100; i < 140; i++) m.set(i, i); // rehash
+ return drainKeys(it).length;
+}
+
+function clearDuringIteration() {
+ const m = new Map();
+ for (let i = 0; i < 8; i++) m.set(i, i * 10);
+ const it = m.entries();
+ it.next();
+ m.clear();
+ return drainKeys(it).length;
+}
+
+function shrinkDuringIteration() {
+ const m = new Map();
+ for (let i = 0; i < 32; i++) m.set(i, i);
+ const it = m.entries();
+ it.next();
+ for (let i = 0; i < 30; i++) m.delete(i);
+ return drainKeys(it).length;
+}
+
+%PrepareFunctionForOptimization(drainKeys);
+
+for (const fn of [growDuringIteration, clearDuringIteration,
+ shrinkDuringIteration]) {
+ %PrepareFunctionForOptimization(fn);
+ const want = fn();
+ assertEquals(want, fn());
+ %OptimizeMaglevOnNextCall(drainKeys);
+ %OptimizeMaglevOnNextCall(fn);
+ assertEquals(want, fn());
+ assertEquals(want, fn());
+}
+
+// A receiver that is not a collection iterator has to fall back to the
+// builtin rather than abort the reduction.
+const mapNext = new Map().entries().next;
+
+function callNextOn(o) {
+ return mapNext.call(o);
+}
+
+{
+ const m = new Map([[1, 10]]);
+ %PrepareFunctionForOptimization(callNextOn);
+ assertEquals({ value: [1, 10], done: false }, callNextOn(m.entries()));
+ assertThrows(() => callNextOn({}), TypeError);
+ assertThrows(() => callNextOn(new Set().values()), TypeError);
+ %OptimizeMaglevOnNextCall(callNextOn);
+ assertEquals({ value: [1, 10], done: false }, callNextOn(m.entries()));
+ assertThrows(() => callNextOn({}), TypeError);
+ assertThrows(() => callNextOn(new Set().values()), TypeError);
+}
+
+// When entries()/keys()/values() are inlined, next() gets a freshly allocated
+// iterator whose table_ it then overwrites. Obsoleting the table from the loop
+// body has to be observed by the transition loop.
+function forOfKeysWithDeletes(m) {
+ const out = [];
+ for (const k of m.keys()) {
+ out.push(k);
+ m.delete(k);
+ }
+ return out;
+}
+
+function forOfValuesWithDeletes(m) {
+ const out = [];
+ for (const v of m.values()) {
+ out.push(v);
+ m.delete(v);
+ }
+ return out;
+}
+
+function forOfWithClear(m) {
+ const out = [];
+ let first = true;
+ for (const [k] of m) {
+ out.push(k);
+ if (first) {
+ m.clear();
+ first = false;
+ }
+ }
+ return out;
+}
+
+function countingMap(n) {
+ const m = new Map();
+ for (let i = 0; i < n; i++) m.set(i, i);
+ return m;
+}
+
+{
+ const wantKeys = forOfKeysWithDeletes(countingMap(20));
+ const wantValues = forOfValuesWithDeletes(countingMap(20));
+ const wantClear = forOfWithClear(countingMap(8));
+ %PrepareFunctionForOptimization(forOfKeysWithDeletes);
+ %PrepareFunctionForOptimization(forOfValuesWithDeletes);
+ %PrepareFunctionForOptimization(forOfWithClear);
+ forOfKeysWithDeletes(countingMap(20));
+ forOfValuesWithDeletes(countingMap(20));
+ forOfWithClear(countingMap(8));
+ %OptimizeMaglevOnNextCall(forOfKeysWithDeletes);
+ %OptimizeMaglevOnNextCall(forOfValuesWithDeletes);
+ %OptimizeMaglevOnNextCall(forOfWithClear);
+ assertEquals(wantKeys, forOfKeysWithDeletes(countingMap(20)));
+ assertEquals(wantValues, forOfValuesWithDeletes(countingMap(20)));
+ assertEquals(wantClear, forOfWithClear(countingMap(8)));
+}
+
+// A polymorphic site over set iterator kinds, as above for maps.
+function stepSet(it) {
+ return it.next().value;
+}
+
+{
+ const s = new Set([7, 8]);
+ %PrepareFunctionForOptimization(stepSet);
+ assertEquals(7, stepSet(s.values()));
+ assertEquals([7, 7], stepSet(s.entries()));
+ assertEquals(7, stepSet(s.keys()));
+ %OptimizeMaglevOnNextCall(stepSet);
+ assertEquals(7, stepSet(s.values()));
+ assertEquals([7, 7], stepSet(s.entries()));
+ assertEquals(7, stepSet(s.keys()));
+}
+
+// Deleting while iterating a set takes the healing path too.
+function iterSetWithDeletes(s) {
+ const out = [];
+ for (const v of s) {
+ out.push(v);
+ s.delete(v);
+ }
+ return out;
+}
+
+function* genIterSet(s) {
+ for (const v of s) yield v;
+}
+
+function drainGenIterSet(s) {
+ const out = [];
+ for (const x of genIterSet(s)) out.push(x);
+ return out;
+}
+
+{
+ const wantDeletes = iterSetWithDeletes(freshSet(20));
+ const wantGen = drainGenIterSet(freshSet(9));
+ %PrepareFunctionForOptimization(iterSetWithDeletes);
+ %PrepareFunctionForOptimization(drainGenIterSet);
+ assertEquals(wantDeletes, iterSetWithDeletes(freshSet(20)));
+ assertEquals(wantGen, drainGenIterSet(freshSet(9)));
+ %OptimizeMaglevOnNextCall(iterSetWithDeletes);
+ %OptimizeMaglevOnNextCall(drainGenIterSet);
+ assertEquals(wantDeletes, iterSetWithDeletes(freshSet(20)));
+ assertEquals(wantGen, drainGenIterSet(freshSet(9)));
+}
+
+// A site that sees both a map and a set iterator matches neither builtin's
+// iterator maps, and has to fall back.
+function stepEither(it) {
+ return it.next().value;
+}
+
+{
+ const m = new Map([[1, 10]]);
+ const s = new Set([7]);
+ %PrepareFunctionForOptimization(stepEither);
+ assertEquals([1, 10], stepEither(m.entries()));
+ assertEquals(7, stepEither(s.values()));
+ %OptimizeMaglevOnNextCall(stepEither);
+ assertEquals([1, 10], stepEither(m.entries()));
+ assertEquals(7, stepEither(s.values()));
+}
+
+// The iterator result and the key-value array belong to the realm of the
+// next() being called, not to the realm of the caller.
+{
+ const realm = Realm.create();
+ Realm.eval(realm, 'globalThis.m = new Map([[1, 2]]);');
+ const otherObjectPrototype = Realm.eval(realm, 'Object.prototype');
+ const otherArrayPrototype = Realm.eval(realm, 'Array.prototype');
+
+ function crossRealmNext(it) {
+ const result = it.next();
+ return [Object.getPrototypeOf(result) === otherObjectPrototype,
+ Object.getPrototypeOf(result.value) === otherArrayPrototype,
+ result.value[0], result.value[1], result.done];
+ }
+
+ const want = [true, true, 1, 2, false];
+ %PrepareFunctionForOptimization(crossRealmNext);
+ assertEquals(want, crossRealmNext(Realm.eval(realm, 'm.entries()')));
+ assertEquals(want, crossRealmNext(Realm.eval(realm, 'm.entries()')));
+ %OptimizeMaglevOnNextCall(crossRealmNext);
+ assertEquals(want, crossRealmNext(Realm.eval(realm, 'm.entries()')));
+ assertEquals(want, crossRealmNext(Realm.eval(realm, 'm.entries()')));
+}
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 f2597ff671d..f626f3089d7 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
@@ -37,3 +37,24 @@ function test() {
test();
assertTrue(isMaglevved(foo));
+
+const source = new ArrayBuffer(8);
+new BigUint64Array(source)[0] = 0xfff2800000000000n;
+const signalingNaN = new Float64Array(source)[0];
+
+const target = new Float64Array(1);
+const targetBits = new BigUint64Array(target.buffer);
+
+function storeSignalingNaN(value) {
+ target[0] = value;
+}
+
+%PrepareFunctionForOptimization(storeSignalingNaN);
+storeSignalingNaN(signalingNaN);
+const expectedBits = targetBits[0];
+
+%OptimizeMaglevOnNextCall(storeSignalingNaN);
+storeSignalingNaN(signalingNaN);
+
+assertTrue(isMaglevved(storeSignalingNaN));
+assertEquals(expectedBits, targetBits[0]);
diff --git a/deps/v8/test/mjsunit/maglev/float64-conversions.js b/deps/v8/test/mjsunit/maglev/float64-conversions.js
new file mode 100644
index 00000000000..52466085703
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/float64-conversions.js
@@ -0,0 +1,351 @@
+// 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
+
+// Exercises every path of the conversions into Float64 and into HoleyFloat64:
+// each source representation, each assumed input type, the cached alternatives,
+// and the inputs that make the conversions deopt.
+
+const packed = [1.5, 2.5, 3.5]; // PACKED_DOUBLE_ELEMENTS
+const holey = [1.5, , 3.5]; // HOLEY_DOUBLE_ELEMENTS
+const smis = [1, 2, 3]; // PACKED_SMI_ELEMENTS
+const objects = [{}, {}]; // PACKED_ELEMENTS
+const typed = new Float64Array([1.5, 2.5]);
+
+// ---------------------------------------------------------------- to Float64
+
+// The value is already a Float64.
+(function Float64Source() {
+ function f(a, i) { return Math.sqrt(a[i]); }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(Math.sqrt(1.5), f(packed, 0));
+ assertEquals(Math.sqrt(1.5), f(packed, 0));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(Math.sqrt(2.5), f(packed, 1));
+ assertTrue(isMaglevved(f));
+})();
+
+// An Int32, and a Uint32.
+(function IntSources() {
+ function f(x) { return Math.sqrt(x | 0); }
+ function g(x) { return Math.sqrt(x >>> 0); }
+ %PrepareFunctionForOptimization(f);
+ %PrepareFunctionForOptimization(g);
+ assertEquals(2, f(4));
+ assertEquals(2, f(4));
+ assertEquals(2, g(4));
+ // Warm g with a value above 2^31, so that it is really the Uint32 conversion
+ // that gets compiled and the optimized call below does not deopt.
+ assertEquals(Math.sqrt(2 ** 32 - 1), g(-1));
+ %OptimizeMaglevOnNextCall(f);
+ %OptimizeMaglevOnNextCall(g);
+ assertEquals(3, f(9));
+ assertEquals(3, g(9));
+ assertEquals(Math.sqrt(2 ** 32 - 1), g(-1));
+ assertTrue(isMaglevved(f));
+ assertTrue(isMaglevved(g));
+})();
+
+// A tagged value known to be a Smi, which is untagged and converted from its
+// Int32 representation.
+(function TaggedSmiSource() {
+ function f(a, i) { return Math.sqrt(a[i]); }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(1, f(smis, 0));
+ assertEquals(1, f(smis, 0));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(Math.sqrt(2), f(smis, 1));
+ assertTrue(isMaglevved(f));
+})();
+
+// A tagged value that is a number but not a Smi.
+(function TaggedNumberSource() {
+ function f(o) { return Math.sqrt(o.x); }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(1.5, f({x: 2.25}));
+ assertEquals(1.5, f({x: 2.25}));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(2.5, f({x: 6.25}));
+ // A non-number deopts rather than converting.
+ assertEquals(NaN, f({x: "no"}));
+})();
+
+// A tagged oddball, converted the way ToNumber would.
+(function TaggedOddballSource() {
+ function f(v) { return v + 1; }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(2.25, f(1.25));
+ assertEquals(NaN, f(undefined));
+ assertEquals(2, f(true));
+ assertEquals(1, f(null));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(2.25, f(1.25));
+ assertEquals(NaN, f(undefined));
+ assertEquals(2, f(true));
+ assertEquals(1, f(false));
+ assertEquals(1, f(null));
+})();
+
+// A HoleyFloat64 whose use does not tolerate the hole: it deopts.
+(function HoleySourceIntolerant() {
+ function f(a, i) { return Math.sqrt(a[i]); }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(Math.sqrt(1.5), f(holey, 0));
+ assertEquals(Math.sqrt(1.5), f(holey, 0));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(Math.sqrt(3.5), f(holey, 2));
+ assertEquals(NaN, f(holey, 1)); // Math.sqrt(undefined) is NaN
+})();
+
+// A HoleyFloat64 whose use tolerates the hole: it converts it to NaN.
+(function HoleySourceTolerant() {
+ function f(a, i) { return a[i] + 1; }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(2.5, f(holey, 0));
+ assertEquals(NaN, f(holey, 1));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(4.5, f(holey, 2));
+ assertEquals(NaN, f(holey, 1));
+ assertTrue(isMaglevved(f));
+})();
+
+// A HoleyFloat64 stored into a packed double array, where the hole is not a
+// valid element and so has to deopt.
+(function HoleySourceChecked() {
+ function f(a, j, p, i) { p[i] = a[j]; }
+ const warm = [1.5, 2.5, 3.5];
+ %PrepareFunctionForOptimization(f);
+ f(holey, 0, warm, 0);
+ f(holey, 0, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const p = [1.5, 2.5, 3.5];
+ f(holey, 2, p, 0);
+ assertEquals(3.5, p[0]);
+ f(holey, 1, p, 1); // the hole is not a number: deopt, then store undefined
+ assertEquals(undefined, p[1]);
+})();
+
+// A tagged value already known to be a number, whose Float64 was not kept
+// across the merge, so it is converted again without a check.
+(function KnownNumberSource() {
+ function f(v, c) {
+ let x = v * 1;
+ if (c) { x = x + 1; }
+ return Math.sqrt(v) + x;
+ }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(3.75, f(2.25, false));
+ assertEquals(4.75, f(2.25, true));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(8.75, f(6.25, false));
+ assertEquals(9.75, f(6.25, true));
+ assertTrue(isMaglevved(f));
+})();
+
+// An IntPtr, which is what a typed array length is.
+(function IntPtrSource() {
+ function f(t, h, i) { h[i] = t.length; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f(typed, warm, 0);
+ f(typed, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(typed, h, 0);
+ assertEquals(2, h[0]);
+ assertTrue(0 in h);
+})();
+
+// The type of the input contradicts what the conversion assumes.
+(function ImpossibleType() {
+ function f(a, i) { return a[i] * 2; }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(NaN, f(objects, 0));
+ assertEquals(NaN, f(objects, 0));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(NaN, f(objects, 1));
+})();
+
+// The Float64 of a value is reused once it has been converted.
+(function ReusedFloat64Alternative() {
+ function f(o) { return Math.sqrt(o.x) + Math.sqrt(o.x) + o.x; }
+ %PrepareFunctionForOptimization(f);
+ assertEquals(5.25, f({x: 2.25}));
+ assertEquals(5.25, f({x: 2.25}));
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(11.25, f({x: 6.25}));
+ assertTrue(isMaglevved(f));
+})();
+
+// ----------------------------------------------------------- to HoleyFloat64
+
+// Storing into a holey double array converts into HoleyFloat64. Each case
+// checks that the element is a real element with the right value, i.e. that its
+// bits were not left meaning the hole or undefined.
+function store(v, i) {
+ const h = [1.5, , 3.5, 4.5];
+ h[i] = v;
+ return h;
+}
+
+// The value is already a HoleyFloat64, hole included.
+(function HoleyToHoley() {
+ function f(a, j, h, i) { h[i] = a[j]; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f(holey, 0, warm, 0);
+ // Warm the hole too, so that the optimized call below does not deopt on it.
+ f(holey, 1, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(holey, 2, h, 0);
+ assertEquals(3.5, h[0]);
+ f(holey, 1, h, 0); // the hole reads as undefined and stays undefined
+ assertTrue(0 in h);
+ assertEquals(undefined, h[0]);
+ assertTrue(isMaglevved(f));
+})();
+
+// A constant, including the undefined one.
+(function ConstantToHoley() {
+ function f(h, i) { h[i] = 1.5; }
+ function g(h, i) { h[i] = undefined; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ %PrepareFunctionForOptimization(g);
+ f(warm, 0); f(warm, 0); g(warm, 0); g(warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+ %OptimizeMaglevOnNextCall(g);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(h, 0);
+ assertEquals(1.5, h[0]);
+ g(h, 0);
+ assertTrue(0 in h);
+ assertEquals(undefined, h[0]);
+})();
+
+// An Int32 and a Uint32, which cannot mean the hole and so are widened for
+// free.
+(function IntToHoley() {
+ function f(h, i, x) { h[i] = x | 0; }
+ function g(h, i, x) { h[i] = x >>> 0; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ %PrepareFunctionForOptimization(g);
+ f(warm, 0, 7); f(warm, 0, 7); g(warm, 0, 7); g(warm, 0, 7);
+ %OptimizeMaglevOnNextCall(f);
+ %OptimizeMaglevOnNextCall(g);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(h, 0, 9);
+ assertEquals(9, h[0]);
+ g(h, 0, -1);
+ assertEquals(2 ** 32 - 1, h[0]);
+ assertTrue(0 in h);
+})();
+
+// A tagged Smi, which goes through the Int32 conversion.
+(function TaggedSmiToHoley() {
+ function f(a, j, h, i) { h[i] = a[j]; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f(smis, 0, warm, 0);
+ f(smis, 0, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(smis, 1, h, 0);
+ assertEquals(2, h[0]);
+ assertTrue(0 in h);
+})();
+
+// A tagged number that is not a Smi.
+(function TaggedNumberToHoley() {
+ function f(o, h, i) { h[i] = o.x; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f({x: 2.25}, warm, 0);
+ f({x: 2.25}, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f({x: 6.25}, h, 0);
+ assertEquals(6.25, h[0]);
+ assertTrue(0 in h);
+})();
+
+// A tagged oddball: undefined is a valid element of a holey double array, the
+// others deopt or convert as ToNumber would.
+(function TaggedOddballToHoley() {
+ function f(v, h, i) { h[i] = v; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f(2.25, warm, 0);
+ f(undefined, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(6.25, h, 0);
+ assertEquals(6.25, h[0]);
+ f(undefined, h, 0);
+ assertTrue(0 in h);
+ assertEquals(undefined, h[0]);
+})();
+
+// A Float64 that cannot be one of the NaN patterns is widened for free, and one
+// that could be is silenced first.
+(function Float64ToHoley() {
+ function arith(a, j, h, i) { h[i] = a[j] * 2; }
+ function load(t, j, h, i) { h[i] = t[j]; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(arith);
+ %PrepareFunctionForOptimization(load);
+ arith(packed, 0, warm, 0); arith(packed, 0, warm, 0);
+ load(typed, 0, warm, 0); load(typed, 0, warm, 0);
+ %OptimizeMaglevOnNextCall(arith);
+ %OptimizeMaglevOnNextCall(load);
+
+ const h = [1.5, , 3.5, 4.5];
+ arith(packed, 1, h, 0);
+ assertEquals(5, h[0]);
+ assertTrue(0 in h);
+ load(typed, 1, h, 0);
+ assertEquals(2.5, h[0]);
+ assertTrue(0 in h);
+})();
+
+// A value whose type contradicts what the store assumes.
+(function ImpossibleTypeToHoley() {
+ function f(a, j, h, i) { h[i] = a[j]; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f(objects, 0, warm, 0);
+ f(objects, 0, warm, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f(objects, 1, h, 0);
+ assertEquals(objects[1], h[0]);
+})();
+
+// The HoleyFloat64 of a value is reused once it has been converted.
+(function ReusedHoleyAlternative() {
+ function f(o, h, i, j) { h[i] = o.x; h[j] = o.x; }
+ const warm = [1.5, , 3.5, 4.5];
+ %PrepareFunctionForOptimization(f);
+ f({x: 2.25}, warm, 0, 2);
+ f({x: 2.25}, warm, 0, 2);
+ %OptimizeMaglevOnNextCall(f);
+
+ const h = [1.5, , 3.5, 4.5];
+ f({x: 6.25}, h, 0, 2);
+ assertEquals(6.25, h[0]);
+ assertEquals(6.25, h[2]);
+ assertTrue(isMaglevved(f));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/generator-next-cross-realm.js b/deps/v8/test/mjsunit/maglev/generator-next-cross-realm.js
new file mode 100644
index 00000000000..c02a44fb7e9
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/generator-next-cross-realm.js
@@ -0,0 +1,126 @@
+// 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
+
+(function() {
+ const realm = Realm.createAllowCrossRealmAccess();
+ const remote_object_prototype = Realm.eval(realm, "Object.prototype");
+ Realm.eval(realm, `
+ function* gen() {
+ yield 1;
+ yield 2;
+ return 3;
+ }
+ `);
+
+ const remote_gen = Realm.eval(realm, "gen");
+
+ function* local_gen() {
+ yield 10;
+ yield 20;
+ return 30;
+ }
+
+ // Test Maglev with cross-realm generator.
+ function testMaglev(g) {
+ return g.next();
+ }
+ %PrepareFunctionForOptimization(testMaglev);
+
+ let g1 = remote_gen();
+ let res1_1 = testMaglev(g1);
+ assertEquals(1, res1_1.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res1_1));
+
+ let res1_2 = testMaglev(g1);
+ assertEquals(2, res1_2.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res1_2));
+
+ %OptimizeMaglevOnNextCall(testMaglev);
+
+ let res1_3 = testMaglev(g1);
+ assertEquals(3, res1_3.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res1_3));
+
+ // Test TurboFan with cross-realm generator.
+ function testTurboFan(g) {
+ return g.next();
+ }
+ %PrepareFunctionForOptimization(testTurboFan);
+
+ let g2 = remote_gen();
+ let res2_1 = testTurboFan(g2);
+ assertEquals(1, res2_1.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res2_1));
+
+ let res2_2 = testTurboFan(g2);
+ assertEquals(2, res2_2.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res2_2));
+
+ %OptimizeFunctionOnNextCall(testTurboFan);
+
+ let res2_3 = testTurboFan(g2);
+ assertEquals(3, res2_3.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res2_3));
+
+ // Test polymorphic case in Maglev.
+ function testPolyMaglev(g) {
+ return g.next();
+ }
+ %PrepareFunctionForOptimization(testPolyMaglev);
+
+ let g_local = local_gen();
+ let g_remote = remote_gen();
+
+ let res_poly_local_1 = testPolyMaglev(g_local);
+ assertEquals(10, res_poly_local_1.value);
+ assertSame(Object.prototype, Object.getPrototypeOf(res_poly_local_1));
+
+ let res_poly_remote_1 = testPolyMaglev(g_remote);
+ assertEquals(1, res_poly_remote_1.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res_poly_remote_1));
+
+ %OptimizeMaglevOnNextCall(testPolyMaglev);
+
+ let res_poly_local_2 = testPolyMaglev(g_local);
+ assertEquals(20, res_poly_local_2.value);
+ assertSame(Object.prototype, Object.getPrototypeOf(res_poly_local_2));
+
+ let res_poly_remote_2 = testPolyMaglev(g_remote);
+ assertEquals(2, res_poly_remote_2.value);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res_poly_remote_2));
+})();
+
+(function() {
+ const realm = Realm.createAllowCrossRealmAccess();
+ const remote_object_prototype = Realm.eval(realm, "Object.prototype");
+ Realm.eval(realm, `
+ function* gen() {
+ yield 1;
+ yield 2;
+ return 3;
+ }
+ `);
+ const remote_gen = Realm.eval(realm, "gen");
+ const remote_next = Object.getPrototypeOf(remote_gen()).next;
+ function testMaglev(g) {
+ return remote_next.call(g);
+ }
+ %PrepareFunctionForOptimization(testMaglev);
+ let g1 = remote_gen();
+ testMaglev(g1);
+ %OptimizeMaglevOnNextCall(testMaglev);
+ let res1_2 = testMaglev(g1);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res1_2));
+ function testTurboFan(g) {
+ return remote_next.call(g);
+ }
+ %PrepareFunctionForOptimization(testTurboFan);
+ let g2 = remote_gen();
+ testTurboFan(g2);
+ %OptimizeFunctionOnNextCall(testTurboFan);
+ let res2_2 = testTurboFan(g2);
+ assertSame(remote_object_prototype, Object.getPrototypeOf(res2_2));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/holey-double-store-canonicalization.js b/deps/v8/test/mjsunit/maglev/holey-double-store-canonicalization.js
new file mode 100644
index 00000000000..c68b060874d
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/holey-double-store-canonicalization.js
@@ -0,0 +1,153 @@
+// 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
+
+// Storing a double into an array only canonicalizes its NaN patterns when they
+// could be the hole or undefined ones. Arithmetic results never can, since
+// those patterns are signalling NaNs and IEEE 754 arithmetic does not return
+// one, but values read out of a Float64Array can be anything, and operations
+// that manipulate bits rather than values can turn them into the patterns.
+
+// A Float64Array lets us build any bit pattern. 0x7FF7FFFF'FFF7FFFF is the hole
+// pattern with the sign bit cleared, so negating it produces the hole itself.
+const bits = new Float64Array(2);
+const words = new Uint32Array(bits.buffer);
+words[0] = 0xFFF7FFFF;
+words[1] = 0x7FF7FFFF; // bits[0] = -hole_nan
+words[2] = 0xFFF7FFFF;
+words[3] = 0xFFF7FFFF; // bits[1] = hole_nan
+
+function makeHoley(a) {
+ a[8] = 1.5; // -> HOLEY_DOUBLE_ELEMENTS, reinterpreting the bits stored below
+ return a;
+}
+
+// (1) Negating a fabricated NaN can produce the hole pattern, so the store has
+// to canonicalize it.
+(function() {
+ function f(out, i, ta, j) { out[i] = -ta[j]; }
+ const warmup = [7.5, 8.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup, 0, bits, 0);
+ f(warmup, 0, bits, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5];
+ f(out, 0, bits, 0);
+ assertTrue(isNaN(out[0]));
+ makeHoley(out);
+ assertTrue(0 in out);
+ assertTrue(isNaN(out[0]));
+})();
+
+// (2) Math.max of a value with itself can be compiled to nothing at all, so a
+// fabricated hole pattern survives it unchanged.
+(function() {
+ function f(out, i, ta, j) { out[i] = Math.max(ta[j], ta[j]); }
+ const warmup = [7.5, 8.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup, 0, bits, 1);
+ f(warmup, 0, bits, 1);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5];
+ f(out, 0, bits, 1);
+ assertTrue(isNaN(out[0]));
+ makeHoley(out);
+ assertTrue(0 in out);
+ assertTrue(isNaN(out[0]));
+})();
+
+// (3) Arithmetic on the same value cannot produce the patterns, so nothing is
+// canonicalized and the element is still a NaN.
+(function() {
+ function f(out, i, ta, j) { out[i] = ta[j] * 1.5; }
+ const warmup = [7.5, 8.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup, 0, bits, 1);
+ f(warmup, 0, bits, 1);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5];
+ f(out, 0, bits, 1);
+ assertTrue(isNaN(out[0]));
+ makeHoley(out);
+ assertTrue(0 in out);
+ assertTrue(isNaN(out[0]));
+})();
+
+// (4) A copy between double arrays goes through a load, which can read a
+// pattern that was fabricated into the source array.
+(function() {
+ function f(out, i, src, j) { out[i] = src[j]; }
+ const warmup = [7.5, 8.5];
+ const src = [1.5, 2.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup, 0, src, 0);
+ f(warmup, 0, src, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5];
+ f(out, 0, src, 1);
+ assertEquals(2.5, out[0]);
+ makeHoley(out);
+ assertTrue(0 in out);
+ assertEquals(2.5, out[0]);
+})();
+
+// (5) Into a holey double array, a hole read out of another one is undefined
+// and stays undefined, while a NaN stays a NaN.
+(function() {
+ function f(out, i, src, j) { out[i] = src[j]; }
+ const src = [1.5, , 2.5];
+ const warmup = [7.5, 8.5, , 9.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup, 0, src, 0);
+ f(warmup, 0, src, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5, , 9.5];
+ f(out, 0, src, 1);
+ assertTrue(0 in out);
+ assertEquals(undefined, out[0]);
+
+ f(out, 1, bits, 1); // a fabricated hole pattern is a NaN, not a hole
+ assertTrue(1 in out);
+ assertTrue(isNaN(out[1]));
+})();
+
+// (6) An arithmetic result stored into a holey double array needs no
+// canonicalization either.
+(function() {
+ function f(out, i, a, j) { out[i] = a[j] + 1; }
+ const a = [1.5, 2.5];
+ const warmup = [7.5, 8.5, , 9.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup, 0, a, 0);
+ f(warmup, 0, a, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5, , 9.5];
+ f(out, 0, a, 1);
+ assertEquals(3.5, out[0]);
+ assertTrue(0 in out);
+})();
+
+// (7) Shrinking an array still writes a real hole into the vacated slot.
+(function() {
+ function f(a) { return a.pop(); }
+ const warmup = [1.5, 2.5, 3.5];
+ %PrepareFunctionForOptimization(f);
+ f(warmup);
+ f(warmup);
+ %OptimizeMaglevOnNextCall(f);
+
+ const a = [1.5, 2.5, 3.5];
+ assertEquals(3.5, f(a));
+ assertEquals(2, a.length);
+ a.length = 3;
+ assertFalse(2 in a);
+ assertEquals(undefined, a[2]);
+})();
diff --git a/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js b/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js
new file mode 100644
index 00000000000..3732ffe9860
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/holey-double-unsilenced-exit.js
@@ -0,0 +1,115 @@
+// 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 HoleyFloat64 -> Float64 conversion of a hole-tolerant use does not silence
+// the hole and undefined NaN patterns anymore, so the resulting Float64 can
+// carry them. Everything that gives those bits back their meaning (storing them
+// into a double array, or rematerializing them on deopt) has to canonicalize
+// them itself, otherwise a plain NaN would read back as a hole or as undefined.
+
+// (1) ToNumber of a hole, stored into a packed double array that later becomes
+// holey: the element must survive the elements-kind transition.
+(function() {
+ function f(a, i, out) { out[0] = +a[i]; }
+ const a = [1.5, , 2.5];
+ const warmup = [7.5, 8.5];
+ %PrepareFunctionForOptimization(f);
+ f(a, 0, warmup);
+ f(a, 0, warmup);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5]; // PACKED_DOUBLE_ELEMENTS
+ f(a, 1, out); // out[0] = +undefined = NaN
+ assertTrue(isNaN(out[0]));
+ out[4] = 9.5; // -> HOLEY_DOUBLE_ELEMENTS
+ assertTrue(0 in out);
+ assertTrue(isNaN(out[0]));
+})();
+
+// (2) Same, for an arithmetic use whose operation folds away.
+(function() {
+ function f(a, i, out) { out[0] = a[i] * 1; }
+ const a = [1.5, , 2.5];
+ const warmup = [7.5, 8.5];
+ %PrepareFunctionForOptimization(f);
+ f(a, 0, warmup);
+ f(a, 0, warmup);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5];
+ f(a, 1, out);
+ assertTrue(isNaN(out[0]));
+ out[4] = 9.5;
+ assertTrue(0 in out);
+ assertTrue(isNaN(out[0]));
+})();
+
+// (3) The same value used to initialize a double array literal.
+(function() {
+ function f(a, i) { return [+a[i], 1.5]; }
+ const a = [1.5, , 2.5];
+ %PrepareFunctionForOptimization(f);
+ f(a, 0);
+ f(a, 0);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = f(a, 1);
+ assertTrue(isNaN(out[0]));
+ out[4] = 9.5;
+ assertTrue(0 in out);
+ assertTrue(isNaN(out[0]));
+})();
+
+// (4) Stored back into a holey double array, it must stay a NaN element rather
+// than becoming a hole or an undefined.
+(function() {
+ function f(a, i, out) { out[1] = +a[i]; }
+ const a = [1.5, , 2.5];
+ const warmup = [7.5, 8.5, , 9.5];
+ %PrepareFunctionForOptimization(f);
+ f(a, 0, warmup);
+ f(a, 0, warmup);
+ %OptimizeMaglevOnNextCall(f);
+
+ const out = [7.5, 8.5, , 9.5]; // HOLEY_DOUBLE_ELEMENTS
+ f(a, 1, out);
+ assertTrue(1 in out);
+ assertTrue(isNaN(out[1]));
+})();
+
+// (5) Rematerialized on a lazy deopt, it must be a NaN and not an undefined.
+(function() {
+ function f(a, i) {
+ const x = +a[i];
+ %DeoptimizeFunction(f);
+ return x;
+ }
+ const a = [1.5, , 2.5];
+ %PrepareFunctionForOptimization(f);
+ assertEquals(1.5, f(a, 0));
+ assertEquals(1.5, f(a, 0));
+ %OptimizeMaglevOnNextCall(f);
+ assertTrue(isNaN(f(a, 1)));
+})();
+
+// (6) A HoleyFloat64 phi feeding an untagging that tolerated undefined must not
+// deopt when it sees a hole.
+(function() {
+ function f(a, i, j, c) {
+ const x = c ? a[i] : a[j];
+ return x + 1;
+ }
+ const a = [1.5, , 2.5, 3.5];
+ %PrepareFunctionForOptimization(f);
+ assertEquals(2.5, f(a, 0, 2, true));
+ assertEquals(3.5, f(a, 0, 2, false));
+ assertTrue(isNaN(f(a, 1, 2, true))); // undefined + 1 = NaN
+ %OptimizeMaglevOnNextCall(f);
+ assertEquals(2.5, f(a, 0, 2, true));
+ assertTrue(isMaglevved(f));
+ assertTrue(isNaN(f(a, 1, 2, true)));
+ assertTrue(isMaglevved(f));
+})();
diff --git a/deps/v8/test/mjsunit/maglev/int32-mod-range.js b/deps/v8/test/mjsunit/maglev/int32-mod-range.js
new file mode 100644
index 00000000000..3e9bedb5ca1
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/int32-mod-range.js
@@ -0,0 +1,77 @@
+// 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
+
+// x % <constant> has a range bounded by the divisor's magnitude. A loop
+// counter bounded by such a value is Smi-sized by construction, which lets
+// the compiler drop the Smi-size check and the increment overflow check on
+// the counter phi.
+
+function fill(bytes, x) {
+ const n = x % 2056;
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ bytes[i] = (i + x) % 256;
+ sum += bytes[i];
+ }
+ return sum;
+}
+
+%PrepareFunctionForOptimization(fill);
+const bytes = new Uint8Array(2056);
+const expected = fill(bytes, 1500);
+%OptimizeFunctionOnNextCall(fill);
+assertEquals(expected, fill(bytes, 1500));
+assertOptimized(fill);
+
+// A negative dividend gives a negative modulus: the loop must not run.
+assertEquals(0, fill(bytes, -1500));
+
+// A zero dividend gives 0 % 2056 == 0: the loop must not run either.
+assertEquals(0, fill(bytes, 0));
+
+// A modulus of a negative constant still bounds the counter.
+function fill_neg_divisor(bytes, x) {
+ const n = x % -100;
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ sum += bytes[i] + i;
+ }
+ return sum;
+}
+
+%PrepareFunctionForOptimization(fill_neg_divisor);
+const expected_neg = fill_neg_divisor(bytes, 99);
+%OptimizeFunctionOnNextCall(fill_neg_divisor);
+assertEquals(expected_neg, fill_neg_divisor(bytes, 99));
+
+// A non-constant divisor bounds the result by the divisor's own range.
+function mod_var_divisor(x, d) {
+ const n = x % (d % 50 + 51);
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ sum += i;
+ }
+ return sum;
+}
+
+%PrepareFunctionForOptimization(mod_var_divisor);
+const expected_var = mod_var_divisor(1000, 30);
+%OptimizeFunctionOnNextCall(mod_var_divisor);
+assertEquals(expected_var, mod_var_divisor(1000, 30));
+
+// The -0 result and zero-divisor deopt paths must stay correct.
+function mod_minus_zero(x, d) {
+ return Object.is(x % d, -0);
+}
+
+%PrepareFunctionForOptimization(mod_minus_zero);
+assertFalse(mod_minus_zero(10, 4));
+assertFalse(mod_minus_zero(8, 4));
+%OptimizeFunctionOnNextCall(mod_minus_zero);
+assertFalse(mod_minus_zero(10, 4));
+assertTrue(mod_minus_zero(-8, 4));
+assertFalse(mod_minus_zero(8, 0));
+assertTrue(Number.isNaN(8 % 0));
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
new file mode 100644
index 00000000000..9ff62204f95
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/keyed-access-thin-constant-key.js
@@ -0,0 +1,35 @@
+// 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 --no-turbofan
+
+// A keyed access with monomorphic name feedback and a constant key that is a
+// ThinString of the recorded name must not deopt unconditionally.
+
+function makeAccessor(key) {
+ return {
+ get(o) { return o[key]; },
+ set(o, v) { o[key] = v; },
+ };
+}
+
+// Turns the (computed, non-internalized) string into a ThinString in place.
+const key = %ConstructThinString('__props$' + 'abcdefghij0123456789');
+const acc = makeAccessor(key);
+const o = {};
+
+%PrepareFunctionForOptimization(acc.set);
+acc.set(o, 1);
+acc.set(o, 2);
+%OptimizeMaglevOnNextCall(acc.set);
+acc.set(o, 3);
+assertTrue(isMaglevved(acc.set));
+assertEquals(3, o[key]);
+
+%PrepareFunctionForOptimization(acc.get);
+assertEquals(3, acc.get(o));
+assertEquals(3, acc.get(o));
+%OptimizeMaglevOnNextCall(acc.get);
+assertEquals(3, acc.get(o));
+assertTrue(isMaglevved(acc.get));
diff --git a/deps/v8/test/mjsunit/maglev/loop-preheader.js b/deps/v8/test/mjsunit/maglev/loop-preheader.js
new file mode 100644
index 00000000000..6c53241d520
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/loop-preheader.js
@@ -0,0 +1,194 @@
+// 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
+
+// Shapes where a bytecode merge point lands exactly on a loop header, giving
+// the header several forward predecessors. The graph builder has to merge
+// those in a pre-header, so that the header keeps exactly two predecessors.
+
+function sideEffect() {
+ globalThis.x = (globalThis.x | 0) + 1;
+}
+
+// Runs {fn} on every argument list of {cases} (a list of [args, expected])
+// interpreted, then in Maglev, then in the top tier.
+function testAllTiers(fn, cases) {
+ %PrepareFunctionForOptimization(fn);
+ for (const [args, expected] of cases) assertEquals(expected, fn(...args));
+ %OptimizeMaglevOnNextCall(fn);
+ for (const [args, expected] of cases) assertEquals(expected, fn(...args));
+ %PrepareFunctionForOptimization(fn);
+ %OptimizeFunctionOnNextCall(fn);
+ for (const [args, expected] of cases) assertEquals(expected, fn(...args));
+}
+
+// An `if` whose join point is the loop header.
+function ifJoin(a, n) {
+ if (a) sideEffect();
+ let sum = 0;
+ while (n > 0) {
+ sum += n;
+ n--;
+ }
+ return sum;
+}
+testAllTiers(ifJoin, [[[true, 3], 6], [[false, 3], 6]]);
+
+// Several switch cases joining on the loop header.
+function switchJoin(a, n) {
+ switch (a) {
+ case 0:
+ sideEffect();
+ break;
+ case 1:
+ break;
+ case 2:
+ sideEffect();
+ sideEffect();
+ break;
+ }
+ let sum = 0;
+ while (n > 0) {
+ sum += n;
+ n--;
+ }
+ return sum;
+}
+testAllTiers(switchJoin,
+ [[[0, 3], 6], [[1, 3], 6], [[2, 3], 6], [[3, 3], 6]]);
+
+// Same, but on an outer loop, which is not eagerly peeled.
+function ifJoinOuterLoop(a, n, m) {
+ if (a) sideEffect();
+ let sum = 0;
+ while (n > 0) {
+ let i = m;
+ while (i > 0) {
+ sum++;
+ i--;
+ }
+ n--;
+ }
+ return sum;
+}
+testAllTiers(ifJoinOuterLoop, [[[true, 3, 2], 6], [[false, 3, 2], 6]]);
+
+// Nested `if`s, so that the header has more than two forward predecessors.
+function manyForwardEdges(a, b, n) {
+ if (a) {
+ sideEffect();
+ } else if (b) {
+ sideEffect();
+ sideEffect();
+ }
+ let sum = 0;
+ while (n > 0) {
+ sum += n;
+ n--;
+ }
+ return sum;
+}
+testAllTiers(
+ manyForwardEdges,
+ [[[true, false, 3], 6], [[false, true, 3], 6], [[false, false, 3], 6]]);
+
+// Values flowing through the pre-header phis into the loop phis.
+function phiThroughPreheader(a, n) {
+ let acc;
+ if (a) {
+ acc = 1;
+ } else {
+ acc = 2.5;
+ }
+ while (n > 0) {
+ acc += n;
+ n--;
+ }
+ return acc;
+}
+testAllTiers(phiThroughPreheader, [[[true, 3], 7], [[false, 3], 8.5]]);
+
+// A `break` out of a (peelable) inner loop landing on the next loop's header.
+function breakOntoLoopHeader(n, m) {
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ if (i == 2) break;
+ sum++;
+ }
+ while (m > 0) {
+ sum += m;
+ m--;
+ }
+ return sum;
+}
+testAllTiers(breakOntoLoopHeader, [[[5, 3], 8], [[1, 3], 7]]);
+
+// The callee's loop header is split after being inlined.
+function inlinee(a, n) {
+ if (a) sideEffect();
+ let sum = 0;
+ while (n > 0) {
+ sum += n;
+ n--;
+ }
+ return sum;
+}
+function inliner(a, n) {
+ return inlinee(a, n);
+}
+%PrepareFunctionForOptimization(inlinee);
+testAllTiers(inliner, [[[true, 3], 6], [[false, 3], 6]]);
+
+// A forward edge that is dead when the graph is built: the `if` body is never
+// executed while collecting feedback, so it deoptimizes unconditionally.
+function neverWarm(x) {
+ return x.someUnknownProperty;
+}
+function deadForwardEdge(a, n) {
+ if (a) neverWarm(a);
+ let sum = 0;
+ while (n > 0) {
+ sum += n;
+ n--;
+ }
+ return sum;
+}
+%PrepareFunctionForOptimization(deadForwardEdge);
+assertEquals(6, deadForwardEdge(false, 3));
+%OptimizeMaglevOnNextCall(deadForwardEdge);
+assertEquals(6, deadForwardEdge(false, 3));
+assertEquals(6, deadForwardEdge({}, 3));
+
+// Resumable loops are entered through their resume edges, which bypass the
+// header, but their forward edges still go through the pre-header.
+function* generatorIfJoin(a, n) {
+ if (a) sideEffect();
+ while (n > 0) {
+ yield n;
+ n--;
+ }
+}
+function drive(a, n) {
+ let sum = 0;
+ for (const value of generatorIfJoin(a, n)) sum += value;
+ return sum;
+}
+%PrepareFunctionForOptimization(generatorIfJoin);
+testAllTiers(drive, [[[true, 3], 6], [[false, 3], 6]]);
+
+// OSR into a loop header preceded by a join.
+function osrIfJoin(a, n) {
+ if (a) sideEffect();
+ let sum = 0;
+ for (let i = 0; i < n; i++) {
+ sum += i;
+ if (i == 3) %OptimizeOsr();
+ }
+ return sum;
+}
+%PrepareFunctionForOptimization(osrIfJoin);
+assertEquals(45, osrIfJoin(true, 10));
+%PrepareFunctionForOptimization(osrIfJoin);
+assertEquals(45, osrIfJoin(false, 10));
diff --git a/deps/v8/test/mjsunit/maglev/map-iterator-creation.js b/deps/v8/test/mjsunit/maglev/map-iterator-creation.js
new file mode 100644
index 00000000000..f4ddb220655
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/map-iterator-creation.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 --maglev
+
+function getEntries(m) {
+ return m.entries();
+}
+
+function getKeys(m) {
+ return m.keys();
+}
+
+function getValues(m) {
+ return m.values();
+}
+
+const map = new Map([[1, 10], [2, 20]]);
+
+%PrepareFunctionForOptimization(getEntries);
+let it1 = getEntries(map);
+assertEquals([1, 10], it1.next().value);
+%OptimizeMaglevOnNextCall(getEntries);
+let it2 = getEntries(map);
+assertEquals([1, 10], it2.next().value);
+assertEquals([2, 20], it2.next().value);
+assertTrue(it2.next().done);
+
+%PrepareFunctionForOptimization(getKeys);
+let kit1 = getKeys(map);
+assertEquals(1, kit1.next().value);
+%OptimizeMaglevOnNextCall(getKeys);
+let kit2 = getKeys(map);
+assertEquals(1, kit2.next().value);
+assertEquals(2, kit2.next().value);
+assertTrue(kit2.next().done);
+
+%PrepareFunctionForOptimization(getValues);
+let vit1 = getValues(map);
+assertEquals(10, vit1.next().value);
+%OptimizeMaglevOnNextCall(getValues);
+let vit2 = getValues(map);
+assertEquals(10, vit2.next().value);
+assertEquals(20, vit2.next().value);
+assertTrue(vit2.next().done);
diff --git a/deps/v8/test/mjsunit/maglev/optimize-large-function.js b/deps/v8/test/mjsunit/maglev/optimize-large-function.js
new file mode 100644
index 00000000000..dc9979de786
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/optimize-large-function.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.
+
+// Flags: --allow-natives-syntax --maglev --no-turbofan
+
+// Functions above --max-optimized-bytecode-size (TurboFan's limit) but below
+// --max-maglev-optimized-bytecode-size must still be optimizable by Maglev
+// (e.g. the ~64KB zlib core function in JetStream2's octane-zlib).
+function buildLongBytecode(count) {
+ let body = '';
+ for (let i = 0; i < count; ++i) body += `sum += ${i};`;
+ return Function(`return function long(sum) { ${body} return sum; };`)();
+}
+
+const long = buildLongBytecode(12000);
+%PrepareFunctionForOptimization(long);
+const expected = long(0);
+%OptimizeMaglevOnNextCall(long);
+assertEquals(expected, long(0));
+assertOptimized(long);
diff --git a/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf-mode-1.js b/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf-mode-1.js
new file mode 100644
index 00000000000..4dad3c1ccd9
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf-mode-1.js
@@ -0,0 +1,63 @@
+// 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 --no-stress-opt
+// Flags: --no-baseline-batch-compilation --use-osr --turbofan
+// Flags: --max-bytecode-size-for-early-opt=0
+// Flags: --no-concurrent-osr
+
+let keep_going = 100000;
+
+function isMaglevOrTurbofan(func) {
+ let opt_status = %GetOptimizationStatus(func);
+ return (opt_status & (V8OptimizationStatus.kTopmostFrameIsMaglev |
+ V8OptimizationStatus.kTopmostFrameIsTurboFanned)) !== 0;
+}
+
+// Test 1: Function f has no OSR code installed on its loop.
+// With --osr-from-maglev=2 (default), Maglev should not emit OSR checks,
+// so f() should not OSR to TurboFan.
+function f() {
+ let sum = 0;
+ for (let i = 0; i < 100; i++) {
+ sum += i;
+ }
+ return sum;
+}
+
+function testNoOsr() {
+ assertTrue(%IsMaglevEnabled());
+ assertTrue(%IsTurbofanEnabled());
+
+ while (!%ActiveTierIsMaglev(f) && --keep_going) {
+ f();
+ }
+ assertTrue(keep_going > 0);
+
+ assertEquals(4950, f());
+ assertFalse(%CurrentFrameIsTurbofan());
+}
+%NeverOptimizeFunction(testNoOsr);
+testNoOsr();
+
+// Test 2: Function g triggers %OptimizeOsr() so OSR code is installed.
+// With --osr-from-maglev=2 (default) and --no-concurrent-osr, %OptimizeOsr() compiles
+// synchronously, installing OSR code.
+function g() {
+ for (let i = 0; i < 20; i++) {
+ if (i == 5) {
+ %OptimizeOsr();
+ }
+ if (i > 10) {
+ if (isMaglevOrTurbofan(g)) {
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+g();
+%PrepareFunctionForOptimization(g);
+assertTrue(g());
diff --git a/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf.js b/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf.js
index 593c60171e7..255147d9817 100644
--- a/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf.js
+++ b/deps/v8/test/mjsunit/maglev/osr-from-ml-to-tf.js
@@ -8,8 +8,7 @@
// Disable small-function TF optimization to avoid flakes that unexpectedly
// tier up `f` before we get a chance to enter the OSR loop.
// Flags: --max-bytecode-size-for-early-opt=0
-// Flags: --osr-from-maglev --concurrent-osr --concurrent-recompilation
-// Flags: --always-osr-from-maglev
+// Flags: --concurrent-osr --concurrent-recompilation --osr-from-maglev=4
let keep_going = 10000000; // A counter to avoid test hangs on failure.
let i; // The loop counter for the test function.
diff --git a/deps/v8/test/mjsunit/maglev/osr-multiple-loops.js b/deps/v8/test/mjsunit/maglev/osr-multiple-loops.js
new file mode 100644
index 00000000000..e8d903be09f
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/osr-multiple-loops.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 --maglev --no-stress-opt
+// Flags: --no-baseline-batch-compilation --use-osr --turbofan
+// Flags: --concurrent-osr --concurrent-recompilation
+// Flags: --osr-from-maglev=4
+
+let keep_going = 10000000;
+
+function multi_loop(select_loop) {
+ let reached_tf = false;
+ if (select_loop === 1) {
+ while (!reached_tf && --keep_going > 0) {
+ reached_tf = %CurrentFrameIsTurbofan();
+ }
+ } else {
+ while (!reached_tf && --keep_going > 0) {
+ reached_tf = %CurrentFrameIsTurbofan();
+ }
+ }
+ return reached_tf;
+}
+
+function test() {
+ assertTrue(%IsTurbofanEnabled());
+ assertTrue(multi_loop(1));
+ assertTrue(keep_going > 0);
+ keep_going = 10000000;
+ assertTrue(multi_loop(2));
+ assertTrue(keep_going > 0);
+}
+%NeverOptimizeFunction(test);
+
+test();
diff --git a/deps/v8/test/mjsunit/maglev/osr-only-interrupt.js b/deps/v8/test/mjsunit/maglev/osr-only-interrupt.js
new file mode 100644
index 00000000000..f26afc06b24
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/osr-only-interrupt.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: --allow-natives-syntax --maglev --no-stress-opt
+// Flags: --no-baseline-batch-compilation --use-osr --turbofan
+// Flags: --concurrent-osr --concurrent-recompilation
+// Flags: --osr-from-maglev=4
+
+let keep_going = 10000000;
+
+function f() {
+ let reached_tf = false;
+ while (!reached_tf && --keep_going > 0) {
+ reached_tf = %CurrentFrameIsTurbofan();
+ }
+ return reached_tf;
+}
+
+function test() {
+ assertTrue(%IsTurbofanEnabled());
+ assertTrue(f());
+ assertTrue(keep_going > 0);
+}
+%NeverOptimizeFunction(test);
+
+test();
diff --git a/deps/v8/test/mjsunit/maglev/osr-to-tf.js b/deps/v8/test/mjsunit/maglev/osr-to-tf.js
index 82ff492623b..2c8a59b6285 100644
--- a/deps/v8/test/mjsunit/maglev/osr-to-tf.js
+++ b/deps/v8/test/mjsunit/maglev/osr-to-tf.js
@@ -5,8 +5,7 @@
// Flags: --allow-natives-syntax --maglev --no-stress-opt
// Flags: --no-baseline-batch-compilation --use-osr --turbofan
// Flags: --concurrent-osr --concurrent-recompilation
-// Flags: --osr-from-maglev --concurrent-osr --concurrent-recompilation
-// Flags: --always-osr-from-maglev
+// Flags: --osr-from-maglev=4
let keep_going = 10000000; // A counter to avoid test hangs on failure.
diff --git a/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js b/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js
new file mode 100644
index 00000000000..9d6c244560a
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/promise-catch-reduction.js
@@ -0,0 +1,162 @@
+// 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: --no-stress-opt --no-stress-incremental-marking
+
+// Promise.prototype.catch on a JSPromise with the initial Promise.prototype and
+// callable-or-undefined reaction reduces to an inlined result-promise
+// allocation plus a direct PerformPromiseThen call; rejection paths,
+// non-callable reactions, and subclassed receivers must keep their semantics.
+
+(async () => {
+ // 1. Basic reduction on fulfilled and rejected promises.
+ {
+ async function catchTest(p) {
+ return p.catch(e => -e);
+ }
+ %PrepareFunctionForOptimization(catchTest);
+ assertEquals(42, await catchTest(Promise.resolve(42)));
+ assertEquals(-5, await catchTest(Promise.reject(5)));
+ %OptimizeMaglevOnNextCall(catchTest);
+ assertEquals(42, await catchTest(Promise.resolve(42)));
+ assertEquals(-5, await catchTest(Promise.reject(5)));
+ assertTrue(isMaglevved(catchTest));
+ }
+
+ // 2. Non-callable reaction behaves like identity.
+ {
+ async function nonCallableCatch(p) {
+ return p.catch(123);
+ }
+ %PrepareFunctionForOptimization(nonCallableCatch);
+ assertEquals(10, await nonCallableCatch(Promise.resolve(10)));
+ assertEquals(10, await nonCallableCatch(Promise.resolve(10)));
+ %OptimizeMaglevOnNextCall(nonCallableCatch);
+ assertEquals(10, await nonCallableCatch(Promise.resolve(10)));
+ assertTrue(isMaglevved(nonCallableCatch));
+ }
+
+ // 3. Subclassed promise receiver.
+ {
+ class MyPromise extends Promise {}
+ function subCatch(p) {
+ return p.catch(e => -e);
+ }
+ %PrepareFunctionForOptimization(subCatch);
+ const p1 = subCatch(MyPromise.reject(2));
+ assertInstanceof(p1, MyPromise);
+ assertEquals(-2, await p1);
+
+ %OptimizeMaglevOnNextCall(subCatch);
+ const p2 = subCatch(MyPromise.reject(3));
+ assertInstanceof(p2, MyPromise);
+ assertEquals(-3, await p2);
+ assertTrue(isMaglevved(subCatch));
+ }
+
+ // 4. Chained catch handler.
+ {
+ async function chainedCatch(p) {
+ return p.catch(e => e + 1).catch(e => e * 2);
+ }
+ %PrepareFunctionForOptimization(chainedCatch);
+ assertEquals(10, await chainedCatch(Promise.resolve(10)));
+ assertEquals(6, await chainedCatch(Promise.reject(5)));
+ %OptimizeMaglevOnNextCall(chainedCatch);
+ assertEquals(10, await chainedCatch(Promise.resolve(10)));
+ assertEquals(6, await chainedCatch(Promise.reject(5)));
+ assertTrue(isMaglevved(chainedCatch));
+ }
+
+ // 5. Catch with zero arguments (on_rejected defaults to undefined).
+ {
+ async function zeroArgsCatch(p) {
+ return p.catch();
+ }
+ %PrepareFunctionForOptimization(zeroArgsCatch);
+ assertEquals(42, await zeroArgsCatch(Promise.resolve(42)));
+ let caught = false;
+ try {
+ await zeroArgsCatch(Promise.reject(5));
+ } catch (e) {
+ caught = true;
+ assertEquals(5, e);
+ }
+ assertTrue(caught);
+
+ %OptimizeMaglevOnNextCall(zeroArgsCatch);
+ assertEquals(42, await zeroArgsCatch(Promise.resolve(42)));
+ caught = false;
+ try {
+ await zeroArgsCatch(Promise.reject(5));
+ } catch (e) {
+ caught = true;
+ assertEquals(5, e);
+ }
+ assertTrue(caught);
+ assertTrue(isMaglevved(zeroArgsCatch));
+ }
+
+ // 6. Catch with extra arguments (extra arguments are ignored).
+ {
+ async function extraArgsCatch(p) {
+ return p.catch(e => -e, () => 'extra_ignored', 123);
+ }
+ %PrepareFunctionForOptimization(extraArgsCatch);
+ assertEquals(42, await extraArgsCatch(Promise.resolve(42)));
+ assertEquals(-5, await extraArgsCatch(Promise.reject(5)));
+ %OptimizeMaglevOnNextCall(extraArgsCatch);
+ assertEquals(42, await extraArgsCatch(Promise.resolve(42)));
+ assertEquals(-5, await extraArgsCatch(Promise.reject(5)));
+ assertTrue(isMaglevved(extraArgsCatch));
+ }
+
+ // 7. Spread call p.catch(...args) (skips reduction and falls back to generic call).
+ {
+ async function spreadCatch(p, args) {
+ return p.catch(...args);
+ }
+ %PrepareFunctionForOptimization(spreadCatch);
+ 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), []));
+ %OptimizeMaglevOnNextCall(spreadCatch);
+ 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));
+ }
+
+ // 8. Reduction registers a dependency on PromiseThenProtector.
+ // When Promise.prototype.then is modified, the protector is invalidated,
+ // the optimized code must deoptimize, and re-optimization must not re-reduce.
+ {
+ function testThenProtector(p) {
+ return p.catch(x => x);
+ }
+ const p = Promise.resolve(1);
+ %PrepareFunctionForOptimization(testThenProtector);
+ testThenProtector(p);
+ testThenProtector(p);
+ %OptimizeMaglevOnNextCall(testThenProtector);
+ testThenProtector(p);
+ assertTrue(isMaglevved(testThenProtector));
+
+ // Invalidate PromiseThenProtector.
+ Promise.prototype.then = function() {
+ return 'patched';
+ };
+ assertUnoptimized(testThenProtector);
+ assertEquals('patched', testThenProtector(p));
+
+ // Re-optimization must refuse reduction and continue to invoke patched .then.
+ %PrepareFunctionForOptimization(testThenProtector);
+ testThenProtector(p);
+ testThenProtector(p);
+ %OptimizeMaglevOnNextCall(testThenProtector);
+ assertEquals('patched', testThenProtector(p));
+ assertTrue(isMaglevved(testThenProtector));
+ }
+})();
diff --git a/deps/v8/test/mjsunit/maglev/regress-394119934.js b/deps/v8/test/mjsunit/maglev/regress-394119934.js
new file mode 100644
index 00000000000..b0cc600fa76
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-394119934.js
@@ -0,0 +1,35 @@
+// 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 --no-stress-opt
+// Flags: --no-baseline-batch-compilation --use-osr --turbofan
+// Flags: --max-bytecode-size-for-early-opt=0
+// Flags: --osr-from-maglev=4 --maglev-loop-peeling
+
+let keep_going = 1000000;
+let i;
+
+function f() {
+ let sum = 0;
+ while (--i > 0 && !%CurrentFrameIsTurbofan() && --keep_going) {
+ sum += i;
+ }
+ return sum;
+}
+
+function g() {
+ if (!%IsMaglevEnabled() || !%IsTurbofanEnabled()) return;
+
+ while (!%ActiveTierIsMaglev(f) && --keep_going) {
+ i = 5;
+ f();
+ }
+
+ i = 10000;
+ f();
+ assertTrue(keep_going > 0);
+}
+%NeverOptimizeFunction(g);
+
+g();
diff --git a/deps/v8/test/mjsunit/maglev/regress-536945254.js b/deps/v8/test/mjsunit/maglev/regress-536945254.js
index 522bcfd8ff2..470f1b21d68 100644
--- a/deps/v8/test/mjsunit/maglev/regress-536945254.js
+++ b/deps/v8/test/mjsunit/maglev/regress-536945254.js
@@ -3,6 +3,7 @@
// found in the LICENSE file.
// Flags: --allow-natives-syntax --maglev --no-turbofan
+// Flags: --max-maglev-optimized-bytecode-size=61440
// Keeps `count` Int32 and Float64 values live at once, so Maglev needs roughly
// two stack slots per value while the bytecode stays small.
diff --git a/deps/v8/test/mjsunit/maglev/regress-538562119.js b/deps/v8/test/mjsunit/maglev/regress-538562119.js
new file mode 100644
index 00000000000..33588ef0386
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-538562119.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 --maglev --concurrent-recompilation
+// Flags: --no-turbofan
+
+// A concurrent Maglev job that fails on the background thread must still reach
+// the main thread, which is the only place that resets tiering_in_progress.
+// Dropping it there leaves the flag set and locks the function out of all
+// further tiering, including Turbofan.
+
+// Keeps `count` Int32 and Float64 values live at once, so Maglev needs more
+// stack slots than it is willing to emit a frame for, while the bytecode stays
+// small enough to pass the size check in PrepareJobImpl.
+function buildWideFrame(count) {
+ let preload = '';
+ let integerFold = '';
+ let doubleFold = '';
+ for (let i = 0; i < count; ++i) {
+ preload += `0.5 + (input ^ ${i});`;
+ integerFold += `integer ^= (input ^ ${i});`;
+ doubleFold += `double += (input ^ ${i});`;
+ }
+ return Function(`
+ return function wide(input) {
+ input |= 0;
+ let result = 0;
+ for (let iteration = 0; iteration < 20; ++iteration) {
+ ${preload}
+ let integer = 0;
+ ${integerFold}
+ let double = 0.5;
+ ${doubleFold}
+ result = (integer + double) | 0;
+ }
+ return result;
+ };
+ `)();
+}
+
+const wide = buildWideFrame(400);
+%PrepareFunctionForOptimization(wide);
+const expected = wide(1);
+
+// Establish that Maglev really does fail on this function, otherwise the check
+// below would pass vacuously.
+%OptimizeMaglevOnNextCall(wide);
+assertEquals(expected, wide(1));
+assertUnoptimized(wide);
+
+// Now let the same failure happen on a background thread.
+%OptimizeMaglevOnNextCall(wide, 'concurrent');
+assertEquals(expected, wide(1));
+%WaitForBackgroundOptimization();
+%FinalizeOptimization();
+
+// The job is gone, so no tiering is in progress anymore. A leaked
+// tiering_in_progress keeps kOptimizingConcurrently set here and makes every
+// later tiering request for `wide` a silent no-op.
+assertFalse(
+ (%GetOptimizationStatus(wide) &
+ V8OptimizationStatus.kOptimizingConcurrently) !== 0,
+ 'tiering_in_progress leaked by dropped background job');
diff --git a/deps/v8/test/mjsunit/maglev/regress-538884561-1.js b/deps/v8/test/mjsunit/maglev/regress-538884561-1.js
new file mode 100644
index 00000000000..1dbc1629aba
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-538884561-1.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 --no-maglev-optimistic-peeled-loops
+// Flags: --maglev-non-eager-inlining --max-maglev-eager-inlined-bytecode-size=0
+
+let o = { x : 42 };
+o.x = "abc"; // Making non-const and AnyTagged representation.
+
+function store(v) {
+ o.x = v;
+}
+
+function foo() {
+ for (let phi = 0; phi < 10; phi) {
+ ~phi; // Smi feedback, will insert CheckedSmiUntag
+ store(phi);
+ phi = 0x7fffffff;
+ o.x = phi; // Tagging {phi}.
+ }
+}
+
+%PrepareFunctionForOptimization(store);
+%PrepareFunctionForOptimization(foo);
+foo();
+foo();
+
+%OptimizeMaglevOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/maglev/regress-538884561-2.js b/deps/v8/test/mjsunit/maglev/regress-538884561-2.js
new file mode 100644
index 00000000000..8dbcfd6313e
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-538884561-2.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: --allow-natives-syntax --no-maglev-optimistic-peeled-loops
+// Flags: --maglev-non-eager-inlining --max-maglev-eager-inlined-bytecode-size=0
+
+let o = { x : 42 };
+o.x = "abc"; // Making non-const and AnyTagged representation.
+
+function store(v) {
+ o.x = v;
+}
+
+function foo(b) {
+ for (let phi = 0; phi < 10; phi) {
+ if (b) {
+ ~phi; // Smi feedback, will insert CheckedSmiUntag
+ store(phi);
+ }
+ phi = 0x7fffffff;
+ o.x = phi; // Tagging {phi}.
+ }
+}
+
+%PrepareFunctionForOptimization(store);
+%PrepareFunctionForOptimization(foo);
+foo(true);
+foo(false);
+
+%OptimizeMaglevOnNextCall(foo);
+foo(true);
+foo(false);
diff --git a/deps/v8/test/mjsunit/maglev/regress-539121142.js b/deps/v8/test/mjsunit/maglev/regress-539121142.js
new file mode 100644
index 00000000000..b6fd76eb36d
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-539121142.js
@@ -0,0 +1,43 @@
+// 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
+
+// Test JS-to-Wasm wrapper inlining in Turbolev and ensure eager deopt during
+// argument conversion does not rewind execution past non-idempotent calls.
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+const sig = builder.addType(makeSig([kWasmI32, kWasmI32], []));
+
+// 1. Import JS callback 'cb' as Wasm function index 0.
+const importIdx = builder.addImport('env', 'f', sig);
+
+// 2. Export function index 0 (the imported JS callback 'cb') as 'main'.
+builder.addExport('main', importIdx);
+
+let count = 0;
+let wasmFn;
+function cb(n) {
+ count++;
+ if (n > 0) {
+ wasmFn(n - 1, 0);
+ // Passing a JSObject to an i32 parameter.
+ // Baseline: Out-of-line wrapper converts to i32 (0) without deopting.
+ // Turbolev: Inlined wrapper eagerly deoptimizes cb.
+ wasmFn(n - 1, {});
+ }
+}
+
+// 3. 'wasmFn' is the JS-to-Wasm export wrapper wrapping imported JS callback 'cb'.
+wasmFn = builder.instantiate({ env: { f: cb } }).exports.main;
+
+%PrepareFunctionForOptimization(cb);
+cb(1);
+assertEquals(3, count);
+
+%OptimizeFunctionOnNextCall(cb);
+cb(1);
+assertEquals(6, count);
diff --git a/deps/v8/test/mjsunit/maglev/regress-540467501.js b/deps/v8/test/mjsunit/maglev/regress-540467501.js
new file mode 100644
index 00000000000..f629913ee45
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-540467501.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
+
+
+function foo(x) {
+ return x !== this.length;
+}
+
+%PrepareFunctionForOptimization(foo);
+foo("test");
+
+for (let i = 0; i < 5; i++) {
+ %PrepareFunctionForOptimization(%GetFunctionForCurrentFrame());
+ %OptimizeOsr();
+ const arr = Array();
+ arr.forEach(foo, arr);
+}
diff --git a/deps/v8/test/mjsunit/maglev/regress-540905585.js b/deps/v8/test/mjsunit/maglev/regress-540905585.js
new file mode 100644
index 00000000000..d6ad9ef56ae
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-540905585.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.
+
+// Flags: --allow-natives-syntax --no-lazy-feedback-allocation
+// Flags: --no-maglev-optimistic-peeled-loops --maglev-non-eager-inlining
+
+function inlinee() {
+ return eval("1");
+}
+%PrepareFunctionForOptimization(inlinee);
+
+function test() {
+ for (let loop_var = 0; loop_var < 1; ) {
+ ~loop_var;
+ inlinee(loop_var);
+ loop_var = 2.5;
+ }
+}
+
+%PrepareFunctionForOptimization(test);
+test();
+%OptimizeMaglevOnNextCall(test);
+test();
diff --git a/deps/v8/test/mjsunit/maglev/regress-543919179.js b/deps/v8/test/mjsunit/maglev/regress-543919179.js
new file mode 100644
index 00000000000..21e58d563ae
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-543919179.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: --maglev-non-eager-inlining --maglev-disable-builtin-reducers
+
+let dummy;
+
+function inner() {
+ try {
+ for (var j = 0; j < 33; j++) {
+ }
+ } catch (e) {}
+}
+
+function foo(n) {
+ var limit = Math.pow(2, n);
+ for (var i = 0; i < limit; i = i * 1.01 + 1) {
+ inner(), Math.clz32({});
+ }
+}
+foo(40);
diff --git a/deps/v8/test/mjsunit/maglev/regress-544053478.js b/deps/v8/test/mjsunit/maglev/regress-544053478.js
new file mode 100644
index 00000000000..29c01bd48ab
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-544053478.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.
+
+// Flags: --allow-natives-syntax --no-lazy-feedback-allocation
+// Flags: --maglev-non-eager-inlining --maglev-disable-builtin-reducers
+
+let dummy;
+
+function inner(a, b) {
+ try {
+ return Math.floor(a / b);
+ } catch (e) {}
+}
+
+function outer() {
+ return inner();
+}
+
+%PrepareFunctionForOptimization(outer);
+inner("4");
+outer();
+%OptimizeMaglevOnNextCall(outer);
+assertEquals(NaN, outer());
diff --git a/deps/v8/test/mjsunit/maglev/regress-547330043.js b/deps/v8/test/mjsunit/maglev/regress-547330043.js
new file mode 100644
index 00000000000..e49424f6bcc
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-547330043.js
@@ -0,0 +1,53 @@
+// 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 foo(arr1, arr2) {
+ let x = arr1[0];
+ for (let i = 0; i < 4; i++) {
+ arr2[i] = x;
+ x = arr1[i];
+ }
+ +x;
+ return `${x}`;
+}
+
+let arr1 = [1.1, 2.2, 3.3, 4.4, 5.5];
+delete arr1[4];
+let arr2 = [1.1, 2.2, 3.3, 4.4, 5.5];
+delete arr2[4];
+
+%PrepareFunctionForOptimization(foo);
+for (let i = 0; i < 20; i++) {
+ assertEquals("4.4", foo(arr1, arr2));
+}
+%OptimizeMaglevOnNextCall(foo);
+assertEquals("4.4", foo(arr1, arr2));
+
+// `x` is now the hole after the loop, which stringifies to "undefined".
+delete arr1[3];
+assertEquals("undefined", foo(arr1, arr2));
+
+function bar(arr1, arr2) {
+ let x = arr1[0];
+ for (let i = 0; i < 4; i++) {
+ arr2[i] = x;
+ x = arr1[i];
+ }
+ +x;
+ return `${x}`;
+}
+
+let int1 = [1.5, 2, 3, 4, 5];
+delete int1[4];
+let int2 = [1.5, 2, 3, 4, 5];
+delete int2[4];
+
+%PrepareFunctionForOptimization(bar);
+for (let i = 0; i < 20; i++) {
+ assertEquals("4", bar(int1, int2));
+}
+%OptimizeMaglevOnNextCall(bar);
+assertEquals("4", bar(int1, int2));
diff --git a/deps/v8/test/mjsunit/maglev/regress-551265173.js b/deps/v8/test/mjsunit/maglev/regress-551265173.js
new file mode 100644
index 00000000000..fc750836091
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-551265173.js
@@ -0,0 +1,29 @@
+// 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-assert
+
+function bar() {
+ throw 0;
+}
+%NeverOptimizeFunction(bar);
+
+async function foo() {
+ for (let i = 0; i < 2; i++) {
+ try {
+ bar(i);
+ } catch {
+ [i];
+ while (i > 10) {
+ await 0;
+ }
+ }
+ }
+}
+
+%PrepareFunctionForOptimization(foo);
+foo();
+
+%OptimizeMaglevOnNextCall(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/maglev/regress-552832446.js b/deps/v8/test/mjsunit/maglev/regress-552832446.js
new file mode 100644
index 00000000000..8cce05596ba
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-552832446.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.
+
+// Flags: --allow-natives-syntax
+
+function f(obj, ...args) {
+ obj['toString'](...args);
+}
+%PrepareFunctionForOptimization(f);
+
+function g(x) {
+ /1/.test(x);
+ for (let i = 0; i < x.length; ++i) {
+ for (let j = 0; j < 1; j++) {
+ x--;
+ }
+ }
+ f(true, x);
+}
+%PrepareFunctionForOptimization(g);
+g(1);
+%OptimizeMaglevOnNextCall(g);
+g(1);
diff --git a/deps/v8/test/mjsunit/maglev/regress-556962428.js b/deps/v8/test/mjsunit/maglev/regress-556962428.js
new file mode 100644
index 00000000000..2ac8ce6dc4b
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-556962428.js
@@ -0,0 +1,25 @@
+// 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
+
+function* gen(x) {
+ /1/.test(x);
+ for (let i = 0; i < x.length; ++i) {
+ for (let j = 0; j < 1; j++) {
+ x--;
+ }
+ }
+ yield x;
+}
+%PrepareFunctionForOptimization(gen);
+
+let g = gen(1);
+assertEquals({value: 1, done: false}, g.next());
+
+%OptimizeMaglevOnNextCall(gen);
+let g2 = gen(1);
+assertOptimized(gen);
+assertEquals({value: 1, done: false}, g2.next());
+assertEquals({value: undefined, done: true}, g2.next());
diff --git a/deps/v8/test/mjsunit/maglev/regress-int32mod-cse.js b/deps/v8/test/mjsunit/maglev/regress-int32mod-cse.js
new file mode 100644
index 00000000000..8c52a2c62f4
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-int32mod-cse.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.
+
+// Flags: --allow-natives-syntax --turbolev
+
+function foo(x) {
+ if (x < 0) return 0;
+ let a = (x % 7) | 0;
+ let b = (x % 8) | 0;
+ return b;
+}
+
+%PrepareFunctionForOptimization(foo);
+for (let i = 0; i < 20; i++) {
+ foo(i);
+}
+%OptimizeFunctionOnNextCall(foo);
+foo(0);
+
+assertEquals(0, foo(8));
diff --git a/deps/v8/test/mjsunit/maglev/regress-truncated-int32-product.js b/deps/v8/test/mjsunit/maglev/regress-truncated-int32-product.js
new file mode 100644
index 00000000000..842eea59be1
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-truncated-int32-product.js
@@ -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.
+
+// Flags: --allow-natives-syntax --maglev --no-additive-safe-int-feedback
+
+// The truncation pass rewrites the addition chain into wrapping Int32Adds,
+// dropping their overflow checks, so `s` no longer holds a genuine Int32: its
+// JavaScript value is 5 * 2^31. It then truncates `s * 1000003` as well,
+// because the multiplication was marked truncatable from the *static* Int32
+// range of `s` rather than from the value it really holds. JavaScript computes
+// a double product above 2^53 and rounds it, so the wrapping product differs.
+//
+// Neither the additive safe integer feedback nor the speculative truncation it
+// enables is involved: the chain is built from Int32AddWithOverflow, and the
+// multiplication is a plain Float64Multiply.
+function makeChain(tag) {
+ return new Function('a, b, c, d, e',
+ 'var s = (a|0) + (b|0) + (c|0) + (d|0) + (e|0);' +
+ 'var m = s * 1000003;' +
+ 'return m | 0; //' + tag);
+}
+
+// Identical `new Function` sources share a SharedFunctionInfo, so each copy
+// needs a distinct body.
+const reference = makeChain('ref');
+%NeverOptimizeFunction(reference);
+const chain = makeChain('opt');
+
+// Warm up with heap numbers, so that `| 0` keeps accepting them, with sums
+// that stay Smi sized, so the additions keep SignedSmall feedback and become
+// Int32AddWithOverflow, and with a product that does not, so the
+// multiplication gets Number feedback and becomes Float64Multiply.
+%PrepareFunctionForOptimization(chain);
+for (let i = 0; i < 100; i++) chain(400.5, 400.5, 400.5, 400.5, 400.5);
+%OptimizeMaglevOnNextCall(chain);
+chain(400.5, 400.5, 400.5, 400.5, 400.5);
+
+const v = 2147483647.5;
+assertEquals(reference(v, v, v, v, v), chain(v, v, v, v, v));
diff --git a/deps/v8/test/mjsunit/maglev/regress-truncated-region-bound.js b/deps/v8/test/mjsunit/maglev/regress-truncated-region-bound.js
new file mode 100644
index 00000000000..1ed0aea7ac6
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-truncated-region-bound.js
@@ -0,0 +1,45 @@
+// 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 --no-additive-safe-int-feedback
+
+// `big` adds a constant just under 2^53, so its exact value leaves the range
+// where wrapping Int32 arithmetic still agrees with rounded Number semantics,
+// and the truncation pass has to refuse it. Refusing it also has to refuse
+// `sum`, which is computed from it: otherwise `small` is truncated on its own,
+// and `sum`, now holding one Int32 and one Float64 operand, converts the Int32
+// back with a ChangeInt32ToFloat64 -- widening the wrapped value rather than
+// the value it stands for, with no check anywhere on that path.
+//
+// The tagged use of `big` is what made this reachable: it clears the
+// truncation flag of `big` alone, leaving `sum` truncatable.
+//
+// Neither the additive safe integer feedback nor the speculative truncation it
+// enables is involved.
+let escape;
+function makeChain(tag) {
+ return new Function('a, b',
+ 'var x = (a|0) + 1;' +
+ 'var y = (b|0) + 1;' +
+ 'var small = x + (-4294967296);' +
+ 'var big = y + 9007197107257343;' +
+ 'escape = big;' +
+ 'var sum = small + big;' +
+ 'return sum | 0; //' + tag);
+}
+
+// Identical `new Function` sources share a SharedFunctionInfo, so each copy
+// needs a distinct body.
+const reference = makeChain('ref');
+%NeverOptimizeFunction(reference);
+const chain = makeChain('opt');
+
+// Warm up with heap numbers, so that `| 0` keeps accepting them, and with
+// small values, so the additions stay in the Int32 range they are built from.
+%PrepareFunctionForOptimization(chain);
+chain(1.5, 1.5);
+%OptimizeMaglevOnNextCall(chain);
+chain(1.5, 1.5);
+
+assertEquals(reference(2147483646, 2), chain(2147483646, 2));
diff --git a/deps/v8/test/mjsunit/maglev/regress-truncated-region-operand.js b/deps/v8/test/mjsunit/maglev/regress-truncated-region-operand.js
new file mode 100644
index 00000000000..3f54a60db21
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-truncated-region-operand.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 --maglev --no-additive-safe-int-feedback
+
+// Same shape as regress-truncated-region-bound.js, but the tagged use of `big`
+// now comes *after* `sum`, so the backward propagation pass clears the
+// truncation flag of `big` before it evaluates `sum`. `sum` then no longer
+// walks into `big` to bound it, and has to bound it as a plain operand -- from
+// its static range, which is just under 2^53. Charging it the additive safe
+// integer feedback range instead would accept `sum`, leaving `small` truncated
+// on its own and widened back with a ChangeInt32ToFloat64 that carries the
+// wrapped value rather than the value it stands for.
+//
+// Neither the additive safe integer feedback nor the speculative truncation it
+// enables is involved.
+let escape;
+function makeChain(tag) {
+ return new Function('a, b',
+ 'var x = (a|0) + 1;' +
+ 'var y = (b|0) + 1;' +
+ 'var small = x + (-4294967296);' +
+ 'var big = y + 9007197107257343;' +
+ 'var sum = small + big;' +
+ 'escape = big;' +
+ 'return sum | 0; //' + tag);
+}
+
+// Identical `new Function` sources share a SharedFunctionInfo, so each copy
+// needs a distinct body.
+const reference = makeChain('ref');
+%NeverOptimizeFunction(reference);
+const chain = makeChain('opt');
+
+// Warm up with heap numbers, so that `| 0` keeps accepting them, and with
+// small values, so the additions stay in the Int32 range they are built from.
+%PrepareFunctionForOptimization(chain);
+chain(1.5, 1.5);
+%OptimizeMaglevOnNextCall(chain);
+chain(1.5, 1.5);
+
+assertEquals(reference(2147483646, 2), chain(2147483646, 2));
+assertEquals(2 + 1 + 9007197107257343, escape);
diff --git a/deps/v8/test/mjsunit/maglev/regress-yield-star-lazy-deopt.js b/deps/v8/test/mjsunit/maglev/regress-yield-star-lazy-deopt.js
new file mode 100644
index 00000000000..202880f3c9d
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress-yield-star-lazy-deopt.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 --maglev
+
+function* inner() {
+ yield "inner 1";
+ yield "inner 2";
+}
+
+function* outer() {
+ yield "outer 1";
+ let v = yield* inner();
+ yield v;
+}
+
+function test(g) {
+ try {
+ return g.next();
+ } catch (e) {}
+}
+
+%PrepareFunctionForOptimization(test);
+let g = outer();
+assertEquals("outer 1", test(g).value);
+
+%OptimizeMaglevOnNextCall(test);
+assertEquals("inner 1", test(g).value);
+assertOptimized(test);
+
+// Deoptimize while outer generator is suspended inside yield*:
+%DeoptimizeFunction(test);
+assertEquals("inner 2", test(g).value);
+
+let res = test(g);
+assertEquals(undefined, res.value);
+assertEquals(false, res.done);
diff --git a/deps/v8/test/mjsunit/maglev/regress/regress-546472719.js b/deps/v8/test/mjsunit/maglev/regress/regress-546472719.js
new file mode 100644
index 00000000000..59cbcd703fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress/regress-546472719.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: --allow-natives-syntax --maglev --turbofan --use-osr
+// Flags: --osr-from-maglev=3 --concurrent-recompilation
+
+function test() {
+ let sum = 0;
+ for (let i = 0; i < 1000; i++) {
+ sum += i;
+ }
+ return sum;
+}
+
+%PrepareFunctionForOptimization(test);
+for (let i = 0; i < 20; i++) {
+ test();
+}
+%OptimizeMaglevOnNextCall(test, "concurrent");
+for (let i = 0; i < 50; i++) {
+ test();
+}
diff --git a/deps/v8/test/mjsunit/maglev/regress/regress-546792433.js b/deps/v8/test/mjsunit/maglev/regress/regress-546792433.js
new file mode 100644
index 00000000000..6a075dba065
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress/regress-546792433.js
@@ -0,0 +1,101 @@
+// 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: --maglev --allow-natives-syntax
+
+const realm = Realm.createAllowCrossRealmAccess();
+
+{
+ const otherValues = Realm.eval(realm, 'Array.prototype.values');
+ const otherIteratorPrototype = Realm.eval(
+ realm,
+ 'Object.getPrototypeOf(Array.prototype.values.call([]))'
+ );
+
+ function testArrayValues(fn, receiver) {
+ return fn.call(receiver);
+ }
+
+ %PrepareFunctionForOptimization(testArrayValues);
+ testArrayValues(otherValues, [1]);
+ testArrayValues(otherValues, [2]);
+ %OptimizeMaglevOnNextCall(testArrayValues);
+ const it = testArrayValues(otherValues, [3]);
+ assertEquals(Object.getPrototypeOf(it), otherIteratorPrototype);
+
+ function testArrayValuesDirect() {
+ return otherValues.call([1]);
+ }
+
+ %PrepareFunctionForOptimization(testArrayValuesDirect);
+ testArrayValuesDirect();
+ testArrayValuesDirect();
+ %OptimizeMaglevOnNextCall(testArrayValuesDirect);
+ const itDirect = testArrayValuesDirect();
+ assertEquals(Object.getPrototypeOf(itDirect), otherIteratorPrototype);
+}
+
+{
+ const otherStringIterator = Realm.eval(
+ realm,
+ 'String.prototype[Symbol.iterator]'
+ );
+ const otherStringIteratorPrototype = Realm.eval(
+ realm,
+ 'Object.getPrototypeOf(String.prototype[Symbol.iterator].call(""))'
+ );
+
+ function testStringIterator(fn, receiver) {
+ return fn.call(receiver);
+ }
+
+ %PrepareFunctionForOptimization(testStringIterator);
+ testStringIterator(otherStringIterator, 'a');
+ testStringIterator(otherStringIterator, 'b');
+ %OptimizeMaglevOnNextCall(testStringIterator);
+ const it = testStringIterator(otherStringIterator, 'c');
+ assertEquals(Object.getPrototypeOf(it), otherStringIteratorPrototype);
+
+ function testStringIteratorDirect() {
+ return otherStringIterator.call('abc');
+ }
+
+ %PrepareFunctionForOptimization(testStringIteratorDirect);
+ testStringIteratorDirect();
+ testStringIteratorDirect();
+ %OptimizeMaglevOnNextCall(testStringIteratorDirect);
+ const itDirect = testStringIteratorDirect();
+ assertEquals(Object.getPrototypeOf(itDirect), otherStringIteratorPrototype);
+}
+
+{
+ const otherMapEntries = Realm.eval(realm, 'Map.prototype.entries');
+ const otherMapIteratorPrototype = Realm.eval(
+ realm,
+ 'Object.getPrototypeOf(new Map().entries())'
+ );
+ const map = Realm.eval(realm, 'new Map([[1, 2]])');
+
+ function testMapEntries(fn, receiver) {
+ return fn.call(receiver);
+ }
+
+ %PrepareFunctionForOptimization(testMapEntries);
+ testMapEntries(otherMapEntries, map);
+ testMapEntries(otherMapEntries, map);
+ %OptimizeMaglevOnNextCall(testMapEntries);
+ const it = testMapEntries(otherMapEntries, map);
+ assertEquals(Object.getPrototypeOf(it), otherMapIteratorPrototype);
+
+ function testMapEntriesDirect() {
+ return otherMapEntries.call(map);
+ }
+
+ %PrepareFunctionForOptimization(testMapEntriesDirect);
+ testMapEntriesDirect();
+ testMapEntriesDirect();
+ %OptimizeMaglevOnNextCall(testMapEntriesDirect);
+ const itDirect = testMapEntriesDirect();
+ assertEquals(Object.getPrototypeOf(itDirect), otherMapIteratorPrototype);
+}
diff --git a/deps/v8/test/mjsunit/maglev/regress/regress-551320574.js b/deps/v8/test/mjsunit/maglev/regress/regress-551320574.js
new file mode 100644
index 00000000000..7089b150082
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress/regress-551320574.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 --maglev-non-eager-inlining
+
+const f64 = new Float64Array(1);
+const u32 = new Uint32Array(f64.buffer);
+u32[0] = 0xFFF7FFFF;
+u32[1] = 0xFFF7FFFF;
+const holeNan = f64[0];
+
+function minusZero(flag) {
+ if (flag) {
+ let q = 1;
+ for (let i = 0; i < 10; ++i) q += i;
+ }
+ return -0;
+}
+
+function makeAdd(x, flag) {
+ const o = {};
+ o.p = x + minusZero(flag);
+ return o;
+}
+
+(function testAddIdentity() {
+ %PrepareFunctionForOptimization(minusZero);
+ %PrepareFunctionForOptimization(makeAdd);
+ makeAdd(1.5, false);
+ makeAdd(2.5, false);
+ %OptimizeMaglevOnNextCall(makeAdd);
+
+ const victim = makeAdd(holeNan, false);
+
+ function readP() {
+ return victim.p;
+ }
+
+ %PrepareFunctionForOptimization(readP);
+ readP();
+ readP();
+ %OptimizeMaglevOnNextCall(readP);
+
+ assertTrue(isNaN(readP()));
+ victim.p = 42.5;
+ assertEquals(42.5, readP());
+})();
+
+function one(flag) {
+ if (flag) {
+ let q = 1;
+ for (let i = 0; i < 10; ++i) q += i;
+ }
+ return 1.0;
+}
+
+function makeMul(x, flag) {
+ const o = {};
+ o.p = x * one(flag);
+ return o;
+}
+
+(function testMulIdentity() {
+ %PrepareFunctionForOptimization(one);
+ %PrepareFunctionForOptimization(makeMul);
+ makeMul(1.5, false);
+ makeMul(2.5, false);
+ %OptimizeMaglevOnNextCall(makeMul);
+
+ const victim = makeMul(holeNan, false);
+
+ function readP() {
+ return victim.p;
+ }
+
+ %PrepareFunctionForOptimization(readP);
+ readP();
+ readP();
+ %OptimizeMaglevOnNextCall(readP);
+
+ assertTrue(isNaN(readP()));
+ victim.p = 84.5;
+ assertEquals(84.5, readP());
+})();
diff --git a/deps/v8/test/mjsunit/maglev/regress/regress-552783942.js b/deps/v8/test/mjsunit/maglev/regress/regress-552783942.js
new file mode 100644
index 00000000000..0bac0b71324
--- /dev/null
+++ b/deps/v8/test/mjsunit/maglev/regress/regress-552783942.js
@@ -0,0 +1,98 @@
+// 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-non-eager-inlining
+
+const f64 = new Float64Array(1);
+const u32 = new Uint32Array(f64.buffer);
+u32[0] = 0xFFF7FFFF;
+u32[1] = 0xFFF7FFFF;
+const holeNan = f64[0];
+
+function dummy(flag) {
+ if (flag) {
+ let q = 1;
+ for (let i = 0; i < 10; ++i) q += i;
+ }
+ return -0;
+}
+
+function makeMin(x, flag) {
+ const o = {};
+ o.p = Math.min(x, x) + dummy(flag);
+ return o;
+}
+
+(function testMinIdentity() {
+ %PrepareFunctionForOptimization(dummy);
+ %PrepareFunctionForOptimization(makeMin);
+ makeMin(1.5, false);
+ makeMin(2.5, false);
+ %OptimizeMaglevOnNextCall(makeMin);
+
+ const victim = makeMin(holeNan, false);
+
+ function readP() {
+ return victim.p;
+ }
+
+ %PrepareFunctionForOptimization(readP);
+ readP();
+ readP();
+ %OptimizeMaglevOnNextCall(readP);
+
+ assertTrue(isNaN(readP()));
+ victim.p = 42.5;
+ assertEquals(42.5, readP());
+})();
+
+function makeMax(x, flag) {
+ const o = {};
+ o.p = Math.max(x, x) + dummy(flag);
+ return o;
+}
+
+(function testMaxIdentity() {
+ %PrepareFunctionForOptimization(dummy);
+ %PrepareFunctionForOptimization(makeMax);
+ makeMax(1.5, false);
+ makeMax(2.5, false);
+ %OptimizeMaglevOnNextCall(makeMax);
+
+ const victim = makeMax(holeNan, false);
+
+ function readP() {
+ return victim.p;
+ }
+
+ %PrepareFunctionForOptimization(readP);
+ readP();
+ readP();
+ %OptimizeMaglevOnNextCall(readP);
+
+ assertTrue(isNaN(readP()));
+ victim.p = 84.5;
+ assertEquals(84.5, readP());
+})();
+
+(function testReturnedBitsQuieted() {
+ function foldMin(ta) {
+ const x = ta[0];
+ return Math.min(x, x);
+ }
+ %PrepareFunctionForOptimization(foldMin);
+ foldMin(new Float64Array([1.1]));
+ foldMin(new Float64Array([2.2]));
+ %OptimizeMaglevOnNextCall(foldMin);
+
+ const r = foldMin(f64);
+ const out = new Float64Array(1);
+ const outU64 = new BigUint64Array(out.buffer);
+ out[0] = r;
+
+ assertTrue(isNaN(r));
+ assertNotEquals(0xFFF7FFFF_FFF7FFFFn, outU64[0]);
+ const kQuietNanBit = 0x00080000_00000000n;
+ assertTrue((outU64[0] & kQuietNanBit) !== 0n);
+})();
diff --git a/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-1.js b/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-1.js
index 79653b8b23d..59087844568 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-1.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-1.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-2.js b/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-2.js
index 31001276878..87941a1e430 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-2.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/array-iterator-modification-2.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/basic.js b/deps/v8/test/mjsunit/math-sum-precise/basic.js
index c3f4ee0d91a..a5a3acfa5f0 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/basic.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/basic.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/closing.js b/deps/v8/test/mjsunit/math-sum-precise/closing.js
index 57ab7f3ffd2..5cb1a36a0f9 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/closing.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/closing.js
@@ -1,8 +1,6 @@
// 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-sum-precise
(function() {
function test(obj) {
diff --git a/deps/v8/test/mjsunit/math-sum-precise/holey.js b/deps/v8/test/mjsunit/math-sum-precise/holey.js
index a168347492a..3c1e384f297 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/holey.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/holey.js
@@ -1,8 +1,6 @@
// 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-sum-precise
const sparseArray1 = [1, , 3];
const otherArray = [,2];
diff --git a/deps/v8/test/mjsunit/math-sum-precise/holey2.js b/deps/v8/test/mjsunit/math-sum-precise/holey2.js
index 0fc60ae2b6c..dd7992deb0f 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/holey2.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/holey2.js
@@ -1,8 +1,6 @@
// 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-sum-precise
(function() {
const arr = [1, , 3];
diff --git a/deps/v8/test/mjsunit/math-sum-precise/iterator-clear-on-error.js b/deps/v8/test/mjsunit/math-sum-precise/iterator-clear-on-error.js
index 9488d1da4d1..3eae0a951b5 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/iterator-clear-on-error.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/iterator-clear-on-error.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.
-// Flags: --js-sum-precise
-
(function TestArrayIteratorClearedOnError() {
const it = [10, 20, "bad", 30, 40][Symbol.iterator]();
assertThrows(() => Math.sumPrecise(it), TypeError);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/regress-494013010.js b/deps/v8/test/mjsunit/math-sum-precise/regress-494013010.js
index ed715eb6b7c..62a04c2e0ed 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/regress-494013010.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/regress-494013010.js
@@ -1,8 +1,6 @@
// 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-sum-precise
(function () {
let set = new Set([1, 3]);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/regress-513719178.js b/deps/v8/test/mjsunit/math-sum-precise/regress-513719178.js
index 2b3fba0a537..08987be4751 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/regress-513719178.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/regress-513719178.js
@@ -1,8 +1,6 @@
// 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-sum-precise
(function () {
let __v_0 = new Set([1, 3]);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/regress.js b/deps/v8/test/mjsunit/math-sum-precise/regress.js
index 0ee591f17e8..766c4b76202 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/regress.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/regress.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
let r = ([2.1]).slice(3);
Math.sumPrecise(r);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/set-iterator-clear-on-error.js b/deps/v8/test/mjsunit/math-sum-precise/set-iterator-clear-on-error.js
index 9c5300864cd..0aa59d9cf75 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/set-iterator-clear-on-error.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/set-iterator-clear-on-error.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.
-// Flags: --js-sum-precise
-
(function TestSetIteratorNotClearedOnError() {
let s = new Set([1, "a", 3]);
let it = s[Symbol.iterator]();
diff --git a/deps/v8/test/mjsunit/math-sum-precise/set-regress.js b/deps/v8/test/mjsunit/math-sum-precise/set-regress.js
index 6164f98c458..7d94ffa8099 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/set-regress.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/set-regress.js
@@ -1,8 +1,6 @@
// 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-sum-precise
let s = new Set([1, 2, 3]);
let it = s.values();
diff --git a/deps/v8/test/mjsunit/math-sum-precise/set-regress2.js b/deps/v8/test/mjsunit/math-sum-precise/set-regress2.js
index 100f81d0e2b..a27414ce47b 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/set-regress2.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/set-regress2.js
@@ -1,8 +1,6 @@
// 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-sum-precise
let s = new Set([1, 2, 3]);
let it = s.values();
diff --git a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-1.js b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-1.js
index 7b6f3950f10..437b22d77bf 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-1.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-1.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-2.js b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-2.js
index d64ba94e2c4..4fa448c5780 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-2.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-2.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-3.js b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-3.js
index 71788d215d9..faa499370f1 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-3.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-4.js b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-4.js
index 9ce23665908..cc75e0def6a 100644
--- a/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-4.js
+++ b/deps/v8/test/mjsunit/math-sum-precise/typed-array-iterator-modification-4.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: --js-sum-precise --allow-natives-syntax
+// Flags: --allow-natives-syntax
function assertSum(expected, iterable) {
let res = Math.sumPrecise(iterable);
diff --git a/deps/v8/test/mjsunit/mjsunit.status b/deps/v8/test/mjsunit/mjsunit.status
index 9a883f9e8df..aaa65a3666f 100644
--- a/deps/v8/test/mjsunit/mjsunit.status
+++ b/deps/v8/test/mjsunit/mjsunit.status
@@ -75,6 +75,7 @@
'maglev/regress-421228426': [PASS, SLOW, ['mode == debug', SKIP]],
'turbolev/regress-532607231': [PASS, SLOW],
+ 'turbolev/regress-540717862': [PASS, SLOW],
'turboshaft/regress-554421904': [PASS, SLOW],
# https://crbug.com/1129854
@@ -89,8 +90,16 @@
# https://crbug.com/485267831
'regress/regress-485267831': [SKIP],
- # https://crbug.com/532595489
- 'regress/regress-532595489': [FAIL, CRASH, NO_VARIANTS, ['not pointer_compression', SKIP]],
+
+ # TODO(542447324): --shared-string-table together with
+ # --transition-strings-during-gc-with-stack was never intended to work.
+ # Consider reverting the changes introduced to fix misbehaviour.
+ 'regress/regress-526275356': [SKIP],
+ 'regress/regress-526275356-2': [SKIP],
+ 'regress/regress-537813778': [SKIP],
+ 'regress/regress-538529872': [SKIP],
+ 'regress/regress-538529872-2': [SKIP],
+ 'turboshaft/regress-523436017': [SKIP],
##############################################################################
# Tests where variants make no sense.
@@ -117,6 +126,9 @@
# https://crbug.com/505063230
'sandbox/regress-488362583': [SKIP],
+ # Fails on unrelated commit.
+ 'sandbox/hardware-watchpoints/regress-524854777': [SKIP],
+
##############################################################################
# Long-running tests.
# We really should find better solutions for these.
@@ -124,6 +136,7 @@
'harmony/promise-any-overflow-1': [SKIP],
'migrations': [SKIP],
'regress/regress-2073': [SKIP],
+ 'wasm/wrapper-microbenchmark': [SKIP],
##############################################################################
# Tests verifying CHECK and ASSERT.
@@ -160,7 +173,6 @@
# Slow tests.
'array-functions-prototype-misc': [PASS, SLOW],
'array-tostring-stack-overflow': [PASS, SLOW, ['arch != x64', SKIP]],
- 'compiler/deopt-pretenure': [PASS, SLOW],
'compiler/regress-461531853': [PASS, SLOW],
'compiler/regress-9017': [PASS, SLOW],
'compiler/regress-crbug-11564': [PASS, SLOW],
@@ -183,6 +195,9 @@
'regress/regress-605470': [PASS, SLOW],
'regress/regress-655573': [PASS, SLOW],
'regress/regress-1200351': [PASS, SLOW],
+ # Runs a few thousand localeCompare calls, each of which re-runs an ICU
+ # collator check under --enable-slow-asserts.
+ 'regress/regress-539212794': [PASS, SLOW],
'regress/regress-381390367': [PASS, SLOW, ['(arch == arm or arch == arm64) and simulator_run', SKIP]],
'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]],
@@ -193,6 +208,7 @@
'regress/regress-7558019': [PASS, SLOW],
'regress/regress-499721612': [PASS, SLOW],
'regress/regress-498010834': [PASS, SLOW],
+ '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],
'sealed-array-reduce': [PASS, SLOW],
@@ -299,6 +315,182 @@
'arbitrary-length-varargs-prototype-setter': [PASS, ['mode == debug or simulator_run or lower_limits_mode', SKIP]],
'regress/regress-509622555*': [['not sparkplug_plus', SKIP]],
+
+ # Because of frontend lowerings being different in Maglev and Turbofan, some
+ # unit tests don't pass when using Maglev as a frontend for Turboshaft.
+
+ # Const tracking let is different in Turbofan and Maglev.
+ 'const-tracking-let-*': [SKIP],
+
+ # Maglev doesn't silent holey NaNs if it hasn't seen any, unlike Turbofan.
+ 'getters-on-elements': [SKIP],
+
+ # Maglev deopts more aggressively on insufficient feedback.
+ 'array-literal-transitions': [SKIP],
+
+ # Maglev doesn't inline String.prototype.includes.
+ 'optimized-string-includes': [SKIP],
+
+ # Maglev doesn't optimize string wrapper addition.
+ 'string-wrapper-add-1': [SKIP],
+ 'string-wrapper-add-2': [SKIP],
+
+ # Maglev doesn't specialize == on mixed objects/smi/oddballs inputs.
+ 'compiler/abstract-equal-undetectable': [SKIP],
+ 'compiler/abstract-equal-oddball': [SKIP],
+ 'compiler/abstract-equal-receiver': [SKIP],
+
+ # Maglev doesn't specialize much when it comes to BigInt operations.
+ 'compiler/bigint-bitwise-*': [SKIP],
+ 'compiler/bigint-asuintn': [SKIP],
+ 'compiler/bigint-compare': [SKIP],
+ 'compiler/bigint-divide': [SKIP],
+ 'compiler/bigint-modulus': [SKIP],
+ 'compiler/bigint-asintn': [SKIP],
+ 'compiler/bigint-equal': [SKIP],
+ 'compiler/bigint-add-no-deopt-loop': [SKIP],
+ 'compiler/bigint-multiply': [SKIP],
+ 'compiler/bigint64-mul-no-deopt-loop': [SKIP],
+ 'compiler/bigint64-add-no-deopt-loop': [SKIP],
+ 'compiler/bigint64-sub-no-deopt-loop': [SKIP],
+ 'compiler/bigint64-div-no-deopt-loop': [SKIP],
+ 'compiler/bigint64-array': [SKIP],
+ 'compiler/bigint-shift-right': [SKIP],
+ 'compiler/bigint-shift-left': [SKIP],
+ 'compiler/bigint-multiply-truncate': [SKIP],
+ 'compiler/bigint64-mod-no-deopt-loop': [SKIP],
+ 'regress/regress-1212583': [SKIP],
+ 'regress/regress-1371935': [SKIP],
+ 'regress/regress-9441': [SKIP],
+
+ # Maglev doesn't inline some Dataview accessors.
+ 'compiler/dataview-detached': [SKIP],
+ 'compiler/dataview-deopt': [SKIP],
+ 'compiler/dataview-get': [SKIP],
+ 'compiler/dataview-set': [SKIP],
+
+ # Maglev doesn't lower CallWithSpread.
+ 'compiler/regress-385386138': [SKIP],
+
+ # Maglev doesn't unroll constant arrays in apply.
+ 'compiler/function-apply-constant-array': [SKIP],
+ 'compiler/function-apply-constant-slow-array': [SKIP],
+
+ # Various missing lowerings/specializations in Maglev.
+ 'compiler/deopt-pretenure': [SKIP, SLOW],
+ 'compiler/opt-higher-order-functions': [SKIP],
+ 'compiler/constant-fold-cow-array': [SKIP],
+ 'compiler/promise-resolve-stable-maps': [SKIP],
+ 'compiler/array-multiple-receiver-maps': [SKIP],
+ 'compiler/string-charAt': [SKIP],
+ 'compiler/strict-equal-receiver': [SKIP],
+ 'compiler/string-endswith': [SKIP],
+ 'compiler/string-from-code-point': [SKIP],
+ 'compiler/regress-9945-1': [SKIP],
+ 'es6/iterator-eager-deopt': [SKIP],
+ 'es6/array-iterator-turbo': [SKIP],
+ 'compiler/typedarray-resizablearraybuffer': [SKIP],
+ 'optimized-filter': [SKIP],
+ 'optimized-map': [SKIP],
+ 'compiler/bound-functions-serialize': [SKIP],
+ 'field-type-tracking': [SKIP],
+
+ # %TurbofanStaticAssert that don't hold because of various missing
+ # optimizations in Turbolev.
+ 'compiler/concurrent-inlining-1': [SKIP],
+ 'compiler/concurrent-inlining-2': [SKIP],
+ 'compiler/construct-bound-function': [SKIP],
+ 'compiler/js-create-arguments': [SKIP],
+ 'compiler/js-create': [SKIP],
+ 'compiler/load-elimination-const-field': [SKIP],
+ 'compiler/reference-equal-boolean': [SKIP],
+ 'compiler/serializer-feedback-propagation-2': [SKIP],
+
+ # --maglev-inline-api-calls is currently not supported by the translation.
+ 'regress/regress-crbug-1496606': [SKIP],
+
+ # --jitless tests not supported
+ 'regress/regress-992389': [SKIP],
+ 'regress/regress-crbug-419454582': [SKIP],
+
+ # Turboshaft cannot call Construct_WithFeedback, which is required to make
+ # this test pass with Maglev as a frontend (Turbofan does other lowering
+ # that don't require calling Construct_WithFeedback).
+ 'array-constructor-feedback': ['arch == arm64', SKIP],
+
+ # Maglev deopts on non-int division, even if the result is truncated after.
+ 'shift-for-integer-div': [SKIP],
+ # Maglev deopts on negative zero for int32, even if truncated afterward.
+ 'compiler/number-abs': [SKIP],
+ 'compiler/number-floor': [SKIP],
+ 'compiler/number-ceil': [SKIP],
+ 'compiler/number-min': [SKIP],
+ 'compiler/number-max': [SKIP],
+ 'compiler/number-round': [SKIP],
+ 'compiler/number-trunc': [SKIP],
+ 'compiler/number-modulus': [SKIP],
+ 'compiler/number-toboolean': [SKIP],
+ 'compiler/number-comparison-truncations': [SKIP],
+ 'regress/regress-2132': [SKIP],
+ 'compiler/regress-1199345': [SKIP],
+ 'wasm/bigint-opt': [SKIP],
+ # Maglev doesn't inline the call being tested here.
+ 'compiler/call-with-arraylike-or-spread': [SKIP],
+ 'compiler/call-with-arraylike-or-spread-3': [SKIP],
+ 'compiler/call-with-arraylike-or-spread-4': [SKIP],
+ 'compiler/call-with-arraylike-or-spread-5': [SKIP],
+ 'compiler/call-with-arraylike-or-spread-6': [SKIP],
+ 'compiler/call-with-arraylike-or-spread-7': [SKIP],
+ 'compiler/serializer-call': [SKIP],
+ 'compiler/serializer-apply': [SKIP],
+ 'compiler/serializer-accessors': [SKIP],
+ 'compiler/serializer-transition-propagation': [SKIP],
+ 'compiler/serializer-dead-after-jump': [SKIP],
+ 'compiler/serializer-dead-after-return': [SKIP],
+ 'es6/super-ic-opt-no-turboprop': [SKIP],
+ 'regress/regress-1049982-1': [SKIP],
+ 'regress/regress-1049982-2': [SKIP],
+ # Maglev doesn't support fast API calls.
+ 'compiler/fast-api-annotations': [SKIP],
+ 'compiler/fast-api-attributes': [SKIP],
+ 'compiler/fast-api-calls': [SKIP],
+ 'compiler/fast-api-calls-8args': [SKIP],
+ 'compiler/fast-api-calls-nested': [SKIP],
+ 'compiler/fast-api-calls-string': [SKIP],
+ 'compiler/fast-api-calls-pointer': [SKIP],
+ 'compiler/fast-api-calls-64-bit-integer-values': [SKIP],
+ 'compiler/fast-api-calls-throw': [SKIP],
+ 'compiler/fast-api-deopt': [SKIP],
+ 'compiler/fast-api-interface-types': [SKIP],
+ 'compiler/fast-api-sequences*': [SKIP],
+ 'wasm/fast-api-calls-with-wellknown-imports*': [SKIP],
+ 'regress/wasm/regress-368086282': [SKIP],
+ 'regress/wasm/regress-438770394': [SKIP],
+ 'regress/regress-505551322': [SKIP],
+ 'regress/regress-508672637': [SKIP],
+ 'regress/regress-fast-api-uint64-negative': [SKIP],
+ 'regress/regress-366323469': [SKIP],
+ 'regress/regress-366635361': [SKIP],
+ # Maglev doesn't specialise the IsBeingInterpreted runtime func.
+ 'compiler/is-being-interpreted-1': [SKIP],
+ # This test appears to be relying on no adding a map stability check, but
+ # instead using a field representation dependency and allowing a read from
+ # the deprecated map. Wiring this through in Maglev would be too messy to be
+ # worth it.
+ 'regress/regress-map-invalidation-2': [SKIP],
+ 'turboshaft/extras-cped': [SKIP],
+ # Maglev does not support additive safe ints.
+ 'additive-safe-int-feedback': [SKIP],
+ 'regress-398879933': [SKIP],
+ 'regress-399698534': [SKIP],
+ 'regress-414738826': [SKIP],
+
+ # TODO(dmercadier,505648716): fix LateLoadElimination's map tracking and re-enable this test.
+ 'turbolev/load-elimination-backing-store-alias': [SKIP],
+
+ # Turbofan specific synchronization point.
+ 'sandbox/regress/regress-502997649': [SKIP],
+
}], # ALWAYS
################################################################################
@@ -373,11 +565,6 @@
'sandbox/*': [SKIP],
}],
-################################################################################
-['not cppgc_microtask_queue', {
- 'sandbox/regress/regress-508092629': [SKIP],
-}],
-
################################################################################
['not lower_limits_mode', {
# Skip tests that's supposed to run only in lower_limits_mode.
@@ -469,28 +656,13 @@
# Skip tests not suitable for GC stress.
'allocation-site-info': [SKIP],
'array-constructor-feedback': [SKIP],
- 'array-feedback': [SKIP],
- 'array-literal-feedback': [SKIP],
'd8/d8-performance-now': [SKIP],
- 'elements-kind': [SKIP],
- 'elements-transition-hoisting': [SKIP],
- 'fast-prototype': [SKIP],
- 'field-type-tracking': [SKIP],
- 'getters-on-elements': [SKIP],
- 'es6/block-let-crankshaft': [SKIP],
- 'maglev/osr-to-tf': [SKIP],
- 'maglev/unstable-map-transition': [SKIP],
'opt-elements-kind': [SKIP],
- 'osr-elements-kind': [SKIP],
- 'compiler/number-divide': [SKIP],
- 'regress/regress-crbug-137689': [SKIP],
'regress/regress-trap-allocation-memento': [SKIP],
- 'regress/regress-2249': [SKIP],
- 'regress/regress-3709': [SKIP],
'regress/regress-4121': [SKIP],
- 'regress/regress-6989': [SKIP],
- 'compare-known-objects-slow': [SKIP],
- 'compiler/array-multiple-receiver-maps': [SKIP],
+ # --concurrent-recompilation-delay sleeps before the compile starts, so the
+ # test's cell rotation finishes before the broker reads the cell.
+ 'regress/regress-crbug-560233248': [SKIP],
# Tests taking too long
'regress/regress-1122': [SKIP],
'regress/regress-353551': [SKIP],
@@ -556,14 +728,12 @@
# BUG(v8:12561)
'spread-large-map': [SKIP],
- # Flaky tests due to GC interferring with optimization.
- 'compiler/regress-crbug-1323114': [SKIP],
- 'wasm/wasm-gc-inlining': [SKIP], #BUG(397252111)
- 'maglev/load_mutable_heap_slot_context_specialized': [SKIP],
-
# https://crbug.com/v8/13461
'maglev/inner-function': [SKIP],
+ # https://crbug.com/552791801
+ 'maglev/float64-conversions': [SKIP],
+
# https://crbug.com/v8/13916
'readonly': [SKIP],
@@ -572,6 +742,9 @@
# The --stress-compaction flag prevents minor GCs.
'weakrefs/minor-gc-*': [SKIP],
+
+ # GC stress sets --concurrent-recompilation-delay itself.
+ 'compiler/regress-542923494': [SKIP],
}], # 'gc_stress'
##############################################################################
@@ -605,6 +778,7 @@
'weakrefs/finalizationregistry-independent-lifetime-multiple': [SKIP],
'weakrefs/finalizationregistry-keeps-holdings-alive': [SKIP],
'weakrefs/finalizationregistry-scheduled-for-cleanup-multiple-times': [SKIP],
+ 'weakrefs/minor-gc-*': [SKIP],
'weakrefs/multiple-dirty-finalization-groups': [SKIP],
'weakrefs/reentrant-gc-from-cleanup': [SKIP],
'weakrefs/symbol-as-weakref-target-gc': [SKIP],
@@ -666,6 +840,7 @@
##############################################################################
['not has_wasm_interpreter or variant != jitless', {
# Tests to run only with the Wasm interpreter.
+ 'regress/wasm/regress-interpreter-failed-reentry': [SKIP],
'wasm/wasm-interpreter-fuzzer' : [SKIP],
'wasm/wasm-interpreter-memory*' : [SKIP],
}], # not has_wasm_interpreter or variant != jitless
@@ -693,6 +868,11 @@
# Skip tests that require Wasm experimental features not supported by the
# Wasm interpreter, or that explicitly require compilation.
+ # Wasm debugging that runs GC while paused at a trap safepoint is not
+ # supported by the Wasm interpreter; it crashes (BUS_ADRALN) in the DrumBrake
+ # safepoint path in jitless mode. Passes in JIT variants.
+ 'wasm/regress-534579660': [SKIP],
+
# --wasm-inlining
'regress/wasm/regress-crbug-1510626': [SKIP],
@@ -729,6 +909,13 @@
'wasm/memory-control': [SKIP],
'regress/wasm/regress-493307331': [SKIP],
+ # --experimental-wasm-acquire-release
+ 'wasm/acq-rel-fence': [SKIP],
+ 'wasm/acq-rel-load-and-store': [SKIP],
+ 'wasm/acq-rel-rmw-operations': [SKIP],
+ 'regress/wasm/regress-516102113': [SKIP],
+ 'regress/wasm/regress-518131466': [SKIP],
+
# exnref
'regress/wasm/regress-14689': [SKIP],
'regress/wasm/regress-1502837': [SKIP],
@@ -759,7 +946,9 @@
'wasm/growable-stacks': [SKIP],
# --wasm-growable-stacks
+ 'regress/wasm/regress-421055121': [SKIP],
'regress/wasm/regress-513250424': [SKIP],
+ 'regress/wasm/regress-520777574': [SKIP],
# --wasm-wasmfx
'regress/wasm/regress-455832038': [SKIP],
@@ -782,9 +971,6 @@
'wasm/stack-switching*': [SKIP],
'wasm/wasmfx*': [SKIP],
- # --wasm-growable-stacks
- 'regress/wasm/regress-421055121': [SKIP],
-
# --wasm-stringref
'regress/wasm/regress-324475066': [SKIP],
'regress/wasm/regress-324690505': [SKIP],
@@ -983,6 +1169,7 @@
'compiler/fast-api-calls-wasm': [SKIP],
'regress/wasm/regress-403308742': [SKIP],
'regress/wasm/regress-488943662': [SKIP],
+ 'regress/wasm/regress-526163463': [SKIP], # --wasm-code-coverage
'wasm/regression-521715545': [SKIP], # --wasm-code-coverage
'wasm/async-compile': [SKIP],
'wasm/log-code-after-post-message': [SKIP],
@@ -999,6 +1186,7 @@
# d8.exe --no-wasm-trap-handler.
'regress/wasm/regress-842501': [SKIP],
+ 'regress/wasm/regress-513413942': [SKIP],
# TODO(paolosev): Support Wasm to JS calls to JSApiObjects.
'wasm/ffi': [SKIP],
@@ -1035,8 +1223,13 @@
'regress/wasm/regress-518697709': [SKIP],
'regress/wasm/regress-524792614': [SKIP],
'regress/wasm/regress-530658019': [SKIP],
+ 'regress/wasm/regress-535659723': [SKIP],
+ 'regress/wasm/regress-538378084': [SKIP],
+ 'regress/wasm/regress-540446645': [SKIP],
+ 'regress/wasm/regress-543901836': [SKIP],
'regress/wasm/regress-crbug-1507751': [SKIP],
'regress/wasm/regress-simd-518058891': [SKIP],
+ 'regress/wasm/regress-simd-525600038': [SKIP],
'regress/wasm/regress-simd-526303929': [SKIP],
'regress/wasm/regress-simd-528884838': [SKIP],
'wasm/bit-shift-right': [SKIP],
@@ -1085,16 +1278,10 @@
'regress/wasm/regress-498818401': [SKIP],
'regress/wasm/regress-500113958': [SKIP],
- # --wasm-acquire-release
- 'regress/wasm/regress-516102113': [SKIP],
- 'regress/wasm/regress-518131466': [SKIP],
- 'wasm/acq-rel-*': [SKIP],
-
# The interpreter call stack contains an additional top frame if we throw a
# type-mismatch exception before executing the Wasm function.
'regress/wasm/regress-366635354': [SKIP],
-
# Interpreter needs more stack space
'wasm/turboshaft/reduction-shuffle': [SKIP],
@@ -1143,6 +1330,7 @@
'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],
@@ -1173,9 +1361,6 @@
'regress/regress-10138': [SKIP],
'regress/regress-1078913': [SKIP],
- # Flag --no-jitless incompatible with jitless
- 'opt-proto-seq/*': [SKIP],
-
# Baseline incompatible with jitless
'baseline/*': [SKIP],
@@ -1188,6 +1373,7 @@
# Case-insensitive unicode regexp relies on case mapping provided by ICU.
'es6/unicode-regexp-ignore-case': [FAIL],
'es7/regexp-ui-word': [FAIL],
+ 'regexp/first-character-reject-bitset': [FAIL],
'regress/regress-5036': [FAIL],
# Desugaring regexp property class relies on ICU. Anything goes as long as we
@@ -1224,6 +1410,7 @@
'regress/regress-1447383': [SKIP],
'regress/regress-crbug-335592010': [SKIP],
'regress/regress-352402863': [SKIP],
+ 'regress/regress-549231120': [SKIP],
'string-localecompare-inline': [SKIP],
# Non-BMP characters currently aren't considered identifiers without i18n
@@ -1278,6 +1465,7 @@
'regress/regress-354626177': [SKIP],
'regress/wasm/regress-398439335': [SKIP],
'turbolev/regress-488090094': [SKIP],
+ 'turbolev/dataview-deopt-oob': [SKIP],
'maglev/regress-498816446-3': [SKIP],
'maglev/regress-521604719': [SKIP],
@@ -1447,6 +1635,8 @@
['tsan == True', {
# TODO(354103254): There are still data races on background compilation.
'regress/regress-350779648': [SKIP],
+ # TODO(558522508): Data race on background compilation.
+ 'regress/regress-crbug-521483370': [SKIP],
# https://bugs.chromium.org/p/v8/issues/detail?id=7102
# Flaky due to huge string allocation.
@@ -1854,7 +2044,10 @@
'shared-memory/regress-crbug-1395117': [SKIP],
# Synchronization point tests don't play well with multiple isolates.
+ # https://crbug.com/539796962
+ 'compiler/concurrent-string-ext-seq': [SKIP],
'compiler/regress-519664497': [SKIP],
+ 'turboshaft/regress-539984773': [SKIP],
}], # 'isolates'
@@ -2017,6 +2210,9 @@
'wasm/shared-memory*': [FUZZ_RARE, PASS],
# Fails due to CWD changes in arguments processing.
'd8/cwd/working_dir': [SKIP],
+
+ # https://crbug.com/556584687
+ 'turboshaft/regress-508265328-*': [SKIP],
}], # num_fuzzer
##############################################################################
@@ -2125,7 +2321,8 @@
# Wasm code coverage is not supported yet.
'regress/wasm/regress-488943662': [SKIP],
'wasm/wasm-code-coverage': [SKIP],
- 'wasm/regression-521715545': [SKIP]
+ 'wasm/regression-521715545': [SKIP],
+ 'regress/wasm/regress-526163463': [SKIP]
}], # arch in [ppc64, s390x]'
##############################################################################
@@ -2463,8 +2660,6 @@
'harmony/import-from-compilation-errored': [SKIP],
'harmony/private-fields-special-object': [SKIP],
'regress/regress-676025': [SKIP],
- # Skip, since import errors since they refer to the script via debug symbols
- 'harmony/import-from-instantiation-errored': [SKIP],
# The entire snapshotting code assumes that the snapshot size fits
# into an int, so it doesn't support huge TypedArrays.
'regress/regress-319722-ArrayBuffer': [SKIP],
@@ -2553,7 +2748,6 @@
##############################################################################
['variant == stress_incremental_marking', {
'harmony/sharedarraybuffer-worker-gc-stress': [PASS, ['gc_stress', SKIP]],
- 'regress/regress-740784': [PASS, ['tsan', SKIP]],
'regress/regress-crbug-820312': [PASS, SLOW],
'wasm/shared-memory-worker-stress': [PASS, SLOW, ['tsan', SKIP]],
}], # variant == stress_incremental_marking
@@ -2572,6 +2766,8 @@
'regress/regress-430201b': [PASS, ['tsan', SKIP]],
# Slow test due to generating heap snapshots on every GC.
'regress/regress-494583765' : [SKIP],
+ # Exceeds expected timeouts.
+ 'compiler/concurrent-string-ext-seq': [SKIP],
}], # variant == stress_concurrent_allocation
##############################################################################
@@ -2751,6 +2947,7 @@
'regress/wasm/regress-349640002': [SKIP],
'regress/wasm/regress-455832038': [SKIP],
'regress/wasm/regress-483269968': [SKIP],
+ 'regress/wasm/regress-543901836': [SKIP],
'regress/wasm/regress-560536735': [SKIP],
'compiler/regress-347724915': [SKIP],
'regress/regress-crbug-418520151': [SKIP],
@@ -2763,11 +2960,8 @@
# TODO(42204563): These tests rely on the shared heap which is incompatible
# with single generation.
'regress/regress-461969023': [SKIP],
- 'regress/regress-526275356': [SKIP],
- 'regress/regress-526275356-2': [SKIP],
- 'regress/regress-537813778': [SKIP],
'regress/wasm/regress-536581698': [SKIP],
- 'turboshaft/regress-523436017': [SKIP],
+ 'regress/wasm/regress-552026580': [SKIP],
# We need this here because it needs --fuzzing, and in that case we do not
# check for contradictory flags.
'regress/wasm/regress-510448957': [SKIP],
@@ -2822,6 +3016,7 @@
'compiler/fast-api-annotations': [SKIP],
'regress/regress-505551322': [SKIP],
'regress/regress-508672637': [SKIP],
+ 'regress/regress-fast-api-uint64-negative': [SKIP],
}], # arch != x64 and arch != arm64 and arch != loong64 and arch != mips64 and arch != riscv64'
##############################################################################
@@ -2929,83 +3124,6 @@
'regexp-tier-up-multiple': [SKIP],
}], # variant == stress_regexp_jit or variant == always_sparkplug_and_stress_regexp_jit
-##############################################################################
-# Behavioural differences between Maglev and Turbofan when the former is used
-# for OptimizeFunctionOnNextCall or as a frontend for Turboshaft.
-['variant in (stress_maglev, stress_maglev_tracing, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future)', {
- # Maglev deopts on non-int division, even if the result is truncated after.
- 'shift-for-integer-div': [FAIL],
- # Maglev deopts on negative zero for int32, even if truncated afterward.
- 'compiler/number-abs': [FAIL],
- 'compiler/number-floor': [FAIL],
- 'compiler/number-ceil': [FAIL],
- 'compiler/number-min': [FAIL],
- 'compiler/number-max': [FAIL],
- 'compiler/number-round': [FAIL],
- 'compiler/number-trunc': [FAIL],
- 'compiler/number-modulus': [FAIL],
- 'compiler/number-toboolean': [FAIL],
- 'compiler/number-comparison-truncations': [FAIL],
- 'regress/regress-2132': [FAIL],
- 'compiler/regress-1199345': [FAIL],
- 'wasm/bigint-opt': [FAIL],
- # Maglev doesn't inline the call being tested here.
- 'compiler/call-with-arraylike-or-spread': [FAIL],
- 'compiler/call-with-arraylike-or-spread-3': [FAIL],
- 'compiler/call-with-arraylike-or-spread-4': [FAIL],
- 'compiler/call-with-arraylike-or-spread-5': [FAIL],
- 'compiler/call-with-arraylike-or-spread-6': [FAIL],
- 'compiler/call-with-arraylike-or-spread-7': [FAIL],
- 'compiler/serializer-call': [FAIL],
- 'compiler/serializer-apply': [FAIL],
- 'compiler/serializer-accessors': [FAIL],
- 'compiler/serializer-transition-propagation': [FAIL],
- 'compiler/serializer-dead-after-jump': [FAIL],
- 'compiler/serializer-dead-after-return': [FAIL],
- 'es6/super-ic-opt-no-turboprop': [FAIL],
- 'regress/regress-1049982-1': [FAIL],
- 'regress/regress-1049982-2': [FAIL],
- # Maglev doesn't support fast API calls.
- 'compiler/fast-api-annotations': [FAIL],
- 'compiler/fast-api-attributes': [FAIL],
- 'compiler/fast-api-calls': [FAIL],
- 'compiler/fast-api-calls-8args': [FAIL],
- 'compiler/fast-api-calls-nested': [FAIL],
- 'compiler/fast-api-calls-string': [FAIL],
- 'compiler/fast-api-calls-pointer': [FAIL],
- 'compiler/fast-api-calls-64-bit-integer-values': [FAIL],
- 'compiler/fast-api-calls-throw': [FAIL],
- 'compiler/fast-api-deopt': [FAIL],
- 'compiler/fast-api-interface-types': [FAIL],
- 'compiler/fast-api-sequences*': [FAIL],
- 'wasm/fast-api-calls-with-wellknown-imports*': [SKIP],
- 'regress/wasm/regress-368086282': [SKIP],
- 'regress/wasm/regress-438770394': [SKIP],
- 'regress/regress-505551322': [SKIP],
- 'regress/regress-508672637': [SKIP],
- 'regress/regress-366323469': [FAIL],
- 'regress/regress-366635361': [FAIL],
- # Maglev doesn't specialise the IsBeingInterpreted runtime func.
- 'compiler/is-being-interpreted-1': [FAIL],
- # Maglev doesn't support elements transitions (yet!).
- 'compiler/regress-9945-1': [FAIL],
- # This test appears to be relying on no adding a map stability check, but
- # instead using a field representation dependency and allowing a read from
- # the deprecated map. Wiring this through in Maglev would be too messy to be
- # worth it.
- 'regress/regress-map-invalidation-2': [FAIL],
- 'turboshaft/extras-cped': [SKIP],
- # Maglev does not support additive safe ints.
- 'additive-safe-int-feedback': [SKIP],
- 'regress-398879933': [SKIP],
- 'regress-399698534': [SKIP],
- 'regress-414738826': [SKIP],
-
- # TODO(dmercadier,505648716): fix LateLoadElimination's map tracking and re-enable this test.
- 'turbolev/load-elimination-backing-store-alias': [SKIP],
-}], # variant in (stress_maglev, stress_maglev_tracing, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future)
-
-
##############################################################################
['variant in (stress_maglev, stress_maglev_tracing, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan)', {
# Maglev doesn't support %TurbofanStaticAssert.
@@ -3017,14 +3135,6 @@
}], # variant in (stress_maglev, stress_maglev_tracing, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan)
-##############################################################################
-['(variant in (stress_maglev, stress_maglev_tracing, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future)) and (arch != arm)', {
- # Maglev doesn't suppress BigInt size errors on truncation.
- # On Arm that works, since we always _and_ the shift amount first.
- 'compiler/bigint-shift-left': [FAIL],
- 'compiler/bigint-multiply-truncate': [FAIL],
-}], # (variant in (stress_maglev, stress_maglev_tracing, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan, turbolev, turbolev_future, stress_turbolev_future))' and (arch != arm)
-
##############################################################################
['variant == stress_maglev_tracing', {
# Hangs with trace flags.
@@ -3035,116 +3145,8 @@
}], # variant == stress_maglev_tracing
##############################################################################
-['variant in (turbolev, turbolev_future, stress_turbolev_future)', {
- # Because of frontend lowerings being different in Maglev and Turbofan, some
- # unit tests don't pass when using Maglev as a frontend for Turboshaft.
-
- # Const tracking let is different in Turbofan and Maglev.
- 'const-tracking-let-*': [SKIP],
-
- # Maglev doesn't silent holey NaNs if it hasn't seen any, unlike Turbofan.
- 'getters-on-elements': [SKIP],
-
- # Maglev deopts more aggressively on insufficient feedback.
- 'array-literal-transitions': [SKIP],
- 'sealed-array-reduce': [SKIP],
- 'frozen-array-reduce': [SKIP],
- 'non-extensible-array-reduce': [SKIP],
-
- # Maglev doesn't inline String.prototype.includes.
- 'optimized-string-includes': [SKIP],
-
- # Maglev doesn't optimize string wrapper addition.
- 'string-wrapper-add-1': [SKIP],
- 'string-wrapper-add-2': [SKIP],
-
- # Maglev doesn't specialize == on mixed objects/smi/oddballs inputs.
- 'compiler/abstract-equal-undetectable': [SKIP],
- 'compiler/abstract-equal-oddball': [SKIP],
- 'compiler/abstract-equal-receiver': [SKIP],
-
- # Maglev doesn't specialize much when it comes to BigInt operations.
- 'compiler/bigint-bitwise-*': [SKIP],
- 'compiler/bigint-asuintn': [SKIP],
- 'compiler/bigint-compare': [SKIP],
- 'compiler/bigint-divide': [SKIP],
- 'compiler/bigint-modulus': [SKIP],
- 'compiler/bigint-asintn': [SKIP],
- 'compiler/bigint-equal': [SKIP],
- 'compiler/bigint-add-no-deopt-loop': [SKIP],
- 'compiler/bigint-multiply': [SKIP],
- 'compiler/bigint64-mul-no-deopt-loop': [SKIP],
- 'compiler/bigint64-add-no-deopt-loop': [SKIP],
- 'compiler/bigint64-sub-no-deopt-loop': [SKIP],
- 'compiler/bigint64-div-no-deopt-loop': [SKIP],
- 'compiler/bigint64-array': [SKIP],
- 'compiler/bigint-shift-right': [SKIP],
- 'compiler/bigint-shift-left': [SKIP],
- 'compiler/bigint64-mod-no-deopt-loop': [SKIP],
- 'regress/regress-1212583': [SKIP],
- 'regress/regress-1371935': [SKIP],
- 'regress/regress-9441': [SKIP],
-
- # Maglev doesn't inline some Dataview accessors.
- 'compiler/dataview-detached': [SKIP],
- 'compiler/dataview-deopt': [SKIP],
- 'compiler/dataview-get': [SKIP],
- 'compiler/dataview-set': [SKIP],
-
- # Maglev doesn't lower CallWithSpread.
- 'compiler/regress-385386138': [SKIP],
-
- # Maglev doesn't unroll constant arrays in apply.
- 'compiler/function-apply-constant-array': [SKIP],
- 'compiler/function-apply-constant-slow-array': [SKIP],
-
- # Various missing lowerings/specializations in Maglev.
- 'compiler/deopt-pretenure': [SKIP],
- 'compiler/opt-higher-order-functions': [SKIP],
- 'compiler/constant-fold-cow-array': [SKIP],
- 'compiler/promise-resolve-stable-maps': [SKIP],
- 'compiler/array-multiple-receiver-maps': [SKIP],
- 'compiler/string-charAt': [SKIP],
- 'compiler/strict-equal-receiver': [SKIP],
- 'compiler/string-endswith': [SKIP],
- 'compiler/string-from-code-point': [SKIP],
- 'compiler/regress-9945-1': [SKIP],
- 'es6/iterator-eager-deopt': [SKIP],
- 'compiler/typedarray-resizablearraybuffer': [SKIP],
- 'optimized-filter': [SKIP],
- 'optimized-map': [SKIP],
- 'compiler/bound-functions-serialize': [SKIP],
- 'field-type-tracking': [SKIP],
-
- # %TurbofanStaticAssert that don't hold because of various missing
- # optimizations in Turbolev.
- 'compiler/concurrent-inlining-1': [SKIP],
- 'compiler/concurrent-inlining-2': [SKIP],
- 'compiler/construct-bound-function': [SKIP],
- 'compiler/js-create-arguments': [SKIP],
- 'compiler/js-create': [SKIP],
- 'compiler/load-elimination-const-field': [SKIP],
- 'compiler/reference-equal-boolean': [SKIP],
- 'compiler/serializer-feedback-propagation-2': [SKIP],
-
- # --maglev-inline-api-calls is currently not supported by the translation.
- 'regress/regress-crbug-1496606': [SKIP],
-
- # --jitless tests not supported
- 'regress/regress-992389': [SKIP],
- 'regress/regress-crbug-419454582': [SKIP],
-
-}], # 'variant in (turbolev, turbolev_future, stress_turbolev_future)'
-##############################################################################
-['(variant in (turbolev, turbolev_future, stress_turbolev_future)) and (arch == arm64)', {
- # Turboshaft cannot call Construct_WithFeedback, which is required to make
- # this test pass with Maglev as a frontend (Turbofan does other lowering
- # that don't require calling Construct_WithFeedback).
- 'array-constructor-feedback': [SKIP],
-}], # (variant in (turbolev, turbolev_future, stress_turbolev_future)) and (arch == arm64)
-##############################################################################
['variant == stress_maglev_tests_with_turbofan', {
# This test deopts in Turbofan because it doesn't realize than nan==nan,
# whereas Maglev has special handling for this.
@@ -3226,6 +3228,8 @@
'shared-memory/regress-crbug-1395117': [SKIP],
# Fails due to CWD changes in arguments processing.
'd8/cwd/working_dir': [SKIP],
+ # Too slow.
+ 'regress/regress-539212794': [SKIP],
}], # variant == code_serializer
##############################################################################
@@ -3284,6 +3288,7 @@
# Wasm code coverage is not currently supported.
'regress/wasm/regress-488943662': [SKIP],
'wasm/wasm-code-coverage': [SKIP],
+ 'regress/wasm/regress-526163463': [SKIP],
# Tests that require the sampler/profiler, which doesn't work on older kernel
# versions if hardware sandboxing is active. See https://crbug.com/429173713.
@@ -3303,14 +3308,6 @@
'wasm/log-wasm-to-js-wrapper-indirect': [SKIP],
}], # sandbox_hardware_support
-['variant == minor_ms', {
- 'weakrefs/minor-gc-*': [SKIP],
-}], # variant == minor_ms
-
-['variant == scavenger_chaos_mode', {
- 'weakrefs/minor-gc-*': [SKIP],
-}], # variant == scavenger_chaos_mode
-
['variant == experimental_regexp', {
'regress/regress-503097371': [SKIP],
}], # variant == experimental_regexp
@@ -3500,4 +3497,11 @@
'compiler/concurrent-string-ext-seq': [SKIP],
'regress/regress-511263221': [SKIP],
}], # not test_only_sync_points
+
+##############################################################################
+['not sandbox', {
+ # Requires V8 sandbox to be enabled (relies on external pointer table index layout
+ # and fails in-place externalization without sandbox on 64-bit pointer compression builds).
+ 'regress/regress-539212794': [SKIP],
+}], # not sandbox
]
diff --git a/deps/v8/test/mjsunit/modules-many-bindings-lazy.mjs b/deps/v8/test/mjsunit/modules-many-bindings-lazy.mjs
new file mode 100644
index 00000000000..f1520df305c
--- /dev/null
+++ b/deps/v8/test/mjsunit/modules-many-bindings-lazy.mjs
@@ -0,0 +1,457 @@
+// 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.
+
+// Module scopes with more than kScopeInfoMaxInlinedLocalNamesSize module
+// variables (imports + exports) keep a name -> entry hashtable in their
+// ScopeInfo, which ScopeInfo::ModuleIndex() consults when a lazily compiled
+// function resolves a free variable against the module scope. Exercise that
+// lookup for imported bindings, exported bindings, a namespace import and
+// live bindings, from functions that are only compiled after the module's
+// top-level code has run.
+
+import * as ns from "modules-skip-many-bindings.mjs";
+import {e0, e1, e2, e3, e4, e5, e6, e7, e8, e9, e10, e11, e12, e13, e14, e15, e16, e17, e18, e19, e20, e21, e22, e23, e24, e25, e26, e27, e28, e29, e30, e31, e32, e33, e34, e35, e36, e37, e38, e39, e40, e41, e42, e43, e44, e45, e46, e47, e48, e49, e50, e51, e52, e53, e54, e55, e56, e57, e58, e59, e60, e61, e62, e63, e64, e65, e66, e67, e68, e69, e70, e71, e72, e73, e74, e75, e76, e77, e78, e79, e80, e81, e82, e83, e84, e85, e86, e87, e88, e89, e90, e91, e92, e93, e94, e95, e96, e97, e98, e99, e100, e101, e102, e103, e104, e105, e106, e107, e108, e109, e110, e111, e112, e113, e114, e115, e116, e117, e118, e119, e120, e121, e122, e123, e124, e125, e126, e127, e128, e129, e130, e131, e132, e133, e134, e135, e136, e137, e138, e139, e140, e141, e142, e143, e144, e145, e146, e147, e148, e149, e150, e151, e152, e153, e154, e155, e156, e157, e158, e159, e160, e161, e162, e163, e164, e165, e166, e167, e168, e169, e170, e171, e172, e173, e174, e175, e176, e177, e178, e179, e180, e181, e182, e183, e184, e185, e186, e187, e188, e189, e190, e191, e192, e193, e194, e195, e196, e197, e198, e199, bump} from "modules-skip-many-bindings.mjs";
+
+export let x0 = 0 * 2;
+export let x1 = 1 * 2;
+export let x2 = 2 * 2;
+export let x3 = 3 * 2;
+export let x4 = 4 * 2;
+export let x5 = 5 * 2;
+export let x6 = 6 * 2;
+export let x7 = 7 * 2;
+export let x8 = 8 * 2;
+export let x9 = 9 * 2;
+export let x10 = 10 * 2;
+export let x11 = 11 * 2;
+export let x12 = 12 * 2;
+export let x13 = 13 * 2;
+export let x14 = 14 * 2;
+export let x15 = 15 * 2;
+export let x16 = 16 * 2;
+export let x17 = 17 * 2;
+export let x18 = 18 * 2;
+export let x19 = 19 * 2;
+export let x20 = 20 * 2;
+export let x21 = 21 * 2;
+export let x22 = 22 * 2;
+export let x23 = 23 * 2;
+export let x24 = 24 * 2;
+export let x25 = 25 * 2;
+export let x26 = 26 * 2;
+export let x27 = 27 * 2;
+export let x28 = 28 * 2;
+export let x29 = 29 * 2;
+export let x30 = 30 * 2;
+export let x31 = 31 * 2;
+export let x32 = 32 * 2;
+export let x33 = 33 * 2;
+export let x34 = 34 * 2;
+export let x35 = 35 * 2;
+export let x36 = 36 * 2;
+export let x37 = 37 * 2;
+export let x38 = 38 * 2;
+export let x39 = 39 * 2;
+export let x40 = 40 * 2;
+export let x41 = 41 * 2;
+export let x42 = 42 * 2;
+export let x43 = 43 * 2;
+export let x44 = 44 * 2;
+export let x45 = 45 * 2;
+export let x46 = 46 * 2;
+export let x47 = 47 * 2;
+export let x48 = 48 * 2;
+export let x49 = 49 * 2;
+export let x50 = 50 * 2;
+export let x51 = 51 * 2;
+export let x52 = 52 * 2;
+export let x53 = 53 * 2;
+export let x54 = 54 * 2;
+export let x55 = 55 * 2;
+export let x56 = 56 * 2;
+export let x57 = 57 * 2;
+export let x58 = 58 * 2;
+export let x59 = 59 * 2;
+export let x60 = 60 * 2;
+export let x61 = 61 * 2;
+export let x62 = 62 * 2;
+export let x63 = 63 * 2;
+export let x64 = 64 * 2;
+export let x65 = 65 * 2;
+export let x66 = 66 * 2;
+export let x67 = 67 * 2;
+export let x68 = 68 * 2;
+export let x69 = 69 * 2;
+export let x70 = 70 * 2;
+export let x71 = 71 * 2;
+export let x72 = 72 * 2;
+export let x73 = 73 * 2;
+export let x74 = 74 * 2;
+export let x75 = 75 * 2;
+export let x76 = 76 * 2;
+export let x77 = 77 * 2;
+export let x78 = 78 * 2;
+export let x79 = 79 * 2;
+export let x80 = 80 * 2;
+export let x81 = 81 * 2;
+export let x82 = 82 * 2;
+export let x83 = 83 * 2;
+export let x84 = 84 * 2;
+export let x85 = 85 * 2;
+export let x86 = 86 * 2;
+export let x87 = 87 * 2;
+export let x88 = 88 * 2;
+export let x89 = 89 * 2;
+export let x90 = 90 * 2;
+export let x91 = 91 * 2;
+export let x92 = 92 * 2;
+export let x93 = 93 * 2;
+export let x94 = 94 * 2;
+export let x95 = 95 * 2;
+export let x96 = 96 * 2;
+export let x97 = 97 * 2;
+export let x98 = 98 * 2;
+export let x99 = 99 * 2;
+export let x100 = 100 * 2;
+export let x101 = 101 * 2;
+export let x102 = 102 * 2;
+export let x103 = 103 * 2;
+export let x104 = 104 * 2;
+export let x105 = 105 * 2;
+export let x106 = 106 * 2;
+export let x107 = 107 * 2;
+export let x108 = 108 * 2;
+export let x109 = 109 * 2;
+export let x110 = 110 * 2;
+export let x111 = 111 * 2;
+export let x112 = 112 * 2;
+export let x113 = 113 * 2;
+export let x114 = 114 * 2;
+export let x115 = 115 * 2;
+export let x116 = 116 * 2;
+export let x117 = 117 * 2;
+export let x118 = 118 * 2;
+export let x119 = 119 * 2;
+export let x120 = 120 * 2;
+export let x121 = 121 * 2;
+export let x122 = 122 * 2;
+export let x123 = 123 * 2;
+export let x124 = 124 * 2;
+export let x125 = 125 * 2;
+export let x126 = 126 * 2;
+export let x127 = 127 * 2;
+export let x128 = 128 * 2;
+export let x129 = 129 * 2;
+export let x130 = 130 * 2;
+export let x131 = 131 * 2;
+export let x132 = 132 * 2;
+export let x133 = 133 * 2;
+export let x134 = 134 * 2;
+export let x135 = 135 * 2;
+export let x136 = 136 * 2;
+export let x137 = 137 * 2;
+export let x138 = 138 * 2;
+export let x139 = 139 * 2;
+export let x140 = 140 * 2;
+export let x141 = 141 * 2;
+export let x142 = 142 * 2;
+export let x143 = 143 * 2;
+export let x144 = 144 * 2;
+export let x145 = 145 * 2;
+export let x146 = 146 * 2;
+export let x147 = 147 * 2;
+export let x148 = 148 * 2;
+export let x149 = 149 * 2;
+export let x150 = 150 * 2;
+export let x151 = 151 * 2;
+export let x152 = 152 * 2;
+export let x153 = 153 * 2;
+export let x154 = 154 * 2;
+export let x155 = 155 * 2;
+export let x156 = 156 * 2;
+export let x157 = 157 * 2;
+export let x158 = 158 * 2;
+export let x159 = 159 * 2;
+export let x160 = 160 * 2;
+export let x161 = 161 * 2;
+export let x162 = 162 * 2;
+export let x163 = 163 * 2;
+export let x164 = 164 * 2;
+export let x165 = 165 * 2;
+export let x166 = 166 * 2;
+export let x167 = 167 * 2;
+export let x168 = 168 * 2;
+export let x169 = 169 * 2;
+export let x170 = 170 * 2;
+export let x171 = 171 * 2;
+export let x172 = 172 * 2;
+export let x173 = 173 * 2;
+export let x174 = 174 * 2;
+export let x175 = 175 * 2;
+export let x176 = 176 * 2;
+export let x177 = 177 * 2;
+export let x178 = 178 * 2;
+export let x179 = 179 * 2;
+export let x180 = 180 * 2;
+export let x181 = 181 * 2;
+export let x182 = 182 * 2;
+export let x183 = 183 * 2;
+export let x184 = 184 * 2;
+export let x185 = 185 * 2;
+export let x186 = 186 * 2;
+export let x187 = 187 * 2;
+export let x188 = 188 * 2;
+export let x189 = 189 * 2;
+export let x190 = 190 * 2;
+export let x191 = 191 * 2;
+export let x192 = 192 * 2;
+export let x193 = 193 * 2;
+export let x194 = 194 * 2;
+export let x195 = 195 * 2;
+export let x196 = 196 * 2;
+export let x197 = 197 * 2;
+export let x198 = 198 * 2;
+export let x199 = 199 * 2;
+
+// Lazily compiled: references every imported and every exported binding.
+function sumImports() {
+ return e0 + e1 + e2 + e3 + e4 + e5 + e6 + e7 + e8 + e9 + e10 + e11 + e12 + e13 + e14 + e15 + e16 + e17 + e18 + e19 + e20 + e21 + e22 + e23 + e24 + e25 + e26 + e27 + e28 + e29 + e30 + e31 + e32 + e33 + e34 + e35 + e36 + e37 + e38 + e39 + e40 + e41 + e42 + e43 + e44 + e45 + e46 + e47 + e48 + e49 + e50 + e51 + e52 + e53 + e54 + e55 + e56 + e57 + e58 + e59 + e60 + e61 + e62 + e63 + e64 + e65 + e66 + e67 + e68 + e69 + e70 + e71 + e72 + e73 + e74 + e75 + e76 + e77 + e78 + e79 + e80 + e81 + e82 + e83 + e84 + e85 + e86 + e87 + e88 + e89 + e90 + e91 + e92 + e93 + e94 + e95 + e96 + e97 + e98 + e99 + e100 + e101 + e102 + e103 + e104 + e105 + e106 + e107 + e108 + e109 + e110 + e111 + e112 + e113 + e114 + e115 + e116 + e117 + e118 + e119 + e120 + e121 + e122 + e123 + e124 + e125 + e126 + e127 + e128 + e129 + e130 + e131 + e132 + e133 + e134 + e135 + e136 + e137 + e138 + e139 + e140 + e141 + e142 + e143 + e144 + e145 + e146 + e147 + e148 + e149 + e150 + e151 + e152 + e153 + e154 + e155 + e156 + e157 + e158 + e159 + e160 + e161 + e162 + e163 + e164 + e165 + e166 + e167 + e168 + e169 + e170 + e171 + e172 + e173 + e174 + e175 + e176 + e177 + e178 + e179 + e180 + e181 + e182 + e183 + e184 + e185 + e186 + e187 + e188 + e189 + e190 + e191 + e192 + e193 + e194 + e195 + e196 + e197 + e198 + e199;
+}
+function sumExports() {
+ return x0 + x1 + x2 + x3 + x4 + x5 + x6 + x7 + x8 + x9 + x10 + x11 + x12 + x13 + x14 + x15 + x16 + x17 + x18 + x19 + x20 + x21 + x22 + x23 + x24 + x25 + x26 + x27 + x28 + x29 + x30 + x31 + x32 + x33 + x34 + x35 + x36 + x37 + x38 + x39 + x40 + x41 + x42 + x43 + x44 + x45 + x46 + x47 + x48 + x49 + x50 + x51 + x52 + x53 + x54 + x55 + x56 + x57 + x58 + x59 + x60 + x61 + x62 + x63 + x64 + x65 + x66 + x67 + x68 + x69 + x70 + x71 + x72 + x73 + x74 + x75 + x76 + x77 + x78 + x79 + x80 + x81 + x82 + x83 + x84 + x85 + x86 + x87 + x88 + x89 + x90 + x91 + x92 + x93 + x94 + x95 + x96 + x97 + x98 + x99 + x100 + x101 + x102 + x103 + x104 + x105 + x106 + x107 + x108 + x109 + x110 + x111 + x112 + x113 + x114 + x115 + x116 + x117 + x118 + x119 + x120 + x121 + x122 + x123 + x124 + x125 + x126 + x127 + x128 + x129 + x130 + x131 + x132 + x133 + x134 + x135 + x136 + x137 + x138 + x139 + x140 + x141 + x142 + x143 + x144 + x145 + x146 + x147 + x148 + x149 + x150 + x151 + x152 + x153 + x154 + x155 + x156 + x157 + x158 + x159 + x160 + x161 + x162 + x163 + x164 + x165 + x166 + x167 + x168 + x169 + x170 + x171 + x172 + x173 + x174 + x175 + x176 + x177 + x178 + x179 + x180 + x181 + x182 + x183 + x184 + x185 + x186 + x187 + x188 + x189 + x190 + x191 + x192 + x193 + x194 + x195 + x196 + x197 + x198 + x199;
+}
+function pick(i) {
+ switch (i) {
+ case 0: return [e0, x0, ns.e0];
+ case 1: return [e1, x1, ns.e1];
+ case 74: return [e74, x74, ns.e74];
+ case 75: return [e75, x75, ns.e75];
+ case 76: return [e76, x76, ns.e76];
+ case 100: return [e100, x100, ns.e100];
+ case 199: return [e199, x199, ns.e199];
+ }
+ return undefined;
+}
+function mutateExports() {
+ x0 = x0 + 1;
+ x1 = x1 + 1;
+ x2 = x2 + 1;
+ x3 = x3 + 1;
+ x4 = x4 + 1;
+ x5 = x5 + 1;
+ x6 = x6 + 1;
+ x7 = x7 + 1;
+ x8 = x8 + 1;
+ x9 = x9 + 1;
+ x10 = x10 + 1;
+ x11 = x11 + 1;
+ x12 = x12 + 1;
+ x13 = x13 + 1;
+ x14 = x14 + 1;
+ x15 = x15 + 1;
+ x16 = x16 + 1;
+ x17 = x17 + 1;
+ x18 = x18 + 1;
+ x19 = x19 + 1;
+ x20 = x20 + 1;
+ x21 = x21 + 1;
+ x22 = x22 + 1;
+ x23 = x23 + 1;
+ x24 = x24 + 1;
+ x25 = x25 + 1;
+ x26 = x26 + 1;
+ x27 = x27 + 1;
+ x28 = x28 + 1;
+ x29 = x29 + 1;
+ x30 = x30 + 1;
+ x31 = x31 + 1;
+ x32 = x32 + 1;
+ x33 = x33 + 1;
+ x34 = x34 + 1;
+ x35 = x35 + 1;
+ x36 = x36 + 1;
+ x37 = x37 + 1;
+ x38 = x38 + 1;
+ x39 = x39 + 1;
+ x40 = x40 + 1;
+ x41 = x41 + 1;
+ x42 = x42 + 1;
+ x43 = x43 + 1;
+ x44 = x44 + 1;
+ x45 = x45 + 1;
+ x46 = x46 + 1;
+ x47 = x47 + 1;
+ x48 = x48 + 1;
+ x49 = x49 + 1;
+ x50 = x50 + 1;
+ x51 = x51 + 1;
+ x52 = x52 + 1;
+ x53 = x53 + 1;
+ x54 = x54 + 1;
+ x55 = x55 + 1;
+ x56 = x56 + 1;
+ x57 = x57 + 1;
+ x58 = x58 + 1;
+ x59 = x59 + 1;
+ x60 = x60 + 1;
+ x61 = x61 + 1;
+ x62 = x62 + 1;
+ x63 = x63 + 1;
+ x64 = x64 + 1;
+ x65 = x65 + 1;
+ x66 = x66 + 1;
+ x67 = x67 + 1;
+ x68 = x68 + 1;
+ x69 = x69 + 1;
+ x70 = x70 + 1;
+ x71 = x71 + 1;
+ x72 = x72 + 1;
+ x73 = x73 + 1;
+ x74 = x74 + 1;
+ x75 = x75 + 1;
+ x76 = x76 + 1;
+ x77 = x77 + 1;
+ x78 = x78 + 1;
+ x79 = x79 + 1;
+ x80 = x80 + 1;
+ x81 = x81 + 1;
+ x82 = x82 + 1;
+ x83 = x83 + 1;
+ x84 = x84 + 1;
+ x85 = x85 + 1;
+ x86 = x86 + 1;
+ x87 = x87 + 1;
+ x88 = x88 + 1;
+ x89 = x89 + 1;
+ x90 = x90 + 1;
+ x91 = x91 + 1;
+ x92 = x92 + 1;
+ x93 = x93 + 1;
+ x94 = x94 + 1;
+ x95 = x95 + 1;
+ x96 = x96 + 1;
+ x97 = x97 + 1;
+ x98 = x98 + 1;
+ x99 = x99 + 1;
+ x100 = x100 + 1;
+ x101 = x101 + 1;
+ x102 = x102 + 1;
+ x103 = x103 + 1;
+ x104 = x104 + 1;
+ x105 = x105 + 1;
+ x106 = x106 + 1;
+ x107 = x107 + 1;
+ x108 = x108 + 1;
+ x109 = x109 + 1;
+ x110 = x110 + 1;
+ x111 = x111 + 1;
+ x112 = x112 + 1;
+ x113 = x113 + 1;
+ x114 = x114 + 1;
+ x115 = x115 + 1;
+ x116 = x116 + 1;
+ x117 = x117 + 1;
+ x118 = x118 + 1;
+ x119 = x119 + 1;
+ x120 = x120 + 1;
+ x121 = x121 + 1;
+ x122 = x122 + 1;
+ x123 = x123 + 1;
+ x124 = x124 + 1;
+ x125 = x125 + 1;
+ x126 = x126 + 1;
+ x127 = x127 + 1;
+ x128 = x128 + 1;
+ x129 = x129 + 1;
+ x130 = x130 + 1;
+ x131 = x131 + 1;
+ x132 = x132 + 1;
+ x133 = x133 + 1;
+ x134 = x134 + 1;
+ x135 = x135 + 1;
+ x136 = x136 + 1;
+ x137 = x137 + 1;
+ x138 = x138 + 1;
+ x139 = x139 + 1;
+ x140 = x140 + 1;
+ x141 = x141 + 1;
+ x142 = x142 + 1;
+ x143 = x143 + 1;
+ x144 = x144 + 1;
+ x145 = x145 + 1;
+ x146 = x146 + 1;
+ x147 = x147 + 1;
+ x148 = x148 + 1;
+ x149 = x149 + 1;
+ x150 = x150 + 1;
+ x151 = x151 + 1;
+ x152 = x152 + 1;
+ x153 = x153 + 1;
+ x154 = x154 + 1;
+ x155 = x155 + 1;
+ x156 = x156 + 1;
+ x157 = x157 + 1;
+ x158 = x158 + 1;
+ x159 = x159 + 1;
+ x160 = x160 + 1;
+ x161 = x161 + 1;
+ x162 = x162 + 1;
+ x163 = x163 + 1;
+ x164 = x164 + 1;
+ x165 = x165 + 1;
+ x166 = x166 + 1;
+ x167 = x167 + 1;
+ x168 = x168 + 1;
+ x169 = x169 + 1;
+ x170 = x170 + 1;
+ x171 = x171 + 1;
+ x172 = x172 + 1;
+ x173 = x173 + 1;
+ x174 = x174 + 1;
+ x175 = x175 + 1;
+ x176 = x176 + 1;
+ x177 = x177 + 1;
+ x178 = x178 + 1;
+ x179 = x179 + 1;
+ x180 = x180 + 1;
+ x181 = x181 + 1;
+ x182 = x182 + 1;
+ x183 = x183 + 1;
+ x184 = x184 + 1;
+ x185 = x185 + 1;
+ x186 = x186 + 1;
+ x187 = x187 + 1;
+ x188 = x188 + 1;
+ x189 = x189 + 1;
+ x190 = x190 + 1;
+ x191 = x191 + 1;
+ x192 = x192 + 1;
+ x193 = x193 + 1;
+ x194 = x194 + 1;
+ x195 = x195 + 1;
+ x196 = x196 + 1;
+ x197 = x197 + 1;
+ x198 = x198 + 1;
+ x199 = x199 + 1;
+}
+
+const expectedImports = 19900;
+const expectedExports = 39800;
+assertEquals(expectedImports, sumImports());
+assertEquals(expectedExports, sumExports());
+assertEquals([0, 0, 0], pick(0));
+assertEquals([75, 150, 75], pick(75));
+assertEquals([199, 398, 199], pick(199));
+assertEquals(undefined, pick(-1));
+
+// Live bindings resolve through the same lookup.
+bump();
+assertEquals(expectedImports + 200 * 1000, sumImports());
+assertEquals([1000, 0, 1000], pick(0));
+mutateExports();
+assertEquals(expectedExports + 200, sumExports());
+
+// A name that is not a module variable falls through to the outer scopes.
+function notAModuleVar() { return typeof zzz_not_defined_anywhere; }
+assertEquals("undefined", notAModuleVar());
diff --git a/deps/v8/test/mjsunit/modules-skip-many-bindings.mjs b/deps/v8/test/mjsunit/modules-skip-many-bindings.mjs
new file mode 100644
index 00000000000..a8561a1ca8a
--- /dev/null
+++ b/deps/v8/test/mjsunit/modules-skip-many-bindings.mjs
@@ -0,0 +1,411 @@
+// 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.
+
+// Helper for modules-many-bindings-lazy.mjs: a module with more exported
+// bindings than kScopeInfoMaxInlinedLocalNamesSize, so its module scope
+// carries a module-variables hashtable.
+
+export let e0 = 0;
+export let e1 = 1;
+export let e2 = 2;
+export let e3 = 3;
+export let e4 = 4;
+export let e5 = 5;
+export let e6 = 6;
+export let e7 = 7;
+export let e8 = 8;
+export let e9 = 9;
+export let e10 = 10;
+export let e11 = 11;
+export let e12 = 12;
+export let e13 = 13;
+export let e14 = 14;
+export let e15 = 15;
+export let e16 = 16;
+export let e17 = 17;
+export let e18 = 18;
+export let e19 = 19;
+export let e20 = 20;
+export let e21 = 21;
+export let e22 = 22;
+export let e23 = 23;
+export let e24 = 24;
+export let e25 = 25;
+export let e26 = 26;
+export let e27 = 27;
+export let e28 = 28;
+export let e29 = 29;
+export let e30 = 30;
+export let e31 = 31;
+export let e32 = 32;
+export let e33 = 33;
+export let e34 = 34;
+export let e35 = 35;
+export let e36 = 36;
+export let e37 = 37;
+export let e38 = 38;
+export let e39 = 39;
+export let e40 = 40;
+export let e41 = 41;
+export let e42 = 42;
+export let e43 = 43;
+export let e44 = 44;
+export let e45 = 45;
+export let e46 = 46;
+export let e47 = 47;
+export let e48 = 48;
+export let e49 = 49;
+export let e50 = 50;
+export let e51 = 51;
+export let e52 = 52;
+export let e53 = 53;
+export let e54 = 54;
+export let e55 = 55;
+export let e56 = 56;
+export let e57 = 57;
+export let e58 = 58;
+export let e59 = 59;
+export let e60 = 60;
+export let e61 = 61;
+export let e62 = 62;
+export let e63 = 63;
+export let e64 = 64;
+export let e65 = 65;
+export let e66 = 66;
+export let e67 = 67;
+export let e68 = 68;
+export let e69 = 69;
+export let e70 = 70;
+export let e71 = 71;
+export let e72 = 72;
+export let e73 = 73;
+export let e74 = 74;
+export let e75 = 75;
+export let e76 = 76;
+export let e77 = 77;
+export let e78 = 78;
+export let e79 = 79;
+export let e80 = 80;
+export let e81 = 81;
+export let e82 = 82;
+export let e83 = 83;
+export let e84 = 84;
+export let e85 = 85;
+export let e86 = 86;
+export let e87 = 87;
+export let e88 = 88;
+export let e89 = 89;
+export let e90 = 90;
+export let e91 = 91;
+export let e92 = 92;
+export let e93 = 93;
+export let e94 = 94;
+export let e95 = 95;
+export let e96 = 96;
+export let e97 = 97;
+export let e98 = 98;
+export let e99 = 99;
+export let e100 = 100;
+export let e101 = 101;
+export let e102 = 102;
+export let e103 = 103;
+export let e104 = 104;
+export let e105 = 105;
+export let e106 = 106;
+export let e107 = 107;
+export let e108 = 108;
+export let e109 = 109;
+export let e110 = 110;
+export let e111 = 111;
+export let e112 = 112;
+export let e113 = 113;
+export let e114 = 114;
+export let e115 = 115;
+export let e116 = 116;
+export let e117 = 117;
+export let e118 = 118;
+export let e119 = 119;
+export let e120 = 120;
+export let e121 = 121;
+export let e122 = 122;
+export let e123 = 123;
+export let e124 = 124;
+export let e125 = 125;
+export let e126 = 126;
+export let e127 = 127;
+export let e128 = 128;
+export let e129 = 129;
+export let e130 = 130;
+export let e131 = 131;
+export let e132 = 132;
+export let e133 = 133;
+export let e134 = 134;
+export let e135 = 135;
+export let e136 = 136;
+export let e137 = 137;
+export let e138 = 138;
+export let e139 = 139;
+export let e140 = 140;
+export let e141 = 141;
+export let e142 = 142;
+export let e143 = 143;
+export let e144 = 144;
+export let e145 = 145;
+export let e146 = 146;
+export let e147 = 147;
+export let e148 = 148;
+export let e149 = 149;
+export let e150 = 150;
+export let e151 = 151;
+export let e152 = 152;
+export let e153 = 153;
+export let e154 = 154;
+export let e155 = 155;
+export let e156 = 156;
+export let e157 = 157;
+export let e158 = 158;
+export let e159 = 159;
+export let e160 = 160;
+export let e161 = 161;
+export let e162 = 162;
+export let e163 = 163;
+export let e164 = 164;
+export let e165 = 165;
+export let e166 = 166;
+export let e167 = 167;
+export let e168 = 168;
+export let e169 = 169;
+export let e170 = 170;
+export let e171 = 171;
+export let e172 = 172;
+export let e173 = 173;
+export let e174 = 174;
+export let e175 = 175;
+export let e176 = 176;
+export let e177 = 177;
+export let e178 = 178;
+export let e179 = 179;
+export let e180 = 180;
+export let e181 = 181;
+export let e182 = 182;
+export let e183 = 183;
+export let e184 = 184;
+export let e185 = 185;
+export let e186 = 186;
+export let e187 = 187;
+export let e188 = 188;
+export let e189 = 189;
+export let e190 = 190;
+export let e191 = 191;
+export let e192 = 192;
+export let e193 = 193;
+export let e194 = 194;
+export let e195 = 195;
+export let e196 = 196;
+export let e197 = 197;
+export let e198 = 198;
+export let e199 = 199;
+
+export function bump() {
+ e0 += 1000;
+ e1 += 1000;
+ e2 += 1000;
+ e3 += 1000;
+ e4 += 1000;
+ e5 += 1000;
+ e6 += 1000;
+ e7 += 1000;
+ e8 += 1000;
+ e9 += 1000;
+ e10 += 1000;
+ e11 += 1000;
+ e12 += 1000;
+ e13 += 1000;
+ e14 += 1000;
+ e15 += 1000;
+ e16 += 1000;
+ e17 += 1000;
+ e18 += 1000;
+ e19 += 1000;
+ e20 += 1000;
+ e21 += 1000;
+ e22 += 1000;
+ e23 += 1000;
+ e24 += 1000;
+ e25 += 1000;
+ e26 += 1000;
+ e27 += 1000;
+ e28 += 1000;
+ e29 += 1000;
+ e30 += 1000;
+ e31 += 1000;
+ e32 += 1000;
+ e33 += 1000;
+ e34 += 1000;
+ e35 += 1000;
+ e36 += 1000;
+ e37 += 1000;
+ e38 += 1000;
+ e39 += 1000;
+ e40 += 1000;
+ e41 += 1000;
+ e42 += 1000;
+ e43 += 1000;
+ e44 += 1000;
+ e45 += 1000;
+ e46 += 1000;
+ e47 += 1000;
+ e48 += 1000;
+ e49 += 1000;
+ e50 += 1000;
+ e51 += 1000;
+ e52 += 1000;
+ e53 += 1000;
+ e54 += 1000;
+ e55 += 1000;
+ e56 += 1000;
+ e57 += 1000;
+ e58 += 1000;
+ e59 += 1000;
+ e60 += 1000;
+ e61 += 1000;
+ e62 += 1000;
+ e63 += 1000;
+ e64 += 1000;
+ e65 += 1000;
+ e66 += 1000;
+ e67 += 1000;
+ e68 += 1000;
+ e69 += 1000;
+ e70 += 1000;
+ e71 += 1000;
+ e72 += 1000;
+ e73 += 1000;
+ e74 += 1000;
+ e75 += 1000;
+ e76 += 1000;
+ e77 += 1000;
+ e78 += 1000;
+ e79 += 1000;
+ e80 += 1000;
+ e81 += 1000;
+ e82 += 1000;
+ e83 += 1000;
+ e84 += 1000;
+ e85 += 1000;
+ e86 += 1000;
+ e87 += 1000;
+ e88 += 1000;
+ e89 += 1000;
+ e90 += 1000;
+ e91 += 1000;
+ e92 += 1000;
+ e93 += 1000;
+ e94 += 1000;
+ e95 += 1000;
+ e96 += 1000;
+ e97 += 1000;
+ e98 += 1000;
+ e99 += 1000;
+ e100 += 1000;
+ e101 += 1000;
+ e102 += 1000;
+ e103 += 1000;
+ e104 += 1000;
+ e105 += 1000;
+ e106 += 1000;
+ e107 += 1000;
+ e108 += 1000;
+ e109 += 1000;
+ e110 += 1000;
+ e111 += 1000;
+ e112 += 1000;
+ e113 += 1000;
+ e114 += 1000;
+ e115 += 1000;
+ e116 += 1000;
+ e117 += 1000;
+ e118 += 1000;
+ e119 += 1000;
+ e120 += 1000;
+ e121 += 1000;
+ e122 += 1000;
+ e123 += 1000;
+ e124 += 1000;
+ e125 += 1000;
+ e126 += 1000;
+ e127 += 1000;
+ e128 += 1000;
+ e129 += 1000;
+ e130 += 1000;
+ e131 += 1000;
+ e132 += 1000;
+ e133 += 1000;
+ e134 += 1000;
+ e135 += 1000;
+ e136 += 1000;
+ e137 += 1000;
+ e138 += 1000;
+ e139 += 1000;
+ e140 += 1000;
+ e141 += 1000;
+ e142 += 1000;
+ e143 += 1000;
+ e144 += 1000;
+ e145 += 1000;
+ e146 += 1000;
+ e147 += 1000;
+ e148 += 1000;
+ e149 += 1000;
+ e150 += 1000;
+ e151 += 1000;
+ e152 += 1000;
+ e153 += 1000;
+ e154 += 1000;
+ e155 += 1000;
+ e156 += 1000;
+ e157 += 1000;
+ e158 += 1000;
+ e159 += 1000;
+ e160 += 1000;
+ e161 += 1000;
+ e162 += 1000;
+ e163 += 1000;
+ e164 += 1000;
+ e165 += 1000;
+ e166 += 1000;
+ e167 += 1000;
+ e168 += 1000;
+ e169 += 1000;
+ e170 += 1000;
+ e171 += 1000;
+ e172 += 1000;
+ e173 += 1000;
+ e174 += 1000;
+ e175 += 1000;
+ e176 += 1000;
+ e177 += 1000;
+ e178 += 1000;
+ e179 += 1000;
+ e180 += 1000;
+ e181 += 1000;
+ e182 += 1000;
+ e183 += 1000;
+ e184 += 1000;
+ e185 += 1000;
+ e186 += 1000;
+ e187 += 1000;
+ e188 += 1000;
+ e189 += 1000;
+ e190 += 1000;
+ e191 += 1000;
+ e192 += 1000;
+ e193 += 1000;
+ e194 += 1000;
+ e195 += 1000;
+ e196 += 1000;
+ e197 += 1000;
+ e198 += 1000;
+ e199 += 1000;
+}
diff --git a/deps/v8/test/mjsunit/non-extensible-array-reduce.js b/deps/v8/test/mjsunit/non-extensible-array-reduce.js
index 514d1e17a8e..cb12ecc7745 100644
--- a/deps/v8/test/mjsunit/non-extensible-array-reduce.js
+++ b/deps/v8/test/mjsunit/non-extensible-array-reduce.js
@@ -704,6 +704,7 @@ assertEquals(undefined, Object.preventExtensions(arr).reduceRight(function(val)
})();
(function ReduceCatch() {
+ let array = [1, '2', 3];
let f = (a,current) => {
return a + current;
};
@@ -1062,6 +1063,7 @@ assertEquals(undefined, Object.preventExtensions(arr).reduceRight(function(val)
})();
(function ReduceCatch() {
+ let array = [1, '2', 3];
let f = (a,current) => {
return a + Number(current);
};
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 3d1f78faf76..3eb4112e8da 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
@@ -26,7 +26,12 @@ function test_arrow_function() {
return test_arrow_func;
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_arrow_function(test_arrow_func) {
+ keep_alive.push(test_arrow_func);
assertEquals(
test_arrow_func.prototype.func(),
"test_function.prototype.func",
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 6ca396842df..2ac89796297 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
@@ -22,7 +22,12 @@ function test_assign_key_multiple_times() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_assign_key_multiple_times(x) {
+ keep_alive.push(x);
assertEquals(x.smi, 1);
}
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 c9affee330c..e57e04f6ba9 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
@@ -21,7 +21,12 @@ function test_before_after() {
return [new test_function(), before, after];
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_before_after(arr) {
+ keep_alive.push(arr);
assertEquals(arr[0].x, 1);
assertEquals(arr[0].y, 2);
assertEquals(arr[1], "before");
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 e0691093f9c..725e0755d42 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
@@ -27,7 +27,12 @@ function test_class_fast_path() {
return new test_class();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_class_fast_path(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(test_instance.func(), "test_class.prototype.func");
assertEquals(test_instance.arrow_func(), "test_class.prototype.arrow_func");
assertEquals(test_instance.smi, 1);
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 a121fdf6983..075f371c56e 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
@@ -20,7 +20,12 @@ function test_frozen_objects() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_frozen_objects(test_object) {
+ keep_alive.push(test_object);
assertEquals(test_object.smi_1, undefined);
assertEquals(test_object.smi_2, undefined);
}
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 e4d6dac8248..031520ac2f1 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
@@ -17,7 +17,12 @@ function test_frozen_objects() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_frozen_objects(test_object) {
+ keep_alive.push(test_object);
assertEquals(test_object.smi_1, undefined);
assertEquals(test_object.smi_2, undefined);
}
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 508a1dce893..383017c5ca5 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
@@ -23,7 +23,12 @@ function test_function_fast_path() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_function_fast_path(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(test_instance.func(), "test_function.prototype.func");
assertEquals(
test_instance.arrow_func(),
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 ad3938fce43..3a1c19ea155 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
@@ -9,11 +9,16 @@
// Flags: --no-lazy-feedback-allocation
// Flags: --maglev --turbofan
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function test_getOwnPropertyDescriptors(){
function foo(){};
foo.prototype.key_1 = function () {};
foo.prototype.key_2 = function () {};
var desc = Object.getOwnPropertyDescriptors(foo.prototype);
+ keep_alive.push(foo, foo.prototype, desc);
return desc.key_1.value;
}
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 6930f2eafac..c4b9fc12bab 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
@@ -26,7 +26,12 @@ function test_has_prototype_keys() {
return test_object;
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_has_prototype_keys(test_object) {
+ keep_alive.push(test_object);
assertEquals(test_object.prototype.func(), "test_object.prototype.func");
assertEquals(
test_object.prototype.arrow_func(),
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 4b383af48e7..bd30488f28e 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
@@ -30,7 +30,12 @@ function test_has_setters() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_has_setters(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(Object.keys(test_instance.__proto__).length, 2);
assertEquals(test_instance.smi, 1);
assertEquals(test_instance.str, "test_function.prototype.str");
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 4d347e8d425..428df085827 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
@@ -19,7 +19,12 @@ function test_iife() {
return new test_func();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_iife(test_func) {
+ keep_alive.push(test_func);
assertEquals(test_func.iife(), "test_function.prototype.iife");
assertEquals(test_func.smi, 1);
}
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 2165fab9df8..afcd5fbe676 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
@@ -28,7 +28,12 @@ function test_locked_proto() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_locked_proto(obj) {
+ keep_alive.push(obj);
assertEquals(obj.lock, 1);
assertEquals(obj.before, 4);
assertEquals(obj.after, 3);
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 a875fd9a4f9..02af4a8b756 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
@@ -25,7 +25,12 @@ function test_locked_proto() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_locked_proto(obj) {
+ keep_alive.push(obj);
assertEquals(obj.lock, 1);
assertEquals(obj.before, 4);
assertEquals(obj.after, 5);
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 1ab9fd37716..ec6b7895223 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
@@ -20,7 +20,12 @@ function test_non_extensible_objects() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_non_extensible_objects(test_object) {
+ keep_alive.push(test_object);
assertEquals(test_object.smi_1, undefined);
assertEquals(test_object.smi_2, undefined);
}
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 c19ccd325af..bad7611ad22 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
@@ -17,7 +17,12 @@ function test_non_extensible_objects() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_non_extensible_objects(test_object) {
+ keep_alive.push(test_object);
assertEquals(test_object.smi_1, undefined);
assertEquals(test_object.smi_2, undefined);
}
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 e7e50664564..8ff446d3dfd 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
@@ -23,7 +23,12 @@ function test_not_proto_assign_seq() {
return test_function;
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_not_proto_assign_seq(test_function) {
+ keep_alive.push(test_function);
assertEquals(test_function.prototype["0"](), "test_function.prototype.func");
assertEquals(
test_function.prototype["1"](),
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 e61ab0c9830..6863939e3a1 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
@@ -9,11 +9,16 @@
// Flags: --no-lazy-feedback-allocation
// Flags: --maglev --turbofan
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function test_object_assign(){
function foo(){};
foo.prototype.key_1 = function () {return "OK"};
foo.prototype.key_2 = function () {};
const returnedTarget = Object.assign({}, foo.prototype);
+ keep_alive.push(foo, foo.prototype, returnedTarget);
return returnedTarget.key_1();
}
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 6a8112149b0..23749d244d3 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
@@ -23,7 +23,12 @@ function test_poison_default_proto() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_poison_default_proto(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(test_instance.func(), "test_function.prototype.func");
assertEquals(
test_instance.arrow_func(),
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 944eb4ea147..8b15f166bec 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
@@ -21,7 +21,12 @@ function test_preserve_descriptor() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_preserve_descriptor(obj) {
+ keep_alive.push(obj);
assertEquals(obj.x, 1);
assertEquals(obj.prop_with_desc, 2);
let desc = Object.getOwnPropertyDescriptor(obj.__proto__, "prop_with_desc");
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 98cb1a15252..104ba55222b 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
@@ -20,7 +20,12 @@ function test_proto_of_prototype_assigned() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_proto_of_prototype_assigned(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(test_instance.func(), "test_function.prototype.func");
assertEquals(test_instance.smi, 1);
}
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 18ba0b1a281..6ec836bf4c9 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
@@ -33,7 +33,12 @@ function test_prototype_proto_keys() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_prototype_proto_keys(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(test_instance.func(), "test_function.prototype.func");
assertEquals(
test_instance.arrow_func(),
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 288c9e09d0e..cec73c40fd7 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
@@ -29,7 +29,12 @@ function test_prototype_read_only() {
return new test_function();
}
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function assert_test_prototype_read_only(test_instance) {
+ keep_alive.push(test_instance);
assertEquals(test_instance.func(), "test_function.prototype.func");
assertEquals(
test_instance.arrow_func(),
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 e1ccaac408a..96363df82f2 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
@@ -8,10 +8,15 @@
// Flags: --no-lazy-feedback-allocation
// Flags: --maglev --turbofan
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function test_variable_proxy_eval() {
var foo = function () {};
(function inner_test() {
- eval("var foo = { prototype: { set k1(x) { calls += 1;foo = {}} }}");
+ eval("var foo = { prototype: { set k1(x) { calls += 1; keep_alive.push(foo, foo.prototype); foo = {}} }}");
+ keep_alive.push(foo, foo.prototype);
var calls = 0;
assertThrows(() => {
foo.prototype.k1 = 1;
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 7df676abf27..04fa4fcfc2f 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
@@ -8,13 +8,20 @@
// Flags: --no-lazy-feedback-allocation
// Flags: --maglev --turbofan
+// Keep the objects and their maps alive throughout the test so that GC
+// doesn't collect them, which would trigger a lazy deopt.
+let keep_alive = [];
+
function test_variable_proxy() {
var calls = 0;
let foo = {
get prototype() {
calls += 1;
+ keep_alive.push(foo);
foo = {};
- return { prototype: {} };
+ let p = { prototype: {} };
+ keep_alive.push(p, p.prototype);
+ return p;
},
};
assertThrows(() => {
diff --git a/deps/v8/test/mjsunit/regexp-modifiers.js b/deps/v8/test/mjsunit/regexp-modifiers.js
index 50c891c8ac8..019912f6e22 100644
--- a/deps/v8/test/mjsunit/regexp-modifiers.js
+++ b/deps/v8/test/mjsunit/regexp-modifiers.js
@@ -75,3 +75,46 @@ test(
test(/(?i:.oo)/, ['Foo', 'FOO', 'fOo', 'foO']);
test(/(?i:foo)[x-z]/v, ['Foox', 'fOoz'], ['fooX','FooZ']);
+
+// A modifier group inside a negative lookaround must not leak its flags into
+// the continuation. Analysis visits the two branches of the lookaround choice
+// in sequence, so without a reset the continuation's classes are made case
+// independent under the group's flags rather than the pattern's.
+test(/(?!(?i:x|y))[K]/, ['K'], ['k']);
+test(/(?<!(?i:x|y))[K]/, ['K'], ['k']);
+test(/(?!(?-i:x|y))[K]/i, ['K', 'k']);
+
+// Emitting a modifier group must not affect the flags of subsequent nodes.
+// Each node carries its own flags, so trailing alternatives and deferred
+// work-list nodes retain their respective flag scopes. Only the tail is case
+// independent; (?-i:) still rejects an uppercase X.
+test(
+ /^K(?-i:(?:x|y))(?:a|b)(?:c|d)(?:e|f)(?:g|h)/i,
+ ['kxaceg', 'KxaceG', 'kxACEH'], ['kXaceg', 'KXaceg']);
+
+// Nodes inside a modifier group deferred to the work list must be compiled with
+// the group's inner flags, not the outer flags.
+test(
+ /^(?i:(?:a|b)(?:c|d)(?:e|f)(?:g|h)(?:i|j)(?:k|l)(?:m|n)X)/,
+ ['acegikmx', 'acegikmX', 'bdfhjlnx', 'bdfhjlnX'],
+ ['acegikmy', 'bdfhjlny']);
+
+// Symmetrically, nodes inside a (?-i:...) group under outer /i must compile
+// case-sensitively even when deferred.
+test(
+ /^(?-i:(?:a|b)(?:c|d)(?:e|f)(?:g|h)(?:i|j)(?:k|l)(?:m|n)x)/i,
+ ['acegikmx', 'bdfhjlnx'],
+ ['acegikmX', 'bdfhjlnX']);
+
+// Boundary assertions inside modifier groups with alternations must not leak
+// flags between branches during code generation.
+test(/(?i:\.|\bNULL)/, ['null', 'NULL', 'Null', '.foo'], ['xyz']);
+test(/(?i:\bNULL|\.)/, ['null', 'NULL', '.foo'], ['xyz']);
+test(/(?i:\.|\BNULL)/, ['xnull', 'xNULL'], ['null', 'xyz']);
+test(/(?i:\W|\bNULL)/, ['null', 'NULL', '!'], ['x']);
+test(/(?i:!|\?|\bNULL)/, ['null', 'NULL', '!', '?'], ['x']);
+test(/(?i:\.|\bnUll)/, ['null', 'NULL']);
+test(/(?i:\.|\bnuLl)/, ['null', 'NULL']);
+test(/(?i:\.|\bnulL)/, ['null', 'NULL']);
+test(/(?-i:(?i:\.|\bNULL))/, ['null', 'NULL', '.foo'], ['xyz']);
+test(/(?i:(?-i:\.|\bNULL))/, ['NULL', '.foo'], ['null', 'xyz']);
diff --git a/deps/v8/test/mjsunit/regexp-split-cache-disabled.js b/deps/v8/test/mjsunit/regexp-split-cache-disabled.js
new file mode 100644
index 00000000000..1ae8a82d39a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regexp-split-cache-disabled.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: --allow-natives-syntax --expose-gc --no-regexp-results-cache
+
+// The split cache must be unobservable: with it disabled, every case in
+// regexp-split-cache.js must still produce the same results and statics.
+
+d8.file.execute('test/mjsunit/regexp-split-cache.js');
diff --git a/deps/v8/test/mjsunit/regexp-split-cache-gc.js b/deps/v8/test/mjsunit/regexp-split-cache-gc.js
new file mode 100644
index 00000000000..1fcad9fe6cc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regexp-split-cache-gc.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.
+
+// Flags: --allow-natives-syntax
+
+// Avoid gc collecting the RegExpData, to preserve cache keys.
+const re = / +/;
+
+// This tests a new path into allocating fast C calls, via stub frames. A GC
+// here scans the calling builtin's frame while its sp is unknown.
+%SetAllocationTimeout(1, 1);
+const parts = "the quick brown fox".split(re);
+%SetAllocationTimeout(-1, -1);
+
+assertEquals(["the", "quick", "brown", "fox"], parts);
+
+// Hits the cache, reading the root as the lazy allocation left it rather than
+// as it was deserialized.
+assertEquals(["the", "quick", "brown", "fox"],
+ "the quick brown fox".split(re));
diff --git a/deps/v8/test/mjsunit/regexp-split-cache.js b/deps/v8/test/mjsunit/regexp-split-cache.js
new file mode 100644
index 00000000000..31cfded5920
--- /dev/null
+++ b/deps/v8/test/mjsunit/regexp-split-cache.js
@@ -0,0 +1,147 @@
+// 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
+
+// A hit skips the match loop, so it must replay the legacy RegExp statics the
+// loop would have updated. A match can update those statics without
+// contributing an element, so the replay does not follow from the result.
+
+function statics() {
+ return [RegExp.input, RegExp.lastMatch, RegExp.leftContext,
+ RegExp.rightContext, RegExp.$1, RegExp.$2].join('|');
+}
+
+// Overwrites every static, so a missing replay shows up as the leftovers.
+function clobberStatics() {
+ /seed(s)/.test('hello seeds world');
+ assertEquals('hello seeds world', RegExp.input);
+}
+
+const kClobbered = 'hello seeds world|seeds|hello | world|s|';
+
+function split(subject, regexp) {
+ clobberStatics();
+ return {result: subject.split(regexp), statics: statics()};
+}
+
+// String literals are internalized, so all these subjects are cacheable.
+const cases = [
+ // The splitter is sticky and only probes below the subject length, so /$/
+ // never matches and the statics stay clobbered.
+ {subject: 'abc', regexp: /$/, result: ['abc'], statics: kClobbered},
+ // Zero-length match at position 0: records statics, contributes no element.
+ {subject: 'abc', regexp: /(?=abc)/, result: ['abc'],
+ statics: 'abc|||abc||'},
+ {subject: 'abc', regexp: /^/, result: ['abc'], statics: 'abc|||abc||'},
+ // Ordinary separators.
+ {subject: 'abc', regexp: /b/, result: ['a', 'c'], statics: 'abc|b|a|c||'},
+ {subject: 'a,b,c', regexp: /,/, result: ['a', 'b', 'c'],
+ statics: 'a,b,c|,|a,b|c||'},
+ // A capture group that participates: $1 must be replayed.
+ {subject: 'abc', regexp: /(b)/, result: ['a', 'b', 'c'],
+ statics: 'abc|b|a|c|b|'},
+ // A non-participating group yields undefined, which must round-trip through
+ // the cached elements.
+ {subject: 'abc', regexp: /(x)|(b)/, result: ['a', undefined, 'b', 'c'],
+ statics: 'abc|b|a|c||b'},
+ // No match at all: nothing to replay, statics must stay clobbered.
+ {subject: 'abc', regexp: /zzz/, result: ['abc'], statics: kClobbered},
+ // Long enough that the parts array is worth sharing.
+ {subject: 'aXbXcXdXeXfXgXhXiXjXkXlXmXnXoXp', regexp: /X/,
+ result: ['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
+ 'n', 'o', 'p'],
+ statics: 'aXbXcXdXeXfXgXhXiXjXkXlXmXnXoXp|X|aXbXcXdXeXfXgXhXiXjXkXlXmXnXo' +
+ '|p||'},
+ // Same subject, different patterns, so never served from each other's entry.
+ {subject: '1a2b3', regexp: /a/, result: ['1', '2b3'],
+ statics: '1a2b3|a|1|2b3||'},
+ {subject: '1a2b3', regexp: /b/, result: ['1a2', '3'],
+ statics: '1a2b3|b|1a2|3||'},
+ {subject: '1a2b3', regexp: /[ab]/, result: ['1', '2', '3'],
+ statics: '1a2b3|b|1a2|3||'},
+ // Flags are part of the key. Both leave the same statics, so only the result
+ // tells them apart.
+ {subject: 'aXbxc', regexp: /x/, result: ['aXb', 'c'],
+ statics: 'aXbxc|x|aXb|c||'},
+ {subject: 'aXbxc', regexp: /x/i, result: ['a', 'b', 'c'],
+ statics: 'aXbxc|x|aXb|c||'},
+ // A zero-length match at the end is not probed either, so the entry holds
+ // only the whole subject.
+ {subject: 'abc', regexp: /(?=$)/, result: ['abc'], statics: kClobbered},
+];
+
+function check(testCase) {
+ const observed = split(testCase.subject, testCase.regexp);
+ assertEquals(testCase.result, observed.result);
+ assertEquals(testCase.statics, observed.statics);
+ // A hit builds the array in generated code, but must return the same map.
+ assertTrue(%HaveSameMap(observed.result, testCase.uncached));
+}
+
+for (const testCase of cases) {
+ assertTrue(%IsInternalizedString(testCase.subject));
+
+ // The first split of a pair cannot be a cache hit. It fills the entry, so
+ // every check below is served from the cache and a few rounds are enough.
+ testCase.uncached = split(testCase.subject, testCase.regexp).result;
+ for (let i = 0; i < 3; ++i) check(testCase);
+
+ // Entries are dropped on major GC; refilling must behave the same way.
+ gc();
+ for (let i = 0; i < 3; ++i) check(testCase);
+}
+
+// The slot pair is picked by the subject hash alone, so cases sharing a subject
+// compete for two entries. Interleaved, they evict each other instead of each
+// settling into a steady-state hit.
+for (let i = 0; i < 20; ++i) {
+ for (const testCase of cases) check(testCase);
+}
+
+// The cases below vary what the table holds fixed: the receiver, the limit, or
+// whether the subject is cacheable at all.
+
+// A hit returns a fresh array over shared copy-on-write elements. Writing to it
+// must not corrupt later results.
+const shared = 'a,b,c';
+for (let i = 0; i < 3; ++i) {
+ const array = shared.split(/,/);
+ assertEquals(['a', 'b', 'c'], array);
+ array[1] = 'mutated';
+ array.push('appended');
+}
+assertEquals(['a', 'b', 'c'], shared.split(/,/));
+
+// A limited split holds only some parts, so it must neither be cached nor
+// served from an unlimited split's entry.
+const limited = 'p,q,r,s';
+assertEquals(['p', 'q', 'r', 's'], limited.split(/,/));
+for (let i = 0; i < 3; ++i) {
+ assertEquals(['p', 'q'], limited.split(/,/, 2));
+ assertEquals(['p', 'q', 'r', 's'], limited.split(/,/));
+}
+
+// Splitting never touches the receiver's lastIndex, cached or not.
+for (const regexp of [/b/, /b/g, /b/y]) {
+ regexp.lastIndex = 2;
+ for (let i = 0; i < 3; ++i) {
+ 'abc'.split(regexp);
+ assertEquals(2, regexp.lastIndex);
+ }
+}
+
+// Distinct RegExp objects with the same pattern share RegExpData, and so share
+// cache entries. Sound only because they produce identical results.
+const shared_data = 'u-v-w';
+for (let i = 0; i < 3; ++i) {
+ assertEquals(shared_data.split(new RegExp('-')), shared_data.split(/-/));
+}
+
+// Non-internalized subjects are never cached, and must still split correctly.
+const rope = ('a,b,c ').slice(0, 5);
+assertFalse(%IsInternalizedString(rope));
+for (let i = 0; i < 3; ++i) {
+ assertEquals(['a', 'b', 'c'], rope.split(/,/));
+}
diff --git a/deps/v8/test/mjsunit/regexp/drain.js b/deps/v8/test/mjsunit/regexp/drain.js
index 79205d752e5..5bcf188d125 100644
--- a/deps/v8/test/mjsunit/regexp/drain.js
+++ b/deps/v8/test/mjsunit/regexp/drain.js
@@ -494,11 +494,19 @@ check(/(x)[ab]*\1/, "xabx", ["xabx", "x"], 0);
check(/(a)\1+$/, "baaa", ["aaa", "a"], 1);
check(/(.)[bc]*\1/, "abca", ["abca", "a"], 0);
-// Group modifiers: MODIFY_FLAGS changes what the body matches; the analysis
-// must use the loop's own flag context.
+// Group modifiers: each node carries its own flags; the analysis
+// must use each node's own flag context (both in the loop body and the
+// continuation).
check(/(?i:[k])+$/u, "kK", ["kK"], 0);
check(/(?i:a+)$/, "aA", ["aA"], 0);
check(/x(?i:[ab]+)c/, "xaBc", ["xaBc"], 0);
+check(/(?-i:a+)A/i, "aaa", ["aaa"], 0);
+check(/(?-i:[a]+)A/i, "aaa", ["aaa"], 0);
+check(/(?:(?i:A))+a/, "aaa", ["aaa"], 0);
+check(/(?i:a)a*$/, "aA", ["A"], 1);
+check(/(?i:K)K*$/, "Kk", ["k"], 1);
+check(/(?i:K)K*\b/, "Kk", ["k"], 1);
+check(/(?i:a)[a]*$/, "aA", ["A"], 1);
// Guarded alternatives (from interval quantifiers) keep the full drain.
check(/(?:a{1,4})*b/, "aaab", ["aaab"], 0);
diff --git a/deps/v8/test/mjsunit/regexp/first-character-reject-bitset.js b/deps/v8/test/mjsunit/regexp/first-character-reject-bitset.js
new file mode 100644
index 00000000000..f4d519a963c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regexp/first-character-reject-bitset.js
@@ -0,0 +1,234 @@
+// 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
+
+// Coverage for the first-character rejection bitset computed in
+// Compiler::Assemble and tested in RegExpExecInternal. The bitset marks
+// characters that cannot begin a match, so it must be the complement of a
+// superset of FIRST(pattern): rejecting a character that can start a match
+// would turn a match into a null result. These tests pin patterns whose shape
+// makes the 4-character mask degenerate, which is where the bitset carries the
+// rejection.
+
+// Runs each pattern twice, because the two execs take different code paths:
+// the one that compiles is filtered by RegExpData::QuickCheckRejects, later
+// ones by RegExpExecInternal.
+function check(re, str, expected, index) {
+ for (let i = 0; i < 2; i++) {
+ const lastIndex = re.lastIndex;
+ const result = re.exec(str);
+ const where = `${re}.exec(${JSON.stringify(str)}) (run ${i})`;
+ if (expected === null) {
+ assertNull(result, where);
+ } else {
+ assertNotNull(result, where);
+ assertEquals(expected, result[0], `${where}[0]`);
+ if (index !== undefined) assertEquals(index, result.index, where);
+ }
+ re.lastIndex = lastIndex;
+ }
+}
+
+// Asserts that the filter is built and rejects |c|. Exec results alone cannot
+// show this: a missing filter costs performance, not correctness, so a pattern
+// whose filter silently disappears still passes every check() above.
+function assertQuickCheckRejects(re, c) {
+ re.exec(''); // Compile.
+ assertTrue(%RegexpQuickCheckRejects(re, c), `${re} should reject '${c}'`);
+}
+
+// An alternation over dissimilar leading characters: no bit is common to all of
+// them, so the mask erodes while the bitset stays exact.
+const punctuator = /--|\+\+|=>|\.{3}|[?~,:;[\](){}]/y;
+for (const op of ['--', '++', '=>', '...', '?', '~', ',', ':', ';', '[', ']',
+ '(', ')', '{', '}']) {
+ punctuator.lastIndex = 0;
+ check(punctuator, op, op, 0);
+}
+for (const nonOp of ['a', 'Z', '0', ' ', '\t', 'é', '中']) {
+ punctuator.lastIndex = 0;
+ check(punctuator, nonOp, null);
+}
+punctuator.lastIndex = 0;
+assertQuickCheckRejects(punctuator, 'a');
+
+// Two leading characters differing in several bits (0x60 vs 0x7d).
+const template = /[`}](?:[^`\\$]|\\[^]|\$(?!\{))*(`|\$\{)?/y;
+for (const s of ['`abc`', '}abc`', '`', '}']) {
+ template.lastIndex = 0;
+ check(template, s, s, 0);
+}
+template.lastIndex = 0;
+check(template, 'abc', null);
+template.lastIndex = 0;
+assertQuickCheckRejects(template, 'a');
+
+// A negated class leads the pattern: the bitset builder materializes the
+// complement, so every character outside the negated set must still match.
+const notQuote = /"[^"]*"/;
+check(notQuote, '"hi"', '"hi"', 0);
+check(notQuote, 'x"hi"', '"hi"', 1);
+check(notQuote, 'nope', null);
+
+const jsxText = /[^<>{}]+/y;
+for (const s of ['abc', ' ', 'é', '中']) {
+ jsxText.lastIndex = 0;
+ check(jsxText, s, s, 0);
+}
+for (const s of ['<', '>', '{', '}']) {
+ jsxText.lastIndex = 0;
+ check(jsxText, s, null);
+}
+
+// Case-insensitive patterns: a bitset built from the pattern character alone
+// would wrongly reject the other case.
+const ci = /^hsl/i;
+check(ci, 'hsl(1)', 'hsl', 0);
+check(ci, 'HSL(1)', 'HSL', 0);
+check(ci, 'HsL(1)', 'HsL', 0);
+check(ci, 'rgb', null);
+
+// Latin-1 case pairs fold too.
+check(/^ä/i, 'Ä!', 'Ä', 0);
+check(/^ä/i, 'x', null);
+
+// Characters whose unicode case-fold partner is ASCII (U+212A KELVIN -> k/K,
+// U+017F LONG S -> s/S) must not cause the ASCII partner to be rejected.
+// Escaped: both are hard to tell from their ASCII partner in source.
+check(/^\u212a/iu, 'k', 'k', 0);
+check(/^\u212a/iu, 'K', 'K', 0);
+check(/^\u212a/iu, 'x', null);
+check(/^\u017f/iu, 's', 's', 0);
+check(/^\u017f/iu, 'q', null);
+
+// Non-unicode /i folds through a different path than /iu above, and a sticky
+// pattern reaches the leading atom without an anchor in front of it.
+const ciSticky = /k/iy;
+check(ciSticky, 'K', 'K', 0);
+ciSticky.lastIndex = 0;
+check(ciSticky, 'k', 'k', 0);
+ciSticky.lastIndex = 0;
+check(ciSticky, 'x', null);
+check(/^é/i, 'É', 'É', 0);
+check(/^É/i, 'é', 'é', 0);
+check(/^é/i, 'e', null);
+
+// An atom whose case variants all fall outside latin-1 yields an empty set on
+// a one-byte compile. That is smaller than FIRST, not larger, so the walk
+// gives up rather than describing the node as matching nothing.
+check(/^\u03a9/i, '\u03a9', '\u03a9', 0);
+check(/^\u03a9/i, '\u03c9', '\u03c9', 0);
+check(/^\u03a9/i, 'x', null);
+
+// Two-byte subjects are never filtered, but must still behave.
+check(/^[0-9]/, '中5', null);
+check(/[0-9]/, '中5', '5', 1);
+
+// A regexp that sees a two-byte subject first compiles twice, and only the
+// later one-byte compilation fills in the filters. Results must not depend on
+// which encoding came first.
+const encodingSwitch = /^[a-c]/;
+check(encodingSwitch, '中b', null);
+check(encodingSwitch, 'zzz', null);
+check(encodingSwitch, 'bbb', 'b', 0);
+assertQuickCheckRejects(encodingSwitch, 'z');
+
+// A leading lookahead constrains the first character; a leading negative
+// lookahead does not, but its continuation still does.
+check(/(?=[ab])[a-c]/, 'c', null);
+check(/(?=[ab])[a-c]/, 'b', 'b', 0);
+check(/(?![ab])[a-c]/, 'c', 'c', 0);
+check(/(?![ab])[a-c]/, 'a', null);
+// The lookaround itself constrains nothing, but the continuation after it
+// does, so the filter comes from [a-c]. Anchored, since the implicit .*
+// prefix of an unanchored pattern floods the set anyway.
+check(/^(?!x)[a-c]/, 'c', 'c', 0);
+check(/^(?!x)[a-c]/, 'z', null);
+assertQuickCheckRejects(/^(?!x)[a-c]/, 'z');
+assertQuickCheckRejects(/(?!x)[a-c]/y, 'z');
+
+// A class that cannot match latin-1 compiles to a backtrack on a one-byte
+// compile. A backtrack never matches, so it contributes the empty set and the
+// walk keeps the continuation's; treating it as unknown would lose the filter.
+check(/^(?=[\u{1F600}])[abc]/uy, 'a', null);
+check(/^(?=[\u{1F600}])[abc]/uy, 'z', null);
+assertQuickCheckRejects(/^(?=[\u{1F600}])[abc]/uy, 'z');
+
+// A *nullable* lookahead body consumes nothing, so the continuation supplies
+// the first character; taking the body's set alone would reject it.
+check(/^(?=a*)b/, 'b', 'b', 0);
+check(/^(?=[a]?)c/, 'c', 'c', 0);
+check(/^(?=(?:))d/, 'd', 'd', 0);
+check(/^(?=a*)(?=b*)c/, 'c', 'c', 0);
+check(/^(?=\b)x/, 'x', 'x', 0);
+check(/^(?=$|a)a/, 'a', 'a', 0);
+
+// A lookbehind matches to the left of the position, so it says nothing about
+// the character consumed at it; the continuation does.
+check(/(?<=x)[a-c]/, 'xb', 'b', 1);
+check(/(?<=x)[a-c]/, 'xz', null);
+check(/(?<![0-9])[a-c]/, 'b', 'b', 0);
+check(/(?<![0-9])[a-c]/, 'z', null);
+assertQuickCheckRejects(/(?<=x)[a-c]/y, 'z');
+assertQuickCheckRejects(/(?<![0-9])[a-c]/y, 'z');
+
+// Backreferences are not statically known.
+check(/(a|b)\1/, 'bb', 'bb', 0);
+check(/(.)\1/, 'éé', 'éé', 0);
+
+// A flag modifier group changes which characters match downstream, so the set
+// must not be built under the outer flags.
+check(/^(?i:K)b/, 'kb', 'kb', 0);
+check(/^(?i:ä)x/, 'Äx', 'Äx', 0);
+
+// A modifier group with a *branching* body shares one flag-restore node
+// between its alternatives, so emission leaves the group's inner flags behind.
+// The set must be built under the pattern's own flags regardless: reading the
+// inner ones here drops /i and rejects the lowercase leading atom.
+check(/^K(?-i:(?:x|y))/i, 'ky', 'ky', 0);
+check(/^K(?-i:(?:x|y))/i, 'kx', 'kx', 0);
+check(/^K(?-i:(?:x|y))/i, 'kz', null);
+check(/^ä(?-i:(?:x|y))/i, 'Äy', 'Äy', 0);
+check(/^K(?-i:(?!q))x/i, 'kx', 'kx', 0);
+check(/^k(?i:(?:X|Y))/, 'kY', 'kY', 0);
+check(/^k(?i:(?:X|Y))/, 'Ky', null);
+
+// A quantified nullable body inserts an empty-match check, which conditionally
+// fails rather than consuming.
+check(/^(?:a?)*b/, 'b', 'b', 0);
+
+// Supplementary code points are matched via an unanchored advance.
+check(/^./su, '\u{1F0A1}', '\u{1F0A1}', 0);
+
+// An empty-matching pattern accepts at any position, so nothing may be
+// rejected.
+check(/a*/y, 'zzz', '', 0);
+check(/(?:)/y, 'zzz', '', 0);
+
+// Sticky patterns filter at lastIndex rather than 0.
+const sticky = /[0-9]+/y;
+sticky.lastIndex = 2;
+check(sticky, 'ab123', '123', 2);
+sticky.lastIndex = 0;
+check(sticky, 'ab123', null);
+assertEquals(0, sticky.lastIndex);
+
+// Anchored-at-end and multiline patterns must not be filtered against
+// position 0 alone.
+check(/^a$/m, 'b\na', 'a', 2);
+check(/^[0-9]$/m, 'x\n7', '7', 2);
+
+// Unanchored patterns can match anywhere, so no first character constrains
+// them.
+check(/[0-9]+/, 'abc99', '99', 3);
+check(/foo/, 'xxfoo', 'foo', 2);
+
+// The filter must survive the pattern being recompiled to a different one.
+const recompiled = /^a+/;
+check(recompiled, 'abc', 'a', 0);
+check(recompiled, 'zzz', null);
+recompiled.compile('^z+');
+check(recompiled, 'zzz', 'zzz', 0);
+check(recompiled, 'abc', null);
diff --git a/deps/v8/test/mjsunit/regress-414738826.js b/deps/v8/test/mjsunit/regress-414738826.js
index f55a3e8fbaa..7f0cb6d70a7 100644
--- a/deps/v8/test/mjsunit/regress-414738826.js
+++ b/deps/v8/test/mjsunit/regress-414738826.js
@@ -3,6 +3,7 @@
// found in the LICENSE file.
// Flags: --allow-natives-syntax --additive-safe-int-feedback
+// Flags: --turbolev --turbolev-additive-safe-int-feedback
let a = [0, 1, , 2];
function foo(i) {
diff --git a/deps/v8/test/mjsunit/regress/modules-import-defer-cross-realm-synthetic.mjs b/deps/v8/test/mjsunit/regress/modules-import-defer-cross-realm-synthetic.mjs
index c3f83bafc04..26d0bbb0c1a 100644
--- a/deps/v8/test/mjsunit/regress/modules-import-defer-cross-realm-synthetic.mjs
+++ b/deps/v8/test/mjsunit/regress/modules-import-defer-cross-realm-synthetic.mjs
@@ -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: --js-import-text --js-defer-import-eval
+// Flags: --js-defer-import-eval
let r1 = Realm.create();
diff --git a/deps/v8/test/mjsunit/regress/regress-42204525.js b/deps/v8/test/mjsunit/regress/regress-42204525.js
new file mode 100644
index 00000000000..8f9c7c86d27
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-42204525.js
@@ -0,0 +1,26 @@
+// Copyright 2024 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 test(arr, val, x) {
+ // Use Int32Add to create an Int32 node in Maglev graph
+ // that is larger than Smi::kMaxValue (1073741823) without deopting.
+ let idx = 1000000000 + x;
+ return arr.indexOf(val, idx);
+}
+%PrepareFunctionForOptimization(test);
+
+let arr = [1, 2, 3];
+
+// Warm up the function
+test(arr, 1, 0);
+test(arr, 1, 0);
+
+%OptimizeMaglevOnNextCall(test);
+
+// Pass a value that makes idx = 1073741824, which exceeds Smi::kMaxValue.
+// In the buggy commit, this is passed as a HeapNumber to the ArrayIndexOfSmi
+// CSA builtin, which expects a Smi, leading to a type cast failure (crash).
+test(arr, 1, 73741824);
diff --git a/deps/v8/test/mjsunit/regress/regress-450237486.js b/deps/v8/test/mjsunit/regress/regress-450237486.js
new file mode 100644
index 00000000000..c6fe5a97976
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-450237486.js
@@ -0,0 +1,13 @@
+// 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-immutable-arraybuffer
+
+const buffer = new ArrayBuffer(10);
+const immBuf = buffer.transferToImmutable();
+const immTA = new Uint8Array(immBuf);
+
+assertThrows(() => {
+ immTA.set([1], -1);
+}, TypeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-476989751.js b/deps/v8/test/mjsunit/regress/regress-476989751.js
new file mode 100644
index 00000000000..fdebda161fb
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-476989751.js
@@ -0,0 +1,139 @@
+// 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
+
+// Test Atomics.notify with resizable SharedArrayBuffer: length retrieved
+// before index coercion.
+{
+ const gsab = new SharedArrayBuffer(0, {maxByteLength: 4});
+ const ta = new Int32Array(gsab);
+
+ let countCalled = false;
+ const index = {
+ valueOf() {
+ gsab.grow(4);
+ return 0;
+ }
+ };
+ const count = {
+ valueOf() {
+ countCalled = true;
+ return 1;
+ }
+ };
+
+ assertThrows(() => Atomics.notify(ta, index, count), RangeError);
+ assertEquals(false, countCalled);
+ assertEquals(4, gsab.byteLength);
+}
+
+// Test Atomics.notify with non-shared resizable ArrayBuffer: length retrieved
+// before index coercion.
+{
+ const rab = new ArrayBuffer(0, {maxByteLength: 4});
+ const ta = new Int32Array(rab);
+
+ let countCalled = false;
+ const index = {
+ valueOf() {
+ rab.resize(4);
+ return 0;
+ }
+ };
+ const count = {
+ valueOf() {
+ countCalled = true;
+ return 1;
+ }
+ };
+
+ assertThrows(() => Atomics.notify(ta, index, count), RangeError);
+ assertEquals(false, countCalled);
+ assertEquals(4, rab.byteLength);
+}
+
+// Test Atomics.notify with non-shared detached ArrayBuffer: length retrieved
+// before index coercion.
+{
+ const ab = new ArrayBuffer(4);
+ const ta = new Int32Array(ab);
+
+ const index = {
+ valueOf() {
+ %ArrayBufferDetach(ab);
+ return 0;
+ }
+ };
+
+ assertEquals(0, Atomics.notify(ta, index));
+ assertEquals(0, ab.byteLength);
+}
+
+// Test Atomics.notify with non-shared resized-to-zero ArrayBuffer: length
+// retrieved before index coercion.
+{
+ const rab = new ArrayBuffer(4, {maxByteLength: 4});
+ const ta = new Int32Array(rab);
+
+ const index = {
+ valueOf() {
+ rab.resize(0);
+ return 0;
+ }
+ };
+
+ assertEquals(0, Atomics.notify(ta, index));
+ assertEquals(0, rab.byteLength);
+}
+
+// Test Atomics.wait with resizable SharedArrayBuffer: length retrieved before
+// index coercion.
+if (typeof Atomics.wait === 'function') {
+ const gsab = new SharedArrayBuffer(0, {maxByteLength: 4});
+ const ta = new Int32Array(gsab);
+
+ let valueCalled = false;
+ const index = {
+ valueOf() {
+ gsab.grow(4);
+ return 0;
+ }
+ };
+ const value = {
+ valueOf() {
+ valueCalled = true;
+ return 0;
+ }
+ };
+
+ assertThrows(() => Atomics.wait(ta, index, value, 0), RangeError);
+ assertEquals(false, valueCalled);
+ assertEquals(4, gsab.byteLength);
+}
+
+// Test Atomics.waitAsync with resizable SharedArrayBuffer: length retrieved
+// before index coercion.
+if (typeof Atomics.waitAsync === 'function') {
+ const gsab = new SharedArrayBuffer(0, {maxByteLength: 4});
+ const ta = new Int32Array(gsab);
+
+ let valueCalled = false;
+ const index = {
+ valueOf() {
+ gsab.grow(4);
+ return 0;
+ }
+ };
+ const value = {
+ valueOf() {
+ valueCalled = true;
+ return 0;
+ }
+ };
+
+ assertThrows(() => Atomics.waitAsync(ta, index, value, 0), RangeError);
+ assertEquals(false, valueCalled);
+ assertEquals(4, gsab.byteLength);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-504697280.js b/deps/v8/test/mjsunit/regress/regress-504697280.js
new file mode 100644
index 00000000000..46e2cbbeadf
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-504697280.js
@@ -0,0 +1,8 @@
+// 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.
+
+assertThrows(() => {
+ let re = new RegExp("(?=(a))" + "(?:a|b)".repeat(100000));
+ re.exec("a");
+}, SyntaxError, /Stack overflow/);
diff --git a/deps/v8/test/mjsunit/regress/regress-514071819.js b/deps/v8/test/mjsunit/regress/regress-514071819.js
index 3b564442d84..d77fafbaa13 100644
--- a/deps/v8/test/mjsunit/regress/regress-514071819.js
+++ b/deps/v8/test/mjsunit/regress/regress-514071819.js
@@ -51,9 +51,9 @@ Realm.shared.mainCaptureStack = mainCaptureStack;
Realm.eval(remoteRealm, `
async function remoteBaz(throwFromRemote) {
if (throwFromRemote) {
- return Realm.shared.remoteCaptureStack();
+ return (0, Realm.shared.remoteCaptureStack)();
} else {
- return Realm.shared.mainCaptureStack();
+ return (0, Realm.shared.mainCaptureStack)();
}
}
Realm.shared.remoteBaz = remoteBaz;
@@ -61,7 +61,7 @@ Realm.eval(remoteRealm, `
async function bar(throwFromRemote) {
await Promise.resolve();
- return Realm.shared.remoteBaz(throwFromRemote);
+ return (0, Realm.shared.remoteBaz)(throwFromRemote);
}
async function foo(throwFromRemote) {
@@ -79,7 +79,7 @@ foo(true)
checkStackTrace(remoteRealm, frames);
})
.catch((e) => {
- console.error(e);
+ console.error(e.stack);
quit(1);
});
@@ -94,7 +94,7 @@ foo(false)
checkStackTrace(mainRealm, frames);
})
.catch((e) => {
- console.error(e);
+ console.error(e.stack);
quit(1);
});
@@ -109,7 +109,7 @@ Promise.all([foo(true)])
checkStackTrace(remoteRealm, frames);
})
.catch((e) => {
- console.error(e);
+ console.error(e.stack);
quit(1);
});
@@ -124,6 +124,6 @@ Promise.all([foo(false)])
checkStackTrace(mainRealm, frames);
})
.catch((e) => {
- console.error(e);
+ console.error(e.stack);
quit(1);
});
diff --git a/deps/v8/test/mjsunit/regress/regress-531513399-1.js b/deps/v8/test/mjsunit/regress/regress-531513399-1.js
new file mode 100644
index 00000000000..27238a69241
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-531513399-1.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.
+
+// Flags: --no-lazy-feedback-allocation
+
+class C {
+ m() {
+ return super.stack;
+ }
+ mKeyed(k) {
+ return super[k];
+ }
+}
+Object.setPrototypeOf(C.prototype, Error());
+
+// Api getters without signature checks (like Error.prototype.stack) convert
+// undefined/null receiver to global_proxy (returning undefined) without
+// throwing.
+assertEquals(undefined, new C().m.call(undefined));
+assertEquals(undefined, new C().mKeyed.call(undefined, 'stack'));
diff --git a/deps/v8/test/mjsunit/regress/regress-531513399-2.js b/deps/v8/test/mjsunit/regress/regress-531513399-2.js
new file mode 100644
index 00000000000..8144c4b9d2f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-531513399-2.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: --no-lazy-feedback-allocation
+
+globalThis.leak = 'leak_value';
+
+function ParentSloppy() {}
+Object.defineProperty(ParentSloppy.prototype, 'prop', {
+ get: function() {
+ return this.leak;
+ },
+ configurable: true
+});
+
+class ChildSloppy extends ParentSloppy {
+ m() {
+ return super.prop;
+ }
+ mKeyed(k) {
+ return super[k];
+ }
+}
+
+// Sloppy JS getters convert undefined receiver to globalThis (reading
+// globalThis.leak).
+assertEquals('leak_value', ChildSloppy.prototype.m.call(undefined));
+assertEquals(
+ 'leak_value', ChildSloppy.prototype.mKeyed.call(undefined, 'prop'));
diff --git a/deps/v8/test/mjsunit/regress/regress-531513399-3.js b/deps/v8/test/mjsunit/regress/regress-531513399-3.js
new file mode 100644
index 00000000000..7c5ed630456
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-531513399-3.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: --no-lazy-feedback-allocation
+
+class ParentClass {
+ get prop() {
+ return this.leak;
+ }
+}
+
+class ChildClass extends ParentClass {
+ m() {
+ return super.prop;
+ }
+ mKeyed(k) {
+ return super[k];
+ }
+}
+
+// Strict JS getters (class getters) receive undefined as this when called with
+// undefined receiver, throwing TypeError when accessing properties on this.
+assertThrows(() => ChildClass.prototype.m.call(undefined), TypeError);
+assertThrows(
+ () => ChildClass.prototype.mKeyed.call(undefined, 'prop'), TypeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-531513399-4.js b/deps/v8/test/mjsunit/regress/regress-531513399-4.js
new file mode 100644
index 00000000000..8699c9aa8d5
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-531513399-4.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: --no-lazy-feedback-allocation
+
+class ParentData {}
+ParentData.prototype.data = 42;
+
+class ChildData extends ParentData {
+ m() {
+ return super.data;
+ }
+}
+
+assertEquals(42, ChildData.prototype.m.call(undefined));
diff --git a/deps/v8/test/mjsunit/regress/regress-531513399-5.js b/deps/v8/test/mjsunit/regress/regress-531513399-5.js
new file mode 100644
index 00000000000..08af9ac0e3f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-531513399-5.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.
+
+// Flags: --no-lazy-feedback-allocation
+
+Object.defineProperty(Number.prototype, 'strictGetterThisType', {
+ get() {
+ 'use strict';
+ return typeof this;
+ },
+ configurable: true
+});
+
+class ParentNumber extends Number {}
+class ChildNumber extends ParentNumber {
+ getSuperStrictThisType() {
+ return super.strictGetterThisType;
+ }
+}
+
+// Strict JS getters (like strict getters defined on Number.prototype) receive
+// primitive this unboxed without throwing.
+assertEquals('number', ChildNumber.prototype.getSuperStrictThisType.call(42));
diff --git a/deps/v8/test/mjsunit/regress/regress-532595489.js b/deps/v8/test/mjsunit/regress/regress-532595489.js
index c80f7e089bc..baa23f42951 100644
--- a/deps/v8/test/mjsunit/regress/regress-532595489.js
+++ b/deps/v8/test/mjsunit/regress/regress-532595489.js
@@ -14,4 +14,6 @@ const pseudo_re = {
constructor: { [Symbol.species]: Species },
};
-RegExp.prototype[Symbol.matchAll].call(pseudo_re, '').next();
+const result = RegExp.prototype[Symbol.matchAll].call(pseudo_re, '').next();
+assertEquals({ value: [''], done: false }, result);
+assertEquals(1073741824, re.lastIndex);
diff --git a/deps/v8/test/mjsunit/regress/regress-533049459.js b/deps/v8/test/mjsunit/regress/regress-533049459.js
new file mode 100644
index 00000000000..594b19ddbda
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-533049459.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.
+
+// Flags: --no-lazy-feedback-allocation
+
+Number.prototype.valueOf;
+delete Number.prototype.valueOf;
+delete Object.prototype.valueOf;
+Object.prototype.valueOf = 1.1;
+
+assertEquals('5', JSON.stringify(new Number(5)));
diff --git a/deps/v8/test/mjsunit/regress/regress-533926191.js b/deps/v8/test/mjsunit/regress/regress-533926191.js
new file mode 100644
index 00000000000..c48cd93cbb0
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-533926191.js
@@ -0,0 +1,11 @@
+// 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 options = {
+ get create_own_microtask_queue() {
+ throw 'bonk!';
+ }
+};
+
+this.Realm.create(options);
diff --git a/deps/v8/test/mjsunit/regress/regress-538529872-2.js b/deps/v8/test/mjsunit/regress/regress-538529872-2.js
new file mode 100644
index 00000000000..0c9b87ce725
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-538529872-2.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: --allow-natives-syntax --shared-string-table
+// Flags: --transition-strings-during-gc-with-stack --gc-global
+
+// StringToArray unpacks the subject, then allocates the result backing store.
+// With --gc-global and --transition-strings-during-gc-with-stack, that
+// allocation internalizes the subject in place and forwards it to a ThinString,
+// leaving the data pointer taken afterwards aimed at unrelated heap data.
+
+// Build the content dynamically, so that it is not internalized on creation.
+function dyn(s) { return s.slice(0, s.length - 1) + s[s.length - 1]; }
+
+const content = "ABCDEFGHIJKLMNOP";
+// Internalize an equal string first, so that the subject below forwards to a
+// distinct object. A string internalized in place is never thinned.
+%ConstructInternalizedString(dyn(content));
+const subject = %ShareObject(dyn(content));
+%ConstructInternalizedString(subject);
+
+// Compute the expected value before simulating a full new space: splitting
+// {content} allocates too and would consume the simulated fullness.
+const expected = content.split("");
+
+%SimulateNewspaceFull();
+assertEquals(expected, subject.split(""));
diff --git a/deps/v8/test/mjsunit/regress/regress-538529872.js b/deps/v8/test/mjsunit/regress/regress-538529872.js
new file mode 100644
index 00000000000..33b164af11f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-538529872.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: --allow-natives-syntax --shared-string-table
+// Flags: --expose-externalize-string
+// Flags: --transition-strings-during-gc-with-stack --gc-global
+
+// The lowercasing builtin unpacks the source, then allocates the result. With
+// --gc-global and --transition-strings-during-gc-with-stack, that allocation
+// internalizes the source in place and forwards it to a ThinString. Reading it
+// as a sequential string afterwards would interpret the ThinString's fields as
+// character data, so the builtin must re-check and bail to the runtime.
+
+// Build the content dynamically, so that it is not internalized on creation.
+function dyn(s) { return s.slice(0, s.length - 1) + s[s.length - 1]; }
+
+function makeThinnable(content) {
+ // Internalize an equal string first, so that the victim below forwards to a
+ // distinct object. A string internalized in place is never thinned.
+ %ConstructInternalizedString(dyn(content));
+ const victim = %ShareObject(dyn(content));
+ %ConstructInternalizedString(victim);
+ return victim;
+}
+
+// Strings up to 24 chars take the CSA lookup-table path, longer ones call
+// into C.
+for (const length of [16, 64]) {
+ const upper = "ABCDEFGHIJKLMNOP".repeat(length / 16);
+ const lower = "abcdefghijklmnop".repeat(length / 16);
+
+ const a = makeThinnable(upper);
+ %SimulateNewspaceFull();
+ assertEquals(lower, a.toLowerCase());
+
+ const b = makeThinnable(upper);
+ %SimulateNewspaceFull();
+ assertEquals(lower, b.toLocaleLowerCase());
+
+ const c = makeThinnable(upper);
+ %SimulateNewspaceFull();
+ assertEquals(lower, c.toLocaleLowerCase("en"));
+}
+
+// The source can equally be an external string, whose resource internalization
+// frees.
+{
+ const upper = "ABCDEFGHIJKLMNOP";
+ %ConstructInternalizedString(dyn(upper));
+ const external = createExternalizableString(dyn(upper));
+ externalizeString(external);
+ const victim = %ShareObject(external);
+ %ConstructInternalizedString(victim);
+
+ %SimulateNewspaceFull();
+ assertEquals("abcdefghijklmnop", victim.toLowerCase());
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-539212794.js b/deps/v8/test/mjsunit/regress/regress-539212794.js
new file mode 100644
index 00000000000..453d16dbe5d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-539212794.js
@@ -0,0 +1,66 @@
+// 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 --expose-externalize-string
+
+// A string constant baked into optimized code can change shape afterwards.
+// Externalizing one in place swaps in an external string map and shrinks the
+// object, while String::length keeps its old value. Optimized code that
+// decided the constant was a SeqOneByteString and stopped re-checking then
+// walks the shrunk object as if it still held characters.
+//
+// Optimize localeCompare against such constants, externalize them, and
+// require the optimized answers to keep matching an unoptimized reference.
+
+// Warm Intl so localeCompare picks the inlineable fast path.
+assertEquals(0, 'warmup'.localeCompare('warmup'));
+
+// Each constant needs its own function so the literal is baked as a
+// HeapConstant. Contents must be distinct, or a later string internalizes to
+// an earlier one and can then no longer be externalized on its own.
+const N = 16;
+globalThis.entries = [];
+let src = '';
+for (let i = 0; i < N; i++) {
+ const s = String.fromCharCode(97 + Math.floor(i / 25), 98 + (i % 25));
+ src += `entries.push({ key: "${s}",`;
+ src += ` f: function(x) { return "${s}".localeCompare(x); } });\n`;
+}
+eval(src);
+
+for (const e of entries) {
+ %PrepareFunctionForOptimization(e.f);
+ e.f('zz');
+ e.f('zz');
+ %OptimizeFunctionOnNextCall(e.f);
+ e.f('zz');
+ assertOptimized(e.f);
+}
+
+for (const e of entries) externalizeString(e.key);
+
+// Two-character constants keep the misread inside the shrunk object, where it
+// hits the resource field rather than memory past the end. With the sandbox
+// that field holds (index << 6), so a stale read yields 0x00 or 0x40 followed
+// by an index byte; enumerate that space so some argument matches it. Without
+// the sandbox the field is a raw pointer and a match is unlikely, which only
+// costs detection, never correctness.
+const args = [];
+for (const first of [0x00, 0x40]) {
+ for (let second = 0; second < 128; second++) {
+ args.push(String.fromCharCode(first, second));
+ }
+}
+
+// The unoptimized builtin reads the externalized string correctly, so it is
+// the oracle for what every optimized answer has to be.
+const reference = (left, right) =>
+ String.prototype.localeCompare.call(left, right);
+
+for (const e of entries) {
+ for (const arg of args) {
+ assertEquals(Math.sign(reference(e.key, arg)), Math.sign(e.f(arg)),
+ `${JSON.stringify(e.key)} vs ${JSON.stringify(arg)}`);
+ }
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-539350801-long-chain-int32-operand.js b/deps/v8/test/mjsunit/regress/regress-539350801-long-chain-int32-operand.js
new file mode 100644
index 00000000000..9d5a41a6637
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-539350801-long-chain-int32-operand.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: --allow-natives-syntax
+
+const maxFeedback = 1125899906842623; // 2^50 - 1
+
+// Same root cause as regress-539350801-int32-operand.js, over a chain long
+// enough that the cumulative bound is accumulated many times. The leading
+// terms cancel so the value reaching the trailing run stays within the
+// feedback range, and the trailing terms then leave the safe integer range.
+let terms = ['s'];
+for (let i = 0; i < 4400; i++) terms.push(i % 2 ? 'b' : 'a');
+for (let i = 0; i < 900; i++) terms.push('c');
+const source = `const s = x & 0x3ffffff; return (${terms.join('+')})|0;`;
+
+// Identical `new Function` sources share a SharedFunctionInfo, so the two
+// copies need distinct bodies.
+const reference = new Function('x', 'a', 'b', 'c', source + '//ref');
+%NeverOptimizeFunction(reference);
+const chain = new Function('x', 'a', 'b', 'c', source + '//opt');
+
+// The seed has to be zero during warmup: any larger value pushes the running
+// sum past the feedback range, which degrades the feedback to Number and makes
+// the test vacuous.
+%PrepareFunctionForOptimization(chain);
+chain(0, maxFeedback, -maxFeedback, 2 ** 40);
+%OptimizeFunctionOnNextCall(chain);
+chain(0, maxFeedback, -maxFeedback, 2 ** 40);
+
+const c = maxFeedback - 4;
+assertEquals(reference(0, maxFeedback, -maxFeedback, c),
+ chain(0, maxFeedback, -maxFeedback, c));
diff --git a/deps/v8/test/mjsunit/regress/regress-539350801-long-chain.js b/deps/v8/test/mjsunit/regress/regress-539350801-long-chain.js
new file mode 100644
index 00000000000..cc5533e458a
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-539350801-long-chain.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
+
+const maxFeedback = 1125899906842623; // 2^50 - 1
+
+// Same root cause as regress-539350801.js, but over a chain long enough that
+// the cumulative bound is accumulated many times. The leading terms cancel so
+// the value reaching the trailing run stays within the feedback range, and the
+// trailing terms then leave the safe integer range.
+let terms = [];
+for (let i = 0; i < 4400; i++) terms.push(i % 2 ? 'b' : 'a');
+for (let i = 0; i < 900; i++) terms.push('c');
+const source = `return (${terms.join('+')})|0;`;
+
+// Identical `new Function` sources share a SharedFunctionInfo, so the two
+// copies need distinct bodies.
+const reference = new Function('a', 'b', 'c', source + '//ref');
+%NeverOptimizeFunction(reference);
+const chain = new Function('a', 'b', 'c', source + '//opt');
+
+%PrepareFunctionForOptimization(chain);
+for (let i = 0; i < 100; i++) chain(maxFeedback, -maxFeedback, 2 ** 40);
+%OptimizeFunctionOnNextCall(chain);
+chain(maxFeedback, -maxFeedback, 2 ** 40);
+
+const c = maxFeedback - 4;
+assertEquals(reference(maxFeedback, -maxFeedback, c),
+ chain(maxFeedback, -maxFeedback, c));
diff --git a/deps/v8/test/mjsunit/regress/regress-539350801-nine-terms.js b/deps/v8/test/mjsunit/regress/regress-539350801-nine-terms.js
new file mode 100644
index 00000000000..ef3f31531a4
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-539350801-nine-terms.js
@@ -0,0 +1,39 @@
+// 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 maxFeedback = 1125899906842623; // 2^50 - 1
+
+// Nine terms is the shortest chain that can leave the exactly representable
+// range: every operand is range checked against the feedback range, so eight
+// of them sum to 2^53 - 8, which is still exactly representable, and the ninth
+// crosses 2^53, above which the odd integers are no longer representable. No
+// multiplication is involved, so the divergence comes purely from the chain.
+// The masked seed carries no value; it only gives the chain an operand that is
+// already Int32 represented.
+function chain(x, a, b, c, d, e, f, g, h, i) {
+ const s = x & 0x3ffffff;
+ return (s + a + b + c + d + e + f + g + h + i) | 0;
+}
+
+function reference(x, a, b, c, d, e, f, g, h, i) {
+ const s = x & 0x3ffffff;
+ return (s + a + b + c + d + e + f + g + h + i) | 0;
+}
+%NeverOptimizeFunction(reference);
+
+// Warm up with pairwise cancelling operands, so the feedback is
+// AdditiveSafeInteger and no intermediate leaves the representable range. The
+// seed has to be zero here: any larger value pushes the running sum past the
+// feedback range, which degrades the feedback to Number and makes the test
+// vacuous.
+const m = maxFeedback;
+%PrepareFunctionForOptimization(chain);
+chain(0, m, -m, m, -m, m, -m, m, -m, m);
+%OptimizeFunctionOnNextCall(chain);
+chain(0, m, -m, m, -m, m, -m, m, -m, m);
+
+assertEquals(reference(0, m, m, m, m, m, m, m, m, m),
+ chain(0, m, m, m, m, m, m, m, m, m));
diff --git a/deps/v8/test/mjsunit/regress/regress-539350801.js b/deps/v8/test/mjsunit/regress/regress-539350801.js
new file mode 100644
index 00000000000..75c3ccd4dc1
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-539350801.js
@@ -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.
+
+// Flags: --allow-natives-syntax
+
+const maxFeedback = 1125899906842623; // 2^50 - 1
+
+// Every operand stays inside the additive safe integer feedback range, but the
+// running sum of the leading terms leaves the exactly representable range and
+// gets rounded. The additions must not be truncated to Word32, otherwise the
+// optimized code computes the exact sum where JavaScript rounds.
+const params = [];
+for (let i = 0; i < 20; i++) params.push('p' + i);
+const body = 'return ((' + params.join(') + (') + ')) | 0;';
+
+// Identical `new Function` sources share a SharedFunctionInfo, so the two
+// copies need distinct bodies.
+const reference = new Function(...params, body + '//ref');
+%NeverOptimizeFunction(reference);
+const optimized = new Function(...params, body + '//opt');
+
+const x = maxFeedback - 4;
+// Ten positive terms first: the running sum passes 2^53 and is rounded. The
+// trailing negative terms then cancel it back down.
+const args = [];
+for (let i = 0; i < 10; i++) args.push(x);
+for (let i = 0; i < 10; i++) args.push(-x);
+
+// Warm up with pairwise cancelling operands, so the feedback is
+// AdditiveSafeInteger and no intermediate leaves the representable range.
+const warmup = [];
+for (let i = 0; i < 20; i++) warmup.push(i % 2 ? -maxFeedback : maxFeedback);
+
+%PrepareFunctionForOptimization(optimized);
+for (let i = 0; i < 100; i++) optimized(...warmup);
+%OptimizeFunctionOnNextCall(optimized);
+optimized(...warmup);
+
+assertEquals(reference(...args), optimized(...args));
diff --git a/deps/v8/test/mjsunit/regress/regress-540471948.js b/deps/v8/test/mjsunit/regress/regress-540471948.js
new file mode 100644
index 00000000000..eb9821b042c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-540471948.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
+
+const generic = { x: 29 };
+generic.x = function() {};
+
+function foo() {
+ var o = { x: 1 };
+ for (var i = 0; i < 1; i = {}) {
+ i += o.x + 4294967295;
+ i += o.x + 4294967295;
+ }
+}
+
+%PrepareFunctionForOptimization(foo);
+foo();
+%OptimizeFunctionOnNextCall(foo);
+foo();
+
+// Same None handling, reached with a live value use: the replacement for a
+// None typed node is an Unreachable, and a live value use of one has to be a
+// DeadValue. Here the loop phi keeps the addition alive.
+const maxFeedback = 1125899906842623; // 2^50 - 1
+const word = 1099511627775; // 2^40 - 1
+
+function liveUse(a, n) {
+ let v = 0;
+ for (let i = 0; i < (n & 3); i++) {
+ v = v + ((a | 0) + maxFeedback);
+ }
+ return v | 0;
+}
+
+const args = [[0, 0], [word, -word], [word - 4, word - 3], [word, 1]];
+%PrepareFunctionForOptimization(liveUse);
+for (let k = 0; k < 10; k++) liveUse(...args[k % 4]);
+%OptimizeFunctionOnNextCall(liveUse);
+assertEquals(-2, liveUse(...args[1]));
diff --git a/deps/v8/test/mjsunit/regress/regress-540482886.js b/deps/v8/test/mjsunit/regress/regress-540482886.js
new file mode 100644
index 00000000000..8b6cb547828
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-540482886.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: --allow-natives-syntax
+
+// An operand of a Word32 truncated additive safe integer operation is only
+// range checked when it needs a representation change. These operands are
+// already Word32 or Word64, so the check disappears and exact Word32
+// arithmetic diverges from the rounded Number semantics.
+
+const mask = 0x5A82799; // mask * mask is just below 2^53.
+
+// The result of the inner addition reaches 2^53, twice the range its operands
+// are checked against.
+function smallIntegerAdd(x, c) {
+ const m = x & 0x3ffffff;
+ const p = m * m;
+ return ((p + p) + c) | 0;
+}
+
+// The multiplication is truncated to Int32Mul, and its type only bounds it by
+// the safe integer range.
+function multiply(x, c) {
+ const m = x & mask;
+ return ((m * m) + c) | 0;
+}
+
+// Math.max is lowered to Int64Max, and the Word64 to Word32 truncation used to
+// drop the check as well.
+function word64(x, c) {
+ const m = x & mask;
+ return (Math.max(m * m, 0) + c) | 0;
+}
+
+%PrepareFunctionForOptimization(smallIntegerAdd);
+for (let i = 0; i < 5; i++) {
+ smallIntegerAdd(1, 0x2000000000000);
+ smallIntegerAdd(2, 3);
+}
+%OptimizeFunctionOnNextCall(smallIntegerAdd);
+assertEquals(0, smallIntegerAdd(0x3ffffff, 0xFFFFFFF));
+
+%PrepareFunctionForOptimization(multiply);
+for (let i = 0; i < 5; i++) {
+ multiply(1, 0x2000000000000);
+ multiply(2, 3);
+}
+%OptimizeFunctionOnNextCall(multiply);
+assertEquals(15726960, multiply(mask, 0x8000000));
+
+%PrepareFunctionForOptimization(word64);
+for (let i = 0; i < 5; i++) {
+ word64(0x1000000, 3);
+ word64(0x1000000, 5);
+}
+%OptimizeFunctionOnNextCall(word64);
+assertEquals(15726960, word64(mask, 0x8000000));
diff --git a/deps/v8/test/mjsunit/regress/regress-541491578.js b/deps/v8/test/mjsunit/regress/regress-541491578.js
new file mode 100644
index 00000000000..1be64b86ac2
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-541491578.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: --allow-natives-syntax
+
+function EnsureDictionaryMode(obj) {
+ obj.foo = 0;
+ obj.bar = 0;
+ // Delete the second-to-last property first to force normalization.
+ delete obj.foo;
+ delete obj.bar;
+ assertFalse(%HasFastProperties(obj));
+}
+
+var o = Object.seal([]);
+assertTrue(%HasFastProperties(o));
+assertTrue(Object.isSealed(o));
+assertFalse(Object.isFrozen(o));
+
+var o = [];
+EnsureDictionaryMode(o);
+Object.seal(o);
+%DebugPrint(o);
+assertFalse(%HasFastProperties(o));
+assertTrue(Object.isSealed(o));
+assertFalse(Object.isFrozen(o));
diff --git a/deps/v8/test/mjsunit/regress/regress-542377192.js b/deps/v8/test/mjsunit/regress/regress-542377192.js
new file mode 100644
index 00000000000..5974fb028e5
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-542377192.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: --turbolev --maglev-disable-builtin-reducers
+
+// Constant `0` from-index causes Select to fold into an empty subgraph,
+// exercising the empty-subgraph buffer stashing path without mutating
+// the iterated block vector mid-visit.
+function __f_11(__v_29, __v_30, __v_31) {
+ return __v_29.indexOf(__v_30, __v_31);
+}
+for (var __v_23 = 0; __v_23 < 2e5; ++__v_23) {
+ var __v_24 = [];
+ assertEquals(-1, __f_11(__v_24, 'abcd', 0));
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-542636068.js b/deps/v8/test/mjsunit/regress/regress-542636068.js
new file mode 100644
index 00000000000..6cde31547cf
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-542636068.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
+
+// Maglev unwraps bound functions recursively when reducing instanceof. A long
+// bound_target_function chain must not overflow the compiler's stack.
+// Turbolev is requested explicitly because the classic Turbofan pipeline hits
+// an unrelated deep recursion in late load elimination on the same input.
+function mkBound(depth) {
+ function C() {}
+ let g = C;
+ for (let i = 0; i < depth; ++i) g = g.bind();
+ return g;
+}
+
+// Constant callable.
+const kDeep = mkBound(50000);
+function constant_callable(o) {
+ try {
+ return o instanceof kDeep;
+ } catch (e) {
+ return 'threw';
+ }
+}
+%PrepareFunctionForOptimization(constant_callable);
+constant_callable({});
+%OptimizeFunctionOnNextCall(constant_callable);
+constant_callable({});
+
+// Callable from instanceof feedback.
+function feedback_callable(o, callable) {
+ try {
+ return o instanceof callable;
+ } catch (e) {
+ return 'threw';
+ }
+}
+%PrepareFunctionForOptimization(feedback_callable);
+feedback_callable({}, kDeep);
+%OptimizeFunctionOnNextCall(feedback_callable);
+feedback_callable({}, kDeep);
+
+// Shallow bound chains still reduce correctly.
+function C() {}
+const bound = C.bind().bind();
+function shallow(o) {
+ return o instanceof bound;
+}
+%PrepareFunctionForOptimization(shallow);
+assertTrue(shallow(new C()));
+assertFalse(shallow({}));
+%OptimizeFunctionOnNextCall(shallow);
+assertTrue(shallow(new C()));
+assertFalse(shallow({}));
diff --git a/deps/v8/test/mjsunit/regress/regress-544223867.js b/deps/v8/test/mjsunit/regress/regress-544223867.js
new file mode 100644
index 00000000000..8259f2d7547
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-544223867.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: --expose-statistics
+
+Object.defineProperty(Object.prototype, "reloc_info_total_size", {
+ set: getV8Statistics,
+});
+getV8Statistics();
diff --git a/deps/v8/test/mjsunit/regress/regress-545767601.js b/deps/v8/test/mjsunit/regress/regress-545767601.js
new file mode 100644
index 00000000000..02e1200be97
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-545767601.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: --allow-natives-syntax
+
+function onFinally() {
+ leakedFinally = onFinally.caller;
+}
+function attachFinally(promise) {
+ return promise.finally(onFinally);
+}
+async function trigger() {
+ %PrepareFunctionForOptimization(attachFinally);
+ attachFinally(Promise.resolve());
+ %OptimizeFunctionOnNextCall(attachFinally);
+ attachFinally(Promise.resolve());
+ await Promise.resolve();
+ const objectResult = {field: 0x41414141};
+ let returnPrimitive = false;
+ Promise.prototype.then = function() {
+ return returnPrimitive ? 1 : objectResult;
+ };
+ function readConstructedField() {
+ new leakedFinally().field;
+ }
+ %PrepareFunctionForOptimization(readConstructedField);
+ readConstructedField();
+ %OptimizeFunctionOnNextCall(readConstructedField);
+ returnPrimitive = true;
+ readConstructedField();
+}
+
+assertThrowsAsync(trigger(), TypeError);
diff --git a/deps/v8/test/mjsunit/regress/regress-546308452.js b/deps/v8/test/mjsunit/regress/regress-546308452.js
new file mode 100644
index 00000000000..033e9521938
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-546308452.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 --turbolev --turbolev-future --no-lazy-feedback-allocation
+
+for (let v0 = 0; v0 < 5; v0++) {
+ const v3 = [1.5, 2.5];
+ async function* f4(a5, a6, ...a7) {
+ for (let v8 = 0; v8 < 5; v8++) {
+ v8++;
+ for (let v11 = 0; v11 < 5; v11++) {
+ %OptimizeOsr();
+ }
+ function f13(a14, a15) {
+ return a15;
+ }
+ f13(v0, Symbol);
+ }
+ for (let v19 = 0; v19 < 5; v19++) {
+ const v22 = Array(undefined, v19);
+ const v24 = {
+ [Symbol]() {},
+ };
+ for await (await using v25 of v3) {}
+ v22[99] = Array;
+ }
+ return Symbol;
+ }
+ f4(Symbol, v3, Symbol, v0, v0, v0).next(v3).catch(() => {});
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-546370262.js b/deps/v8/test/mjsunit/regress/regress-546370262.js
new file mode 100644
index 00000000000..5e1ff0c8c61
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-546370262.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 --expose-fast-api --turbo-fast-api-calls
+
+const fastApi = new d8.test.FastCAPI();
+
+function callWithNegativeConstant() {
+ return fastApi.sum_uint64_as_number(-1, 0);
+}
+
+%PrepareFunctionForOptimization(callWithNegativeConstant);
+assertThrows(() => callWithNegativeConstant(), Error);
+%OptimizeFunctionOnNextCall(callWithNegativeConstant);
+assertThrows(() => callWithNegativeConstant(), Error);
diff --git a/deps/v8/test/mjsunit/regress/regress-546665034.js b/deps/v8/test/mjsunit/regress/regress-546665034.js
new file mode 100644
index 00000000000..3d2f3ace969
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-546665034.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.
+
+// Flags: --allow-natives-syntax
+
+function EnsureDictionaryMode(obj) {
+ obj.foo = 0;
+ obj.bar = 0;
+ // Delete the second-to-last property first to force normalization.
+ delete obj.foo;
+ delete obj.bar;
+ assertFalse(%HasFastProperties(obj));
+}
+
+var n = 0x100000000;
+var rab;
+try {
+ rab = new ArrayBuffer(n + 1, { maxByteLength: n + 1 });
+} catch(e) {
+ // It must be a "RangeError: Invalid array buffer length" on 32-bit
+ // configurations. Skip it.
+ quit(0);
+}
+var ta = new Int8Array(rab);
+
+// Test stores to an indexed property with a big index while there's
+// a typed array in the prototype chain.
+
+(function TestFastModeDataProperty() {
+ function A() {}
+ var obj = new A();
+ Object.setPrototypeOf(obj, ta);
+ obj[n] = 42;
+})();
+
+(function TestSlowModeDataProperty() {
+ function A() {}
+ var obj = new A();
+ EnsureDictionaryMode(obj);
+ Object.setPrototypeOf(obj, ta);
+ obj[n] = 42;
+})();
+
+// Put this case to the end since it modifies the Object.prototype.
+(function TestGlobalObjectDataProperty() {
+ var globalProto = Object.getPrototypeOf(globalThis);
+ Object.setPrototypeOf(globalProto, ta);
+ globalThis[n] = 42;
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-546815249.js b/deps/v8/test/mjsunit/regress/regress-546815249.js
new file mode 100644
index 00000000000..18701ac2a53
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-546815249.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 --verify-heap --no-lazy-feedback-allocation
+
+// Math.atanh(42) is a signalling NaN, so folding it hands the double array store
+// a Float64Constant carrying those bits. A double array element must never be a
+// signalling NaN, so the store has to canonicalize it.
+
+const f64 = new Float64Array(1);
+const u64 = new BigUint64Array(f64.buffer);
+
+function assertQuietNan(x) {
+ f64[0] = x;
+ const bits = u64[0];
+ assertTrue((bits & 0x7FF0000000000000n) === 0x7FF0000000000000n);
+ assertTrue((bits & 0x000FFFFFFFFFFFFFn) !== 0n); // A NaN, not an infinity.
+ assertTrue((bits & 0x0008000000000000n) !== 0n); // Quiet.
+}
+
+// Into a holey double array, which is what an element that is undefined makes
+// the literal below.
+(function() {
+ function call(f) {
+ try {
+ return f();
+ } catch (e) {
+ }
+ }
+ function f() {
+ const nan = call(() => Math.atanh(42));
+ const undef = call();
+ return [nan, undef];
+ }
+ %PrepareFunctionForOptimization(call);
+ %PrepareFunctionForOptimization(f);
+ f();
+ %OptimizeMaglevOnNextCall(f);
+
+ const a = f();
+ assertQuietNan(a[0]);
+ assertEquals(undefined, a[1]);
+})();
+
+// And into a packed one.
+(function() {
+ function f() {
+ return [Math.atanh(42), 1.5];
+ }
+ %PrepareFunctionForOptimization(f);
+ f();
+ %OptimizeMaglevOnNextCall(f);
+
+ const a = f();
+ assertQuietNan(a[0]);
+ assertEquals(1.5, a[1]);
+})();
+
+// A HeapNumber holding a signalling NaN reaches the store as an untagged phi
+// input instead, which the phi representation selector has to silence for the
+// same reason.
+(function() {
+ const buf = new ArrayBuffer(8);
+ new BigUint64Array(buf)[0] = 0x7FF4000000000000n;
+ const snan = new Float64Array(buf)[0];
+
+ function f(out, i, c) {
+ let x;
+ if (c) {
+ x = snan;
+ } else {
+ x = out[3];
+ }
+ out[i] = x;
+ }
+ const out = [1.5, 2.5, , 3.5];
+ %PrepareFunctionForOptimization(f);
+ f(out, 0, false);
+ f(out, 0, true);
+ %OptimizeMaglevOnNextCall(f);
+
+ f(out, 0, true);
+ assertQuietNan(out[0]);
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-547027738-wasm.js b/deps/v8/test/mjsunit/regress/regress-547027738-wasm.js
new file mode 100644
index 00000000000..d7a79f02e48
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-547027738-wasm.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
+
+load("test/mjsunit/wasm/wasm-module-builder.js");
+
+(function() {
+if (typeof WebAssembly === 'undefined') return;
+
+Error.stackTraceLimit = 20;
+
+let capturedSites = null;
+Error.prepareStackTrace = (_error, callSites) => {
+ capturedSites = callSites;
+ return callSites;
+};
+
+const realm1 = Realm.create();
+
+let builder2 = new WasmModuleBuilder();
+builder2.addImport("env", "trigger", kSig_v_v);
+builder2.addFunction("main", kSig_v_v).addBody([
+ kExprCallFunction, 0
+]).exportFunc();
+const wasmBytes2 = builder2.toArray();
+
+const captureInRealm1 = Realm.eval(realm1, `
+ (function capture(wasmBytes, target) {
+ let importObj = {
+ env: {
+ trigger: function() {
+ Error.captureStackTrace(target);
+ }
+ }
+ };
+
+ let instance = new WebAssembly.Instance(
+ new WebAssembly.Module(new Uint8Array(wasmBytes)),
+ importObj
+ );
+
+ instance.exports.main();
+ })
+`);
+
+const target = {};
+captureInRealm1(wasmBytes2, target);
+void target.stack;
+
+assertTrue(Array.isArray(capturedSites));
+assertTrue(capturedSites.length > 0);
+
+// The first three frames should be:
+// 1. trigger (from realm1)
+// 2. main (Wasm frame, instantiated in realm1)
+// 3. capture (from realm1)
+// The remaining frames are from the main realm (e.g. the top-level script).
+for (let i = 0; i < 3; i++) {
+ const site = capturedSites[i];
+ assertEquals("", site.toString());
+ assertEquals(undefined, site.getFunction());
+ assertEquals(undefined, site.getThis());
+ assertEquals(null, site.getFunctionName());
+ assertEquals(null, site.getMethodName());
+}
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-547027738.js b/deps/v8/test/mjsunit/regress/regress-547027738.js
new file mode 100644
index 00000000000..854380a6aef
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-547027738.js
@@ -0,0 +1,45 @@
+// 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() {
+Error.stackTraceLimit = 20;
+
+let capturedSites = null;
+Error.prepareStackTrace = (_error, callSites) => {
+ capturedSites = callSites;
+ return callSites;
+};
+
+const realm1 = Realm.create();
+const captureInRealm1 = Realm.eval(realm1, `
+ (() => {
+ globalThis.realm1Receiver = {};
+
+ function realm1Function(target) {
+ Error.captureStackTrace(target);
+ }
+
+ return function(target) {
+ realm1Function.call(globalThis.realm1Receiver, target);
+ };
+ })()
+`);
+
+const target = {};
+captureInRealm1(target);
+void target.stack;
+
+assertTrue(Array.isArray(capturedSites));
+assertTrue(capturedSites.length > 0);
+
+// The first two frames are inside realm1. Their function, receiver,
+// and function name must be filtered out when accessed by the main realm.
+for (let i = 0; i < 2; i++) {
+ const site = capturedSites[i];
+ assertEquals("", site.toString());
+ assertEquals(undefined, site.getFunction());
+ assertEquals(undefined, site.getThis());
+ assertEquals(null, site.getFunctionName());
+}
+})();
diff --git a/deps/v8/test/mjsunit/regress/regress-547982135.js b/deps/v8/test/mjsunit/regress/regress-547982135.js
new file mode 100644
index 00000000000..480a5ccb6f3
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-547982135.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-assert-types
+
+function testIndexOf(arr, val, x) {
+ let idx = 1000000000 + x;
+ return arr.indexOf(val, idx);
+}
+%PrepareFunctionForOptimization(testIndexOf);
+
+function testIncludes(arr, val, x) {
+ let idx = 1000000000 + x;
+ return arr.includes(val, idx);
+}
+%PrepareFunctionForOptimization(testIncludes);
+
+let arr = [1, 2, 3];
+
+testIndexOf(arr, 1, 0);
+testIndexOf(arr, 1, 0);
+testIncludes(arr, 1, 0);
+testIncludes(arr, 1, 0);
+
+%OptimizeMaglevOnNextCall(testIndexOf);
+%OptimizeMaglevOnNextCall(testIncludes);
+
+assertEquals(-1, testIndexOf(arr, 1, 73741824));
+assertEquals(false, testIncludes(arr, 1, 73741824));
diff --git a/deps/v8/test/mjsunit/regress/regress-549226708.js b/deps/v8/test/mjsunit/regress/regress-549226708.js
new file mode 100644
index 00000000000..e9efdf78b94
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-549226708.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
+
+class Base {
+ constructor(x) {
+ this.a = 1;
+ }
+}
+
+class Derived extends Base {
+ constructor(x) {
+ try {
+ if (x) throw 1;
+ super(x);
+ throw 2;
+ } catch (e) {
+ return { caught: e };
+ }
+ }
+}
+
+function foo(x) {
+ return new Derived(x);
+}
+
+%PrepareFunctionForOptimization(foo);
+%PrepareFunctionForOptimization(Derived);
+%PrepareFunctionForOptimization(Base);
+
+for (let i = 0; i < 50; i++) {
+ foo(i % 2 === 0);
+}
+
+%OptimizeMaglevOnNextCall(foo);
+foo(false);
diff --git a/deps/v8/test/mjsunit/regress/regress-549231120.js b/deps/v8/test/mjsunit/regress/regress-549231120.js
new file mode 100644
index 00000000000..f18dc08b7e1
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-549231120.js
@@ -0,0 +1,54 @@
+// 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.
+
+// Ensure that invalid or duplicate variants (including underscore delimiters)
+// throw RangeError without crashing ICU.
+assertThrows(
+ () => new Intl.Locale("en", {
+ variants: Array(31).fill("posix").join("_"),
+ calendar: "gregory"
+ }),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "posix_posix"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "posix_1990"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "posix-posix"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "posix-POSIX"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "-posix"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "posix-"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "posix--oxendict"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "abc"}),
+ RangeError);
+
+assertThrows(
+ () => new Intl.Locale("en", {variants: "abcdefghi"}),
+ RangeError);
+
+// Valid variants should work.
+assertEquals("en-u-va-posix", new Intl.Locale("en", {variants: "posix"}).toString());
+assertEquals(
+ "en-oxendict-spanglis",
+ new Intl.Locale("en", {variants: "spanglis-oxendict"}).toString());
diff --git a/deps/v8/test/mjsunit/regress/regress-551047528.js b/deps/v8/test/mjsunit/regress/regress-551047528.js
new file mode 100644
index 00000000000..054abefe749
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-551047528.js
@@ -0,0 +1,14 @@
+// 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: --compile-hints-magic --parallel-compile-tasks-for-eager-toplevel
+
+function outer() {
+ class C {
+ x = () => 1;
+ }
+ return new C();
+}
+
+//# allFunctionsCalledOnLoad
diff --git a/deps/v8/test/mjsunit/regress/regress-551186503.js b/deps/v8/test/mjsunit/regress/regress-551186503.js
new file mode 100644
index 00000000000..f9b15584656
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-551186503.js
@@ -0,0 +1,13 @@
+// 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: --log-or-trace-osr --allow-natives-syntax
+
+function foo() {
+ for (var i = 0; i < 10; i++) {
+ %OptimizeOsr();
+ }
+}
+%PrepareFunctionForOptimization(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/regress/regress-557062659.js b/deps/v8/test/mjsunit/regress/regress-557062659.js
new file mode 100644
index 00000000000..63faeffd3e2
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-557062659.js
@@ -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.
+
+// Flags: --cache=after-execute
+
+var R = Array.of(() => { 'use strict'; return eval('1'); }, "hello_world");
+assertEquals("hello_world", R[1]);
+assertEquals(1, R[0]());
diff --git a/deps/v8/test/mjsunit/regress/regress-558005441.js b/deps/v8/test/mjsunit/regress/regress-558005441.js
new file mode 100644
index 00000000000..2c9dc7fa923
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-558005441.js
@@ -0,0 +1,14 @@
+// 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.
+
+for (let i = 0; i < 2; i++) {
+ let w1 = new Worker(`
+ let w2 = new Worker(\`
+ let ab = new ArrayBuffer(1024);
+ postMessage(ab, [ab]);
+ \`, {type: "string"});
+ `, {type: "string"});
+ let w3 = new Worker(`
+ `, {type: "string"});
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-558186672.js b/deps/v8/test/mjsunit/regress/regress-558186672.js
new file mode 100644
index 00000000000..4bf706ed3e5
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-558186672.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: --parse-only --stress-runs=2 --throws
+// Files: test/mjsunit/regress/non-existent-file-for-558186672.js
+
+// This test verifies that trying to parse a non-existent file with
+// --parse-only and --stress-runs does not leak unhandled exceptions onto the
+// isolate or crash during Genesis in subsequent runs.
diff --git a/deps/v8/test/mjsunit/regress/regress-558280524.js b/deps/v8/test/mjsunit/regress/regress-558280524.js
new file mode 100644
index 00000000000..89ef5a662a2
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-558280524.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.
+
+// Flags: --allow-natives-syntax --proto-assign-seq-lazy-func-opt
+
+// Arrow function without prototype property.
+{
+ let f = () => {};
+ function C() {}
+ C.prototype = f;
+ function test(C) {
+ C.prototype.prototype = function () { return 1; };
+ C.prototype.m1 = function () { return 2; };
+ }
+ test(C);
+ %HeapObjectVerify(f);
+ assertEquals(1, f.prototype());
+ assertEquals(2, f.m1());
+ %HeapObjectVerify(f);
+}
+
+// Concise method without prototype property.
+{
+ let obj = {
+ m() {}
+ };
+ function C() {}
+ C.prototype = obj.m;
+ function test(C) {
+ C.prototype.prototype = function () { return 3; };
+ C.prototype.m1 = function () { return 4; };
+ }
+ test(C);
+ %HeapObjectVerify(obj.m);
+ assertEquals(3, obj.m.prototype());
+ assertEquals(4, obj.m.m1());
+ %HeapObjectVerify(obj.m);
+}
+
+// Async function without prototype property.
+{
+ let f = async () => {};
+ function C() {}
+ C.prototype = f;
+ function test(C) {
+ C.prototype.prototype = function () { return 5; };
+ C.prototype.m1 = function () { return 6; };
+ }
+ test(C);
+ %HeapObjectVerify(f);
+ assertEquals(5, f.prototype());
+ assertEquals(6, f.m1());
+ %HeapObjectVerify(f);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-559580852.js b/deps/v8/test/mjsunit/regress/regress-559580852.js
new file mode 100644
index 00000000000..7068e4aad03
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-559580852.js
@@ -0,0 +1,19 @@
+// 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 --concurrent-marking-high-priority-threads
+
+const POOL = 2048;
+const pool = new Array(POOL);
+let head = 0;
+
+for (let iter = 0; iter < 100000; iter++) {
+ const ta = new Uint8Array(16);
+ const old = pool[head];
+ if (old !== undefined) {
+ const b = old.buffer;
+ }
+ pool[head] = ta;
+ head = (head + 1) % POOL;
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-559756520.js b/deps/v8/test/mjsunit/regress/regress-559756520.js
new file mode 100644
index 00000000000..37765cc5a90
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-559756520.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
+
+{
+ const arr = Object.freeze([1]);
+ assertThrows(() => %StoreInArrayLiteralIC_Slow(4, arr, 1), TypeError);
+}
+
+{
+ const arr = [1];
+ Object.defineProperty(arr, 'length', { writable: false });
+ assertThrows(() => %StoreInArrayLiteralIC_Slow(4, arr, 1), TypeError);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-563235411.js b/deps/v8/test/mjsunit/regress/regress-563235411.js
new file mode 100644
index 00000000000..9f0756ee689
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-563235411.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.
+
+// Flags: --no-lazy-feedback-allocation
+
+class Base {
+ constructor(o) {
+ return o;
+ }
+}
+
+class Derived extends Base {
+ #x = 42;
+ #m() {
+ return this.#x;
+ }
+ static getX(o) {
+ return o.#x;
+ }
+ static setX(o, v) {
+ o.#x = v;
+ }
+ static callM(o) {
+ return o.#m();
+ }
+}
+
+for (let i = 0; i < 20; i++) {
+ const allowed = d8.test.createAccessCheckedObject(true);
+ new Derived(allowed);
+ assertEquals(42, Derived.getX(allowed));
+ assertEquals(42, Derived.callM(allowed));
+
+ for (let j = 0; j < 5; j++) {
+ Derived.setX(allowed, i + j);
+ }
+ assertEquals(i + 4, Derived.getX(allowed));
+
+ d8.test.setAccessPolicy(allowed, false);
+ assertThrows(() => Derived.setX(allowed, 999), TypeError);
+ assertThrows(() => Derived.getX(allowed), TypeError);
+ assertThrows(() => Derived.callM(allowed), TypeError);
+
+ d8.test.setAccessPolicy(allowed, true);
+ assertEquals(i + 4, Derived.getX(allowed));
+
+ const denied = d8.test.createAccessCheckedObject(false);
+ assertThrows(() => new Derived(denied), TypeError);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-563716534.js b/deps/v8/test/mjsunit/regress/regress-563716534.js
new file mode 100644
index 00000000000..45c80b20175
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-563716534.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: --no-concurrent-sparkplug --stack-size=100
+
+const many_char_codes = new Array(11000).fill(48).join(",");
+const loop_then_large_call = new Function(`
+ for (let i = 0; i < 50; i++) {
+ if (i === 49) return String.fromCharCode(${many_char_codes});
+ }
+`);
+
+try {
+ loop_then_large_call();
+} catch (e) {
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-567538973.js b/deps/v8/test/mjsunit/regress/regress-567538973.js
new file mode 100644
index 00000000000..3b7a353a9c6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-567538973.js
@@ -0,0 +1,43 @@
+// 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 reg = new FinalizationRegistry(() => {});
+const keep = {};
+let sink = null;
+
+function mk(i) {
+ const o = {};
+ o.a0 = i;
+ o.a1 = i;
+ o.a2 = i;
+ o.a3 = i;
+ o.a4 = i;
+ o.a5 = i;
+ o.a6 = i;
+ o.a7 = i;
+ return o;
+}
+
+function f(i) {
+ const o = mk(i);
+ reg.register(keep, i, o);
+ const x = o.a5;
+ const arr = new Array(4000);
+ const y = o.a6;
+ sink = arr;
+ return x + y;
+}
+
+%PrepareFunctionForOptimization(mk);
+%PrepareFunctionForOptimization(f);
+for (let i = 0; i < 10; i++) {
+ f(i);
+}
+%OptimizeFunctionOnNextCall(f);
+let s = 0;
+for (let i = 0; i < 2000; i++) {
+ s += f(i);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1440685.js b/deps/v8/test/mjsunit/regress/regress-crbug-1440685.js
index a743698dc80..b00d0721e84 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-1440685.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-1440685.js
@@ -2,6 +2,6 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-Reflect.get(new Error(), "stack", false);
-assertThrows(() => Reflect.get(new Error(), "stack", null), TypeError);
-assertThrows(() => Reflect.get(new Error(), "stack", undefined), TypeError);
+assertEquals(undefined, Reflect.get(new Error(), 'stack', false));
+assertEquals(undefined, Reflect.get(new Error(), 'stack', null));
+assertEquals(undefined, Reflect.get(new Error(), 'stack', undefined));
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-1509910.js b/deps/v8/test/mjsunit/regress/regress-crbug-1509910.js
index 9a0d8e3747e..3160ab6b205 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-1509910.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-1509910.js
@@ -1,8 +1,6 @@
// Copyright 2023 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: --embedder-instance-types
class C extends d8.dom.Div {
}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-514165662.js b/deps/v8/test/mjsunit/regress/regress-crbug-514165662.js
new file mode 100644
index 00000000000..8ac8b8473d7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-514165662.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.
+
+// The regexp results cache kicks in for internalized subjects above a length
+// threshold. Its entries must not hand the same groups object to more than one
+// replace callback.
+
+// Longer than kMinLengthToCache, and internalized: string literals are
+// internalized when their script is compiled, hence the eval.
+const kLong = eval('"' + 'xy'.repeat(0x900) + '"');
+const kShort = eval('"' + 'xy'.repeat(4) + '"');
+const kNotInternalized = ('xy'.repeat(0x900) + 'z').slice(0, -1);
+
+// Returns the last argument the first invocation of the callback received,
+// which is the groups object for patterns that have named captures.
+function firstLastArg(subject, re, mutate = false) {
+ let seen;
+ subject.replace(re, function(...args) {
+ if (seen === undefined) {
+ seen = args[args.length - 1];
+ if (mutate) {
+ seen.n = 'mutated';
+ seen.added = 'added';
+ }
+ }
+ return '';
+ });
+ return seen;
+}
+
+const kNamed = /(?<n>x)y/g;
+
+// Populates the cache, then mutates the groups object it handed out.
+const poisoned = firstLastArg(kLong, kNamed, true);
+
+const groups = firstLastArg(kLong, kNamed);
+assertNotSame(poisoned, groups);
+assertEquals('x', groups.n);
+assertFalse(Object.hasOwn(groups, 'added'));
+assertEquals(null, Object.getPrototypeOf(groups));
+
+// The copying is gated on the pattern having named captures, and only runs
+// where the cache applies at all. Each condition below skips it; the last
+// argument is then the subject string rather than a groups object.
+assertSame(kLong, firstLastArg(kLong, /xy/g));
+assertSame(kLong, firstLastArg(kLong, /(x)y/g));
+
+// Below the length threshold, and non-internalized: the cache is never
+// consulted, so each call builds its own groups object.
+for (const subject of [kShort, kNotInternalized]) {
+ const first = firstLastArg(subject, kNamed, true);
+ const second = firstLastArg(subject, kNamed);
+ assertNotSame(first, second);
+ assertEquals('x', second.n);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-542403045.js b/deps/v8/test/mjsunit/regress/regress-crbug-542403045.js
index e60a974f878..ddb6ff3fc19 100644
--- a/deps/v8/test/mjsunit/regress/regress-crbug-542403045.js
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-542403045.js
@@ -74,6 +74,9 @@ function withProperty() {
function sortSameKind(a) {
return a.sort((x, y) => 0);
}
+// The inlined path embeds the receiver maps weakly, so keep an instance of the
+// with-property map alive for the assertOptimized below.
+const keepAlive = withProperty();
%PrepareFunctionForOptimization(sortSameKind);
for (let i = 0; i < 100; ++i) {
sortSameKind([{}, {}]);
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-552342545.js b/deps/v8/test/mjsunit/regress/regress-crbug-552342545.js
new file mode 100644
index 00000000000..8a2ab94cb6c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-552342545.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.
+
+const proxy = new Proxy([], {
+ get(t, p) {
+ if (p === 'length') throw new Error('stopped_early');
+ return Reflect.get(t, p);
+ }
+});
+
+const o = [];
+o.length = 2000000000;
+o[0] = proxy;
+
+assertThrows(() => {
+ o.flat({
+ valueOf() {
+ o.length = 8;
+ o.fill(proxy);
+ return 1;
+ }
+ });
+}, Error, 'stopped_early');
diff --git a/deps/v8/test/mjsunit/regress/regress-crbug-560233248.js b/deps/v8/test/mjsunit/regress/regress-crbug-560233248.js
new file mode 100644
index 00000000000..c1d7b97410f
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-crbug-560233248.js
@@ -0,0 +1,77 @@
+// 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 --no-turbolev
+
+// Replace and transition a global cell's value between the compiler's value
+// and map reads, leaving the compiler with the replaced object's map.
+
+const template = [1.125, 1.125, 1.125];
+const marker = {};
+
+// The named property keeps these arrays off the shared array maps, so the
+// object-elements map below stays stable. slice() copies without an allocation
+// site, so transitioning a copy does not generalize later copies.
+function mkDouble() { const a = template.slice(); a.tag = 0; return a; }
+function transition(a) { a[1] = marker; return a; }
+
+// Bring the cell to kConstantType and warm the store IC's property cell case.
+// From here on, storing a same-map value does not change the cell details.
+gl = mkDouble();
+function set(x) { gl = x; }
+for (let i = 0; i < 100; i++) set(mkDouble());
+
+const objElements = transition(mkDouble());
+
+const kPoolSize = 500;
+function mkPool() {
+ const pool = [];
+ for (let i = 0; i < kPoolSize; i++) pool.push(mkDouble());
+ return pool;
+}
+// Rotate the cell through same-map arrays, transitioning each one as soon as
+// it leaves the cell.
+function rotate(pool) {
+ let prev = mkDouble();
+ for (let i = 0; i < kPoolSize; i++) {
+ const t = pool[i];
+ set(t);
+ transition(prev);
+ prev = t;
+ }
+ set(mkDouble());
+}
+
+for (let j = 0; j < 10; j++) {
+ // Each attempt needs fresh functions: the element access must only ever see
+ // the object-elements map, and one read through gl would make it
+ // polymorphic. The interpolated j keeps the compilation cache from reusing
+ // the script.
+ const [get, read] = Function(`
+ function get(a, real) {
+ if (real) return a[0];
+ return ${j};
+ }
+ return [get, function read(real) { return get(gl, real); }];`)();
+ %PrepareFunctionForOptimization(get);
+ %PrepareFunctionForOptimization(read);
+ for (let i = 0; i < 5; i++) {
+ get(objElements, true);
+ get(objElements, false);
+ read(false);
+ }
+
+ // Only stores made during the compile can hit the window between the
+ // broker's two reads, so fill the pool first and start rotating as soon as
+ // the job is dispatched.
+ const pool = mkPool();
+ %OptimizeFunctionOnNextCall(read, "concurrent");
+ read(false);
+ rotate(pool);
+ %WaitForBackgroundOptimization();
+ %FinalizeOptimization();
+ // gl holds a packed-double array, so this must produce its double element.
+ // The stale map made this load read that double as a tagged pointer.
+ assertEquals(1.125, read(true));
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-fast-api-uint64-negative.js b/deps/v8/test/mjsunit/regress/regress-fast-api-uint64-negative.js
new file mode 100644
index 00000000000..3849e30d25d
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-fast-api-uint64-negative.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: --allow-natives-syntax --expose-fast-api --turbo-fast-api-calls
+// Flags: --deopt-every-n-times=0 --turbofan
+
+const fast_c_api = new d8.test.FastCAPI();
+
+// Test that Float64 to Uint64 representation change includes proper deopt
+// checks when the input type has a negative static range (subtype of Int64).
+{
+ function testFloat64NegativeRange(v) {
+ let val = (v | 0) + 0.1;
+ val = Math.floor(val);
+ val = Math.max(-10, Math.min(-1, val));
+ return fast_c_api.sum_uint64_as_number(val, 0);
+ }
+
+ %PrepareFunctionForOptimization(testFloat64NegativeRange);
+ assertThrows(() => testFloat64NegativeRange(1), Error);
+ assertThrows(() => testFloat64NegativeRange(-2), Error);
+ %OptimizeFunctionOnNextCall(testFloat64NegativeRange);
+ assertThrows(() => testFloat64NegativeRange(-1), Error);
+ assertUnoptimized(testFloat64NegativeRange);
+}
+
+// Test Float64 to Uint64 with a range containing both positive and negative
+// integers. Valid positive values should use the fast path, while negative
+// values must deopt and throw.
+{
+ function testFloat64MixedRange(v) {
+ let val = (v | 0) + 0.1;
+ val = Math.floor(val);
+ val = Math.max(-10, Math.min(10, val));
+ return fast_c_api.sum_uint64_as_number(val, 0);
+ }
+
+ %PrepareFunctionForOptimization(testFloat64MixedRange);
+ testFloat64MixedRange(1);
+ testFloat64MixedRange(2);
+ %OptimizeFunctionOnNextCall(testFloat64MixedRange);
+ assertEquals(3, testFloat64MixedRange(3));
+
+ fast_c_api.reset_counts();
+ assertEquals(4, testFloat64MixedRange(4));
+ assertTrue(fast_c_api.fast_call_count() > 0);
+
+ assertThrows(() => testFloat64MixedRange(-1), Error);
+ assertUnoptimized(testFloat64MixedRange);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-fast-path-zero-exclusion-object.js b/deps/v8/test/mjsunit/regress/regress-fast-path-zero-exclusion-object.js
new file mode 100644
index 00000000000..b2d8af4b153
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-fast-path-zero-exclusion-object.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(obj) {
+ let { ...rest } = obj;
+ return rest;
+}
+
+assertEquals({}, f({}));
+assertEquals({a: 1}, f({a: 1}));
+
+// Test that null and undefined throw TypeError.
+assertThrows(() => f(null), TypeError);
+assertThrows(() => f(undefined), TypeError);
+
+// Test with prototype properties.
+let proto = { b: 2 };
+let obj = Object.create(proto);
+obj.a = 1;
+assertEquals({a: 1}, f(obj));
+
+// Ensure it compiles and optimizes.
+%PrepareFunctionForOptimization(f);
+f({});
+f({});
+%OptimizeFunctionOnNextCall(f);
+assertEquals({a: 1}, f({a: 1}));
diff --git a/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js b/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js
new file mode 100644
index 00000000000..a2ae1ce7349
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-homomorphic-maglev.js
@@ -0,0 +1,61 @@
+// 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 --homomorphic-ic --maglev --no-turbofan
+
+function createNormalObject() {
+ function C() {}
+ %CompleteInobjectSlackTracking(new C());
+ return new C();
+}
+
+// 1. Interceptor object: Maglev homomorphic access must deopt.
+{
+ function load(o) {
+ return o.a;
+ }
+ %PrepareFunctionForOptimization(load);
+ for (let i = 0; i < 11; i++) {
+ let o = (i % 2 === 0) ? createNormalObject()
+ : d8.test.createSpecialObject({});
+ o.a = i;
+ load(o);
+ }
+ %OptimizeMaglevOnNextCall(load);
+ let sample = createNormalObject();
+ sample.a = 1;
+ assertEquals(1, load(sample));
+ assertOptimized(load);
+
+ let obj = d8.test.createInterceptorObject(() => "intercepted");
+ obj.a = 42;
+ assertEquals("intercepted", load(obj));
+ assertUnoptimized(load);
+}
+
+// 2. Access checked object: Maglev homomorphic access must deopt.
+{
+ function load(o) {
+ return o.a;
+ }
+ %PrepareFunctionForOptimization(load);
+ for (let i = 0; i < 11; i++) {
+ let o = (i % 2 === 0) ? createNormalObject()
+ : d8.test.createSpecialObject({});
+ o.a = i;
+ load(o);
+ }
+ %OptimizeMaglevOnNextCall(load);
+ let sample = createNormalObject();
+ sample.a = 1;
+ assertEquals(1, load(sample));
+ assertOptimized(load);
+
+ let obj = d8.test.createAccessCheckedObject(true);
+ obj.a = 42;
+ d8.test.setAccessPolicy(obj, false);
+
+ assertThrows(() => load(obj), TypeError);
+ assertUnoptimized(load);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js b/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js
new file mode 100644
index 00000000000..0a4717e4697
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-homomorphic-turbofan.js
@@ -0,0 +1,61 @@
+// 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 --homomorphic-ic --turbofan --no-maglev
+
+function createNormalObject() {
+ function C() {}
+ %CompleteInobjectSlackTracking(new C());
+ return new C();
+}
+
+// 1. Interceptor object: Turbofan homomorphic access must deopt.
+{
+ function load(o) {
+ return o.a;
+ }
+ %PrepareFunctionForOptimization(load);
+ for (let i = 0; i < 11; i++) {
+ let o = (i % 2 === 0) ? createNormalObject()
+ : d8.test.createSpecialObject({});
+ o.a = i;
+ load(o);
+ }
+ %OptimizeFunctionOnNextCall(load);
+ let sample = createNormalObject();
+ sample.a = 1;
+ assertEquals(1, load(sample));
+ assertOptimized(load);
+
+ let obj = d8.test.createInterceptorObject(() => "intercepted");
+ obj.a = 42;
+ assertEquals("intercepted", load(obj));
+ assertUnoptimized(load);
+}
+
+// 2. Access checked object: Turbofan homomorphic access must deopt.
+{
+ function load(o) {
+ return o.a;
+ }
+ %PrepareFunctionForOptimization(load);
+ for (let i = 0; i < 11; i++) {
+ let o = (i % 2 === 0) ? createNormalObject()
+ : d8.test.createSpecialObject({});
+ o.a = i;
+ load(o);
+ }
+ %OptimizeFunctionOnNextCall(load);
+ let sample = createNormalObject();
+ sample.a = 1;
+ assertEquals(1, load(sample));
+ assertOptimized(load);
+
+ let obj = d8.test.createAccessCheckedObject(true);
+ obj.a = 42;
+ d8.test.setAccessPolicy(obj, false);
+
+ assertThrows(() => load(obj), TypeError);
+ assertUnoptimized(load);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.js b/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.js
new file mode 100644
index 00000000000..7cc8d874695
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-homomorphic-unoptimized.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.
+
+// Flags: --allow-natives-syntax --homomorphic-ic --no-maglev --no-turbofan
+
+function createNormalObject() {
+ function C() {}
+ %CompleteInobjectSlackTracking(new C());
+ return new C();
+}
+
+function load(o) {
+ return o.a;
+}
+
+%PrepareFunctionForOptimization(load);
+// Warm up with a mix of normal JS objects and API objects so that the LoadIC
+// enters HOMOMORPHIC state.
+for (let i = 0; i < 11; i++) {
+ let o = (i % 2 === 0) ? createNormalObject()
+ : d8.test.createSpecialObject({});
+ o.a = i;
+ assertEquals(i, load(o));
+}
+
+let fb = %GetFeedback(load);
+if (fb !== undefined) {
+ assertEquals(1, fb.length);
+ assertContains("HOMOMORPHIC", fb[0][1]);
+}
+
+// 1. Interceptor object: homomorphic IC must not bypass the interceptor.
+{
+ let obj = d8.test.createInterceptorObject(() => 'intercepted');
+ obj.a = 42;
+ assertEquals('intercepted', load(obj));
+}
+
+// 2. Access checked object: homomorphic IC must not bypass access checks.
+{
+ let obj = d8.test.createAccessCheckedObject(true);
+ obj.a = 42;
+ assertEquals(42, load(obj));
+ d8.test.setAccessPolicy(obj, false);
+ assertThrows(() => load(obj), TypeError);
+}
diff --git a/deps/v8/test/mjsunit/regress/regress-parse-only-stress-runs.js b/deps/v8/test/mjsunit/regress/regress-parse-only-stress-runs.js
new file mode 100644
index 00000000000..6cc695eca10
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-parse-only-stress-runs.js
@@ -0,0 +1,11 @@
+// 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: --parse-only --stress-runs=2 --throws
+
+// This test verifies that parsing an invalid file with --parse-only and
+// --stress-runs does not leak unhandled exceptions onto the isolate or crash
+// during Genesis in subsequent runs.
+
+invalid { javascript code ;
diff --git a/deps/v8/test/mjsunit/regress/regress-rab-proto-oob.js b/deps/v8/test/mjsunit/regress/regress-rab-proto-oob.js
new file mode 100644
index 00000000000..0e9766309e6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-rab-proto-oob.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 testOobProtoWrite(n) {
+ let src = `o["${n}"] = 42`;
+ let setElem = new Function("o", src)
+ var rab = new ArrayBuffer(n+1, { maxByteLength: n+1 });
+ var ta = new Int8Array(rab);
+ for (var i = 0; i < 100; i++) setElem(Object.create(ta));
+ rab.resize(8);
+ var victim = Object.create(ta);
+ setElem(victim);
+ assertEquals(undefined, victim[n]);
+}
+
+testOobProtoWrite(1000);
+
+if (%Is64Bit()) {
+ testOobProtoWrite(0x100000000);
+}
+
+function testOobProtoWriteManyViews(n) {
+ let src = `o["${n}"] = 42`;
+ let setElem = new Function("o", src)
+ var rab = new ArrayBuffer(n+1, { maxByteLength: n+1 });
+ var ta = new Int8Array(rab);
+ var ta2 = new Int8Array(rab); // Second view to trigger kManyViews
+ for (var i = 0; i < 100; i++) setElem(Object.create(ta));
+ rab.resize(8);
+ var victim = Object.create(ta);
+ setElem(victim);
+ assertEquals(undefined, victim[n]);
+}
+
+testOobProtoWriteManyViews(1000);
diff --git a/deps/v8/test/mjsunit/regress/regress-value-serializer.js b/deps/v8/test/mjsunit/regress/regress-value-serializer.js
new file mode 100644
index 00000000000..979c1cef863
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/regress-value-serializer.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.
+
+// Flags: --js-immutable-arraybuffer
+
+const ab = new ArrayBuffer(0);
+const immutable = ab.transferToImmutable();
+
+const w = new Worker('onmessage = function(e) {};', {type: 'string'});
+w.postMessage(immutable);
+w.terminate();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-433984397.js b/deps/v8/test/mjsunit/regress/wasm/regress-433984397.js
index db6d0c862e5..4705b4fbc72 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-433984397.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-433984397.js
@@ -8,13 +8,23 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let builder = new WasmModuleBuilder();
builder.startRecGroup();
-let $top = builder.addStruct({fields: []});
-let $mid = builder.addStruct({fields: [], supertype: $top});
+
+let $top_desc = builder.nextTypeIndex() + 1;
+let $top = builder.addStruct({fields: [], descriptor: $top_desc});
+let top_verify = builder.addStruct({fields: [], describes: $top});
+assertEquals(top_verify, $top_desc);
+
+let $mid_desc = builder.nextTypeIndex() + 1;
+let $mid = builder.addStruct({fields: [], supertype: $top, descriptor: $mid_desc});
+let mid_verify = builder.addStruct({fields: [], supertype: $top_desc, describes: $mid});
+assertEquals(mid_verify, $mid_desc);
+
let $bot_desc = builder.nextTypeIndex() + 1;
let $bot = builder.addStruct({fields: [], supertype: $mid, descriptor: $bot_desc});
-let verify = builder.addStruct({fields: [], describes: $bot});
+let bot_verify = builder.addStruct({fields: [], supertype: $mid_desc, describes: $bot});
+assertEquals(bot_verify, $bot_desc);
+
builder.endRecGroup();
-assertEquals(verify, $bot_desc);
let $g = builder.addGlobal(wasmRefType($bot), false, false, [
kGCPrefix, kExprStructNewDefault, $bot_desc,
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-448404198.js b/deps/v8/test/mjsunit/regress/wasm/regress-448404198.js
index 6aed0b3585e..b15f324fc58 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-448404198.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-448404198.js
@@ -10,7 +10,7 @@ const builder = new WasmModuleBuilder();
builder.startRecGroup();
let $struct1 = builder.nextTypeIndex() + 1;
let $struct0 = builder.addStruct({fields: [], descriptor: $struct1});
-/* $struct1 */ builder.addStruct({fields: [], final: true, describes: $struct0});
+/* $struct1 */ builder.addStruct({fields: [], describes: $struct0});
builder.endRecGroup();
builder.addFunction("main", kSig_v_v).exportFunc()
.addLocals(wasmRefType($struct1), 1)
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-502030575.js b/deps/v8/test/mjsunit/regress/wasm/regress-502030575.js
index f0fd90b7e3c..cea9deab6d1 100644
--- a/deps/v8/test/mjsunit/regress/wasm/regress-502030575.js
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-502030575.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.
-// Flags: --allow-natives-syntax
-
d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
let builder = new WasmModuleBuilder();
@@ -11,9 +9,11 @@ let array_type = builder.addArray(kWasmI64);
// For 32 bit platforms:
// Choose a big constant offset, so that when adding the constant wasm array
-// header offset and the extra offset for the 2nd i32 load we end up with a
-// value that exactly equals INT32_MIN (which is the singular value that
+// header offset and the extra offset for the 2nd i32 load/store we end up with
+// a value that exactly equals INT32_MIN (which is the singular value that
// returns false for LoadOp::OffsetIsValid()).
+// Note: This logic has been replaced and is now handled in the
+// LoadStoreSimplificationReducer exclusively.
const BIG_CONST = 0xFFFFFFE;
const WASM_ARRAY_HEADER = 12; // map + hash + array size (subject to change)
const SECOND_LOAD_OFFSET = 4
@@ -45,6 +45,31 @@ builder.addFunction("test", makeSig([kWasmI32], [kWasmI64]))
])
.exportFunc();
+builder.addFunction("testStore", makeSig([kWasmI32], [kWasmI64]))
+ .addLocals(wasmRefNullType(array_type), 1)
+ .addBody([
+ // Create an array with a single value
+ ...wasmI32Const(1),
+ kGCPrefix, kExprArrayNewDefault, array_type,
+ kExprLocalTee, 1,
+ // Write a value at offset 0 by having the index calculation
+ // (BIG_CONST - BIG_CONST). The i32.const in the code will be folded into
+ // the offset of the store.
+ kExprLocalGet, 0,
+ ...wasmI32Const(BIG_CONST),
+ kExprI32Add,
+ ...wasmI64Const(testValue),
+ kGCPrefix, kExprArraySet, array_type,
+ // Read the value at offset 0.
+ kExprLocalGet, 1,
+ kExprI32Const, 0,
+ kGCPrefix, kExprArrayGet, array_type,
+ ])
+ .exportFunc();
+
let instance = builder.instantiate();
let result = instance.exports.test(-BIG_CONST);
assertEquals(testValue, result);
+
+let storeResult = instance.exports.testStore(-BIG_CONST);
+assertEquals(testValue, storeResult);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-526163463.js b/deps/v8/test/mjsunit/regress/wasm/regress-526163463.js
new file mode 100644
index 00000000000..24772efcbe6
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-526163463.js
@@ -0,0 +1,39 @@
+// 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: --enable-inspector --wasm-code-coverage
+
+// Pausing the debugger while executing Wasm triggers regeneration of the
+// Liftoff debug side table. With --wasm-code-coverage, the regenerated code
+// must include coverage instrumentation so its PC offsets match the original
+// code. Ensure frame inspection does not crash.
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+let setup_idx = builder.addImport('env', 'setup', kSig_v_v);
+builder.addFunction('vuln', kSig_v_v)
+ .addBody([
+ kExprCallFunction, setup_idx,
+ kExprLoop, kWasmVoid,
+ kExprEnd,
+ ])
+ .exportFunc();
+
+let instance = builder.instantiate({
+ env: {
+ setup: function() {
+ send(JSON.stringify({
+ id: 1,
+ method: 'Debugger.enable',
+ }));
+ send(JSON.stringify({
+ id: 2,
+ method: 'Debugger.pause',
+ }));
+ }
+ }
+});
+
+instance.exports.vuln();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-535659723.js b/deps/v8/test/mjsunit/regress/wasm/regress-535659723.js
new file mode 100644
index 00000000000..560d9138d9b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-535659723.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.
+
+// Flags: --expose-fast-api --allow-natives-syntax --turbo-fast-api-calls
+// Flags: --wasm-fast-api --no-wasm-trap-handler --stress-wasm-memory-moving
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+const fast_c_api = new d8.test.FastCAPI();
+const api_function = fast_c_api.call_to_number;
+const bound_func = Function.prototype.call.bind(api_function);
+
+const builder = new WasmModuleBuilder();
+builder.addMemory(1, 100);
+builder.exportMemoryAs('mem');
+
+const sig_index = builder.addType(makeSig([kWasmExternRef, kWasmExternRef], []));
+const $call_to_number = builder.addImport('env', 'call_to_number', sig_index);
+
+builder.addFunction('test', makeSig([kWasmExternRef, kWasmExternRef], []))
+ .exportFunc()
+ .addBody([
+ // Call Fast API call_to_number
+ kExprLocalGet, 0, // receiver (fast_c_api)
+ kExprLocalGet, 1, // arg
+ kExprCallFunction, $call_to_number,
+
+ // Write to memory
+ kExprI32Const, 4,
+ ...wasmI32Const(0x41414141),
+ kExprI32StoreMem, 2, 0,
+ ]);
+
+const instance = builder.instantiate({env: {call_to_number: bound_func}});
+const mem = instance.exports.mem;
+
+%WasmTierUpFunction(instance.exports.test);
+
+let arg = {
+ valueOf: function() {
+ print("Growing memory inside Fast API callback...");
+ mem.grow(10);
+ return 42;
+ }
+};
+
+print("Calling test...");
+instance.exports.test(fast_c_api, arg);
+print("Done!");
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-540446645.js b/deps/v8/test/mjsunit/regress/wasm/regress-540446645.js
new file mode 100644
index 00000000000..db68cc0bec2
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-540446645.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: --allow-natives-syntax
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+const builder = new WasmModuleBuilder();
+builder.addFunction("f", makeSig([kWasmI64], [kWasmI32])).exportFunc()
+.addBody([
+ kExprLocalGet, 0,
+ ...wasmI64Const(1099511627776n), // 1 << 40
+ kExprI64And,
+ kExprI32ConvertI64,
+ kExprIf, kWasmI32,
+ kExprI32Const, 1,
+ kExprElse,
+ kExprI32Const, 0,
+ kExprEnd,
+]);
+
+builder.addFunction("g", makeSig([kWasmI64], [kWasmI32])).exportFunc()
+.addBody([
+ kExprLocalGet, 0,
+ ...wasmI64Const(0x300000000n), // bits 32 and 33 set
+ kExprI64And,
+ kExprI32ConvertI64,
+ kExprIf, kWasmI32,
+ kExprI32Const, 1,
+ kExprElse,
+ kExprI32Const, 0,
+ kExprEnd,
+]);
+
+const {f, g} = builder.instantiate().exports;
+const highBit = 1n << 40n;
+const lowBit = 1n << 8n;
+
+assertEquals(0, f(highBit));
+assertEquals(0, f(lowBit));
+%WasmTierUpFunction(f);
+assertEquals(0, f(0n));
+assertEquals(0, f(highBit));
+assertEquals(0, f(lowBit));
+
+const val = 0x300000000n;
+assertEquals(0, g(val));
+%WasmTierUpFunction(g);
+assertEquals(0, g(0n));
+assertEquals(0, g(val));
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-541316788.js b/deps/v8/test/mjsunit/regress/wasm/regress-541316788.js
new file mode 100644
index 00000000000..03c858e60e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-541316788.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: --wasm-fast-api --expose-fast-api --no-liftoff
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const fast_c_api = new d8.test.FastCAPI();
+const builder = new WasmModuleBuilder();
+builder.addMemory();
+const call_to_number = builder.addImport(
+ 'env', 'call_to_number', makeSig([kWasmExternRef, kWasmExternRef], []));
+builder.addFunction('test', makeSig([kWasmExternRef, kWasmExternRef], []))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet,
+ 0,
+ kExprLocalGet,
+ 1,
+ kExprCallFunction,
+ call_to_number,
+ ]);
+
+const instance = builder.instantiate({
+ env: {
+ call_to_number: Function.call.bind(fast_c_api.call_to_number),
+ },
+});
+
+const arg = {
+ valueOf: () => {
+ console.trace();
+ }
+};
+
+instance.exports.test(fast_c_api, arg);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-543901836.js b/deps/v8/test/mjsunit/regress/wasm/regress-543901836.js
new file mode 100644
index 00000000000..ec603327c32
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-543901836.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: --expose-gc --gc-global --expose-externalize-string
+// Flags: --allow-natives-syntax
+
+const SIZE = 32 * 1024 * 1024;
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+let $sig0 = builder.addType(makeSig([], [wasmRefType(kWasmExternRef)]));
+let $sig1 = builder.addType(makeSig([kWasmExternRef, kWasmI32, kWasmI32],
+ [wasmRefType(kWasmExternRef)]));
+let $getExt = builder.addImport('env', 'getExt', $sig0);
+let substring = builder.addImport('wasm:js-string', 'substring', $sig1);
+builder.addFunction("run", $sig0).exportFunc().addBody([
+ kExprCallFunction, $getExt,
+ kExprI32Const, 0,
+ kExprI32Const, 8,
+ kExprCallFunction, substring,
+ ]);
+
+function makeExternal(s) {
+ const t = createExternalizableString(s);
+ externalizeString(t);
+ return t;
+}
+function getExt() {
+ const s = makeExternal('A'.repeat(SIZE));
+ %SimulateNewspaceFull();
+ return s;
+}
+
+let instance = builder.instantiate(
+ { env: { getExt } }, { builtins: ['js-string'] });
+%WasmTierUpFunction(instance.exports.run);
+
+for (let i = 0; i < 5; i++) {
+ instance.exports.run();
+}
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-550812031.js b/deps/v8/test/mjsunit/regress/wasm/regress-550812031.js
new file mode 100644
index 00000000000..4a5003ed0fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-550812031.js
@@ -0,0 +1,18 @@
+// 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-wasm-generic-wrapper --wasm-shared
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+let imp_s = builder.addImport('mod', 'fn',
+ makeSig([], [wasmRefNullType(kWasmStructRef)]));
+
+builder.addFunction('test', makeSig([], [wasmRefNullType(kWasmStructRef)]))
+ .addBody([kExprCallFunction, imp_s])
+ .exportFunc();
+
+let js_fn = () => null;
+let instance = builder.instantiate({ mod: { fn: js_fn } });
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-552026580.js b/deps/v8/test/mjsunit/regress/wasm/regress-552026580.js
new file mode 100644
index 00000000000..6579b334398
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-552026580.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-shared
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+let builder = new WasmModuleBuilder();
+let kSharedRefExtern = wasmRefType(kWasmExternRef).shared();
+
+let sig_f64_to_shared_extern =
+ builder.addType(makeSig([kWasmF64], [kSharedRefExtern]));
+let double_to_string_import =
+ builder.addImport('mod', 'doubleToString', sig_f64_to_shared_extern);
+
+let struct = builder.addStruct(
+ {fields: [makeField(kSharedRefExtern, true)], shared: true});
+
+builder.addFunction("test", makeSig([kWasmF64], [wasmRefType(struct)]))
+ .addBody([
+ kExprLocalGet, 0,
+ kExprCallFunction, double_to_string_import,
+ kGCPrefix, kExprStructNew, struct
+ ])
+ .exportFunc();
+
+let instance = builder.instantiate({
+ mod: {
+ doubleToString: Function.prototype.call.bind(Number.prototype.toString)
+ }
+});
+instance.exports.test(3.14159);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-554714206.js b/deps/v8/test/mjsunit/regress/wasm/regress-554714206.js
new file mode 100644
index 00000000000..ecdc50d4c0b
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-554714206.js
@@ -0,0 +1,18 @@
+// 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-test-streaming --nowasm-lazy-compilation
+// Flags: --wasm-caching-threshold=0 --wasm-caching-timeout-ms=0
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+let f0 = builder.addFunction('f0', kSig_i_i).addBody([kExprLocalGet, 0]);
+let wasm_bytes = builder.toBuffer();
+let fake_response = {
+ then(resolve) {
+ resolve(wasm_bytes);
+ }
+};
+WebAssembly.compileStreaming(fake_response).catch();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-555812363.js b/deps/v8/test/mjsunit/regress/wasm/regress-555812363.js
new file mode 100644
index 00000000000..83587cbb9a7
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-555812363.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-js-interop
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/wasm/prototype-setup-builder.js');
+
+let builder = new WasmModuleBuilder();
+let proto_config = new WasmPrototypeSetupBuilder(builder);
+
+let $g_proto = builder.addImportedGlobal('p', 'p', kWasmExternRef);
+let $import = builder.addImport('q', 'f', kSig_v_v);
+let $method = builder.addFunction('m', kSig_v_r).exportFunc().addBody([
+ kExprCallFunction, $import,
+]);
+
+proto_config.addConfig($g_proto).addMethod('m', kWasmMethod, $method);
+proto_config.build();
+
+let proto = {};
+function f() {
+ assertEquals(null, f.caller);
+}
+
+let imports = {
+ p: { p: proto },
+ q: { f },
+ c: { constructors: {} },
+};
+builder.instantiate(imports, { builtins: ['js-prototypes'] });
+proto.m();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-558539954.js b/deps/v8/test/mjsunit/regress/wasm/regress-558539954.js
new file mode 100644
index 00000000000..90fd14cb776
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-558539954.js
@@ -0,0 +1,183 @@
+// 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 --turbo-inline-js-wasm-calls
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const builder = new WasmModuleBuilder();
+let array_type = builder.addArray(kWasmI32);
+let struct_type = builder.addStruct([makeField(kWasmI32, true)]);
+
+let make_array = builder.addFunction('make_array', makeSig([], [kWasmExternRef])).exportFunc();
+make_array.addBody([
+ kExprI32Const, 10,
+ kGCPrefix, kExprArrayNewDefault, array_type,
+ kGCPrefix, kExprExternConvertAny,
+]);
+
+let make_struct = builder.addFunction('make_struct', makeSig([], [kWasmExternRef])).exportFunc();
+make_struct.addBody([
+ kExprI32Const, 42,
+ kGCPrefix, kExprStructNew, struct_type,
+ kGCPrefix, kExprExternConvertAny,
+]);
+
+// 1. Abstract cast: ref.cast array
+let abstract_cast = builder.addFunction('abstract_cast', makeSig([kWasmExternRef], [kWasmExternRef])).exportFunc();
+abstract_cast.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefCast, kArrayRefCode,
+ kGCPrefix, kExprExternConvertAny,
+]);
+
+// 2. Abstract cast: ref.cast null array
+let abstract_cast_null = builder.addFunction('abstract_cast_null', makeSig([kWasmExternRef], [kWasmExternRef])).exportFunc();
+abstract_cast_null.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefCastNull, kArrayRefCode,
+ kGCPrefix, kExprExternConvertAny,
+]);
+
+// 3. Concrete cast: ref.cast <array_type>
+let concrete_cast = builder.addFunction('concrete_cast', makeSig([kWasmExternRef], [kWasmExternRef])).exportFunc();
+concrete_cast.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefCast, array_type,
+ kGCPrefix, kExprExternConvertAny,
+]);
+
+// 4. Concrete cast: ref.cast null <array_type>
+let concrete_cast_null = builder.addFunction('concrete_cast_null', makeSig([kWasmExternRef], [kWasmExternRef])).exportFunc();
+concrete_cast_null.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefCastNull, array_type,
+ kGCPrefix, kExprExternConvertAny,
+]);
+
+// 5. Abstract cast then array.len
+let cast_then_len = builder.addFunction('cast_then_len', makeSig([kWasmExternRef], [kWasmI32])).exportFunc();
+cast_then_len.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefCast, kArrayRefCode,
+ kGCPrefix, kExprArrayLen,
+]);
+
+let cast_null_then_len = builder.addFunction('cast_null_then_len', makeSig([kWasmExternRef], [kWasmI32])).exportFunc();
+cast_null_then_len.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprAnyConvertExtern,
+ kGCPrefix, kExprRefCastNull, kArrayRefCode,
+ kGCPrefix, kExprArrayLen,
+]);
+
+// 6. Direct array.len and struct.get with nullable parameter
+let array_len = builder.addFunction('array_len', makeSig([wasmRefNullType(array_type)], [kWasmI32])).exportFunc();
+array_len.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprArrayLen,
+]);
+
+let struct_get = builder.addFunction('struct_get', makeSig([wasmRefNullType(struct_type)], [kWasmI32])).exportFunc();
+struct_get.addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprStructGet, struct_type, 0,
+]);
+
+const instance = builder.instantiate();
+const wasm_array = instance.exports.make_array();
+const wasm_struct = instance.exports.make_struct();
+
+function testOptimized(run, fctToOptimize) {
+ %DeoptimizeFunction(fctToOptimize);
+ %PrepareFunctionForOptimization(fctToOptimize);
+ run();
+ %OptimizeFunctionOnNextCall(fctToOptimize);
+ run();
+ assertOptimized(fctToOptimize);
+}
+
+// Test abstract cast (non-nullable)
+function test_abstract(x) {
+ return instance.exports.abstract_cast(x);
+}
+testOptimized(() => {
+ assertSame(wasm_array, test_abstract(wasm_array));
+ assertThrows(() => test_abstract(null), WebAssembly.RuntimeError, /illegal cast/);
+ assertThrows(() => test_abstract(undefined), WebAssembly.RuntimeError, /illegal cast/);
+ assertThrows(() => test_abstract({}), WebAssembly.RuntimeError, /illegal cast/);
+ assertThrows(() => test_abstract(123), WebAssembly.RuntimeError, /illegal cast/);
+}, test_abstract);
+
+// Test abstract cast (nullable)
+function test_abstract_null(x) {
+ return instance.exports.abstract_cast_null(x);
+}
+testOptimized(() => {
+ assertSame(wasm_array, test_abstract_null(wasm_array));
+ assertEquals(null, test_abstract_null(null));
+ assertThrows(() => test_abstract_null(undefined), WebAssembly.RuntimeError, /illegal cast/);
+ assertThrows(() => test_abstract_null({}), WebAssembly.RuntimeError, /illegal cast/);
+ assertThrows(() => test_abstract_null(123), WebAssembly.RuntimeError, /illegal cast/);
+}, test_abstract_null);
+
+// Test concrete cast (non-nullable)
+function test_concrete(x) {
+ return instance.exports.concrete_cast(x);
+}
+testOptimized(() => {
+ assertSame(wasm_array, test_concrete(wasm_array));
+ assertThrows(() => test_concrete(null), WebAssembly.RuntimeError, /illegal cast/);
+ assertThrows(() => test_concrete(wasm_struct), WebAssembly.RuntimeError, /illegal cast/);
+}, test_concrete);
+
+// Test concrete cast (nullable)
+function test_concrete_null(x) {
+ return instance.exports.concrete_cast_null(x);
+}
+testOptimized(() => {
+ assertSame(wasm_array, test_concrete_null(wasm_array));
+ assertEquals(null, test_concrete_null(null));
+ assertThrows(() => test_concrete_null(wasm_struct), WebAssembly.RuntimeError, /illegal cast/);
+}, test_concrete_null);
+
+// Test cast then array.len
+function test_cast_len(x) {
+ return instance.exports.cast_then_len(x);
+}
+testOptimized(() => {
+ assertEquals(10, test_cast_len(wasm_array));
+ assertThrows(() => test_cast_len(null), WebAssembly.RuntimeError, /illegal cast/);
+}, test_cast_len);
+
+function test_cast_null_len(x) {
+ return instance.exports.cast_null_then_len(x);
+}
+testOptimized(() => {
+ assertEquals(10, test_cast_null_len(wasm_array));
+ assertThrows(() => test_cast_null_len(null), WebAssembly.RuntimeError, /null pointer/);
+}, test_cast_null_len);
+
+// Test direct array.len on null
+function test_len(x) {
+ return instance.exports.array_len(x);
+}
+testOptimized(() => {
+ assertEquals(10, test_len(wasm_array));
+ assertThrows(() => test_len(null), WebAssembly.RuntimeError, /null pointer/);
+}, test_len);
+
+// Test direct struct.get on null
+function test_get(x) {
+ return instance.exports.struct_get(x);
+}
+testOptimized(() => {
+ assertEquals(42, test_get(wasm_struct));
+ assertThrows(() => test_get(null), WebAssembly.RuntimeError, /null pointer/);
+}, test_get);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-drumbrake-unreachable-cast.js b/deps/v8/test/mjsunit/regress/wasm/regress-drumbrake-unreachable-cast.js
new file mode 100644
index 00000000000..7e6ea787e91
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-drumbrake-unreachable-cast.js
@@ -0,0 +1,243 @@
+// 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');
+
+// Test 1: br_on_cast_fail missing SetUnreachableMode on TypeCheckAlwaysFails branch.
+(function testBrOnCastFailUnreachable() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ let $Super = builder.addStruct({fields: [makeField(kWasmI32, true)], supertype: kNoSuperType, final: false});
+ let $SubA = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)], supertype: $Super});
+ let $SubB = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI64, true)], supertype: $Super});
+
+ let $sig_if = builder.addType(makeSig([wasmRefNullType($SubB)], [wasmRefType($SubB)]));
+
+ builder.addFunction('main', makeSig([], [kWasmI64])).exportFunc()
+ .addLocals(wasmRefNullType($Super), 1)
+ .addBody([
+ // Local 0 = instance of struct $SubA (field 0 = 42, field 1 = 100)
+ ...wasmI32Const(42),
+ ...wasmI32Const(100),
+ kGCPrefix, kExprStructNew, $SubA,
+ kExprLocalSet, 0,
+
+ kExprBlock, kWasmRefNull, ...wasmEncodeHeapType(wasmRefNullType($Super)),
+ kExprBlock, kWasmRefNull, ...wasmEncodeHeapType(wasmRefNullType($Super)),
+ kExprLocalGet, 0,
+ // Cast check: (ref $Super) -> (ref null $SubB).
+ // TypeCheckAlwaysFails($SubA, $SubB) == true -> emits s2s_Branch to end of block.
+ ...wasmBrOnCastFail(1, wasmRefNullType($Super), wasmRefNullType($SubB)),
+ // Dead suffix inside block:
+ kExprI32Const, 0,
+ kExprIf, $sig_if,
+ kExprDrop,
+ kGCPrefix, kExprStructNewDefault, $SubB,
+ kExprElse,
+ kExprDrop,
+ kGCPrefix, kExprStructNewDefault, $SubB,
+ kExprEnd,
+ kGCPrefix, kExprRefCast, $SubB,
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ kExprDrop,
+ ...wasmI64Const(0),
+ kExprReturn,
+ kExprEnd,
+ kExprDrop,
+ kGCPrefix, kExprStructNewDefault, $Super,
+ kExprEnd,
+
+ // Outer block target: local 0 physically contains struct $SubA.
+ // Must trap with kTrapIllegalCast.
+ kGCPrefix, kExprRefCast, $SubB,
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ ]);
+
+ const instance = builder.instantiate({});
+ assertTraps(kTrapIllegalCast, () => instance.exports.main());
+})();
+
+// Test 2: ref.cast / ref.cast_null missing SetUnreachableMode on TypeCheckAlwaysFails branch.
+(function testRefCastUnreachable() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ let $Super = builder.addStruct({fields: [makeField(kWasmI32, true)], supertype: kNoSuperType, final: false});
+ let $SubA = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)], supertype: $Super});
+ let $SubB = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI64, true)], supertype: $Super});
+
+ let $sig_if_cond = builder.addType(makeSig([], []));
+ let $sig_if_nested = builder.addType(makeSig([wasmRefNullType($SubB)], [wasmRefNullType($SubB)]));
+
+ builder.addFunction('main', makeSig([], [kWasmI64])).exportFunc()
+ .addLocals(wasmRefNullType($Super), 1)
+ .addBody([
+ // Local 0 = instance of struct $SubA (field 0 = 42, field 1 = 100)
+ ...wasmI32Const(42),
+ ...wasmI32Const(100),
+ kGCPrefix, kExprStructNew, $SubA,
+ kExprLocalSet, 0,
+
+ // Outer if: condition 1 (always true)
+ ...wasmI32Const(1),
+ kExprIf, ...wasmSignedLeb($sig_if_cond),
+ // Then arm: empty
+ kExprElse,
+ // Else arm (runtime skipped):
+ // 1. Always-failing ref.cast $SubB on local 0 -> emits s2s_TrapIllegalCast + SetUnreachableMode()
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCast, $SubB,
+ kExprDrop,
+ // 2. Dead suffix: supply ref.null $SubB and nested if
+ kExprRefNull, ...wasmEncodeHeapType(wasmRefNullType($SubB)),
+ ...wasmI32Const(0),
+ kExprIf, ...wasmSignedLeb($sig_if_nested),
+ kExprElse,
+ kExprEnd,
+ kExprDrop,
+ kExprEnd,
+
+ // Outside if: load local 0 (physically contains struct $SubA).
+ // Must trap with kTrapIllegalCast.
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCast, $SubB,
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ ]);
+
+ const instance = builder.instantiate({});
+ assertTraps(kTrapIllegalCast, () => instance.exports.main());
+})();
+
+// Test 3: ref.cast null on unrelated nullable type when object is null.
+// Exercises TypeCheckAlwaysFails path where null succeeds, verifying RefPush(resulting_value_type) updates stack type.
+(function testRefCastNullAlwaysFailsNullSucceeds() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ let $Super = builder.addStruct({fields: [makeField(kWasmI32, true)], supertype: kNoSuperType, final: false});
+ let $SubA = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)], supertype: $Super});
+ let $SubB = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI64, true)], supertype: $Super});
+
+ builder.addFunction('main', makeSig([], [kWasmI64])).exportFunc()
+ .addLocals(wasmRefNullType($SubA), 1) // Local 0 is null (ref null $SubA)
+ .addBody([
+ // Explicitly push ref.null $SubA
+ kExprRefNull, ...wasmEncodeHeapType(wasmRefNullType($SubA)),
+ // ref.cast null $SubB on null (ref null $SubA) -> TypeCheckAlwaysFails holds, but null succeeds.
+ // Emits s2s_AssertNullTypecheck, pops (ref null $SubA), pushes (ref null $SubB).
+ kGCPrefix, kExprRefCastNull, $SubB,
+ // struct.get $SubB on the resulting null -> must throw kTrapNullDereference.
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ ]);
+
+ const instance = builder.instantiate({});
+ assertTraps(kTrapNullDereference, () => instance.exports.main());
+})();
+
+// Test 4: ref.as_non_null updates stack type to non-nullable (ref $T).
+// Verifies RefPush(value_type.AsNonNull()) in kExprRefAsNonNull correctly marks result as non-nullable.
+(function testRefAsNonNullUpdatesStackType() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ let $SubA = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)], supertype: kNoSuperType});
+
+ builder.addFunction('main', makeSig([], [kWasmI32])).exportFunc()
+ .addLocals(wasmRefNullType($SubA), 1)
+ .addBody([
+ // Local 0 = struct $SubA instance
+ ...wasmI32Const(42),
+ ...wasmI32Const(100),
+ kGCPrefix, kExprStructNew, $SubA,
+ kExprLocalSet, 0,
+
+ kExprLocalGet, 0,
+ // ref.as_non_null converts (ref null $SubA) -> (ref $SubA) on stack
+ kExprRefAsNonNull,
+ // Following ref.cast to non-nullable $SubA:
+ // With RefPush(value_type.AsNonNull()), obj_type is non-nullable (ref $SubA).
+ // TypeCheckAlwaysSucceeds holds and obj_type is non-nullable -> elides extra s2s_AssertNotNullTypecheck.
+ kGCPrefix, kExprRefCast, $SubA,
+ kGCPrefix, kExprStructGet, $SubA, 0,
+ ]);
+
+ const instance = builder.instantiate({});
+ assertEquals(42, instance.exports.main());
+})();
+
+// Test 5: Reachable always-failing ref.cast executed directly at runtime.
+// Verifies reachable s2s_TrapIllegalCast traps with kTrapIllegalCast without stream corruption.
+(function testRefCastReachable() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ let $Super = builder.addStruct({fields: [makeField(kWasmI32, true)], supertype: kNoSuperType, final: false});
+ let $SubA = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)], supertype: $Super});
+ let $SubB = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI64, true)], supertype: $Super});
+
+ builder.addFunction('main', makeSig([], [kWasmI64])).exportFunc()
+ .addLocals(wasmRefNullType($Super), 1)
+ .addBody([
+ ...wasmI32Const(42),
+ ...wasmI32Const(100),
+ kGCPrefix, kExprStructNew, $SubA,
+ kExprLocalSet, 0,
+
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCast, $SubB,
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ ]);
+
+ const instance = builder.instantiate({});
+ assertTraps(kTrapIllegalCast, () => instance.exports.main());
+})();
+
+// Test 6: br_on_cast missing SetUnreachableMode on TypeCheckAlwaysSucceeds branch.
+(function testBrOnCastAlwaysSucceedsUnreachable() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ let $Super = builder.addStruct({fields: [makeField(kWasmI32, true)], supertype: kNoSuperType, final: false});
+ let $SubA = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)], supertype: $Super});
+ let $SubB = builder.addStruct({fields: [makeField(kWasmI32, true), makeField(kWasmI64, true)], supertype: $Super});
+
+ let $sig_if = builder.addType(makeSig([wasmRefNullType($SubA)], [wasmRefType($SubB)]));
+
+ builder.addFunction('main', makeSig([], [kWasmI64])).exportFunc()
+ .addLocals(wasmRefNullType($SubA), 1)
+ .addBody([
+ // Local 0 = instance of struct $SubA
+ ...wasmI32Const(42),
+ ...wasmI32Const(100),
+ kGCPrefix, kExprStructNew, $SubA,
+ kExprLocalSet, 0,
+
+ kExprBlock, kWasmRefNull, ...wasmEncodeHeapType(wasmRefNullType($SubA)),
+ kExprLocalGet, 0,
+ // Cast check: (ref null $SubA) -> (ref null $SubA).
+ // TypeCheckAlwaysSucceeds($SubA, $SubA) == true && null_succeeds == true.
+ // Emits s2s_Branch + SetUnreachableMode().
+ ...wasmBrOnCast(0, wasmRefNullType($SubA), wasmRefNullType($SubA)),
+ // Dead suffix inside block:
+ kExprI32Const, 0,
+ kExprIf, $sig_if,
+ kExprDrop,
+ kGCPrefix, kExprStructNewDefault, $SubB,
+ kExprElse,
+ kExprDrop,
+ kGCPrefix, kExprStructNewDefault, $SubB,
+ kExprEnd,
+ kGCPrefix, kExprRefCast, $SubB,
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ kExprDrop,
+ ...wasmI64Const(0),
+ kExprReturn,
+ kExprEnd,
+ kExprDrop,
+
+ // Outside block: local 0 physically contains struct $SubA.
+ // Casting local 0 to $SubB must trap with kTrapIllegalCast.
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefCast, $SubB,
+ kGCPrefix, kExprStructGet, $SubB, 1,
+ ]);
+
+ const instance = builder.instantiate({});
+ assertTraps(kTrapIllegalCast, () => instance.exports.main());
+})();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-interpreter-failed-reentry.js b/deps/v8/test/mjsunit/regress/wasm/regress-interpreter-failed-reentry.js
new file mode 100644
index 00000000000..cfd36ace223
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-interpreter-failed-reentry.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: --jitless --wasm-jitless
+
+// Regression test for an out-of-bounds tagged write in the DrumBrake
+// interpreter after a failed same-runtime reentry. When a reentry fails in
+// WasmInterpreterRuntime::BeginExecution because the interpreter stack cannot
+// be grown, the ExpandStack failure path removed the just-started activation
+// via FinishActivation() but did not restore current_frame_ (unlike the normal
+// teardown in ContinueExecution). The suspended outer frame then resumed with
+// the failed inner activation's stale ref_array_current_sp_, so StoreWasmRef
+// added a stale base to the bytecode-provided reference index and wrote out of
+// bounds of the reference-stack FixedArray.
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Each `ref.null extern; drop` gets a distinct eight-byte interpreter slot.
+// The interpreter frame must exceed 16 MiB so that a same-runtime reentry
+// begins beyond the 32 MiB reservation and fails. 2*2^20 + 1 slots gives a
+// frame just past 16 MiB.
+//
+// The 16-vs-32 MiB factor of two comes from how the reentry's frame base is
+// computed. ExecuteImportedFunction calls SetCurrentActivationFrame with
+// `current_sp_ + slot_offset` as the frame pointer and `slot_offset` as the
+// frame size, so WasmInterpreterThread::NextFrameAddress(), which returns
+// `current_fp_ + current_frame_size_`, hands the reentry a base of
+// `current_sp_ + 2 * slot_offset`. An outer frame just over 16 MiB therefore
+// starts the nested activation past the 32 MiB kMaxStackSize reservation, and
+// ExpandStack fails.
+const kFillerRefCount = 2 * 1024 * 1024 + 1;
+
+const builder = new WasmModuleBuilder();
+const sig_v_v = builder.addType(kSig_v_v);
+
+// Imported function that reenters the interpreter.
+const kReenterImport = builder.addImport('m', 'reenter', sig_v_v);
+
+// An empty export used as the same-instance reentry target.
+builder.addFunction('inner', sig_v_v).addBody([]).exportFunc();
+
+// The outer function whose suspended frame resumes after the failed reentry.
+
+// An outer () -> () function performs enough `ref.null extern; drop` sequences
+// that the interpreter frame is larger than half of the interpreter's 32 MiB
+// stack reservation. It then makes an imported call. JavaScript reenters
+// another export of the same instance; that nested entry overflows the
+// reservation and fails, and JavaScript catches the resulting RangeError. When
+// the imported call returns, the outer function resumes and a trailing
+// reference-producing instruction performs the tagged store.
+const runBody = new Array(kFillerRefCount * 3 + 6);
+let p = 0;
+for (let i = 0; i < kFillerRefCount; ++i) {
+ runBody[p++] = kExprRefNull;
+ runBody[p++] = kExternRefCode;
+ runBody[p++] = kExprDrop;
+}
+runBody[p++] = kExprCallFunction;
+runBody[p++] = kReenterImport;
+runBody[p++] = kExprRefNull;
+runBody[p++] = kExternRefCode;
+runBody[p++] = kExprDrop;
+runBody[p++] = kExprEnd;
+builder.addFunction('run', sig_v_v).addBodyWithEnd(runBody).exportFunc();
+
+let instance;
+let caught = false;
+instance = builder.instantiate({
+ m: {
+ reenter() {
+ try {
+ // Same-instance reentry. This nested entry overflows DrumBrake's stack
+ // reservation and must fail with a RangeError, which we catch.
+ instance.exports.inner();
+ } catch (e) {
+ caught = true;
+ }
+ },
+ },
+});
+
+// Without the fix the resumed outer frame performs an out-of-bounds tagged
+// write here and crashes. With the fix it completes normally.
+instance.exports.run();
+
+assertTrue(caught, 'nested same-runtime reentry should have overflowed');
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-526303932.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-526303932.js
new file mode 100644
index 00000000000..0526c2b8781
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-526303932.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: --wasm-fp16
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+const builder = new WasmModuleBuilder();
+const dummy_index = builder.addImport("env", "dummy", kSig_v_v);
+
+builder.addFunction("test_spill", kSig_f_f)
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ ...wasmF32Const(0.0),
+ kSimdPrefix, ...kExprF16x8Splat,
+ kExprLocalSet, 1,
+ kExprCallFunction, dummy_index,
+ kExprLocalGet, 1,
+ kExprLocalGet, 0,
+ kSimdPrefix, ...kExprF16x8ReplaceLane, 0,
+ kSimdPrefix, ...kExprF16x8ExtractLane, 0,
+ ])
+ .exportFunc();
+
+const instance = builder.instantiate({env: {dummy: () => {}}});
+instance.exports.test_spill(1.5);
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-547572465.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-547572465.js
new file mode 100644
index 00000000000..e4df182bb83
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-547572465.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: --no-enable-avx --liftoff-only
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Test i16x8.q15mulr_sat_s when destination aliases rhs.
+{
+ const builder = new WasmModuleBuilder();
+ builder.addFunction('test_strict', makeSig([kWasmI32, kWasmI32], [kWasmI32]))
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ kExprLocalGet, 0,
+ ...SimdInstr(kExprI16x8Splat),
+ kExprLocalSet, 2, // lhs (in local)
+ kExprLocalGet, 2, // push lhs
+ kExprLocalGet, 1,
+ ...SimdInstr(kExprI16x8Splat), // push rhs (temporary)
+ ...SimdInstr(kExprI16x8Q15MulRSatS),
+ ...SimdInstr(kExprI16x8ExtractLaneS), 0,
+ ])
+ .exportFunc();
+
+ const instance = builder.instantiate();
+ // (16384 * 8192 + 0x4000) >> 15 = 4096
+ // If miscompiled (lhs * lhs): (16384 * 16384 + 0x4000) >> 15 = 8192
+ assertEquals(4096, instance.exports.test_strict(16384, 8192));
+}
+
+// Test i16x8.relaxed_q15mulr_s when destination aliases rhs.
+{
+ const builder = new WasmModuleBuilder();
+ builder.addFunction('test_relaxed', makeSig([kWasmI32, kWasmI32], [kWasmI32]))
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ kExprLocalGet, 0,
+ ...SimdInstr(kExprI16x8Splat),
+ kExprLocalSet, 2, // lhs (in local)
+ kExprLocalGet, 2, // push lhs
+ kExprLocalGet, 1,
+ ...SimdInstr(kExprI16x8Splat), // push rhs (temporary)
+ kSimdPrefix, ...kExprI16x8RelaxedQ15MulRS,
+ ...SimdInstr(kExprI16x8ExtractLaneS), 0,
+ ])
+ .exportFunc();
+
+ const instance = builder.instantiate();
+ assertEquals(4096, instance.exports.test_relaxed(16384, 8192));
+}
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-549328680-2.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-549328680-2.js
new file mode 100644
index 00000000000..fc0009b9a74
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-549328680-2.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: --future-wasm-simd-opt --allow-natives-syntax
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+builder.addFunction('test', makeSig([], [kWasmI32]))
+ .addBody([
+ // Vector A = [0, 0, ...]
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // Vector B = [0, ..., 42] (byte 15 is 42)
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 42,
+ // S2 = shuffle(A, B, [0, 0, ..., 31]) -> S2[0] = 0, S2[15] = 42
+ kSimdPrefix, kExprI8x16Shuffle, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31,
+ // Vector Zero
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // S3 = shuffle(S2, Zero, [0, 15, 0, ...]) -> S3[0] = S2[0] = 0, S3[1] = S2[15] = 42
+ kSimdPrefix, kExprI8x16Shuffle, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // Vector Zero
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // S4 = shuffle(S3, Zero, [1, 0, 0, ...]) -> S4[0] = S3[1] = 42
+ kSimdPrefix, kExprI8x16Shuffle, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // Extract lane 0 -> Expected: 42
+ ...SimdInstr(kExprI8x16ExtractLaneU), 0,
+ ])
+ .exportFunc();
+
+let instance = builder.instantiate();
+assertEquals(42, instance.exports.test());
+%WasmTierUpFunction(instance.exports.test);
+assertEquals(42, instance.exports.test());
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-549328680.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-549328680.js
new file mode 100644
index 00000000000..493c2a816cc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-549328680.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: --future-wasm-simd-opt --allow-natives-syntax
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+let builder = new WasmModuleBuilder();
+builder.addFunction('test', makeSig([], [kWasmI32]))
+ .addBody([
+ // Vector A = [10, 0, 0, ...]
+ kSimdPrefix, kExprS128Const, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // Vector B = [0, ..., 30] (byte 15 = 30)
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 30,
+ // s1 = shuffle(A, B, [0, 31, 0, ...]) -> byte 0 = 10, byte 1 = 30
+ kSimdPrefix, kExprI8x16Shuffle, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // Vector Zero
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // s2 = shuffle(s1, Zero, [1, 0, ...]) -> byte 0 = 30, byte 1 = 10
+ kSimdPrefix, kExprI8x16Shuffle, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // Vector Zero
+ kSimdPrefix, kExprS128Const, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // s3 = shuffle(s2, Zero, [1, 0, ...]) -> byte 0 = 10, byte 1 = 30
+ kSimdPrefix, kExprI8x16Shuffle, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ // extract lane 0 -> must be 10
+ ...SimdInstr(kExprI8x16ExtractLaneU), 0,
+ ])
+ .exportFunc();
+
+let instance = builder.instantiate();
+assertEquals(10, instance.exports.test());
+%WasmTierUpFunction(instance.exports.test);
+assertEquals(10, instance.exports.test());
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-555760230.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-555760230.js
new file mode 100644
index 00000000000..28dfe7a51bf
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-555760230.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.
+
+// Flags: --wasm-revectorize --allow-natives-syntax
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/mjsunit.js');
+
+// Regression test: an unmasked splat index in wasm-revec-reducer.h caused an
+// out-of-bounds memory read when revectorizing a SIMD splat that reads lane 0
+// of the *second* input of a shuffle. The second input's load already points
+// at the right 128-bit vector, but the unmasked index (4 for 32-bit lanes)
+// added an extra 16 bytes to the address, reading past the end of memory.
+//
+// Two adjacent 16-byte stores (offsets 32 and 48) form the store seed that
+// triggers revectorization; both consume the same shuffle-splat result, so the
+// splat gets rewritten into a 256-bit load-transform where the bug lived.
+
+const builder = new WasmModuleBuilder();
+builder.addMemory(1, 1, false);
+builder.exportMemoryAs('memory');
+
+builder.addFunction('test', kSig_v_v)
+ .addLocals(kWasmS128, 1)
+ .addBody([
+ // Load 16 bytes from offset 0 (first shuffle input).
+ kExprI32Const, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+
+ // Load 16 bytes from offset 65520 -- the final 16 bytes of the single
+ // memory page (second shuffle input).
+ kExprI32Const, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, ...wasmUnsignedLeb(65520),
+
+ // Splat lane 0 of the second input (overall 32-bit lane index 4) across all
+ // lanes. Bytes 16..19 of the combined 32-byte shuffle map to the first
+ // 4 bytes of the second input, i.e. memory[65520..65523].
+ kSimdPrefix, kExprI8x16Shuffle,
+ 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19, 16, 17, 18, 19,
+
+ kExprLocalSet, 0,
+
+ // Two adjacent stores of the splat result -> revectorization seed.
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128StoreMem, 0, 48,
+
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128StoreMem, 0, 32,
+ ])
+ .exportFunc();
+
+const instance = builder.instantiate();
+const memory = new Uint8Array(instance.exports.memory.buffer);
+
+// Distinct source bytes so an off-by-16 read (which would land on the trailing
+// zero-filled bytes / out of bounds) produces a detectable mismatch.
+const kSource = [0xde, 0xad, 0xbe, 0xef];
+memory.set(kSource, 65520);
+
+// Execute baseline version first.
+instance.exports.test();
+
+// Tier up the function to trigger revectorization optimization.
+%WasmTierUpFunction(instance.exports.test);
+// This must not read out of bounds while revectorizing the splat.
+instance.exports.test();
+
+// The 32-bit lane at memory[65520..65523] must be splatted across the whole
+// 32-byte destination region [32, 64).
+for (let i = 32; i < 64; i++) {
+ assertEquals(kSource[i % 4], memory[i],
+ `byte at offset ${i} should be the splatted source lane`);
+}
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-555806042-2.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-555806042-2.js
new file mode 100644
index 00000000000..d7690eee37c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-555806042-2.js
@@ -0,0 +1,107 @@
+// 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-revectorize --allow-natives-syntax
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/mjsunit.js');
+
+// Test that revectorization handles a single load feeding two *different*
+// shuffle-splat patterns.
+//
+// 1. Load 16 bytes from offset 0 into local $val.
+// 2. Splat lane 0 of $val via shuffle into local $splat0.
+// 3. Splat lane 1 of $val via shuffle into local $splat1.
+// 4. Two adjacent stores of $splat0 (seed 1) and two adjacent stores of
+// $splat1 (seed 2) each independently trigger 256-bit revectorization,
+// both keyed off the same shared load.
+//
+// Each shuffle-splat pattern gets its own PackNode, but both share the same
+// underlying load. The revectorizer must emit a distinct vector
+// load-transform for each pattern rather than assuming a single load feeds
+// at most one shuffle pattern.
+
+const builder = new WasmModuleBuilder();
+builder.addMemory(1, 1, false);
+builder.exportMemoryAs('memory');
+
+builder.addFunction('test', kSig_v_v)
+ .addLocals(kWasmS128, 3)
+ .addBody([
+ // 1. Load 16 bytes from offset 0 into local 0
+ kExprI32Const, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalSet, 0,
+
+ // 2. Splat lane 0 (bytes 0-3) of local 0 into local 1
+ kExprLocalGet, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16Shuffle,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ kExprLocalSet, 1,
+
+ // 3. Splat lane 1 (bytes 4-7) of local 0 into local 2
+ kExprLocalGet, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16Shuffle,
+ 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7,
+ kExprLocalSet, 2,
+
+ // 4. Seed 1: two adjacent 128-bit stores of local 1 (higher offset
+ // first) -> revectorization seed for the first splat pattern.
+ kExprI32Const, 0,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128StoreMem, 0, 48,
+ kExprI32Const, 0,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128StoreMem, 0, 32,
+
+ // 5. Seed 2: two adjacent 128-bit stores of local 2 (higher offset
+ // first) -> revectorization seed for the second splat pattern, sharing
+ // the same load as seed 1.
+ kExprI32Const, 0,
+ kExprLocalGet, 2,
+ kSimdPrefix, kExprS128StoreMem, 0, 80,
+ kExprI32Const, 0,
+ kExprLocalGet, 2,
+ kSimdPrefix, kExprS128StoreMem, 0, 64,
+ ])
+ .exportFunc();
+
+const instance = builder.instantiate();
+const memory32 = new Int32Array(instance.exports.memory.buffer);
+
+const kLane0Value = 11;
+const kLane1Value = 22;
+
+function runAndCheck() {
+ memory32[0] = kLane0Value;
+ memory32[1] = kLane1Value;
+ instance.exports.test();
+
+ // Seed 1 (offsets 32 and 48) must hold lane 0, splatted.
+ for (const offset of [32, 48]) {
+ for (let lane = 0; lane < 4; lane++) {
+ assertEquals(kLane0Value, memory32[offset / 4 + lane],
+ `offset ${offset} lane ${lane} should hold lane 0 splat`);
+ }
+ }
+
+ // Seed 2 (offsets 64 and 80) must hold lane 1, splatted.
+ for (const offset of [64, 80]) {
+ for (let lane = 0; lane < 4; lane++) {
+ assertEquals(kLane1Value, memory32[offset / 4 + lane],
+ `offset ${offset} lane ${lane} should hold lane 1 splat`);
+ }
+ }
+}
+
+// Baseline execution (Liftoff / interpreter before tier-up).
+runAndCheck();
+
+// Trigger Turboshaft revectorization tier-up and re-verify. Prior to the
+// fix, this crashed with an UNREACHABLE hit in the Simd128Shuffle reducer,
+// because only one ShufflePackNode was tracked per shared load.
+%WasmTierUpFunction(instance.exports.test);
+runAndCheck();
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-555806042.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-555806042.js
new file mode 100644
index 00000000000..96def7c6ffc
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-555806042.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.
+
+// Flags: --wasm-revectorize --allow-natives-syntax
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/mjsunit.js');
+
+// Test that revectorization of a SIMD shuffle-splat into Simd256LoadTransform
+// does not reorder the memory load past an intervening store (RAW hazard).
+//
+// 1. Load 16 bytes from offset 0 into local $val (initial memory value: 42).
+// 2. Intervening store writes 99 into offset 0.
+// 3. Splat lane 0 of $val via shuffle (expected: 42 in all lanes).
+// 4. Two adjacent stores of the splat result trigger 256-bit revectorization.
+//
+// If revectorization delays the load to the shuffle site, it will read 99
+// instead of 42.
+
+const builder = new WasmModuleBuilder();
+builder.addMemory(1, 1, false);
+builder.exportMemoryAs('memory');
+
+builder.addFunction('test', kSig_v_v)
+ .addLocals(kWasmS128, 2)
+ .addBody([
+ // 1. Load 16 bytes from offset 0 into local 1
+ kExprI32Const, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalSet, 1,
+
+ // 2. Intervening store: write 99 to memory[0]
+ kExprI32Const, 0,
+ kExprI32Const, ...wasmSignedLeb(99),
+ kExprI32StoreMem, 0, 0,
+
+ // 3. Splat lane 0 of local 1 across all lanes of local 0
+ kExprLocalGet, 1,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprI8x16Shuffle,
+ 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3, 0, 1, 2, 3,
+ kExprLocalSet, 0,
+
+ // 4. Two adjacent 128-bit stores to offsets 32 and 48 -> revectorization seed
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128StoreMem, 0, 48,
+
+ kExprI32Const, 0,
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128StoreMem, 0, 32,
+ ])
+ .exportFunc();
+
+const instance = builder.instantiate();
+const memory = new Int32Array(instance.exports.memory.buffer);
+
+const kOriginalValue = 42;
+const kNewValue = 99;
+
+// Baseline execution (Liftoff / interpreter before tier-up)
+memory[0] = kOriginalValue;
+instance.exports.test();
+assertEquals(kOriginalValue, memory[32 / 4],
+ 'Baseline: splat must hold original value before store');
+
+// Reset memory and trigger Turboshaft revectorization tier-up
+memory[0] = kOriginalValue;
+%WasmTierUpFunction(instance.exports.test);
+instance.exports.test();
+
+// Under buggy revectorization, memory[32 / 4] gets populated with kNewValue (99)
+// instead of kOriginalValue (42).
+assertEquals(kOriginalValue, memory[32 / 4],
+ 'Optimized: memory load must NOT be reordered past intervening store');
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-557106111.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-557106111.js
new file mode 100644
index 00000000000..f5ae5f3662c
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-557106111.js
@@ -0,0 +1,103 @@
+// 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-revectorize --no-liftoff
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Regression test for https://crbug.com/557106111
+//
+// TryGetExtendIntToF32x4Info in src/compiler/turboshaft/wasm-revec-reducer.cc
+// matches the pattern
+//
+// f32x4.replace_lane 3 (f32x4.replace_lane 2 (f32x4.replace_lane 1
+// (f32x4.splat (f32.convert_i32 (i8x16.extract_lane 0 v))) ...)))
+//
+// and rewrites it into a single integer-to-float widening. It only checked
+// that lane 0 was *some* Simd128SplatOp, never that its kind was f32x4. An
+// f64x2.splat passed the remaining checks as well, because the ChangeOp
+// comparison only looks at the kind (kSignedToFloat) and not at the
+// representation, so Int32->Float64 compares equal to the lanes'
+// Int32->Float32.
+//
+// f64x2.splat(1.0) leaves the low 32 bits of lane 0 as 0, but the bogus
+// rewrite produced float(1) == 0x3f800000 there instead.
+
+let builder = new WasmModuleBuilder();
+builder.addMemory(1, 1, true);
+builder.exportMemoryAs('memory', 0);
+
+let main = builder.addFunction('main', kSig_v_v).exportFunc();
+main.addLocals(kWasmS128, 1);
+
+main.addBody([
+ // v = i8x16.splat(1)
+ kExprI32Const, 1,
+ kSimdPrefix, kExprI8x16Splat,
+ kExprLocalSet, 0,
+
+ // Store at offset 0. Lane 0 comes from an f64x2.splat rather than an
+ // f32x4.splat, so this is not an int-to-f32x4 extend.
+ kExprI32Const, 0,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 0,
+ kExprF64SConvertI32,
+ kSimdPrefix, kExprF64x2Splat,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 1,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4ReplaceLane, 1,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 2,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4ReplaceLane, 2,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 3,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4ReplaceLane, 3,
+
+ kSimdPrefix, kExprS128StoreMem, 0, 0,
+
+ // Store at offset 16. This one is a real int-to-f32x4 extend, and is
+ // adjacent to the first store so that the two get packed together.
+ kExprI32Const, 0,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 4,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4Splat,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 5,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4ReplaceLane, 1,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 6,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4ReplaceLane, 2,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprI8x16ExtractLaneS, 7,
+ kExprF32SConvertI32,
+ kSimdPrefix, kExprF32x4ReplaceLane, 3,
+
+ kSimdPrefix, kExprS128StoreMem, 0, 16,
+]);
+
+const instance = builder.instantiate();
+instance.exports.main();
+
+let mem = new DataView(instance.exports.memory.buffer);
+// Low 32 bits of the f64 1.0 splatted into lane 0. The bug replaced this with
+// float(1) == 0x3f800000. The high 32 bits of that f64 are overwritten by the
+// f32x4.replace_lane 1 below, so only lane 0 survives from the f64x2.splat.
+assertEquals(0, mem.getUint32(0, true));
+assertEquals(0x3f800000, mem.getUint32(4, true));
+assertEquals(0x3f800000, mem.getUint32(8, true));
+assertEquals(0x3f800000, mem.getUint32(12, true));
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-557107091.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-557107091.js
new file mode 100644
index 00000000000..491d52e13c5
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-557107091.js
@@ -0,0 +1,82 @@
+// 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-revectorize --no-liftoff
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+// Regression test for https://crbug.com/557107091
+//
+// TryMatchExtendIntToF32x4 in src/compiler/turboshaft/wasm-revec-reducer.cc
+// compared the two halves' start lanes using min/max, which discards which of
+// node_group[0] / node_group[1] extends from the lower four lanes.
+//
+// That order matters: the group is revectorized into a single in-order 256-bit
+// widening, and GetExtractOpIfNeeded picks the half by the node's position in
+// the pack node group, so node_group[0] always receives lanes start..start+3.
+//
+// Here the store to offset 16 takes lanes 4..7 and the store to offset 32
+// takes lanes 0..3, but the stores are packed in address order. The reversed
+// pair was accepted with start_lane pinned to the minimum, so each store
+// received the other store's half.
+
+const builder = new WasmModuleBuilder();
+builder.addMemory(1, 1);
+builder.exportMemoryAs('memory', 0);
+
+function make_extract_convert_f32x4(local_idx, start_lane) {
+ let insts = [];
+
+ // lane 0: f32x4.splat(f32.convert_i32_s(i16x8.extract_lane_s(start_lane)))
+ insts.push(kExprLocalGet, local_idx);
+ insts.push(kSimdPrefix, kExprI16x8ExtractLaneS, start_lane);
+ insts.push(kExprF32SConvertI32);
+ insts.push(kSimdPrefix, kExprF32x4Splat);
+
+ for (let lane = 1; lane < 4; lane++) {
+ insts.push(kExprLocalGet, local_idx);
+ insts.push(kSimdPrefix, kExprI16x8ExtractLaneS, start_lane + lane);
+ insts.push(kExprF32SConvertI32);
+ insts.push(kSimdPrefix, kExprF32x4ReplaceLane, lane);
+ }
+
+ return insts;
+}
+
+builder.addFunction('test', kSig_v_v).addLocals(kWasmS128, 1)
+ .addBody([
+ // local 0 = i16x8 loaded from offset 0.
+ kExprI32Const, 0,
+ kSimdPrefix, kExprS128LoadMem, 4, 0,
+ kExprLocalSet, 0,
+
+ // Store to the lower address takes the *upper* four lanes ...
+ kExprI32Const, 0,
+ ...make_extract_convert_f32x4(0, 4),
+ kSimdPrefix, kExprS128StoreMem, 4, 16,
+
+ // ... and the store to the higher address takes the lower four lanes.
+ kExprI32Const, 0,
+ ...make_extract_convert_f32x4(0, 0),
+ kSimdPrefix, kExprS128StoreMem, 4, 32,
+ ]).exportFunc();
+
+const instance = builder.instantiate();
+const mem = new DataView(instance.exports.memory.buffer);
+
+for (let i = 0; i < 8; i++) mem.setInt16(2 * i, 10 * (i + 1), true);
+
+instance.exports.test();
+
+// Offset 16 holds lanes 4..7. The bug stored lanes 0..3 here instead.
+assertEquals(50, mem.getFloat32(16, true));
+assertEquals(60, mem.getFloat32(20, true));
+assertEquals(70, mem.getFloat32(24, true));
+assertEquals(80, mem.getFloat32(28, true));
+
+// Offset 32 holds lanes 0..3.
+assertEquals(10, mem.getFloat32(32, true));
+assertEquals(20, mem.getFloat32(36, true));
+assertEquals(30, mem.getFloat32(40, true));
+assertEquals(40, mem.getFloat32(44, true));
diff --git a/deps/v8/test/mjsunit/regress/wasm/regress-simd-557107349.js b/deps/v8/test/mjsunit/regress/wasm/regress-simd-557107349.js
new file mode 100644
index 00000000000..7c069d14a70
--- /dev/null
+++ b/deps/v8/test/mjsunit/regress/wasm/regress-simd-557107349.js
@@ -0,0 +1,98 @@
+// 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 --wasm-revectorize
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+let builder = new WasmModuleBuilder();
+builder.addMemory(16, 16);
+builder.addType(makeSig([], []));
+let sig = builder.addType(makeSig([kWasmI32], []));
+
+let N = 20;
+
+let func = builder.addFunction("test", sig)
+ .addLocals(kWasmS128, N + 10)
+ .exportFunc();
+
+let body = [];
+
+// param1 is local 0.
+let temp1 = 1;
+let temp2 = 2;
+let temp3 = 3;
+let dag_start = 4;
+
+// temp1 = I16x8Splat(10)
+body.push(
+ kExprI32Const, 10,
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8Splat),
+ kExprLocalSet, temp1
+);
+
+// temp2 = I16x8Neg(I16x8Abs(I16x8SConvertI8x16Low(temp1)))
+body.push(
+ kExprLocalGet, temp1,
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8SConvertI8x16Low),
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8Abs),
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8Neg),
+ kExprLocalSet, temp2
+);
+
+// temp3 = I8x16ReplaceLane(temp1, 1)
+body.push(
+ kExprLocalGet, temp1,
+ kExprI32Const, 1,
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI8x16ReplaceLane), 2,
+ kExprLocalSet, temp3
+);
+
+let curr = temp3;
+for (let i = 0; i < N; i++) {
+ let next = dag_start + i;
+ body.push(
+ kExprLocalGet, curr,
+ kExprLocalGet, curr,
+ kExprLocalGet, curr,
+ kSimdPrefix, kExprS128Select,
+ kExprLocalSet, next
+ );
+ curr = next;
+}
+let temp4_input = curr;
+let temp4 = dag_start + N;
+
+// temp4 = I16x8Neg(I16x8Abs(I16x8SConvertI8x16Low(temp4_input)))
+body.push(
+ kExprLocalGet, temp4_input,
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8SConvertI8x16Low),
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8Abs),
+ kSimdPrefix, ...wasmUnsignedLeb(kExprI16x8Neg),
+ kExprLocalSet, temp4
+);
+
+// Store temp4 and temp2 adjacently to force pack them.
+body.push(
+ kExprLocalGet, 0, // param1
+ kExprLocalGet, temp4, // The later one
+ kSimdPrefix, ...wasmUnsignedLeb(kExprS128StoreMem), 0, 0,
+
+ kExprLocalGet, 0, // param1
+ kExprLocalGet, temp2, // The earlier one
+ kSimdPrefix, ...wasmUnsignedLeb(kExprS128StoreMem), 0, 16,
+);
+
+func.addBody(body);
+
+let instance = builder.instantiate();
+instance.exports.test(0);
+
+// The chain of S128Select nodes above forms a diamond-shaped DAG: each level
+// reuses the same predecessor as all 3 of its inputs. Revectorization's
+// ReduceInputsOfOp() does a BFS over the input tree rooted at the packed
+// store nodes; if it doesn't dedupe an OpIndex before (rather than after)
+// enqueueing it, that DAG causes an exponential (3^N) blowup and hangs.
+%WasmTierUpFunction(instance.exports.test);
+instance.exports.test(0);
diff --git a/deps/v8/test/mjsunit/sandbox/regress-530292681.js b/deps/v8/test/mjsunit/sandbox/regress-530292681.js
new file mode 100644
index 00000000000..132dea94f51
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-530292681.js
@@ -0,0 +1,61 @@
+// 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 --regexp-tier-up-ticks=1
+
+// 1. Build a RegExp with 1560 capture groups so that capture group 1550
+// corresponds to result vector offset 0x3070 (elements 3100 and 3101).
+const pattern = '()'.repeat(1549) + '(.*)' +
+ '()'.repeat(11);
+const re = new RegExp(pattern);
+
+const workerScript = `
+ load('test/mjsunit/mjsunit.js');
+
+ const re = ` +
+ re.toString() + `;
+
+ // Prime tier-up with a 65-character OneByte string.
+ // Group 1550 matches the 65 characters and populates output[3101] = 65.
+ re.exec('a'.repeat(65));
+
+ // Prepare a TwoByte string for the next execution.
+ const subject = %FlattenString(('foo' + String.fromCharCode(0x1234))
+ .repeat(5000));
+ const oneByteSample = %FlattenString('bar'.repeat(7000));
+ const mem = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+ const oneByteMap = mem.getUint32(Sandbox.getAddressOf(oneByteSample), true);
+
+ postMessage({
+ subjectAddr: Sandbox.getAddressOf(subject),
+ oneByteMap: oneByteMap
+ });
+
+ onmessage = function() {
+ const result = re.exec(subject);
+ assertEquals(subject, result[1550]);
+ postMessage("done");
+ };
+`;
+
+const w = new Worker(workerScript, {type: 'string'});
+const msg = w.getMessage();
+
+%BlockAt('IrregexpExecRaw_JIT', 5000);
+w.postMessage('go');
+assertTrue(%WaitUntilBlocked('IrregexpExecRaw_JIT', 5000));
+
+// Mutate the subject string's map from TwoByte to OneByte while blocked.
+const mem = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+mem.setUint32(msg.subjectAddr, msg.oneByteMap, true);
+
+// Resume the worker.
+// Without the fix, NativeRegExpMacroAssembler::Execute re-derived is_one_byte
+// from the mutated subject, loading latin1_code_ (RegExpInterpreterTrampoline)
+// and invoking it via the C++ ABI, causing a wild jump outside the sandbox
+// (0x4100000000). With the fix, is_one_byte is passed through from
+// EnsureCompiledIrregexp, ensuring the compiled native code is invoked, and an
+// SBXCHECK guarantees that the code is CodeKind::REGEXP.
+assertTrue(%Resume('IrregexpExecRaw_JIT'));
+assertEquals('done', w.getMessage());
diff --git a/deps/v8/test/mjsunit/sandbox/regress-535892918.js b/deps/v8/test/mjsunit/sandbox/regress-535892918.js
new file mode 100644
index 00000000000..011299099ae
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-535892918.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: --sandbox-testing
+
+let mem1 = new WebAssembly.Memory(
+ {initial: 2, maximum: 20077, shared: true, address: 'i32'});
+let mem2 = new WebAssembly.Memory(
+ {initial: 2, maximum: 20077, shared: true, address: 'i32'});
+
+// mem1/mem2's managed_backing_store is located at offset 16
+let managed1 = Sandbox.readObjectField(mem1, 16);
+let managed2 = Sandbox.readObjectField(mem2, 16);
+
+// Untag the pointers to the TrustedManaged objects
+let addr1 = managed1 - 1;
+let addr2 = managed2 - 1;
+
+let view1 = new DataView(new Sandbox.MemoryView(addr1, 16));
+let view2 = new DataView(new Sandbox.MemoryView(addr2, 16));
+
+// The 32-bit EPT handle is at offset 4 of the Foreign object
+let handle2 = view2.getUint32(4, true);
+
+// Overwrite mem1's handle with mem2's EPT handle
+view1.setUint32(4, handle2, true);
+
+// Drop mem2 so it becomes eligible for Garbage Collection
+mem2 = null;
+managed2 = null;
+view2 = null;
+
+let arrs = [];
+// Grow memory to push V8 closer to the external memory limit.
+// We simultaneously do Wasm memory growth and external ArrayBuffer
+// allocation. Eventually, `mem1.grow()` will hit the exact threshold
+// during its `UpdateEstimatedSize()` step and trigger a Garbage Collection.
+// That GC sweeps the unreachable `mem2` and frees its ManagedPtrDestructor.
+// When the GC returns, `UpdateEstimatedSize()` executes a UAF write on it!
+for (let i = 0; i < 1000; i++) {
+ mem1.grow(10);
+ arrs.push(new ArrayBuffer(1024 * 1024));
+}
diff --git a/deps/v8/test/mjsunit/sandbox/regress-540033151.js b/deps/v8/test/mjsunit/sandbox/regress-540033151.js
new file mode 100644
index 00000000000..5c7645adfae
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-540033151.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: --sandbox-testing --expose-gc
+
+// Regression test for issue 540033151:
+// A sandbox attacker copies an ArrayBufferExtension handle (tagged with
+// kArrayBufferExtensionTag) into an external pointer slot expecting a
+// different tag (e.g. Foreign::foreign_address_ with
+// kAnyForeignExternalPointerTagRange).
+// Marking and evacuation in the ExternalPointerTable must validate that the
+// entry's tag matches slot.tag_range(), safely trapping any mismatch via
+// SBXCHECK.
+
+let ab = new ArrayBuffer(64);
+let abTypeId = Sandbox.getInstanceTypeIdOf(ab);
+let extOffset = Sandbox.getFieldOffset(abTypeId, "extension");
+let mem = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+let extHandle = mem.getUint32(Sandbox.getAddressOf(ab) + extOffset, true);
+
+let marker = {};
+let p = import("data:text/javascript,export const a = 1;");
+let markerAddr = Sandbox.getAddressOf(marker);
+let foreignAddr = 0;
+for (let i = 0; i < 4000; i += 4) {
+ let a = (markerAddr + i) >>> 0;
+ if (Sandbox.isValidObjectAt(a)) {
+ if (Sandbox.getInstanceTypeOfObjectAt(a) === "FOREIGN_TYPE") {
+ foreignAddr = a;
+ break;
+ }
+ }
+}
+assertTrue(foreignAddr !== 0);
+
+let foreignOffset = Sandbox.getFieldOffset(
+ Sandbox.getInstanceTypeIdFor("FOREIGN_TYPE"), "foreign_address");
+
+// Overwrite Foreign's foreign_address with ArrayBuffer's extension handle.
+mem.setUint32(foreignAddr + foreignOffset, extHandle, true);
+
+globalThis.ab = ab;
+globalThis.p = p;
+
+// Major GC visits Foreign and attempts to mark the EPT entry with
+// kAnyForeignExternalPointerTagRange. The mismatch against
+// kArrayBufferExtensionTag must trigger an SBXCHECK trap.
+gc({type: "major"});
+
+assertUnreachable("Cross-tag external pointer table aliasing should be trapped by SBXCHECK");
diff --git a/deps/v8/test/mjsunit/sandbox/regress-554034656.js b/deps/v8/test/mjsunit/sandbox/regress-554034656.js
new file mode 100644
index 00000000000..f50efc54df3
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress-554034656.js
@@ -0,0 +1,39 @@
+// 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
+
+// 65,536 wrapped parameters make the uint16 parameter count wrap to one,
+// while assigning parameter 65,535 writes outside the native argument frame.
+
+const source = 'function victim(){' + ' '.repeat(64) + 'return 0;}';
+(0, eval)(source); // Leave the zero-parameter victim lazily compiled.
+
+const target = globalThis.victim;
+const names = Array.from({length: 0x10000}, (_, i) => 'p' + i);
+const replacement = (' '.repeat('function victim'.length) + 'p65535=1;')
+ .padEnd(source.length, ' ');
+
+const sfi = Sandbox.dereferenceTaggedPointerField(
+ target, 'shared_function_info');
+const script = Sandbox.dereferenceTaggedPointerField(sfi, 'script');
+const elements = Sandbox.dereferenceTaggedPointerField(names, 'elements');
+const offsetOf = (object, field) => Sandbox.getFieldOffset(
+ Sandbox.getInstanceTypeIdOf(object), field);
+
+// Derive otherwise-unexposed fields from neighboring supported API fields.
+const sfiFlags = offsetOf(sfi, 'formal_parameter_count') + 6;
+const scriptPosition = offsetOf(script, 'wasm_managed_native_module');
+const scriptSource = scriptPosition - 36;
+const wrappedArguments = scriptPosition - 4;
+const oldFlags = Sandbox.readObjectField(sfi, sfiFlags, 32);
+const wrappedFlags = ((oldFlags & ~(7 << 7)) | (4 << 7)) >>> 0;
+const tagged = object => (Sandbox.getAddressOf(object) + 1) >>> 0;
+
+// Only these three writes modify memory inside the V8 sandbox.
+Sandbox.corruptObjectField(script, scriptSource, tagged(replacement), 32);
+Sandbox.corruptObjectField(script, wrappedArguments, tagged(elements), 32);
+Sandbox.corruptObjectField(sfi, sfiFlags, wrappedFlags, 32);
+
+assertThrows(() => target(), SyntaxError);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-512160117.js b/deps/v8/test/mjsunit/sandbox/regress/regress-512160117.js
index f2390bd6682..85bd9a8217a 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 < 10; i++) {
+for (let i = 0; i < 11; i++) {
let o = {x: 42};
o['p' + i] = i;
load(o);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-532204454.js b/deps/v8/test/mjsunit/sandbox/regress/regress-532204454.js
new file mode 100644
index 00000000000..00423006264
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-532204454.js
@@ -0,0 +1,90 @@
+// 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 --use-external-strings
+
+const kStateIdx = 0;
+const kTargetAddressIdx = 1;
+const kTargetValueIdx = 2;
+
+let sab;
+for (let i = 0; i < 100; i++) {
+ sab = new SharedArrayBuffer(64);
+ if (Sandbox.getAddressOf(sab) % 8 === 0) break;
+}
+
+let flag = new BigInt64Array(sab);
+let worker = new Worker(`
+ const kStateIdx = 0;
+ const kTargetAddressIdx = 1;
+ const kTargetValueIdx = 2;
+
+ onmessage = function(msg) {
+ let sab = msg.data;
+ let flag = new BigInt64Array(sab);
+ let mem = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+ postMessage("ready");
+ while (true) {
+ while (Atomics.load(flag, kStateIdx) !== 1n) {
+ if (Atomics.load(flag, kStateIdx) === -1n) return;
+ }
+ let addr = Number(Atomics.load(flag, kTargetAddressIdx));
+ let val = Number(Atomics.load(flag, kTargetValueIdx));
+
+ while (Atomics.load(flag, kStateIdx) === 1n) {
+ mem.setUint32(addr, val, true);
+ }
+ }
+ };
+`, {type: 'string'});
+
+worker.postMessage(sab);
+worker.getMessage(); // wait for ready
+
+let mem = new DataView(new Sandbox.MemoryView(0, 0x100000000));
+
+let max_delay = 10000000;
+let steps = 200;
+let step_size = max_delay / steps;
+
+for (let iter = 0; iter < steps; iter++) {
+ let main_delay = Math.max(0, max_delay - iter * step_size);
+
+ let content1 = read("/etc/passwd");
+ let content2 = read("/etc/passwd");
+
+ let resource_offset = Sandbox.getFieldOffset(
+ Sandbox.getInstanceTypeIdOf(content1), "resource");
+
+ let addr1 = Sandbox.getAddressOf(content1);
+ let addr2 = Sandbox.getAddressOf(content2);
+
+ let handle1 = mem.getUint32(addr1 + resource_offset, true);
+ let handle2 = mem.getUint32(addr2 + resource_offset, true);
+
+ mem.setUint32(addr1 + resource_offset, handle2, true);
+
+ Atomics.store(flag, kTargetAddressIdx, BigInt(addr1 + resource_offset));
+ Atomics.store(flag, kTargetValueIdx, BigInt(handle1));
+ Atomics.store(flag, kStateIdx, 1n);
+
+ let x = 0;
+ for (let d = 0; d < main_delay; d++) { x += d; }
+
+ let obj = {};
+ obj[content1] = 42;
+
+ Atomics.store(flag, kStateIdx, 0n);
+
+ try {
+ let len = content2.length;
+ let char = content2.charCodeAt(0);
+
+ for(let i=0; i < 0x1000; i++) {
+ let check = content2.charCodeAt(i);
+ }
+ } catch(e) {}
+}
+
+Atomics.store(flag, kStateIdx, -1n);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-546253900.js b/deps/v8/test/mjsunit/sandbox/regress/regress-546253900.js
new file mode 100644
index 00000000000..f609f607f66
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-546253900.js
@@ -0,0 +1,121 @@
+// 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 CAGE_VIEW_SIZE = 0x100000000;
+const memv = new DataView(new Sandbox.MemoryView(0, CAGE_VIEW_SIZE));
+
+const u32 = (address) => memv.getUint32(address, true);
+const w32 = (address, value) => memv.setUint32(address, value, true);
+const u64 = (address) => memv.getBigUint64(address, true);
+
+// JSArrayBuffer layout tail:
+// raw_byte_length_ (bounded size, 8) | raw_max_byte_length_ (8)
+// | backing_store_ (sandboxed ptr, 8) | extension_ (EPT handle, 4)
+// Bounded sizes are stored shifted left by kBoundedSizeShift == 29.
+function findArrayBufferExtensionOffset() {
+ const length = 0x41410;
+ const probe = new ArrayBuffer(length);
+ const address = Sandbox.getAddressOf(probe);
+ const size = Sandbox.getSizeOf(probe);
+ const encodedLength = BigInt(length) << 29n;
+ for (let offset = 0; offset + 8 <= size; offset += 4) {
+ if (u64(address + offset) === encodedLength) return offset + 24;
+ }
+ throw new Error("could not locate JSArrayBuffer::extension_");
+}
+
+// WasmMemoryObject layout:
+// ... | array_buffer_ (tagged, 4) | managed_backing_store_ (tagged, 4) | ...
+function findWasmMemoryFieldOffsets(memory) {
+ const address = Sandbox.getAddressOf(memory);
+ const size = Sandbox.getSizeOf(memory);
+ const taggedBuffer = (Sandbox.getAddressOf(memory.buffer) + 1) >>> 0;
+ for (let offset = 0; offset + 4 <= size; offset += 4) {
+ if (u32(address + offset) === taggedBuffer) {
+ return {
+ arrayBuffer: offset,
+ managedBackingStore: offset + 4,
+ };
+ }
+ }
+ throw new Error("could not locate WasmMemoryObject::array_buffer_");
+}
+
+const extensionOffset = findArrayBufferExtensionOffset();
+
+// A is transported to the worker but deliberately left unregistered.
+const memoryA =
+ new WebAssembly.Memory({initial: 1, maximum: 16, shared: true});
+// B is the genuine same-tag decoy selected by the substituted extension.
+const memoryB =
+ new WebAssembly.Memory({initial: 1, maximum: 16, shared: true});
+// The keeper roots A's original CppGCManaged<BackingStore> wrapper while the
+// DCHECK build temporarily points memoryA at memoryB's wrapper.
+const keeper =
+ new WebAssembly.Memory({initial: 1, maximum: 16, shared: true});
+
+const sabA = memoryA.buffer;
+const sabB = memoryB.buffer;
+
+const fieldsA = findWasmMemoryFieldOffsets(memoryA);
+const fieldsB = findWasmMemoryFieldOffsets(memoryB);
+const fieldsKeeper = findWasmMemoryFieldOffsets(keeper);
+
+const sabAAddress = Sandbox.getAddressOf(sabA);
+const sabBAddress = Sandbox.getAddressOf(sabB);
+const memoryAAddress = Sandbox.getAddressOf(memoryA);
+const memoryBAddress = Sandbox.getAddressOf(memoryB);
+const keeperAddress = Sandbox.getAddressOf(keeper);
+
+const savedExtension = u32(sabAAddress + extensionOffset);
+const savedManaged =
+ u32(memoryAAddress + fieldsA.managedBackingStore);
+
+function substituteBackingStoreB() {
+ w32(sabAAddress + extensionOffset, u32(sabBAddress + extensionOffset));
+
+ // These tagged writes satisfy the DCHECK in WasmMemoryObject::GetArrayBuffer()
+ // for dcheck_always_on builds.
+ w32(keeperAddress + fieldsKeeper.managedBackingStore, savedManaged);
+ w32(memoryAAddress + fieldsA.managedBackingStore,
+ u32(memoryBAddress + fieldsB.managedBackingStore));
+}
+
+function restoreBackingStoreA() {
+ w32(sabAAddress + extensionOffset, savedExtension);
+ w32(memoryAAddress + fieldsA.managedBackingStore,
+ u32(keeperAddress + fieldsKeeper.managedBackingStore));
+}
+
+const workerSource = `
+ onmessage = function(event) {
+ postMessage("attached");
+ };
+`;
+
+const worker = new Worker(workerSource, {type: "string"});
+
+worker.postMessage({
+ // The delegate sees sabA first and memoizes backing store A by object identity.
+ a: sabA,
+ get b() {
+ // In-cage mutation: swaps extension handle to B during serialization.
+ substituteBackingStoreB();
+ return memoryA;
+ },
+});
+
+worker.getMessage();
+
+restoreBackingStoreA();
+
+// On worker teardown, Purge() must find and remove the worker isolate from
+// backing store A since it was registered upon deserialization.
+worker.terminateAndWait();
+
+// If backing store A was registered properly, this grow() call will not
+// dereference a dangling worker Isolate pointer.
+memoryA.grow(1);
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-561655173-completion.js b/deps/v8/test/mjsunit/sandbox/regress/regress-561655173-completion.js
new file mode 100644
index 00000000000..5ab69746a73
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-561655173-completion.js
@@ -0,0 +1,137 @@
+// 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: --expose-memory-corruption-api --expose-gc --expose-async-hooks
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/sandbox/wasm-jspi.js');
+
+const rejectOffset =
+ Sandbox.getFieldOffset(kPromiseReaction, 'reject_handler');
+
+function handler(promise, reject = false) {
+ const reaction = getField(getPtr(promise), kJSPromiseReactionsOrResultOffset);
+ const offset = reject ? rejectOffset : kPromiseReactionFulfillHandlerOffset;
+ return Sandbox.getObjectAt(getField(reaction, offset));
+}
+
+function makeWasm(body, imported) {
+ const builder = new WasmModuleBuilder();
+ builder.addImport('m', 's', kSig_i_v);
+ builder.addFunction('f', kSig_i_v).addBody(body).exportFunc();
+ return builder.instantiate({m: {s: new WebAssembly.Suspending(imported)}})
+ .exports.f;
+}
+
+const once = [kExprCallFunction, 0];
+const twice = [...once, kExprDrop, ...once];
+const caught = [
+ kExprTry, kWasmI32, ...once,
+ kExprCatchAll, ...wasmI32Const(73),
+ kExprEnd
+];
+
+function start(body = once) {
+ const pending = [];
+ const f = makeWasm(body, () => {
+ const promise = new Promise(() => {});
+ pending.push(promise);
+ return promise;
+ });
+ return {pending, result: WebAssembly.promising(f)()};
+}
+
+function invoke(callback, value) {
+ return value instanceof {[Symbol.hasInstance]: callback};
+}
+
+const sync = WebAssembly.promising(makeWasm([kExprI32Const, 42], () => 0));
+assertPromiseResult(sync(), value => assertEquals(42, value));
+const reason = {};
+const throws = WebAssembly.promising(makeWasm(once, () => { throw reason; }));
+assertPromiseResult(throws(), assertUnreachable,
+ value => assertSame(reason, value));
+
+{
+ const state = start();
+ assertFalse(invoke(handler(state.pending[0]), 42));
+ assertPromiseResult(state.result, value => assertEquals(42, value));
+}
+{
+ const state = start();
+ assertEquals(undefined, handler(state.pending[0])(42));
+ assertPromiseResult(state.result, value => assertEquals(42, value));
+}
+{
+ const state = start();
+ assertEquals(undefined, handler(state.pending[0], true)(reason));
+ assertPromiseResult(state.result, assertUnreachable,
+ value => assertSame(reason, value));
+}
+{
+ const state = start(caught);
+ assertFalse(invoke(handler(state.pending[0], true), reason));
+ assertPromiseResult(state.result, value => assertEquals(73, value));
+}
+{
+ const state = start(twice);
+ assertFalse(invoke(handler(state.pending[0]), 1));
+ assertEquals(2, state.pending.length);
+ assertFalse(invoke(handler(state.pending[1]), 42));
+ assertPromiseResult(state.result, value => assertEquals(42, value));
+}
+
+// A resolve hook can switch stacks again and replace the parent's jump buffer.
+// It must not replace the return address of the outer completion/rejection.
+function testReentry(reject, installHook) {
+ let state;
+ let nested;
+ let hookCount = 0;
+ const disable = installHook(promise => {
+ if (!state || promise !== state.result) return;
+ hookCount++;
+ gc();
+ nested = sync();
+ });
+ try {
+ state = start();
+ assertFalse(invoke(handler(state.pending[0], reject), 42));
+ } finally {
+ disable();
+ }
+ assertEquals(1, hookCount);
+ assertPromiseResult(nested, value => assertEquals(42, value));
+ const check = value => assertEquals(42, value);
+ if (reject) {
+ assertPromiseResult(state.result, assertUnreachable, check);
+ } else {
+ assertPromiseResult(state.result, check);
+ }
+}
+
+// RejectPromise invokes the embedder hook on all d8 configurations.
+testReentry(true, resolve => {
+ const promises = new Map();
+ const hook = async_hooks.createHook({
+ init(id, type, triggerId, promise) { promises.set(id, promise); },
+ promiseResolve(id) { resolve(promises.get(id)); }
+ });
+ hook.enable();
+ return () => hook.disable();
+});
+
+// Direct fulfillment invokes the optional JavaScript context hook.
+let hasContextHooks = false;
+try {
+ d8.promise.setHooks();
+ hasContextHooks = true;
+} catch {}
+if (hasContextHooks) {
+ for (const reject of [false, true]) {
+ testReentry(reject, resolve => {
+ d8.promise.setHooks(undefined, undefined, undefined, resolve);
+ return () => d8.promise.setHooks();
+ });
+ }
+}
diff --git a/deps/v8/test/mjsunit/sandbox/regress/regress-561655173.js b/deps/v8/test/mjsunit/sandbox/regress/regress-561655173.js
new file mode 100644
index 00000000000..8ddadc74c85
--- /dev/null
+++ b/deps/v8/test/mjsunit/sandbox/regress/regress-561655173.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: --sandbox-testing
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+d8.file.execute('test/mjsunit/sandbox/wasm-jspi.js');
+
+function get_resume(promise) {
+ let promise_ptr = getPtr(promise);
+ let reaction = getField(promise_ptr, kJSPromiseReactionsOrResultOffset);
+ return Sandbox.getObjectAt(
+ getField(reaction, kPromiseReactionFulfillHandlerOffset));
+}
+
+let pending;
+let builder = new WasmModuleBuilder();
+let imp_idx = builder.addImport('m', 's', kSig_v_v);
+builder.addFunction('f', kSig_v_v)
+ .addBody([kExprCallFunction, imp_idx])
+ .exportFunc();
+let instance = builder.instantiate({
+ m: {s: new WebAssembly.Suspending(() => pending = new Promise(() => {}))}
+});
+let call = WebAssembly.promising(instance.exports.f);
+call();
+
+let resume = get_resume(pending);
+let rhs = {[Symbol.hasInstance]: resume.bind(null, 0x21212121, 0x22222222)};
+let unused = 0x21212121 instanceof rhs;
+
+assertUnreachable('Over-applied WasmResume call should trap');
diff --git a/deps/v8/test/mjsunit/sealed-array-reduce.js b/deps/v8/test/mjsunit/sealed-array-reduce.js
index cb753ba3ad6..cf8c98e166f 100644
--- a/deps/v8/test/mjsunit/sealed-array-reduce.js
+++ b/deps/v8/test/mjsunit/sealed-array-reduce.js
@@ -705,6 +705,7 @@ assertEquals(undefined, Object.seal(arr).reduceRight(function(val) { return val
})();
(function ReduceCatch() {
+ let array = [1, '2', 3];
let f = (a,current) => {
return a + current;
};
@@ -1068,6 +1069,7 @@ assertEquals(undefined, Object.seal(arr).reduceRight(function(val) { return val
})();
(function ReduceCatch() {
+ let array = [1, '2', 3];
let f = (a,current) => {
return a + Number(current);
};
diff --git a/deps/v8/test/mjsunit/shared-memory/regress/regress-541880797.js b/deps/v8/test/mjsunit/shared-memory/regress/regress-541880797.js
new file mode 100644
index 00000000000..f3005b299b9
--- /dev/null
+++ b/deps/v8/test/mjsunit/shared-memory/regress/regress-541880797.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: --harmony-struct
+
+let MyStruct = new SharedStructType(['field']);
+let obj = new MyStruct();
+assertThrows(() => Function[Symbol.hasInstance].call(MyStruct, obj),
+ TypeError, /Function has non-object prototype 'null'/);
diff --git a/deps/v8/test/mjsunit/string-localecompare-inline.js b/deps/v8/test/mjsunit/string-localecompare-inline.js
index 71915bc86e0..caf47f7130b 100644
--- a/deps/v8/test/mjsunit/string-localecompare-inline.js
+++ b/deps/v8/test/mjsunit/string-localecompare-inline.js
@@ -116,3 +116,40 @@ check(long_a, long_a, 0);
// Tagged-equal long string (pointer-eq path after type guards).
const long_eq = "Aircraft ".repeat(8);
check(long_eq, long_eq, 0);
+
+// --- Constant operands. A string literal is baked into the code as a
+// constant, so the compiler knows its shape and guards accordingly. Feed the
+// other shapes in as arguments: each must reach the builtin instead of being
+// walked as one-byte characters.
+function constCmp(x) { return "Aircraft 0".localeCompare(x); }
+%PrepareFunctionForOptimization(constCmp);
+constCmp("Aircraft 1");
+constCmp("Aircraft 1");
+%OptimizeFunctionOnNextCall(constCmp);
+// Several of these have equal content and differ only in shape, so the shape
+// is what the failure message has to name.
+for (const [shape, arg] of [["seq one-byte", "Aircraft 1"],
+ ["equal content", "Aircraft 0"],
+ ["two-byte", "Aircraft 中"],
+ ["cons", "Air" + "craft 1"],
+ ["sliced", "xAircraft 1".substring(1)]]) {
+ assertEquals(Math.sign(unopt("Aircraft 0", arg)), Math.sign(constCmp(arg)),
+ `constCmp(${shape})`);
+}
+
+// Two-byte constant receiver, which the inline can never handle. The
+// character must be outside Latin-1 ("café" is still stored one-byte) and
+// must come first, since reading a two-byte body as one-byte only changes
+// the answer once the walk reaches it.
+const kTwoByte = "中af";
+function constTwoByte(x) { return "中af".localeCompare(x); }
+%PrepareFunctionForOptimization(constTwoByte);
+constTwoByte("zzz");
+constTwoByte("zzz");
+%OptimizeFunctionOnNextCall(constTwoByte);
+for (let c = 0; c < 128; c++) {
+ const arg = String.fromCharCode(c) + "af";
+ assertEquals(Math.sign(unopt(kTwoByte, arg)), Math.sign(constTwoByte(arg)),
+ `constTwoByte(${JSON.stringify(arg)})`);
+}
+assertEquals(0, constTwoByte(kTwoByte));
diff --git a/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log b/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log
index 32f8ac8a60b..18f86de1f63 100644
--- a/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log
+++ b/deps/v8/test/mjsunit/tools/tickprocessor-test-large.log
@@ -468,10 +468,10 @@ tick,0x7f3662e68f6f,9690,0,0x0,6
tick,0x7f3662dfac6d,9705,0,0x0,6
tick,0x5574259875be,9719,0,0x0,6
code-creation,Builtin,2,9734,0x5574263758e0,1204,GreaterThanOrEqual_WithFeedback
-code-creation,Builtin,2,9748,0x557426375da0,448,BitwiseNot_Baseline
-code-creation,Builtin,2,9757,0x557426375f80,448,Decrement_Baseline
-code-creation,Builtin,2,9766,0x557426376160,448,Increment_Baseline
-code-creation,Builtin,2,9774,0x557426376340,472,Negate_Baseline
+code-creation,Builtin,2,9748,0x557426375da0,448,BitwiseNot_Generic_Baseline
+code-creation,Builtin,2,9757,0x557426375f80,448,Decrement_Generic_Baseline
+code-creation,Builtin,2,9766,0x557426376160,448,Increment_Generic_Baseline
+code-creation,Builtin,2,9774,0x557426376340,472,Negate_Generic_Baseline
code-creation,Builtin,2,9783,0x557426376520,424,BitwiseNot_WithFeedback
code-creation,Builtin,2,9792,0x5574263766e0,420,Decrement_WithFeedback
code-creation,Builtin,2,9801,0x5574263768a0,420,Increment_WithFeedback
diff --git a/deps/v8/test/mjsunit/turbolev/array-holey-double-load.js b/deps/v8/test/mjsunit/turbolev/array-holey-double-load.js
index 6f0b19c11d9..f6240ae61a1 100644
--- a/deps/v8/test/mjsunit/turbolev/array-holey-double-load.js
+++ b/deps/v8/test/mjsunit/turbolev/array-holey-double-load.js
@@ -14,14 +14,9 @@ assertEquals(3.41, load_holey_fixed_double(holey_double_arr, 1));
%OptimizeFunctionOnNextCall(load_holey_fixed_double);
assertEquals(3.41, load_holey_fixed_double(holey_double_arr, 1));
assertOptimized(load_holey_fixed_double);
-// Loading a hole should trigger a deopt
+// Loading a hole returns undefined without deoptimizing: the load is unchecked
+// and the hole is tagged to undefined on the way out.
assertEquals(undefined, load_holey_fixed_double(holey_double_arr, 2));
-assertUnoptimized(load_holey_fixed_double);
-
-// Reoptimizing, holes should now be handled
-%OptimizeMaglevOnNextCall(load_holey_fixed_double);
-assertEquals(3.41, load_holey_fixed_double(holey_double_arr, 1));
-%OptimizeFunctionOnNextCall(load_holey_fixed_double);
+assertOptimized(load_holey_fixed_double);
assertEquals(3.41, load_holey_fixed_double(holey_double_arr, 1));
-assertEquals(undefined, load_holey_fixed_double(holey_double_arr, 2));
assertOptimized(load_holey_fixed_double);
diff --git a/deps/v8/test/mjsunit/turbolev/check-uint32-is-smi.js b/deps/v8/test/mjsunit/turbolev/check-uint32-is-smi.js
new file mode 100644
index 00000000000..50356ab5ff2
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/check-uint32-is-smi.js
@@ -0,0 +1,25 @@
+// 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 test(str, x) {
+ let start = x >>> 0;
+ return str.startsWith("a", start);
+}
+
+%PrepareFunctionForOptimization(test);
+test("abc", 0);
+test("abc", 1);
+%OptimizeFunctionOnNextCall(test);
+test("abc", 0);
+assertOptimized(test);
+
+const kSmiMaxValue = 1073741823;
+test("abc", kSmiMaxValue - 1);
+assertOptimized(test);
+
+// Smi::kMaxValue is a valid Smi and must not deopt.
+test("abc", kSmiMaxValue);
+assertOptimized(test);
diff --git a/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js b/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js
new file mode 100644
index 00000000000..68b88692363
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/dataview-deopt-oob.js
@@ -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.
+
+// Flags: --allow-natives-syntax --turbolev --turbofan
+
+let big_index = 0x80000000;
+let ab = new ArrayBuffer(big_index + 0x40);
+let dv = new DataView(ab);
+
+function test_read(dv, index) {
+ index |= 0;
+ return dv.getInt8(index);
+}
+
+%PrepareFunctionForOptimization(test_read);
+test_read(dv, 0x40000000);
+%OptimizeFunctionOnNextCall(test_read);
+test_read(dv, 0x40000000);
+assertOptimized(test_read);
+
+// Under 64-bit, offset -2147483648 deopts and throws RangeError.
+assertThrows(() => test_read(dv, -2147483648), RangeError);
+assertUnoptimized(test_read);
+
+function test_write(dv, index, val) {
+ index |= 0;
+ dv.setInt8(index, val);
+}
+
+%PrepareFunctionForOptimization(test_write);
+test_write(dv, 0x40000000, 1);
+%OptimizeFunctionOnNextCall(test_write);
+test_write(dv, 0x40000000, 2);
+assertOptimized(test_write);
+
+// Under 64-bit, offset -2147483648 deopts and throws RangeError.
+assertThrows(() => test_write(dv, -2147483648, 99), RangeError);
+assertUnoptimized(test_write);
+
+function test_read32(dv, index) {
+ index |= 0;
+ return dv.getInt32(index);
+}
+
+%PrepareFunctionForOptimization(test_read32);
+test_read32(dv, 0x40000000);
+%OptimizeFunctionOnNextCall(test_read32);
+test_read32(dv, 0x40000000);
+assertOptimized(test_read32);
+
+assertThrows(() => test_read32(dv, -2147483648), RangeError);
+assertUnoptimized(test_read32);
+
+function test_write32(dv, index, val) {
+ index |= 0;
+ dv.setInt32(index, val);
+}
+
+%PrepareFunctionForOptimization(test_write32);
+test_write32(dv, 0x40000000, 1);
+%OptimizeFunctionOnNextCall(test_write32);
+test_write32(dv, 0x40000000, 2);
+assertOptimized(test_write32);
+
+assertThrows(() => test_write32(dv, -2147483648, 99), RangeError);
+assertUnoptimized(test_write32);
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-inside-loop-phi-backedge.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-inside-loop-phi-backedge.js
new file mode 100644
index 00000000000..323a1f4dec3
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-inside-loop-phi-backedge.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 --no-maglev-loop-peeling --turbofan
+// Flags: --turbolev-escape-analysis
+
+function bar() {}
+%NeverOptimizeFunction(bar);
+
+function foo(n) {
+ let phi = 42;
+ let o = { x: null };
+ %AssertEscapeAnalysisElided(o);
+
+ for (let i = 0; i < n; i++) {
+ let inner = { y: i };
+ o.x = null;
+ o.x = inner;
+
+ // We make the GraphBuilder and GraphOptimizer lose track of the value of
+ // {o.x} by using an empty loop with loop peeling disabled, which triggers
+ // an invalidation so {o.x} is loaded with a real LoadTaggedField below.
+ for (let j = 0; j < 2; j++) {
+ bar();
+ }
+
+ phi = o.x;
+ }
+
+ return phi.y;
+}
+
+%PrepareFunctionForOptimization(foo);
+assertEquals(2, foo(3));
+assertEquals(4, foo(5));
+
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(2, foo(3));
+assertEquals(4, foo(5));
+assertOptimized(foo);
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-loop-phi-backedge-dependency.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-loop-phi-backedge-dependency.js
new file mode 100644
index 00000000000..c01ed9a71e7
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-loop-phi-backedge-dependency.js
@@ -0,0 +1,35 @@
+// 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 --turbolev-escape-analysis
+
+function test(cond, n) {
+ let outer_alloc = { f1: 0 };
+
+ let i;
+ if (cond) {
+ outer_alloc.f1 = 1;
+ i = 0;
+ } else {
+ outer_alloc.f1 = 2;
+ i = 0;
+ }
+
+ while (i < n) {
+ let backedge_alloc = { f2: 0 };
+ // Create the dependency: backedge_alloc depends on outer_alloc
+ backedge_alloc.f2 = outer_alloc;
+ // backedge_alloc flows into outer_alloc's Virtual Phi backedge
+ outer_alloc.f1 = backedge_alloc;
+ i++;
+ }
+
+ return outer_alloc.f1;
+}
+
+%PrepareFunctionForOptimization(test);
+test(true, 1);
+test(false, 1);
+%OptimizeFunctionOnNextCall(test);
+test(true, 1);
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-nested-loop-revisit.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-nested-loop-revisit.js
new file mode 100644
index 00000000000..32a8328819a
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-nested-loop-revisit.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 --no-maglev-loop-peeling --turbolev
+// Flags: --turbolev-escape-analysis
+
+function Wrapper(val) {
+ this.f = val;
+}
+
+function test() {
+ const wrapper = new Wrapper(0);
+
+ for (let i = 0; i < 2; i++) {
+
+ for (let j = 0; j < 2; j++) {
+ let cur = wrapper.f;
+ wrapper.f = 100;
+ }
+
+ wrapper.f = 42;
+ }
+}
+
+%PrepareFunctionForOptimization(Wrapper);
+%PrepareFunctionForOptimization(test);
+test();
+
+%OptimizeFunctionOnNextCall(test);
+test();
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-regreee-540324228.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-regreee-540324228.js
new file mode 100644
index 00000000000..a050b151810
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-regreee-540324228.js
@@ -0,0 +1,25 @@
+// 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 --turbolev-escape-analysis
+
+function bar() {
+ throw 1;
+}
+%NeverOptimizeFunction(bar);
+
+function foo() {
+ const o = { x: 1 };
+ while (true) {
+ o.x = 42;
+ bar();
+ }
+}
+
+%PrepareFunctionForOptimization(foo);
+try { foo(); } catch(e) {}
+try { foo(); } catch(e) {}
+
+%OptimizeFunctionOnNextCall(foo);
+try { foo(); } catch(e) {}
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-538666333.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-538666333.js
new file mode 100644
index 00000000000..e9e9461b647
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-538666333.js
@@ -0,0 +1,49 @@
+// 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 --no-maglev-loop-peeling --turbolev
+// Flags: --turbolev-escape-analysis
+
+function ConstructorA() {
+ this.f = 42;
+}
+
+function ConstructorB() {
+ this.f = 42;
+}
+
+function Wrapper(val) {
+ this.f = val;
+}
+
+function test_while(cond) {
+ const o1 = new ConstructorA();
+ const o2 = new ConstructorB();
+
+ const wrapper = new Wrapper(0);
+
+ for (let i = 0; i < 3; i++) {
+ let j = 0;
+ if (cond) {
+ wrapper.f = o1;
+ } else {
+ wrapper.f = o2;
+ }
+
+ while (j < 5) {
+ let cur = wrapper.f;
+ wrapper.f = 0;
+ j++;
+ }
+ }
+}
+
+%PrepareFunctionForOptimization(ConstructorA);
+%PrepareFunctionForOptimization(ConstructorB);
+%PrepareFunctionForOptimization(Wrapper);
+%PrepareFunctionForOptimization(test_while);
+test_while(true);
+test_while(false);
+%OptimizeFunctionOnNextCall(test_while);
+test_while(true);
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-539464276.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-539464276.js
new file mode 100644
index 00000000000..b9825fcdbb9
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-539464276.js
@@ -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.
+
+// Flags: --allow-natives-syntax --no-maglev-loop-peeling --turbolev --turbolev-escape-analysis
+
+function MyObj() {
+ this.x = 17;
+}
+
+function test(cond, n) {
+ let o = new MyObj();
+ let o_back = new MyObj();
+
+ o.x = 19;
+ switch (cond) {
+ case 1:
+ o.x = 23;
+ break;
+ case 2:
+ o.x = 27;
+ break;
+ }
+ let i = 0;
+ while (i < n) {
+ o.x = o_back;
+ i++;
+ }
+
+ return o.x;
+}
+
+%PrepareFunctionForOptimization(MyObj);
+%PrepareFunctionForOptimization(test);
+
+test(1, 1);
+test(2, 1);
+
+%OptimizeFunctionOnNextCall(test);
+assertEquals(test(1, 1), new MyObj());
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-542377197.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-542377197.js
new file mode 100644
index 00000000000..b6f5b75c3f2
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-542377197.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: --allow-natives-syntax --turbolev --turbolev-escape-analysis
+
+Object.prototype.__defineGetter__(0, () => 42);
+
+function foo(x) {
+ return ![, x][0];
+}
+
+%PrepareFunctionForOptimization(foo);
+assertEquals(false, foo("abc"));
+
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(false, foo("abc"));
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-543940209.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-543940209.js
new file mode 100644
index 00000000000..6ad46b6ad73
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-543940209.js
@@ -0,0 +1,29 @@
+// 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 --turbolev-escape-analysis
+
+function trigger() {
+ let box = { x: 1.1 };
+ let o = { field: 1.1 };
+
+ for (let i = 0; i < 2; i++) {
+ o.field = box.x;
+
+ for (let j = 0; j < 2; j++) {
+ o.field = box.x;
+ }
+
+ box.x = {};
+ }
+
+ return o.field;
+}
+
+%PrepareFunctionForOptimization(trigger);
+trigger();
+trigger();
+
+%OptimizeFunctionOnNextCall(trigger);
+trigger();
diff --git a/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-544548648.js b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-544548648.js
new file mode 100644
index 00000000000..a2dd3d09ff8
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/escape-analysis-regress-544548648.js
@@ -0,0 +1,29 @@
+// 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 --no-lazy-feedback-allocation
+// Flags: --turbolev-escape-analysis
+
+function Obj() {
+ this.x = 1.5;
+}
+
+var arr = [];
+
+function f() {
+ let a = new Obj();
+ let b = new Obj();
+ let c = new Obj();
+ for (let i = 0; i < 42; i++) {
+ b.x = c.x;
+ arr[1048182] = {};
+ a.x = b.x;
+ }
+ return a.x;
+}
+
+%PrepareFunctionForOptimization(f);
+assertEquals(1.5, f());
+%OptimizeFunctionOnNextCall(f);
+assertEquals(1.5, f());
diff --git a/deps/v8/test/mjsunit/turbolev/holey-double-load-arith.js b/deps/v8/test/mjsunit/turbolev/holey-double-load-arith.js
new file mode 100644
index 00000000000..6cd352b9391
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/holey-double-load-arith.js
@@ -0,0 +1,108 @@
+// 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
+
+// A holey-double load consumed only by float arithmetic no longer needs the
+// not-hole/undefined check: the hole reads as undefined and `undefined + x` is
+// NaN, which float arithmetic produces from any NaN input. So loading a hole
+// must NOT deopt; it must stay optimized and yield NaN.
+
+// (1) Behavioral flip: arithmetic-only use stays optimized on a hole.
+(function() {
+ function f(a, i) { return 1 + a[i]; }
+ let arr = [0.5, , 1.5]; // HOLEY_DOUBLE_ELEMENTS
+ %PrepareFunctionForOptimization(f);
+ assertEquals(1.5, f(arr, 0));
+ assertEquals(1.5, f(arr, 0));
+ %OptimizeFunctionOnNextCall(f);
+ assertEquals(1.5, f(arr, 0));
+ assertOptimized(f);
+ // Loading a hole must NOT trigger a deopt (the check is elided).
+ assertEquals(NaN, f(arr, 1)); // 1 + undefined = NaN
+ assertOptimized(f);
+})();
+
+// (2) The value crosses a `Star` (let-binding) before the add. The decision is
+// use-based, not bytecode-adjacency-based, so this still elides the check.
+(function() {
+ function foo(a, i, j) { let x = a[i]; let y = a[j]; return x + y; }
+ let arr = [1.5, , 2, 3];
+ %PrepareFunctionForOptimization(foo);
+ assertEquals(3.5, foo(arr, 0, 2));
+ assertEquals(3.5, foo(arr, 0, 2));
+ %OptimizeFunctionOnNextCall(foo);
+ assertEquals(3.5, foo(arr, 0, 2));
+ assertOptimized(foo);
+ assertEquals(NaN, foo(arr, 1, 0)); // undefined + 1.5 = NaN
+ assertOptimized(foo);
+})();
+
+// (3) Relational comparison of a hole is still correct (undefined < x is
+// NaN < x = false). The check is not elided for relational compares in this
+// change, so a hole may deopt; only the value is asserted.
+(function() {
+ function lt(a, i) { return a[i] < 2.0; }
+ let arr = [1.5, , 3.5];
+ %PrepareFunctionForOptimization(lt);
+ assertTrue(lt(arr, 0));
+ assertTrue(lt(arr, 0));
+ %OptimizeFunctionOnNextCall(lt);
+ assertFalse(lt(arr, 1)); // undefined < 2 is false
+})();
+
+// (4) HAZARD: equality is NOT hole-tolerant. `undefined === undefined` is true,
+// `NaN === NaN` is false, so the result must be the interpreter's answer.
+(function() {
+ function eq(a, i, j) { return a[i] === a[j]; }
+ let arr = [1.5, , 2.5];
+ %PrepareFunctionForOptimization(eq);
+ assertTrue(eq(arr, 0, 0));
+ assertFalse(eq(arr, 0, 2));
+ %OptimizeFunctionOnNextCall(eq);
+ assertTrue(eq(arr, 1, 1)); // undefined === undefined
+ assertFalse(eq(arr, 0, 1)); // 1.5 === undefined
+})();
+
+// (5) HAZARD: property access on a hole must throw (undefined.x), not fold.
+(function() {
+ function prop(a, i) { return a[i].x; }
+ let arr = [1.5, , 2.5];
+ %PrepareFunctionForOptimization(prop);
+ assertEquals(undefined, prop(arr, 0)); // (1.5).x is undefined
+ assertEquals(undefined, prop(arr, 0));
+ %OptimizeFunctionOnNextCall(prop);
+ assertThrows(() => prop(arr, 1), TypeError); // undefined.x throws
+})();
+
+// (6) HAZARD: storing an arithmetic result back into a holey-double array must
+// store a real NaN element (silenced), never a hole marker.
+(function() {
+ function s(a, out, i) { out[0] = a[i] * 1; }
+ let arr = [1.5, , 2.5];
+ let out = [7.5, 8.5];
+ %PrepareFunctionForOptimization(s);
+ s(arr, out, 0);
+ s(arr, out, 0);
+ %OptimizeFunctionOnNextCall(s);
+ s(arr, out, 1); // out[0] = undefined * 1 = NaN
+ assertTrue(0 in out);
+ assertEquals(NaN, out[0]);
+})();
+
+// (7) `undefined` stored into a holey-double array (undefined-NaN) flows through
+// arithmetic as NaN and round-trips as undefined.
+(function() {
+ function r(a, i) { return a[i] + 0; }
+ let arr = [1.5, 2.5, 3.5];
+ arr[1] = undefined; // stays HOLEY_DOUBLE, stores the undefined-NaN pattern
+ %PrepareFunctionForOptimization(r);
+ assertEquals(1.5, r(arr, 0));
+ assertEquals(1.5, r(arr, 0));
+ %OptimizeFunctionOnNextCall(r);
+ assertEquals(NaN, r(arr, 1)); // undefined + 0 = NaN
+ assertOptimized(r);
+ assertTrue(1 in arr);
+ assertTrue(arr[1] === undefined);
+})();
diff --git a/deps/v8/test/mjsunit/turbolev/holey-double-phi-distinguish.js b/deps/v8/test/mjsunit/turbolev/holey-double-phi-distinguish.js
new file mode 100644
index 00000000000..bbeab9a075d
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/holey-double-phi-distinguish.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 --turbolev --turbofan
+
+// A loop phi carries holey-double values and has two uses: one that
+// distinguishes the hole/undefined pattern from a genuine NaN (`x ===
+// undefined`), and a Float64 arithmetic use (`x * 2`). The phi-representation
+// selector untags such a phi to HoleyFloat64 (it can never become a silenced
+// Float64, because any HoleyFloat64 input pins `possible_inputs` to
+// {HoleyFloat64}), so the distinguishing use must still see holes as
+// `undefined` and the real NaN as not-`undefined`.
+
+function f(arr) {
+ const n = arr.length;
+ let x = arr[0];
+ let holes = 0;
+ let s = 0.0;
+ for (let i = 1; i < n; i++) {
+ if (x === undefined) holes++; // distinguishes hole/undefined from NaN
+ s += x * 2.0; // Float64 use (hole -> NaN)
+ x = arr[i]; // holey backedge
+ }
+ if (x === undefined) holes++;
+ s += x * 2.0;
+ return [holes, Number.isNaN(s)];
+}
+
+// HOLEY_DOUBLE array: a genuine NaN at index 1, holes at indices 2 and 4.
+function mkArr() { return [1.5, NaN, /*hole*/, 2.5, /*hole*/, 3.5]; }
+
+// The two holes count as `undefined`; the real NaN does not. `s` becomes NaN.
+%PrepareFunctionForOptimization(f);
+assertEquals([2, true], f(mkArr()));
+assertEquals([2, true], f(mkArr()));
+%OptimizeFunctionOnNextCall(f);
+assertEquals([2, true], f(mkArr()));
+assertOptimized(f);
+
+// A hole-free HOLEY_DOUBLE array: no undefineds, `s` is a real number.
+function mkDense() { let a = [1.5, 2.5, /*hole*/, 3.5]; a[2] = 4.5; return a; }
+assertEquals([0, false], f(mkDense()));
+assertOptimized(f);
diff --git a/deps/v8/test/mjsunit/turbolev/keyed-access-thin-constant-key.js b/deps/v8/test/mjsunit/turbolev/keyed-access-thin-constant-key.js
new file mode 100644
index 00000000000..e7263625d09
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/keyed-access-thin-constant-key.js
@@ -0,0 +1,35 @@
+// 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
+
+// A keyed access with monomorphic name feedback and a constant key that is a
+// ThinString of the recorded name must not deopt unconditionally.
+
+function makeAccessor(key) {
+ return {
+ get(o) { return o[key]; },
+ set(o, v) { o[key] = v; },
+ };
+}
+
+// Turns the (computed, non-internalized) string into a ThinString in place.
+const key = %ConstructThinString('__props$' + 'abcdefghij0123456789');
+const acc = makeAccessor(key);
+const o = {};
+
+%PrepareFunctionForOptimization(acc.set);
+acc.set(o, 1);
+acc.set(o, 2);
+%OptimizeFunctionOnNextCall(acc.set);
+acc.set(o, 3);
+assertOptimized(acc.set);
+assertEquals(3, o[key]);
+
+%PrepareFunctionForOptimization(acc.get);
+assertEquals(3, acc.get(o));
+assertEquals(3, acc.get(o));
+%OptimizeFunctionOnNextCall(acc.get);
+assertEquals(3, acc.get(o));
+assertOptimized(acc.get);
diff --git a/deps/v8/test/mjsunit/turbolev/module-export-loop-peel.js b/deps/v8/test/mjsunit/turbolev/module-export-loop-peel.js
new file mode 100644
index 00000000000..ce27fbd58cd
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/module-export-loop-peel.js
@@ -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.
+
+// Flags: --allow-natives-syntax --turbolev
+
+let m;
+import(
+ `data:text/javascript,
+
+ export let value = 0;
+ export function set(x) { value = x; };
+ export let a = 11;
+`).then(mod => {
+ m = mod;
+});
+%PerformMicrotaskCheckpoint();
+
+function foo() {
+ for (let i = 0; i < 5; i++) {
+ let x = m.value;
+ x += m.a;
+ m.set(x);
+ }
+}
+
+function check() {
+ assertEquals(55, m.value);
+ m.set(0);
+}
+
+%PrepareFunctionForOptimization(foo);
+foo();
+check();
+foo();
+check();
+%OptimizeFunctionOnNextCall(foo);
+foo();
+check();
+assertOptimized(foo);
diff --git a/deps/v8/test/mjsunit/turbolev/regress-533979617.js b/deps/v8/test/mjsunit/turbolev/regress-533979617.js
new file mode 100644
index 00000000000..6725c27e3fe
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-533979617.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: --allow-natives-syntax --turbolev
+// Flags: --no-maglev-optimistic-peeled-loops
+
+function bar() {}
+%NeverOptimizeFunction(bar);
+
+function foo() {
+ for (let i = 0; i < 5; i++) {
+
+ for (let j = 0; j < 5; j++) {
+ %OptimizeOsr();
+ }
+
+ for (let k = 0; k < 5;) {
+ typeof k;
+ k = NaN;
+ bar() ?? bar;
+ function inner() { }
+ }
+ }
+}
+
+%PrepareFunctionForOptimization(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-538938804.js b/deps/v8/test/mjsunit/turbolev/regress-538938804.js
new file mode 100644
index 00000000000..1d2ae7cc21b
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-538938804.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: --allow-natives-syntax --turbolev
+// Flags: --no-lazy-feedback-allocation --no-baseline-batch-compilation
+
+let counter = 0;
+let mismatch = 0;
+
+function inc() {
+ counter = counter + 1;
+}
+
+while (counter < 10) {
+ function foo() {
+ var snapshot = counter;
+ for (var i = 0; i < 2; ++i) {
+ for (var j = 1; j < 3; ++j) {
+ inc();
+ if (snapshot + j != counter) {
+ mismatch = counter;
+ }
+ }
+ snapshot = counter;
+ }
+ }
+ %PrepareFunctionForOptimization(foo);
+ foo();
+ %OptimizeFunctionOnNextCall(foo);
+}
+
+assertEquals(0, mismatch);
diff --git a/deps/v8/test/mjsunit/turbolev/regress-539006995-1.js b/deps/v8/test/mjsunit/turbolev/regress-539006995-1.js
new file mode 100644
index 00000000000..032cde21abb
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-539006995-1.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-lazy-feedback-allocation --maglev-non-eager-inlining --allow-natives-syntax --fuzzing
+
+const v2 = Object.getPrototypeOf;
+const v3 = Object.setPrototypeOf;
+function f4(a5, a6) {
+ const v7 = {};
+ const v9 = new Proxy(v2(a6), v7);
+ return v3(a6, v9);
+}
+const v11 = { probe: f4 };
+for (let v12 = 0; v12 < 5; v12++) {
+ function f14(a15, a16, a17, ...a18) {
+ v11.probe("v11", a18);
+ return a18.sort(f14);
+ }
+ f14().includes(v12, v12);
+ const v24 = %OptimizeOsr();
+}
diff --git a/deps/v8/test/mjsunit/turbolev/regress-539006995-2.js b/deps/v8/test/mjsunit/turbolev/regress-539006995-2.js
new file mode 100644
index 00000000000..8a9755af137
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-539006995-2.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 --fuzzing --no-lazy-feedback-allocation --maglev-assert --turbolev --single-threaded
+
+for (let v0 = 0; v0 < 5; v0++) {
+ for (let v2 = 0; v2 < 5; v2++) {
+ function f4(a5, ...a6) {
+ a5.length = v0;
+ try { a6.splice( v2); } catch (e) {}
+ let v8;
+ try { v8 = a6.findLast(); } catch (e) {}
+ v8 ?? f4;
+ v8 ?? v8;
+ a5.prototype = a6;
+ return a6;
+ }
+ f4(f4).includes(v0, v2);
+ }
+ %OptimizeOsr();
+}
diff --git a/deps/v8/test/mjsunit/turbolev/regress-539006995-3.js b/deps/v8/test/mjsunit/turbolev/regress-539006995-3.js
new file mode 100644
index 00000000000..95ed36daaf7
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-539006995-3.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.
+
+// Flags: --allow-natives-syntax --turbolev --fuzzing --maglev-non-eager-inlining --no-lazy-feedback-allocation
+
+function __f_7() {
+ try {
+ return Array.prototype.at;
+ } catch (e) {}
+}
+function __f_8(__v_27) {
+ __v_27[0];
+ return __f_7().call(__v_27, -6);
+}
+try {
+} catch (e) {}
+ %PrepareFunctionForOptimization(__f_8);
+ __f_8([]);
+ %OptimizeFunctionOnNextCall(__f_8);
+ __f_8([]);
diff --git a/deps/v8/test/mjsunit/turbolev/regress-540482606.js b/deps/v8/test/mjsunit/turbolev/regress-540482606.js
new file mode 100644
index 00000000000..ccd422920ce
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-540482606.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.
+
+// Flags: --allow-natives-syntax --turbolev --assert-types
+
+function foo() {
+ for (let v19 = 0; v19 < 4; v19++) {
+ for (let v22 = 0; v22 < 5; v22++) {
+ const v24 = v22++;
+ // v26 is a phi typed as Boolean | Number. v24 > v22 is always false,
+ // so at run time it's always a Number, and the first arm of this
+ // branch is dead.
+ const v26 = v24 > v22 || v24;
+ // The ^ operation has number feedback since we always saw a number.
+ const v27 = v26 ^ 3221225472;
+ [v26, 1.1];
+ v22 = 3221225472;
+ %OptimizeOsr();
+ }
+ }
+}
+%PrepareFunctionForOptimization(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-540651858.js b/deps/v8/test/mjsunit/turbolev/regress-540651858.js
new file mode 100644
index 00000000000..581acbf583a
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-540651858.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: --allow-natives-syntax --no-lazy-feedback-allocation --turbolev-future
+
+function outer() {
+ function inner(a, b) {
+ for (let i = 0; i < 5; i++) {
+ i++;
+ Math.min(b, i) >>> 2;
+ b = a;
+ }
+ return outer;
+ }
+ const result = inner();
+ inner(31960, inner);
+ return result;
+}
+
+%PrepareFunctionForOptimization(outer);
+outer();
+outer();
+%OptimizeMaglevOnNextCall(outer);
+%PrepareFunctionForOptimization(outer());
+%OptimizeFunctionOnNextCall(outer());
+outer();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-540717862.js b/deps/v8/test/mjsunit/turbolev/regress-540717862.js
new file mode 100644
index 00000000000..962a3770185
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-540717862.js
@@ -0,0 +1,25 @@
+// 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 --print-turbolev-frontend
+// Flags: --no-lazy-feedback-allocation
+
+let cases = "";
+for (let i = 0; i < 66000; i++) {
+ cases += `case ${i}: `;
+}
+const g = Function(`switch(x){${cases} default:0;}`);
+
+function f() {
+ let r = 0;
+ for (let i = 0; i < 3; i++) {
+ try { r = g(); } catch (e) {}
+ }
+ return r;
+}
+
+%PrepareFunctionForOptimization(f);
+f();
+%OptimizeFunctionOnNextCall(f);
+f();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-543836266.js b/deps/v8/test/mjsunit/turbolev/regress-543836266.js
new file mode 100644
index 00000000000..ff31ab36d34
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-543836266.js
@@ -0,0 +1,18 @@
+// 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 --no-lazy-feedback-allocation --turbolev
+// Flags: --turbolev-future --maglev-disable-builtin-reducers
+// Flags: --no-concurrent-osr --no-maglev-osr
+
+function wrap(f) {
+ return f();
+}
+
+%OptimizeOsr();
+for (let i = 0; i < 5; i++) {
+ function inner() {}
+ wrap(() => Math.round(inner));
+}
+const dead = 1;
diff --git a/deps/v8/test/mjsunit/turbolev/regress-543954265.js b/deps/v8/test/mjsunit/turbolev/regress-543954265.js
new file mode 100644
index 00000000000..0484a6ca3d2
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-543954265.js
@@ -0,0 +1,14 @@
+// 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-disable-builtin-reducers
+
+function foo() {
+ for (let i = 0; i < 5; i++) {
+ Math.clz32(Math);
+ %OptimizeOsr();
+ }
+}
+%PrepareFunctionForOptimization(foo);
+foo();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-544083885.js b/deps/v8/test/mjsunit/turbolev/regress-544083885.js
new file mode 100644
index 00000000000..8a211cd7d07
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-544083885.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 --turbolev --maglev-disable-builtin-reducers
+
+let dummy;
+
+function callWithDefault(f = true) {
+ return f();
+}
+
+function foo(x) {
+ let a = callWithDefault(() => Math.floor(x));
+ return a + Math.floor(x);
+}
+
+%PrepareFunctionForOptimization(foo);
+assertTrue(Number.isNaN(foo()));
+assertTrue(Number.isNaN(foo()));
+%OptimizeFunctionOnNextCall(foo);
+assertTrue(Number.isNaN(foo()));
diff --git a/deps/v8/test/mjsunit/turbolev/regress-544150244.js b/deps/v8/test/mjsunit/turbolev/regress-544150244.js
new file mode 100644
index 00000000000..1dd7c1e1da4
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-544150244.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: --turbolev --maglev-disable-builtin-reducers
+
+let dummy;
+
+function round(x) {
+ return Math.round(x);
+}
+
+function main() {
+ const obj = {valueOf: function() { return 16; }};
+ for (let i = 0; i < 1e4; ++i) {
+ if (round(obj) !== 16) throw "Incorrect result";
+ }
+}
+
+main();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-546639196.js b/deps/v8/test/mjsunit/turbolev/regress-546639196.js
new file mode 100644
index 00000000000..81206f0b0b5
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-546639196.js
@@ -0,0 +1,29 @@
+// 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
+
+// Same as the addition case, but through the multiplication identity.
+const f64 = new Float64Array(1);
+const u32 = new Uint32Array(f64.buffer);
+u32[0] = 0xFFF7FFFF;
+u32[1] = 0xFFF7FFFF;
+
+function test(packed_arr, ta) {
+ let inlined_arr = [1.0, 1.1];
+ let res = ta[0] * inlined_arr[0];
+ packed_arr[0] = res;
+}
+
+%PrepareFunctionForOptimization(test);
+test([1.1, 2.2], f64);
+%OptimizeFunctionOnNextCall(test);
+
+const packed = [10.1, 20.2];
+test(packed, f64);
+
+assertTrue(0 in packed);
+assertEquals(NaN, packed[0]);
+assertFalse(packed.includes(undefined));
+assertEquals('[null,20.2]', JSON.stringify(packed));
diff --git a/deps/v8/test/mjsunit/turbolev/regress-546647038.js b/deps/v8/test/mjsunit/turbolev/regress-546647038.js
new file mode 100644
index 00000000000..2c4a97ffa43
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-546647038.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.
+
+// Flags: --allow-natives-syntax --turbolev --no-lazy-feedback-allocation
+
+const max = Math.max;
+let limit;
+
+function foo(x) {
+ const empty = [];
+ let i = 0;
+ for (; i < limit; i++) {
+ }
+ return max(x, i, ...empty);
+}
+
+assertEquals(NaN, foo());
+%PrepareFunctionForOptimization(foo);
+%OptimizeFunctionOnNextCall(foo);
+assertEquals(NaN, foo());
diff --git a/deps/v8/test/mjsunit/turbolev/regress-546842384.js b/deps/v8/test/mjsunit/turbolev/regress-546842384.js
new file mode 100644
index 00000000000..e3efecb93fb
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-546842384.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 --turbolev
+
+// A Float64Array lets us build the hole bit pattern, which an addition would
+// have quieted had the identity fold not removed it.
+const f64 = new Float64Array(1);
+const u32 = new Uint32Array(f64.buffer);
+u32[0] = 0xFFF7FFFF;
+u32[1] = 0xFFF7FFFF;
+
+function test(packed_arr, ta) {
+ let inlined_arr = [-0.0, 1.1];
+ let res = ta[0] + inlined_arr[0];
+ packed_arr[0] = res;
+}
+
+%PrepareFunctionForOptimization(test);
+test([1.1, 2.2], f64);
+%OptimizeFunctionOnNextCall(test);
+
+const packed = [10.1, 20.2];
+test(packed, f64);
+
+assertTrue(0 in packed);
+assertEquals(NaN, packed[0]);
+packed.sort();
+assertTrue(0 in packed);
diff --git a/deps/v8/test/mjsunit/turbolev/regress-546963430.js b/deps/v8/test/mjsunit/turbolev/regress-546963430.js
new file mode 100644
index 00000000000..c8eb663f712
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-546963430.js
@@ -0,0 +1,45 @@
+// 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
+
+function testHoley(arr, arr2) {
+ let zero = -0.0;
+ for (let i = 0; i < arr.length; i++) {
+ let x = arr[i];
+ let y = x + zero;
+ arr2[i] = y;
+ zero = -0.0;
+ }
+}
+
+function testPacked(arr, arr2) {
+ let zero = -0.0;
+ for (let i = 0; i < arr.length; i++) {
+ let x = arr[i];
+ let y = x + zero;
+ arr2[i] = y;
+ zero = -0.0;
+ }
+}
+
+function run(test, dst) {
+ const src = [, 1.1, 3.3];
+ %PrepareFunctionForOptimization(test);
+ dst[0] = 5.5;
+ test(src, dst);
+ assertEquals(NaN, dst[0]);
+ assertTrue(0 in dst);
+
+ dst[0] = 5.5;
+ test(src, dst);
+ dst[0] = 5.5;
+ %OptimizeFunctionOnNextCall(test);
+ test(src, dst);
+ assertEquals(NaN, dst[0]);
+ assertTrue(0 in dst);
+}
+
+run(testHoley, [, 1.1, 3.3]);
+run(testPacked, [1.1, 2.2, 3.3]);
diff --git a/deps/v8/test/mjsunit/turbolev/regress-546979662.js b/deps/v8/test/mjsunit/turbolev/regress-546979662.js
new file mode 100644
index 00000000000..46cf9b7f4c4
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-546979662.js
@@ -0,0 +1,29 @@
+// 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
+
+function foo(src, packed) {
+ let a = src[0];
+ let o = { x: -0.0 };
+ let b = o.x;
+ let x = a + b;
+ packed[0] = x;
+}
+
+const src_hole = [1.1, 2.2];
+src_hole[8] = 1.5;
+delete src_hole[0];
+
+const packed = [1.1, 2.2];
+
+%PrepareFunctionForOptimization(foo);
+foo(src_hole, packed);
+foo(src_hole, packed);
+%OptimizeFunctionOnNextCall(foo);
+foo(src_hole, packed);
+
+assertTrue(0 in packed);
+assertEquals(NaN, packed[0]);
+assertEquals([2.2, NaN], packed.toReversed());
diff --git a/deps/v8/test/mjsunit/turbolev/regress-552783942.js b/deps/v8/test/mjsunit/turbolev/regress-552783942.js
new file mode 100644
index 00000000000..a70d5aaf022
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-552783942.js
@@ -0,0 +1,98 @@
+// 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
+
+const f64 = new Float64Array(1);
+const u32 = new Uint32Array(f64.buffer);
+u32[0] = 0xFFF7FFFF;
+u32[1] = 0xFFF7FFFF;
+const holeNan = f64[0];
+
+function dummy(flag) {
+ if (flag) {
+ let q = 1;
+ for (let i = 0; i < 10; ++i) q += i;
+ }
+ return -0;
+}
+
+function makeMin(x, flag) {
+ const o = {};
+ o.p = Math.min(x, x) + dummy(flag);
+ return o;
+}
+
+(function testMinIdentityTurbolev() {
+ %PrepareFunctionForOptimization(dummy);
+ %PrepareFunctionForOptimization(makeMin);
+ makeMin(1.5, false);
+ makeMin(2.5, false);
+ %OptimizeFunctionOnNextCall(makeMin);
+
+ const victim = makeMin(holeNan, false);
+
+ function readP() {
+ return victim.p;
+ }
+
+ %PrepareFunctionForOptimization(readP);
+ readP();
+ readP();
+ %OptimizeFunctionOnNextCall(readP);
+
+ assertTrue(isNaN(readP()));
+ victim.p = 42.5;
+ assertEquals(42.5, readP());
+})();
+
+function makeMax(x, flag) {
+ const o = {};
+ o.p = Math.max(x, x) + dummy(flag);
+ return o;
+}
+
+(function testMaxIdentityTurbolev() {
+ %PrepareFunctionForOptimization(dummy);
+ %PrepareFunctionForOptimization(makeMax);
+ makeMax(1.5, false);
+ makeMax(2.5, false);
+ %OptimizeFunctionOnNextCall(makeMax);
+
+ const victim = makeMax(holeNan, false);
+
+ function readP() {
+ return victim.p;
+ }
+
+ %PrepareFunctionForOptimization(readP);
+ readP();
+ readP();
+ %OptimizeFunctionOnNextCall(readP);
+
+ assertTrue(isNaN(readP()));
+ victim.p = 84.5;
+ assertEquals(84.5, readP());
+})();
+
+(function testReturnedBitsQuietedTurbolev() {
+ function foldMin(ta) {
+ const x = ta[0];
+ return Math.min(x, x);
+ }
+ %PrepareFunctionForOptimization(foldMin);
+ foldMin(new Float64Array([1.1]));
+ foldMin(new Float64Array([2.2]));
+ %OptimizeFunctionOnNextCall(foldMin);
+
+ const r = foldMin(f64);
+ const out = new Float64Array(1);
+ const outU64 = new BigUint64Array(out.buffer);
+ out[0] = r;
+
+ assertTrue(isNaN(r));
+ assertNotEquals(0xFFF7FFFF_FFF7FFFFn, outU64[0]);
+ const kQuietNanBit = 0x00080000_00000000n;
+ assertTrue((outU64[0] & kQuietNanBit) !== 0n);
+})();
diff --git a/deps/v8/test/mjsunit/turbolev/regress-556768919.js b/deps/v8/test/mjsunit/turbolev/regress-556768919.js
new file mode 100644
index 00000000000..04f8221c273
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-556768919.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 --turbofan
+
+function test_char_at(s, i) {
+ return s.charAt(i);
+}
+
+function test_char_code_at(s, i) {
+ return s.charCodeAt(i);
+}
+
+function test_code_point_at(s, i) {
+ return s.codePointAt(i);
+}
+
+const functions = [
+ { fn: test_char_at, oob_val: "" },
+ { fn: test_char_code_at, oob_val: NaN },
+ { fn: test_code_point_at, oob_val: undefined }
+];
+
+for (const { fn, oob_val } of functions) {
+ %PrepareFunctionForOptimization(fn);
+ fn("hello", 0);
+ fn("hello", "1");
+ %OptimizeFunctionOnNextCall(fn);
+
+ // Trigger out-of-bounds speculation deopt to disable bounds speculation.
+ fn("hello", 10);
+
+ // Re-optimize with speculation disallowed (inlines with branch).
+ %OptimizeFunctionOnNextCall(fn);
+
+ // In Turbolev, negative indices should execute the out-of-bounds branch
+ // and remain optimized without deoptimizing with kNotInt32.
+ assertSame(oob_val, fn("hello", -1));
+ assertOptimized(fn);
+
+ // Test HeapNumber negative index as well.
+ const heap_neg1 = new Float64Array([-1])[0];
+ assertSame(oob_val, fn("hello", heap_neg1));
+ assertOptimized(fn);
+}
diff --git a/deps/v8/test/mjsunit/turbolev/regress-567177599.js b/deps/v8/test/mjsunit/turbolev/regress-567177599.js
new file mode 100644
index 00000000000..9ed14c0b8d9
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/regress-567177599.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 --turbolev
+
+var loop_value = 1.2;
+var exit_value = 2.5;
+loop_value = 1.4;
+exit_value = 1.5;
+
+const box = {value: 1.2};
+const input = {[Symbol.toPrimitive]() { return box.value; }};
+
+function store(n, input) {
+ let value = 1.1;
+ let sum = 0;
+ while (n-- > 0) {
+ sum += value;
+ value = +input;
+ loop_value = value;
+ }
+ exit_value = value;
+ return sum;
+}
+
+%PrepareFunctionForOptimization(store);
+store(3, input);
+
+%OptimizeFunctionOnNextCall(store);
+store(3, input);
+
+box.value = 42;
+store(3, input);
+assertEquals(42, exit_value);
+assertFalse(%IsSmi(exit_value));
diff --git a/deps/v8/test/mjsunit/turbolev/throw-reference-error-if-hole.js b/deps/v8/test/mjsunit/turbolev/throw-reference-error-if-hole.js
new file mode 100644
index 00000000000..fd76184b823
--- /dev/null
+++ b/deps/v8/test/mjsunit/turbolev/throw-reference-error-if-hole.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: --allow-natives-syntax --turbolev
+
+function foo(b, a) {
+ switch (b) {
+ case 1:
+ let x = 10;
+ let val = a & 0xF;
+ if (val <= 16) {
+ return 0;
+ }
+ // Fallthrough
+ case 2:
+ return x;
+ }
+}
+
+%PrepareFunctionForOptimization(foo);
+assertEquals(0, foo(1, 1));
+assertThrows(() => foo(2, 1), ReferenceError,
+ "Cannot access 'x' before initialization");
+
+%OptimizeFunctionOnNextCall(foo);
+assertThrows(() => foo(2, 1), ReferenceError,
+ "Cannot access 'x' before initialization");
diff --git a/deps/v8/test/mjsunit/turbolev/typed-arrays.js b/deps/v8/test/mjsunit/turbolev/typed-arrays.js
index 2b2df7465ee..2a9a02766a2 100644
--- a/deps/v8/test/mjsunit/turbolev/typed-arrays.js
+++ b/deps/v8/test/mjsunit/turbolev/typed-arrays.js
@@ -21,5 +21,5 @@ function typed_arr() {
let a1 = typed_arr();
%OptimizeFunctionOnNextCall(typed_arr);
let a2 = typed_arr();
-assertEquals(a1, a2);
assertOptimized(typed_arr);
+assertEquals(a1, a2);
diff --git a/deps/v8/test/mjsunit/turboshaft/regress-527385397.js b/deps/v8/test/mjsunit/turboshaft/regress-527385397-1.js
similarity index 87%
rename from deps/v8/test/mjsunit/turboshaft/regress-527385397.js
rename to deps/v8/test/mjsunit/turboshaft/regress-527385397-1.js
index e8d929fbeff..8788ed5c9da 100644
--- a/deps/v8/test/mjsunit/turboshaft/regress-527385397.js
+++ b/deps/v8/test/mjsunit/turboshaft/regress-527385397-1.js
@@ -4,12 +4,9 @@
// Flags: --allow-natives-syntax
-// {glob} will be used to publish the allocation to the GC. Its {x} and {y}
-// field must not be at the same offset than `arr[2]` below. And its {y} field
-// must be a Tagged field (rather than Float64) so that it forces tagging when
-// we store to it, which can trigger a GC. (the "offset_16" field is at offset
-// 16 and is needed to that the "y" field isn't).
-let glob = { x : 42, offset_16 : "skipping offset 16", y : "abc" };
+// {glob} will be used to publish the allocation to the GC. Its {x} field must
+// not be at the same offset than `arr[2]` below.
+let glob = { x : 42 };
function foo(x, ...rest) {
// Turboshaft can recognize rotations in xor trees, which Turbofan cannot. As
diff --git a/deps/v8/test/mjsunit/turboshaft/regress-527385397-2.js b/deps/v8/test/mjsunit/turboshaft/regress-527385397-2.js
new file mode 100644
index 00000000000..ebeadfee752
--- /dev/null
+++ b/deps/v8/test/mjsunit/turboshaft/regress-527385397-2.js
@@ -0,0 +1,88 @@
+// 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 --no-turbo-loop-peeling
+
+// Note on the --no-turbo-loop-peeling flag: it just makes the repro a bit nicer
+// to write. It can be replaced by a large number of pure operations in the loop
+// that depends of {i} (which will make the loop be too large to be peeled).
+
+// {glob} will be used to publish the allocation to the GC. Its {x} and {y}
+// field must not be at the same offset than `arr[2]` below. And its {y} field
+// must be a Tagged field (rather than Float64) so that it forces tagging when
+// we store to it, which can trigger a GC. (the "offset_16" field is at offset
+// 16 and is needed to that the "y" field isn't).
+let glob = { x : 42, offset_16 : "skipping offset 16", y : "abc", z : "aze" };
+
+function foo(x, ...rest) {
+ // Turboshaft can recognize rotations in xor trees, which Turbofan cannot. As
+ // a result, {lhs} and {rhs} below will not be recognized as being equal by
+ // Turbofan, but Turboshaft will realize that it's the case...
+ let lhs = (x << 2) ^ x ^ (x >>> 30);
+ let rhs = (x >>> 30) ^ x ^ (x << 2);
+ // ... which means that {cond} will be constant-folded to true but only in
+ // Turboshaft...
+ let cond = lhs == rhs;
+ // ... and len will thus be a Phi for Turbofan but 3 for Turboshaft.
+ let len = cond ? 3 : 4;
+
+ // Note that length 3 is the only one that works because:
+ //
+ // - Only loops with length 3 or less are fully unrolled
+ //
+ // - `new Array` does 2 allocation: the FixedArray backing store and the
+ // JSArray, and to initialize the latter it does 4 stores, at offsets 0
+ // (Map), 4 (properties_or_hash), 8 (elements == the FixedArra backing
+ // store) and 12 (length), and it's important that none of those have the
+ // same offset as the final `arr[2] = 42` (which will be at offset 16).
+
+ // Allocating fixed-sized array. This will be lowered to a NewArray, which
+ // itself will be lowered to a loop with 3 iterations, which will then be
+ // unrolled.
+ let arr = new Array(len);
+
+ // Publishing the array for the GC...
+ glob.y = arr;
+ // ... so that it's seen by the GC here.
+ // We can use %MajorGCForCompilerTesting(), but here we're trying
+ // to prove that the bug can happen organically (although it's hard to force
+ // a GC to happen in this loop exactly, it could theoretically happen given
+ // the right setup).
+ for (let i = 0; i < 42; i++) {
+ // Storing a Float64 to a AnyTagged field, which will require a HeapNumber
+ // allocation.
+ glob.z = i + 0.35;
+
+ // We need to replicate the store from after the loop here so that
+ // StoreStoreElimination correctly sees that `arr[2]` is Unobservable before
+ // the loop.
+
+ // This is a bit limiting: it means that to trigger the bug we need the
+ // tagging of `i + 0.35` above to trigger a GC in the first iteration of
+ // this loop. Still, might be doable.
+ arr[2] = 42;
+ }
+
+ // Storing at offset 2 in {arr}. This should not store-store eliminate with
+ // the initializing store since there is a GC in the middle.
+ arr[2] = 42;
+
+ // Making sure that {arr} escapes.
+ return arr;
+}
+
+// We need to warmup feedback with a non-smi int32 in order to avoid that `x<<2`
+// is lowered to `(x>>1)<<2` because of the untagging, since it would then be
+// optimized to `x<<1`, and the rotation would thus not be matched anymore since
+// `x<<1^x>>30` cannot be optimized to a rotation. With HeapNumber feedback, the
+// untagging will handle both Smi and HeapNumber and thus return a Phi, so
+// Turboshaft won't be able to optimize `x>>1<<2` to `x<<1` anymore.
+let non_smi_int32 = 0x80000000;
+
+%PrepareFunctionForOptimization(foo);
+foo(non_smi_int32);
+foo(42);
+
+%OptimizeFunctionOnNextCall(foo);
+foo(42);
diff --git a/deps/v8/test/mjsunit/turboshaft/regress-539984773.js b/deps/v8/test/mjsunit/turboshaft/regress-539984773.js
new file mode 100644
index 00000000000..ad24f73bb31
--- /dev/null
+++ b/deps/v8/test/mjsunit/turboshaft/regress-539984773.js
@@ -0,0 +1,54 @@
+// 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: --expose-gc --allow-natives-syntax --turbofan --no-turbolev
+// Flags: --no-optimize-on-next-call-optimizes-to-maglev
+// Flags: --concurrent-recompilation --no-stress-background-compile
+
+function makeSeqOneByte(seed) {
+ const chars = [];
+ for (let i = 0; i < 64; ++i) chars.push(65 + ((seed + i) % 23));
+ return String.fromCharCode.apply(null, chars);
+}
+
+// Ensure canonicalTwin is internalized in the string table first.
+const canonicalTwin = makeSeqOneByte(0);
+(new Map()).has(canonicalTwin);
+
+// Create an identical but non-internalized SeqOneByteString.
+const key = makeSeqOneByte(0);
+
+function constantCharCodeAt(i) {
+ return key.charCodeAt(i);
+}
+
+const expected = [];
+for (let i = 0; i < 64; ++i) expected.push(key.charCodeAt(i));
+
+%PrepareFunctionForOptimization(constantCharCodeAt);
+constantCharCodeAt(8);
+constantCharCodeAt(8);
+
+// Block background compilation at TurboshaftMachineLowering phase.
+%BlockAt('TurboshaftMachineLowering', 10000);
+%OptimizeFunctionOnNextCall(constantCharCodeAt, "concurrent");
+constantCharCodeAt(8);
+
+// Wait until background compiler thread reaches TurboshaftMachineLowering.
+assertTrue(%WaitUntilBlocked('TurboshaftMachineLowering', 10000));
+
+// Internalize 'key' on the main thread while background lowering is stopped.
+// Since canonicalTwin is in the string table, 'key' transitions in-place
+// from SeqOneByteString to a 16-byte ThinString.
+(new Map()).has(key);
+gc();
+
+// Resume background compiler thread and wait for compilation to finish.
+assertTrue(%Resume('TurboshaftMachineLowering'));
+%WaitForBackgroundOptimization();
+
+// Verify that all character codes are correct and no out-of-bounds read occurred.
+for (let i = 0; i < 64; ++i) {
+ assertEquals(expected[i], constantCharCodeAt(i));
+}
diff --git a/deps/v8/test/mjsunit/wasm/acq-rel-rmw-operations.js b/deps/v8/test/mjsunit/wasm/acq-rel-rmw-operations.js
index 2db8bb08eb3..eadf76ec4c6 100644
--- a/deps/v8/test/mjsunit/wasm/acq-rel-rmw-operations.js
+++ b/deps/v8/test/mjsunit/wasm/acq-rel-rmw-operations.js
@@ -81,47 +81,46 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
let instance = builder.instantiate();
let exports = instance.exports;
- let i32 = new Int32Array(instance.exports.memory.buffer);
+ let view = new DataView(instance.exports.memory.buffer);
let u8 = new Uint8Array(instance.exports.memory.buffer);
- let u16 = new Uint16Array(instance.exports.memory.buffer);
- i32[0] = 10;
+ view.setInt32(0, 10, true);
assertEquals(10, exports.i32_atomic_add_acq_rel(0, 5));
- assertEquals(15, i32[0]);
+ assertEquals(15, view.getInt32(0, true));
u8[0] = 10;
assertEquals(10, exports.i32_atomic_add8_u_acq_rel(0, 5));
assertEquals(15, u8[0]);
- u16[0] = 10;
+ view.setUint16(0, 10, true);
assertEquals(10, exports.i32_atomic_add16_u_acq_rel(0, 5));
- assertEquals(15, u16[0]);
+ assertEquals(15, view.getUint16(0, true));
- i32[0] = 15;
+ view.setInt32(0, 15, true);
assertEquals(15, exports.i32_atomic_sub_acq_rel(0, 7));
- assertEquals(8, i32[0]);
+ assertEquals(8, view.getInt32(0, true));
- i32[0] = 0b1100;
+ view.setInt32(0, 0b1100, true);
assertEquals(0b1100, exports.i32_atomic_and_acq_rel(0, 0b1010));
- assertEquals(0b1000, i32[0]);
+ assertEquals(0b1000, view.getInt32(0, true));
- i32[0] = 0b1000;
+ view.setInt32(0, 0b1000, true);
assertEquals(0b1000, exports.i32_atomic_or_acq_rel(0, 0b0101));
- assertEquals(0b1101, i32[0]);
+ assertEquals(0b1101, view.getInt32(0, true));
- i32[0] = 0b1101;
+ view.setInt32(0, 0b1101, true);
assertEquals(0b1101, exports.i32_atomic_xor_acq_rel(0, 0b0110));
- assertEquals(0b1011, i32[0]);
+ assertEquals(0b1011, view.getInt32(0, true));
- i32[0] = 0b1011;
+ view.setInt32(0, 0b1011, true);
assertEquals(0b1011, exports.i32_atomic_xchg_acq_rel(0, 12345));
- assertEquals(12345, i32[0]);
+ assertEquals(12345, view.getInt32(0, true));
- i32[0] = 10;
+ view.setInt32(0, 10, true);
assertEquals(10, exports.i32_atomic_cmpxchg_acq_rel(0, 10, 20));
- assertEquals(20, i32[0]);
+ assertEquals(20, view.getInt32(0, true));
assertEquals(20, exports.i32_atomic_cmpxchg_acq_rel(0, 10, 30));
- assertEquals(20, i32[0]);
+ assertEquals(20, view.getInt32(0, true));
})();
(function TestI64AtomicRmwAcqRel() {
@@ -197,50 +196,48 @@ d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
let instance = builder.instantiate();
let exports = instance.exports;
- let i64 = new BigInt64Array(instance.exports.memory.buffer);
+ let view = new DataView(instance.exports.memory.buffer);
let u8 = new Uint8Array(instance.exports.memory.buffer);
- let u16 = new Uint16Array(instance.exports.memory.buffer);
- let u32 = new Uint32Array(instance.exports.memory.buffer);
- i64[0] = 10n;
+ view.setBigInt64(0, 10n, true);
assertEquals(10n, exports.i64_atomic_add_acq_rel(0, 5n));
- assertEquals(15n, i64[0]);
+ assertEquals(15n, view.getBigInt64(0, true));
u8[0] = 10;
assertEquals(10n, exports.i64_atomic_add8_u_acq_rel(0, 5n));
assertEquals(15, u8[0]);
- u16[0] = 10;
+ view.setUint16(0, 10, true);
assertEquals(10n, exports.i64_atomic_add16_u_acq_rel(0, 5n));
- assertEquals(15, u16[0]);
+ assertEquals(15, view.getUint16(0, true));
- u32[0] = 10;
+ view.setUint32(0, 10, true);
assertEquals(10n, exports.i64_atomic_add32_u_acq_rel(0, 5n));
- assertEquals(15, u32[0]);
+ assertEquals(15, view.getUint32(0, true));
- i64[0] = 15n;
+ view.setBigInt64(0, 15n, true);
assertEquals(15n, exports.i64_atomic_sub_acq_rel(0, 7n));
- assertEquals(8n, i64[0]);
+ assertEquals(8n, view.getBigInt64(0, true));
- i64[0] = 0b1100n;
+ view.setBigInt64(0, 0b1100n, true);
assertEquals(0b1100n, exports.i64_atomic_and_acq_rel(0, 0b1010n));
- assertEquals(0b1000n, i64[0]);
+ assertEquals(0b1000n, view.getBigInt64(0, true));
- i64[0] = 0b1000n;
+ view.setBigInt64(0, 0b1000n, true);
assertEquals(0b1000n, exports.i64_atomic_or_acq_rel(0, 0b0101n));
- assertEquals(0b1101n, i64[0]);
+ assertEquals(0b1101n, view.getBigInt64(0, true));
- i64[0] = 0b1101n;
+ view.setBigInt64(0, 0b1101n, true);
assertEquals(0b1101n, exports.i64_atomic_xor_acq_rel(0, 0b0110n));
- assertEquals(0b1011n, i64[0]);
+ assertEquals(0b1011n, view.getBigInt64(0, true));
- i64[0] = 0b1011n;
+ view.setBigInt64(0, 0b1011n, true);
assertEquals(0b1011n, exports.i64_atomic_xchg_acq_rel(0, 1234567890n));
- assertEquals(1234567890n, i64[0]);
+ assertEquals(1234567890n, view.getBigInt64(0, true));
- i64[0] = 10n;
+ view.setBigInt64(0, 10n, true);
assertEquals(10n, exports.i64_atomic_cmpxchg_acq_rel(0, 10n, 20n));
- assertEquals(20n, i64[0]);
+ assertEquals(20n, view.getBigInt64(0, true));
assertEquals(20n, exports.i64_atomic_cmpxchg_acq_rel(0, 10n, 30n));
- assertEquals(20n, i64[0]);
+ assertEquals(20n, view.getBigInt64(0, true));
})();
diff --git a/deps/v8/test/mjsunit/wasm/atomic-wait-multi-memory.js b/deps/v8/test/mjsunit/wasm/atomic-wait-multi-memory.js
index 8c3f97e7ddc..53da934b75f 100644
--- a/deps/v8/test/mjsunit/wasm/atomic-wait-multi-memory.js
+++ b/deps/v8/test/mjsunit/wasm/atomic-wait-multi-memory.js
@@ -36,7 +36,10 @@ const mem1 = new WebAssembly.Memory({initial: 2, maximum: 2, shared: true});
const mem0_value = 0;
const mem1_value = 1;
-new Uint32Array(mem1.buffer).fill(mem1_value);
+const mem1_view = new DataView(mem1.buffer);
+for (let i = 0; i < mem1.buffer.byteLength; i += 4) {
+ mem1_view.setUint32(i, mem1_value, true);
+}
const imports = {
imp: {mem0: mem0, mem1: mem1}
diff --git a/deps/v8/test/mjsunit/wasm/atomics-memory64.js b/deps/v8/test/mjsunit/wasm/atomics-memory64.js
index 04d79d81a2a..71e47fc2a14 100644
--- a/deps/v8/test/mjsunit/wasm/atomics-memory64.js
+++ b/deps/v8/test/mjsunit/wasm/atomics-memory64.js
@@ -106,8 +106,8 @@ function TestAtomicI32Wait(pages, offset) {
assertEquals(kAtomicWaitNotEqual, WasmI32AtomicWait(memory, 0, offset, 42, -1));
assertEquals(kAtomicWaitTimedOut, WasmI32AtomicWait(memory, 0, offset, 0, 0));
- let i32a = new Int32Array(memory.buffer);
- i32a[offset / 4] = 1;
+ let view = new DataView(memory.buffer);
+ view.setInt32(offset, 1, true);
assertEquals(kAtomicWaitNotEqual, WasmI32AtomicWait(memory, offset, 0, 0, -1));
assertEquals(kAtomicWaitTimedOut, WasmI32AtomicWait(memory, offset, 0, 1, 0));
@@ -125,9 +125,9 @@ function TestAtomicI64Wait(pages, offset) {
assertEquals(kAtomicWaitNotEqual, WasmI64AtomicWait(memory, 0, offset, 42, 0, -1));
assertEquals(kAtomicWaitTimedOut, WasmI64AtomicWait(memory, 0, offset, 0, 0, 0));
- let i32a = new Int32Array(memory.buffer);
- i32a[offset / 4] = 1;
- i32a[(offset / 4) + 1] = 2;
+ let view = new DataView(memory.buffer);
+ view.setInt32(offset, 1, true);
+ view.setInt32(offset + 4, 2, true);
assertEquals(kAtomicWaitNotEqual, WasmI64AtomicWait(memory, offset, 0, 2, 1, -1));
assertEquals(kAtomicWaitTimedOut, WasmI64AtomicWait(memory, offset, 0, 1, 2, 0));
diff --git a/deps/v8/test/mjsunit/wasm/atomics.js b/deps/v8/test/mjsunit/wasm/atomics.js
index 53b0168b49e..56c775d240d 100644
--- a/deps/v8/test/mjsunit/wasm/atomics.js
+++ b/deps/v8/test/mjsunit/wasm/atomics.js
@@ -149,26 +149,50 @@ function VerifyBoundsCheck(func, memtype_size) {
// O(2^n), but takes 213 steps to reach 2^32.
const inc = i => i + Math.floor(i/10) + 1;
+function LEArray(buffer, size) {
+ let view = new DataView(buffer);
+ let get, set;
+ switch (size) {
+ case kMemtypeSize8:
+ get = i => view.getUint8(i);
+ set = (i, v) => view.setUint8(i, v);
+ break;
+ case kMemtypeSize16:
+ get = i => view.getUint16(i * size, true);
+ set = (i, v) => view.setUint16(i * size, v, true);
+ break;
+ case kMemtypeSize32:
+ get = i => view.getUint32(i * size, true);
+ set = (i, v) => view.setUint32(i * size, v, true);
+ break;
+ case kMemtypeSize64:
+ get = i => view.getBigUint64(i * size, true);
+ set = (i, v) => view.setBigUint64(i * size, v, true);
+ break;
+ }
+ return {length: buffer.byteLength / size, get, set};
+}
+
function Test32Op(operation, func) {
- let i32 = new Uint32Array(memory.buffer);
+ let i32 = LEArray(memory.buffer, kMemtypeSize32);
for (let i = 0; i < i32.length; i = inc(i)) {
let expected = 0x9cedf00d;
let value = 0x11111111;
- i32[i] = expected;
+ i32.set(i, expected);
assertEquals(expected, func(i * kMemtypeSize32, value) >>> 0);
- assertEquals(operation(expected, value) >>> 0, i32[i]);
+ assertEquals(operation(expected, value) >>> 0, i32.get(i));
}
VerifyBoundsCheck(func, kMemtypeSize32);
}
function Test16Op(operation, func) {
- let i16 = new Uint16Array(memory.buffer);
+ let i16 = LEArray(memory.buffer, kMemtypeSize16);
for (let i = 0; i < i16.length; i = inc(i)) {
let expected = 0xd00d;
let value = 0x1111;
- i16[i] = expected;
+ i16.set(i, expected);
assertEquals(expected, func(i * kMemtypeSize16, value));
- assertEquals(operation(expected, value), i16[i]);
+ assertEquals(operation(expected, value), i16.get(i));
}
VerifyBoundsCheck(func, kMemtypeSize16);
}
@@ -186,37 +210,37 @@ function Test8Op(operation, func) {
}
function Test64Op(operation, func) {
- let i64 = new BigUint64Array(memory.buffer);
+ let i64 = LEArray(memory.buffer, kMemtypeSize64);
for (let i = 0; i < i64.length; i = inc(i)) {
let expected = 987659876543210n;
let value = 111111111111111n;
- i64[i] = expected;
+ i64.set(i, expected);
assertEquals(expected, func(i * kMemtypeSize64, value));
- assertEquals(operation(expected, value), i64[i]);
+ assertEquals(operation(expected, value), i64.get(i));
}
VerifyBoundsCheck64(func, kMemtypeSize64);
}
function Test32Op64(operation, func) {
- let i32 = new Uint32Array(memory.buffer);
+ let i32 = LEArray(memory.buffer, kMemtypeSize32);
for (let i = 0; i < i32.length; i = inc(i)) {
let expected = 123456;
let value = 111111n;
- i32[i] = expected;
+ i32.set(i, expected);
assertEquals(expected, Number(func(i * kMemtypeSize32, value)));
- assertEquals(operation(expected, Number(value)), i32[i]);
+ assertEquals(operation(expected, Number(value)), i32.get(i));
}
VerifyBoundsCheck64(func, kMemtypeSize32);
}
function Test16Op64(operation, func) {
- let i16 = new Uint16Array(memory.buffer);
+ let i16 = LEArray(memory.buffer, kMemtypeSize16);
for (let i = 0; i < i16.length; i = inc(i)) {
let expected = 0xd00d;
let value = 0x1111n;
- i16[i] = expected;
+ i16.set(i, expected);
assertEquals(expected, Number(func(i * kMemtypeSize16, value)));
- assertEquals(operation(expected, Number(value)), i16[i]);
+ assertEquals(operation(expected, Number(value)), i16.get(i));
}
VerifyBoundsCheck64(func, kMemtypeSize16);
}
@@ -490,11 +514,11 @@ function TestCmpExchange(func, buffer, params, size, offset = 0) {
for (let i = 0; i + (offset / size) < buffer.length; i = inc(i)) {
for (let j = 0; j < params.length; j++) {
for (let k = 0; k < params.length; k++) {
- buffer[i + (offset / size)] = params[j];
+ buffer.set(i + (offset / size), params[j]);
let loaded = func(i * size, params[k], params[j]) >>> 0;
let expected = (params[k] == loaded) ? params[j] : loaded;
assertEquals(loaded, params[j]);
- assertEquals(expected, buffer[i + (offset / size)]);
+ assertEquals(expected, buffer.get(i + (offset / size)));
}
}
}
@@ -508,7 +532,7 @@ function TestCmpExchange(func, buffer, params, size, offset = 0) {
const offset = 0x1234;
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange, 2, offset);
- let i32 = new Uint32Array(memory.buffer);
+ let i32 = LEArray(memory.buffer, kMemtypeSize32);
let params = [0x00000001, 0x00000555, 0x00099999, 0xffffffff];
TestCmpExchange(wasmCmpExchange, i32, params, kMemtypeSize32, offset);
})();
@@ -517,7 +541,7 @@ function TestCmpExchange(func, buffer, params, size, offset = 0) {
print(arguments.callee.name);
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange16U, 1, 0);
- let i16 = new Uint16Array(memory.buffer);
+ let i16 = LEArray(memory.buffer, kMemtypeSize16);
let params = [0x0001, 0x0555, 0x9999];
TestCmpExchange(wasmCmpExchange, i16, params, kMemtypeSize16);
})();
@@ -526,14 +550,14 @@ function TestCmpExchange(func, buffer, params, size, offset = 0) {
print(arguments.callee.name);
let wasmCmpExchange =
GetAtomicCmpExchangeFunction(kExprI32AtomicCompareExchange8U, 0, 0);
- let i8 = new Uint8Array(memory.buffer);
+ let i8 = LEArray(memory.buffer, kMemtypeSize8);
let params = [0x01, 0x0d, 0xf9];
TestCmpExchange(wasmCmpExchange, i8, params, kMemtypeSize8);
})();
function TestLoad(func, buffer, value, size) {
for (let i = 0; i < buffer.length; i = inc(i)) {
- buffer[i] = value;
+ buffer.set(i, value);
assertEquals(value, func(i * size) >>> 0);
}
VerifyBoundsCheck(func, size);
@@ -542,7 +566,7 @@ function TestLoad(func, buffer, value, size) {
(function TestAtomicLoad() {
print(arguments.callee.name);
let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad, 2, 0);
- let i32 = new Uint32Array(memory.buffer);
+ let i32 = LEArray(memory.buffer, kMemtypeSize32);
let value = 0xacedaced;
TestLoad(wasmLoad, i32, value, kMemtypeSize32);
})();
@@ -550,7 +574,7 @@ function TestLoad(func, buffer, value, size) {
(function TestAtomicLoad16U() {
print(arguments.callee.name);
let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad16U, 1, 0);
- let i16 = new Uint16Array(memory.buffer);
+ let i16 = LEArray(memory.buffer, kMemtypeSize16);
let value = 0xaced;
TestLoad(wasmLoad, i16, value, kMemtypeSize16);
})();
@@ -558,7 +582,7 @@ function TestLoad(func, buffer, value, size) {
(function TestAtomicLoad8U() {
print(arguments.callee.name);
let wasmLoad = GetAtomicLoadFunction(kExprI32AtomicLoad8U, 0, 0);
- let i8 = new Uint8Array(memory.buffer);
+ let i8 = LEArray(memory.buffer, kMemtypeSize8);
let value = 0xac;
TestLoad(wasmLoad, i8, value, kMemtypeSize8);
})();
@@ -566,7 +590,7 @@ function TestLoad(func, buffer, value, size) {
function TestStore(func, buffer, value, size) {
for (let i = 0; i < buffer.length; i = inc(i)) {
func(i * size, value)
- assertEquals(value, buffer[i]);
+ assertEquals(value, buffer.get(i));
}
VerifyBoundsCheck(func, size);
}
@@ -574,7 +598,7 @@ function TestStore(func, buffer, value, size) {
(function TestAtomicStore() {
print(arguments.callee.name);
let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore, 2, 0);
- let i32 = new Uint32Array(memory.buffer);
+ let i32 = LEArray(memory.buffer, kMemtypeSize32);
let value = 0xacedaced;
TestStore(wasmStore, i32, value, kMemtypeSize32);
})();
@@ -582,7 +606,7 @@ function TestStore(func, buffer, value, size) {
(function TestAtomicStore16U() {
print(arguments.callee.name);
let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore16U, 1, 0);
- let i16 = new Uint16Array(memory.buffer);
+ let i16 = LEArray(memory.buffer, kMemtypeSize16);
let value = 0xaced;
TestStore(wasmStore, i16, value, kMemtypeSize16);
})();
@@ -590,9 +614,9 @@ function TestStore(func, buffer, value, size) {
(function TestAtomicStore8U() {
print(arguments.callee.name);
let wasmStore = GetAtomicStoreFunction(kExprI32AtomicStore8U, 0, 0);
- let i8 = new Uint8Array(memory.buffer);
+ let i8 = LEArray(memory.buffer, kMemtypeSize8);
let value = 0xac;
- TestCmpExchange(wasmStore, i8, value, kMemtypeSize8);
+ TestStore(wasmStore, i8, value, kMemtypeSize8);
})();
(function TestAtomicLoadStoreOffset() {
diff --git a/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js b/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js
index c18772b3377..20b1bfed34c 100644
--- a/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js
+++ b/deps/v8/test/mjsunit/wasm/compiled-module-serialization.js
@@ -40,8 +40,8 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
var wire_bytes = builder.toBuffer();
var module = new WebAssembly.Module(wire_bytes);
var mem_1 = new WebAssembly.Memory({initial: 1});
- var view_1 = new Int32Array(mem_1.buffer);
- view_1[0] = 42;
+ var view_1 = new DataView(mem_1.buffer);
+ view_1.setInt32(0, 42, true);
var outval_1;
var i1 = new WebAssembly.Instance(module, {"":
{some_value: () => 1,
@@ -58,9 +58,9 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
module = d8.wasm.deserializeModule(buff, wire_bytes);
var mem_2 = new WebAssembly.Memory({initial: 2});
- var view_2 = new Int32Array(mem_2.buffer);
+ var view_2 = new DataView(mem_2.buffer);
- view_2[0] = 50;
+ view_2.setInt32(0, 50, true);
var outval_2;
var i2 = new WebAssembly.Instance(module, {"":
diff --git a/deps/v8/test/mjsunit/wasm/custom-descriptors-validity.js b/deps/v8/test/mjsunit/wasm/custom-descriptors-validity.js
index 2d302c22213..980265f269f 100644
--- a/deps/v8/test/mjsunit/wasm/custom-descriptors-validity.js
+++ b/deps/v8/test/mjsunit/wasm/custom-descriptors-validity.js
@@ -111,6 +111,28 @@ CheckInvalid(/Type 0 and its descriptor 1 must have same sharedness/,
builder.addStruct({describes: 0, shared: true});
});
+CheckValid((builder) => {
+ builder.addStruct({descriptor: 1, final: true});
+ builder.addStruct({describes: 0, final: true});
+});
+
+CheckValid((builder) => {
+ builder.addStruct({descriptor: 1, final: false});
+ builder.addStruct({describes: 0, final: false});
+});
+
+CheckInvalid(
+ /Type 0 and its descriptor 1 must have same finality/, (builder) => {
+ builder.addStruct({descriptor: 1, final: true});
+ builder.addStruct({describes: 0, final: false});
+ });
+
+CheckInvalid(
+ /Type 0 and its descriptor 1 must have same finality/, (builder) => {
+ builder.addStruct({descriptor: 1, final: false});
+ builder.addStruct({describes: 0, final: true});
+ });
+
CheckValid((builder) => {
builder.addStruct({descriptor: 1, final: false}); // 0
builder.addStruct({describes: 0, final: false}); // 1
@@ -119,7 +141,7 @@ CheckValid((builder) => {
builder.addStruct({describes: 2, supertype: 1}); // 3
});
-CheckInvalid(/type 4 has invalid explicit supertype 2/, (builder) => {
+CheckInvalid(/type 3 has invalid explicit supertype 0/, (builder) => {
builder.addStruct({final: false}); // 0
}, (builder) => {
builder.addStruct({descriptor: 2}); // 1
@@ -129,7 +151,7 @@ CheckInvalid(/type 4 has invalid explicit supertype 2/, (builder) => {
builder.addStruct({describes: 3, supertype: 2}); // 4
});
-CheckInvalid(/type 3 has invalid explicit supertype 1/, (builder) => {
+CheckInvalid(/type 2 has invalid explicit supertype 0/, (builder) => {
builder.addStruct({final: false}); // 0
builder.addStruct({final: false}); // 1
}, (builder) => {
@@ -149,14 +171,23 @@ CheckInvalid(/type 4 has invalid explicit supertype 2/, (builder) => {
CheckInvalid(/type 2 has invalid explicit supertype 0/, (builder) => {
builder.addStruct({descriptor: 1, final: false}); // 0
- builder.addStruct({describes: 0}); // 1
+ builder.addStruct({describes: 0, final: false}); // 1
}, (builder) => {
builder.addStruct({supertype: 0}); // 2
});
-CheckInvalid(/type 2 has invalid explicit supertype 1/, (builder) => {
- builder.addStruct({descriptor: 1}); // 0
- builder.addStruct({describes: 0, final: false}); // 1
-}, (builder) => {
- builder.addStruct({supertype: 1}); // 2
+CheckInvalid(
+ /type 2 has invalid explicit supertype 1/,
+ (builder) => {
+ builder.addStruct({descriptor: 1, final: false}); // 0
+ builder.addStruct({describes: 0, final: false}); // 1
+ },
+ (builder) => {
+ builder.addStruct({supertype: 1}); // 2
+ });
+
+CheckInvalid(/type 1 has invalid explicit supertype 0/, (builder) => {
+ builder.addStruct({final: false}); // 0
+ builder.addStruct({supertype: 0, descriptor: 2}); // 1
+ builder.addStruct({describes: 1}); // 2
});
diff --git a/deps/v8/test/mjsunit/wasm/futex.js b/deps/v8/test/mjsunit/wasm/futex.js
index 5232a145bbe..a7626729f34 100644
--- a/deps/v8/test/mjsunit/wasm/futex.js
+++ b/deps/v8/test/mjsunit/wasm/futex.js
@@ -181,8 +181,8 @@ function WasmI64AtomicWait(memory, offset, index, val_low,
assertEquals(kAtomicWaitTimedOut, WasmI32AtomicWait(memory, 0, 0, 0, 0));
- let i32a = new Int32Array(memory.buffer);
- i32a[0] = 1;
+ let view = new DataView(memory.buffer);
+ view.setInt32(0, 1, true);
assertEquals(kAtomicWaitNotEqual, WasmI32AtomicWait(memory, 0, 0, 0, -1));
assertEquals(kAtomicWaitTimedOut, WasmI32AtomicWait(memory, 0, 0, 1, 0));
})();
@@ -194,9 +194,9 @@ function WasmI64AtomicWait(memory, offset, index, val_low,
assertEquals(kAtomicWaitTimedOut, WasmI64AtomicWait(memory, 0, 0, 0, 0, 0));
- let i32a = new Int32Array(memory.buffer);
- i32a[0] = 1;
- i32a[1] = 2;
+ let view = new DataView(memory.buffer);
+ view.setInt32(0, 1, true);
+ view.setInt32(4, 2, true);
assertEquals(kAtomicWaitNotEqual, WasmI64AtomicWait(memory, 0, 0, 0, 0, -1));
assertEquals(kAtomicWaitTimedOut, WasmI64AtomicWait(memory, 0, 0, 1, 2, 0));
})();
diff --git a/deps/v8/test/mjsunit/wasm/gc-js-interop.js b/deps/v8/test/mjsunit/wasm/gc-js-interop.js
index d5c7177d134..62d9732bf15 100644
--- a/deps/v8/test/mjsunit/wasm/gc-js-interop.js
+++ b/deps/v8/test/mjsunit/wasm/gc-js-interop.js
@@ -100,12 +100,14 @@ for (const wasm_obj of [struct, array]) {
testThrowsRepeated(
() => {class SubClass extends wasm_obj {}}, TypeError,
'Class extends value [object Object] is not a constructor or null');
- repeated(() => {
+ {
class TestMemberInit {
x = wasm_obj;
- };
- assertSame(wasm_obj, new TestMemberInit().x);
- });
+ }
+ repeated(() => {
+ assertSame(wasm_obj, new TestMemberInit().x);
+ });
+ }
repeated(() => assertSame(wasm_obj, eval('wasm_obj')));
// Test functions of the global object.
diff --git a/deps/v8/test/mjsunit/wasm/import-memory.js b/deps/v8/test/mjsunit/wasm/import-memory.js
index ef00ad0e720..e6002b22c59 100644
--- a/deps/v8/test/mjsunit/wasm/import-memory.js
+++ b/deps/v8/test/mjsunit/wasm/import-memory.js
@@ -11,7 +11,7 @@ var kV8MaxPages = 65536;
print("TestOne");
let memory = new WebAssembly.Memory({initial: 1});
assertEquals(kPageSize, memory.buffer.byteLength);
- let i32 = new Int32Array(memory.buffer);
+ let view = new DataView(memory.buffer);
let builder = new WasmModuleBuilder();
builder.addImportedMemory("mod", "mine");
builder.addFunction("main", kSig_i_v)
@@ -23,7 +23,7 @@ var kV8MaxPages = 65536;
let main = builder.instantiate({mod: {mine: memory}}).exports.main;
assertEquals(0, main());
- i32[0] = 993377;
+ view.setInt32(0, 993377, true);
assertEquals(993377, main());
})();
@@ -67,12 +67,12 @@ var kV8MaxPages = 65536;
i2 = builder.instantiate({fil: {imported_mem: i1.exports.exported_mem}});
}
- let i32 = new Int32Array(i1.exports.exported_mem.buffer);
+ let view = new DataView(i1.exports.exported_mem.buffer);
for (var i = 0; i < 1e11; i = i * 3 + 5) {
for (var j = 0; j < 10; j++) {
var val = i + 99077 + j;
- i32[j] = val;
+ view.setInt32(j * 4, val, true);
assertEquals(val | 0, i1.exports.foo(j * 4));
assertEquals(val | 0, i2.exports.bar(j * 4));
}
diff --git a/deps/v8/test/mjsunit/wasm/import-wrapper-uninhabitable.js b/deps/v8/test/mjsunit/wasm/import-wrapper-uninhabitable.js
new file mode 100644
index 00000000000..7d279dd2036
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/import-wrapper-uninhabitable.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.
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+let builder = new WasmModuleBuilder();
+
+let uninhabitable = wasmRefType(kWasmNullRef);
+
+builder.addImport("m", "f", makeSig([uninhabitable], [uninhabitable]));
+
+builder.addImport("m", "g", makeSig([uninhabitable, kWasmI32],
+ [uninhabitable, kWasmI32]));
+
+builder.addExport("f_exported", 0);
+builder.addExport("g_exported", 1);
+
+let wasm = builder.instantiate(
+ {m: {f: (x) => null, g: (x, y) => [null, 42]}})
+ .exports;
+
+assertThrows(() => wasm.f_exported(null), TypeError,
+ "type incompatibility when transforming from/to JS")
+assertThrows(() => wasm.g_exported(null, 42), TypeError,
+ "type incompatibility when transforming from/to JS");
diff --git a/deps/v8/test/mjsunit/wasm/return-calls.js b/deps/v8/test/mjsunit/wasm/return-calls.js
index 4c83da26b91..3d6a44084f0 100644
--- a/deps/v8/test/mjsunit/wasm/return-calls.js
+++ b/deps/v8/test/mjsunit/wasm/return-calls.js
@@ -204,3 +204,52 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(expect, module.exports.main(...inputs));
}
})();
+
+(function TestReturnCallDropManyStackParams() {
+ print(arguments.callee.name);
+ // Tail-call from a function with many stack parameters to one with none, so
+ // that the stack-pointer adjustment does not fit in a small immediate on all
+ // platforms.
+ const kNumParams = 320;
+ let builder = new WasmModuleBuilder();
+
+ let callee = builder.addFunction('callee', kSig_i_v).addBody([
+ kExprI32Const, 42
+ ]);
+
+ const callerSig =
+ makeSig(new Array(kNumParams).fill(kWasmI64), [kWasmI32]);
+ let caller = builder.addFunction('caller', callerSig).addBody([
+ kExprReturnCall, callee.index
+ ]);
+
+ let body = [];
+ for (let i = 0; i < kNumParams; ++i) body.push(...wasmI64Const(i));
+ body.push(kExprCallFunction, caller.index);
+ builder.addFunction('main', kSig_i_v).addBody(body).exportFunc();
+
+ let instance = builder.instantiate();
+ assertEquals(42, instance.exports.main());
+})();
+
+(function TestReturnCallAddManyStackParams() {
+ print(arguments.callee.name);
+ // Tail-call from a function with no parameters to one with many stack
+ // parameters.
+ const kNumParams = 320;
+ let builder = new WasmModuleBuilder();
+
+ const calleeSig =
+ makeSig(new Array(kNumParams).fill(kWasmI64), [kWasmI32]);
+ let callee = builder.addFunction('callee', calleeSig).addBody([
+ kExprLocalGet, ...wasmUnsignedLeb(kNumParams - 1), kExprI32ConvertI64
+ ]);
+
+ let body = [];
+ for (let i = 0; i < kNumParams; ++i) body.push(...wasmI64Const(i));
+ body.push(kExprReturnCall, callee.index);
+ builder.addFunction('main', kSig_i_v).addBody(body).exportFunc();
+
+ let instance = builder.instantiate();
+ assertEquals(kNumParams - 1, instance.exports.main());
+})();
diff --git a/deps/v8/test/mjsunit/wasm/shared-everything/ref-cast-in-different-isolate.js b/deps/v8/test/mjsunit/wasm/shared-everything/ref-cast-in-different-isolate.js
new file mode 100644
index 00000000000..17fd9285ccc
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/shared-everything/ref-cast-in-different-isolate.js
@@ -0,0 +1,54 @@
+// 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");
+
+(function PostSharedStructTypeCheck() {
+ print(arguments.callee.name);
+
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct(
+ {fields: [makeField(kWasmI32, true)], shared: true});
+ let producer_sig = makeSig([kWasmI32], [wasmRefType(struct)]);
+ builder.addFunction("producer", producer_sig)
+ .addBody([kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct])
+ .exportFunc();
+
+ let instance = builder.instantiate();
+
+ let worker = new Worker(function() {
+ onmessage = function({data:msg}) {
+ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct(
+ {fields: [makeField(kWasmI32, true)], shared: true});
+ let check_sig =
+ makeSig([wasmRefNullType(kWasmAnyRef).shared()], [kWasmI32]);
+ builder.addFunction("check", check_sig)
+ .addBody([
+ kExprLocalGet, 0,
+ kGCPrefix, kExprRefTest,
+ ...wasmEncodeHeapType(wasmRefNullType(struct))
+ ])
+ .exportFunc();
+
+ let instance = builder.instantiate();
+ let is_match = instance.exports.check(msg.struct);
+ postMessage({is_match: is_match});
+ return;
+ }
+ }, {type: 'function'});
+
+ let value = 42;
+ let struct_obj = instance.exports.producer(value);
+ worker.postMessage({struct: struct_obj});
+
+ let response = worker.getMessage();
+ assertEquals(1, response.is_match);
+})();
diff --git a/deps/v8/test/mjsunit/wasm/shared-everything/shared-js-roundtrip.js b/deps/v8/test/mjsunit/wasm/shared-everything/shared-js-roundtrip.js
new file mode 100644
index 00000000000..24c26a0d11e
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/shared-everything/shared-js-roundtrip.js
@@ -0,0 +1,108 @@
+// 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 =
+ builder.addStruct({fields: [makeField(kWasmI32, true)], shared: false});
+let shared_struct =
+ builder.addStruct({fields: [makeField(kWasmI32, true)], shared: true});
+
+builder.addFunction("producer", makeSig([], [wasmRefType(struct)]))
+ .addBody([kGCPrefix, kExprStructNewDefault, struct])
+ .exportFunc();
+
+builder.addFunction(
+ "shared_producer", makeSig([], [wasmRefType(shared_struct)]))
+ .addBody([kGCPrefix, kExprStructNewDefault, shared_struct])
+ .exportFunc();
+
+let struct_type = wasmRefNullType(kWasmStructRef);
+builder.addFunction("id", makeSig([struct_type], [struct_type]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+let shared_struct_type = wasmRefNullType(kWasmStructRef).shared();
+builder.addFunction(
+ "shared_id", makeSig([shared_struct_type], [shared_struct_type]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+builder.addFunction("eq_id", makeSig([kWasmEqRef], [kWasmEqRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+let shared_eq_type = wasmRefNullType(kWasmEqRef).shared();
+
+builder.addFunction("shared_eq_id", makeSig([shared_eq_type], [shared_eq_type]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+builder.addFunction("any_id", makeSig([kWasmAnyRef], [kWasmAnyRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+let shared_any_type = wasmRefNullType(kWasmAnyRef).shared();
+
+builder.addFunction("shared_any_id",
+ makeSig([shared_any_type], [shared_any_type]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+builder.addFunction("extern_id", makeSig([kWasmExternRef], [kWasmExternRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+let shared_extern_type = wasmRefNullType(kWasmExternRef).shared();
+
+builder.addFunction("shared_extern_id",
+ makeSig([shared_extern_type], [shared_extern_type]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+
+let wasm = builder.instantiate().exports;
+
+function error(fn) {
+ assertThrows(fn, TypeError,
+ 'type incompatibility when transforming from/to JS');
+}
+
+// We can roundtrip a non-shared struct as structref and a shared struct as
+// (shared structref)...
+wasm.id(wasm.producer());
+wasm.shared_id(wasm.shared_producer());
+
+// ... but not vice versa.
+error(() => wasm.id(wasm.shared_producer()));
+error(() => wasm.shared_id(wasm.producer()));
+
+// Same for eqref.
+wasm.eq_id(wasm.producer());
+wasm.shared_eq_id(wasm.shared_producer());
+error(() => wasm.eq_id(wasm.shared_producer()));
+error(() => wasm.shared_eq_id(wasm.producer()));
+
+// For anyref (nullable) there are no type errors.
+wasm.any_id(wasm.producer());
+wasm.any_id(wasm.shared_producer());
+// For shared anyref, non-shareable objects throw.
+wasm.shared_any_id(wasm.shared_producer());
+assertEquals("hello", wasm.shared_any_id("hello"));
+assertEquals(42, wasm.shared_any_id(42));
+assertEquals(42.5, wasm.shared_any_id(42.5));
+error(() => wasm.shared_any_id(wasm.producer()));
+error(() => wasm.shared_any_id({}));
+
+// For shared externref, non-shareable objects throw.
+wasm.extern_id(wasm.producer());
+wasm.extern_id(wasm.shared_producer());
+wasm.shared_extern_id(wasm.shared_producer());
+assertEquals("hello", wasm.shared_extern_id("hello"));
+error(() => wasm.shared_extern_id(wasm.producer()));
+error(() => wasm.shared_extern_id({}));
diff --git a/deps/v8/test/mjsunit/wasm/shared-everything/wrapper-type-checks.js b/deps/v8/test/mjsunit/wasm/shared-everything/wrapper-type-checks.js
index 30f3308a53b..7756eabb490 100644
--- a/deps/v8/test/mjsunit/wasm/shared-everything/wrapper-type-checks.js
+++ b/deps/v8/test/mjsunit/wasm/shared-everything/wrapper-type-checks.js
@@ -220,3 +220,50 @@ for (const {name, type, valid, invalid} of tests) {
}
}
}
+
+(function SharedStructInDifferentIsolate() {
+ print(arguments.callee.name);
+
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct(
+ {fields: [makeField(kWasmI32, true)], shared: true});
+ let producer_sig = makeSig([kWasmI32], [wasmRefType(struct)]);
+ builder.addFunction("producer", producer_sig)
+ .addBody([kExprLocalGet, 0, kGCPrefix, kExprStructNew, struct])
+ .exportFunc();
+
+ let instance = builder.instantiate();
+
+ let worker = new Worker(function() {
+ onmessage = function({data:msg}) {
+ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct(
+ {fields: [makeField(kWasmI32, true)], shared: true});
+ let id_sig =
+ makeSig([wasmRefNullType(struct)], [wasmRefNullType(struct)]);
+ builder.addFunction("id", id_sig)
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let instance = builder.instantiate();
+ try {
+ instance.exports.id(msg.struct);
+ postMessage({success: 1});
+ } catch {
+ postMessage({success: 0});
+ }
+ return;
+ }
+ }, {type: 'function'});
+
+ let value = 42;
+ let struct_obj = instance.exports.producer(value);
+ worker.postMessage({struct: struct_obj});
+
+ let response = worker.getMessage();
+ assertEquals(1, response.success);
+})();
diff --git a/deps/v8/test/mjsunit/wasm/simd-dot-i8x16.js b/deps/v8/test/mjsunit/wasm/simd-dot-i8x16.js
index 9f3ecf83fee..54de4c72d25 100644
--- a/deps/v8/test/mjsunit/wasm/simd-dot-i8x16.js
+++ b/deps/v8/test/mjsunit/wasm/simd-dot-i8x16.js
@@ -206,3 +206,171 @@ d8.file.execute('test/mjsunit/value-helper.js');
}
}
})();
+
+(function I32x4DotI8x16SAddReduce() {
+ const builder = new WasmModuleBuilder();
+ builder.addMemory(1, 1, false);
+ builder.exportMemoryAs('memory');
+
+ const load_offsets = [0, 3, 8, 16, 32];
+ builder.addFunction('simd_dot_reduce', kSig_i_ii)
+ .addLocals(kWasmS128, 3)
+ .addBody([
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalTee, 2,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalTee, 3,
+ ...SimdInstr(kExprI16x8ExtMulLowI8x16S),
+ ...SimdInstr(kExprI32x4ExtAddPairwiseI16x8S),
+ kExprLocalGet, 2,
+ kExprLocalGet, 3,
+ ...SimdInstr(kExprI16x8ExtMulHighI8x16S),
+ ...SimdInstr(kExprI32x4ExtAddPairwiseI16x8S),
+ ...SimdInstr(kExprI32x4Add),
+ kExprLocalTee, 4,
+ kSimdPrefix, kExprI32x4ExtractLane, 0,
+ kExprLocalGet, 4,
+ kSimdPrefix, kExprI32x4ExtractLane, 1,
+ kExprLocalGet, 4,
+ kSimdPrefix, kExprI32x4ExtractLane, 2,
+ kExprLocalGet, 4,
+ kSimdPrefix, kExprI32x4ExtractLane, 3,
+ kExprI32Add,
+ kExprI32Add,
+ kExprI32Add,
+ ])
+ .exportFunc();
+
+ const instance = builder.instantiate();
+ const mem = new Int8Array(instance.exports.memory.buffer);
+ for (let i = 0; i < 64; ++i) {
+ mem[i] = int8_array[i % int8_array.length];
+ }
+
+ function expectedDotReduce(left, right) {
+ let sum = 0;
+ for (let i = 0; i < 16; ++i) {
+ sum += mem[left + i] * mem[right + i];
+ }
+ return sum;
+ }
+
+ for (const left of load_offsets) {
+ for (const right of load_offsets) {
+ assertEquals(
+ expectedDotReduce(left, right),
+ instance.exports.simd_dot_reduce(left, right));
+ }
+ }
+})();
+
+(function I32x4DotI8x16SAddReduceLoopWithTwoDotChains() {
+ const builder = new WasmModuleBuilder();
+ builder.addMemory(1, 1, false);
+ builder.exportMemoryAs('memory');
+
+ const load_offsets = [0, 3, 8, 16, 32];
+ const sig = makeSig(
+ [kWasmI32, kWasmI32, kWasmI32, kWasmI32, kWasmI32], [kWasmI32]);
+
+ builder.addFunction('simd_two_dot_chains_loop_reduce', sig)
+ .addLocals(kWasmS128, 3)
+ .addBody([
+ ...wasmS128Const(new Array(16).fill(0)),
+ kExprLocalSet, 5,
+
+ kExprBlock, kWasmVoid,
+ kExprLoop, kWasmVoid,
+ kExprLocalGet, 4,
+ kExprI32Eqz,
+ kExprBrIf, 1,
+
+ kExprLocalGet, 5,
+
+ kExprLocalGet, 0,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalTee, 6,
+ kExprLocalGet, 1,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalTee, 7,
+ ...SimdInstr(kExprI16x8ExtMulLowI8x16S),
+ ...SimdInstr(kExprI32x4ExtAddPairwiseI16x8S),
+ kExprLocalGet, 6,
+ kExprLocalGet, 7,
+ ...SimdInstr(kExprI16x8ExtMulHighI8x16S),
+ ...SimdInstr(kExprI32x4ExtAddPairwiseI16x8S),
+ ...SimdInstr(kExprI32x4Add),
+
+ kExprLocalGet, 2,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalTee, 6,
+ kExprLocalGet, 3,
+ kSimdPrefix, kExprS128LoadMem, 0, 0,
+ kExprLocalTee, 7,
+ ...SimdInstr(kExprI16x8ExtMulLowI8x16S),
+ ...SimdInstr(kExprI32x4ExtAddPairwiseI16x8S),
+ kExprLocalGet, 6,
+ kExprLocalGet, 7,
+ ...SimdInstr(kExprI16x8ExtMulHighI8x16S),
+ ...SimdInstr(kExprI32x4ExtAddPairwiseI16x8S),
+ ...SimdInstr(kExprI32x4Add),
+
+ ...SimdInstr(kExprI32x4Add),
+ ...SimdInstr(kExprI32x4Add),
+ kExprLocalSet, 5,
+
+ kExprLocalGet, 4,
+ kExprI32Const, 1,
+ kExprI32Sub,
+ kExprLocalSet, 4,
+ kExprBr, 0,
+ kExprEnd,
+ kExprEnd,
+
+ kExprLocalGet, 5,
+ kExprLocalTee, 6,
+ kSimdPrefix, kExprI32x4ExtractLane, 0,
+ kExprLocalGet, 6,
+ kSimdPrefix, kExprI32x4ExtractLane, 1,
+ kExprLocalGet, 6,
+ kSimdPrefix, kExprI32x4ExtractLane, 2,
+ kExprLocalGet, 6,
+ kSimdPrefix, kExprI32x4ExtractLane, 3,
+ kExprI32Add,
+ kExprI32Add,
+ kExprI32Add,
+ ])
+ .exportFunc();
+
+ const instance = builder.instantiate();
+ const mem = new Int8Array(instance.exports.memory.buffer);
+ for (let i = 0; i < 128; ++i) {
+ mem[i] = int8_array[i % int8_array.length];
+ }
+
+ function expectedDotReduce(left, right) {
+ let sum = 0;
+ for (let i = 0; i < 16; ++i) {
+ sum += mem[left + i] * mem[right + i];
+ }
+ return sum;
+ }
+
+ for (const left0 of load_offsets) {
+ for (const right0 of load_offsets) {
+ for (const left1 of load_offsets) {
+ for (const right1 of load_offsets) {
+ for (const iterations of [0, 1, 2, 5]) {
+ assertEquals(
+ iterations * (expectedDotReduce(left0, right0) +
+ expectedDotReduce(left1, right1)) | 0,
+ instance.exports.simd_two_dot_chains_loop_reduce(
+ left0, right0, left1, right1, iterations));
+ }
+ }
+ }
+ }
+ }
+})();
diff --git a/deps/v8/test/mjsunit/wasm/stack-switching-minor-gc.js b/deps/v8/test/mjsunit/wasm/stack-switching-minor-gc.js
new file mode 100644
index 00000000000..17732138f11
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/stack-switching-minor-gc.js
@@ -0,0 +1,98 @@
+// 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 --expose-gc
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+(function TestMinorGCOnSuspendedStack() {
+ let builder = new WasmModuleBuilder();
+ let struct_type = builder.addStruct([makeField(kWasmI32, true)]);
+ let struct_ref = wasmRefType(struct_type);
+
+ let sig_i_v = builder.addType(kSig_i_v);
+ let cont_i_v = builder.addCont(sig_i_v);
+
+ let tag0 = builder.addTag(kSig_v_v);
+
+ let block_sig = builder.addType(makeSig([], [wasmRefType(cont_i_v)]));
+ let g_cont = builder.addGlobal(wasmRefNullType(cont_i_v), true, false);
+
+ // Inner function: allocates a struct, stores it in a local, suspends, and reads it after resume.
+ let inner = builder.addFunction("inner", sig_i_v)
+ .addLocals(struct_ref, 1)
+ .addBody([
+ // Allocate a new struct with value 42 and spill it to local 0.
+ ...wasmI32Const(42),
+ kGCPrefix, kExprStructNew, struct_type,
+ kExprLocalSet, 0,
+
+ // Suspend the stack.
+ kExprSuspend, tag0,
+
+ // Verify the struct reference in local 0 is still valid.
+ kExprLocalGet, 0,
+ kGCPrefix, kExprStructGet, struct_type, 0,
+ ]);
+
+ // Outer function on continuation: also allocates a struct and calls inner.
+ let outer = builder.addFunction("outer", sig_i_v)
+ .addLocals(struct_ref, 1)
+ .addBody([
+ // Allocate a struct with value 100 in local 0.
+ ...wasmI32Const(100),
+ kGCPrefix, kExprStructNew, struct_type,
+ kExprLocalSet, 0,
+
+ // Call inner, which will suspend.
+ kExprCallFunction, inner.index,
+
+ // Add the value from local 0 (100) to inner's return value (42).
+ kExprLocalGet, 0,
+ kGCPrefix, kExprStructGet, struct_type, 0,
+ kExprI32Add,
+ ]);
+
+ builder.addDeclarativeElementSegment([outer.index]);
+
+ // Start the continuation and suspend.
+ builder.addFunction("start", kSig_v_v)
+ .addBody([
+ kExprBlock, block_sig,
+ kExprRefFunc, outer.index,
+ kExprContNew, cont_i_v,
+ kExprResume, cont_i_v, 1, kOnSuspend, tag0, 0,
+ // If outer returns without suspending, unreachable.
+ kExprUnreachable,
+ kExprEnd,
+ // Save suspended continuation in global.
+ kExprGlobalSet, g_cont.index,
+ ]).exportFunc();
+
+ // Resume the suspended continuation.
+ builder.addFunction("resume", sig_i_v)
+ .addBody([
+ kExprGlobalGet, g_cont.index,
+ kExprResume, cont_i_v, 0,
+ ]).exportFunc();
+
+ let instance = builder.instantiate();
+
+ // 1. Start the continuation; it will suspend in inner().
+ instance.exports.start();
+
+ // 2. Trigger first minor GC: struct objects survive and copy to to-space.
+ gc({ type: 'minor' });
+
+ // 3. Trigger second minor GC: struct objects are promoted to old space,
+ // setting skip_minor_gc_ = true.
+ gc({ type: 'minor' });
+
+ // 4. Trigger third minor GC: takes the early return path (skipping the stack).
+ gc({ type: 'minor' });
+
+ // 5. Resume the continuation and verify the spilled struct objects were preserved.
+ let result = instance.exports.resume();
+ assertEquals(142, result);
+})();
diff --git a/deps/v8/test/mjsunit/wasm/stringrefs-js.js b/deps/v8/test/mjsunit/wasm/stringrefs-js.js
index d413d945c2f..b03f06c4b1c 100644
--- a/deps/v8/test/mjsunit/wasm/stringrefs-js.js
+++ b/deps/v8/test/mjsunit/wasm/stringrefs-js.js
@@ -249,6 +249,9 @@ function assertInvalid(fn, message) {
"WebAssembly.Table(): " +
"Missing initial value when creating stringref table");
+ let t_zero = new WebAssembly.Table({ element: 'stringref', initial: 0 });
+ assertEquals(0, t_zero.length);
+
let kSig_w_v = makeSig([], [kWasmStringRef]);
let kSig_v_w = makeSig([kWasmStringRef], []);
let builder = new WasmModuleBuilder();
diff --git a/deps/v8/test/mjsunit/wasm/table.js b/deps/v8/test/mjsunit/wasm/table.js
index 629cf76158f..900d470cb31 100644
--- a/deps/v8/test/mjsunit/wasm/table.js
+++ b/deps/v8/test/mjsunit/wasm/table.js
@@ -113,6 +113,29 @@ function assertTableIsValid(table, length) {
assertTableIsValid(table, 10);
})();
+(function TestTableInitialNullShapes() {
+ print("TestTableInitialNullShapes");
+ // funcref table with no initializer
+ let t1 = new WebAssembly.Table({element: "anyfunc", initial: 1});
+ assertEquals(null, t1.get(0));
+
+ // funcref table with explicit null
+ let t2 = new WebAssembly.Table({element: "anyfunc", initial: 1}, null);
+ assertEquals(null, t2.get(0));
+
+ // externref table with no initializer
+ let t3 = new WebAssembly.Table({element: "externref", initial: 1});
+ assertEquals(undefined, t3.get(0));
+
+ // externref table with explicit null
+ let t4 = new WebAssembly.Table({element: "externref", initial: 1}, null);
+ assertEquals(null, t4.get(0));
+
+ // externref table with explicit undefined
+ let t5 = new WebAssembly.Table({element: "externref", initial: 1}, undefined);
+ assertEquals(undefined, t5.get(0));
+})();
+
(function TestMaximumDoesHasProperty() {
var hasPropertyWasCalled = false;
var desc = {element: "anyfunc", initial: 10};
diff --git a/deps/v8/test/mjsunit/wasm/wasm-gc-js-roundtrip.js b/deps/v8/test/mjsunit/wasm/wasm-gc-js-roundtrip.js
index b05b5bf3189..1f8d9cf3b62 100644
--- a/deps/v8/test/mjsunit/wasm/wasm-gc-js-roundtrip.js
+++ b/deps/v8/test/mjsunit/wasm/wasm-gc-js-roundtrip.js
@@ -2,11 +2,18 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+// Flags: --wasm-custom-descriptors
+// (for exact types)
+
d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
let instance = (() => {
let builder = new WasmModuleBuilder();
let struct = builder.addStruct([makeField(kWasmI32, true)]);
+ let sub_struct = builder.addStruct({
+ fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)],
+ supertype: struct
+ });
let array = builder.addArray(kWasmF64);
let sig = builder.addType(makeSig([kWasmI32], [kWasmI32]));
@@ -18,6 +25,10 @@ let instance = (() => {
.addBody([kGCPrefix, kExprStructNewDefault, struct])
.exportFunc();
+ builder.addFunction('sub_struct_producer', makeSig([], [kWasmStructRef]))
+ .addBody([kGCPrefix, kExprStructNewDefault, sub_struct])
+ .exportFunc();
+
builder.addFunction('array_producer', makeSig([], [kWasmArrayRef]))
.addBody([
kExprI32Const, 10,
@@ -37,6 +48,8 @@ let instance = (() => {
struct: kWasmStructRef,
array: kWasmArrayRef,
raw_struct: struct,
+ raw_struct_exact: struct,
+ raw_sub_struct: sub_struct,
raw_array: array,
typed_func: sig,
i31: kWasmI31Ref,
@@ -51,14 +64,33 @@ let instance = (() => {
for (key in test_types) {
let type = wasmRefNullType(test_types[key]);
+ if (key == 'raw_struct_exact') type = type.exact();
builder.addFunction(key + '_id', makeSig([type], [type]))
.addBody([kExprLocalGet, 0])
.exportFunc();
+ let type_encoding = key == 'raw_struct_exact'
+ ? [kWasmExact, ...wasmSignedLeb(test_types[key])]
+ : wasmSignedLeb(test_types[key]);
builder.addFunction(key + '_null', makeSig([], [type]))
- .addBody([kExprRefNull, ...wasmSignedLeb(test_types[key])])
+ .addBody([kExprRefNull, ...type_encoding])
+ .exportFunc();
+ let non_null_type = wasmRefType(test_types[key]);
+ if (key == 'raw_struct_exact') type = type.exact();
+ builder.addFunction(key + "_non_null_id",
+ makeSig([non_null_type], [non_null_type]))
+ .addBody([kExprLocalGet, 0])
.exportFunc();
}
+ // Test that the wrappers behave correctly when a type follows an
+ // uninhabitable type.
+ let uninhabitable = wasmRefType(kWasmNullRef);
+ builder.addFunction(
+ "multi_value_uninhabitable",
+ makeSig([uninhabitable, kWasmI32], [uninhabitable, kWasmI32]))
+ .addBody([kExprLocalGet, 0, kExprLocalGet, 1])
+ .exportFunc();
+
return builder.instantiate({});
})();
@@ -79,6 +111,64 @@ assertThrows(
() => instance.exports.struct_id(instance.exports.i31_as_eq_producer()),
TypeError,
'type incompatibility when transforming from/to JS');
+// We cannot roundtrip undefined as structref.
+assertThrows(
+ () => instance.exports.struct_id(undefined),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip a non-smi number as structref.
+assertThrows(
+ () => instance.exports.struct_id(123.456),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip a JS object as structref.
+assertThrows(
+ () => instance.exports.struct_id({}),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+
+// We can roundtrip a struct as non-null structref.
+instance.exports.struct_non_null_id(instance.exports.struct_producer());
+// We cannot roundtrip an array as non-null structref.
+assertThrows(
+ () => instance.exports.struct_non_null_id(
+ instance.exports.array_producer()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip null as non-null structref.
+assertThrows(
+ () => instance.exports.struct_non_null_id(instance.exports.struct_null()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip an i31 as non-null structref.
+assertThrows(
+ () => instance.exports.struct_non_null_id(
+ instance.exports.i31_as_eq_producer()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip undefined as non-null structref.
+assertThrows(
+ () => instance.exports.struct_non_null_id(undefined),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip a non-smi number as non-null structref.
+assertThrows(
+ () => instance.exports.struct_non_null_id(123.456),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip a JS object as non-null structref.
+assertThrows(
+ () => instance.exports.struct_non_null_id({}),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+
+// We can roundtrip an array as arrayref.
+instance.exports.array_id(instance.exports.array_producer());
+// We cannot roundtrip a struct as arrayref.
+assertThrows(
+ () => instance.exports.array_id(instance.exports.struct_producer()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
// We can roundtrip a struct as eqref.
instance.exports.eq_id(instance.exports.struct_producer());
@@ -87,6 +177,30 @@ instance.exports.eq_id(instance.exports.array_producer());
// We can roundtrip an i31 as eqref/i31ref.
instance.exports.eq_id(instance.exports.i31_as_eq_producer());
instance.exports.i31_id(instance.exports.i31_as_eq_producer());
+// We can roundtrip a number in range as i31.
+instance.exports.i31_id(42);
+instance.exports.i31_id(42.0);
+const kInt31MaxValue = 0x3fffffff;
+const kInt31MinValue = -kInt31MaxValue - 1;
+instance.exports.i31_id(kInt31MaxValue);
+instance.exports.i31_id(kInt31MinValue);
+// We cannot roundtrip a double or a number outside i31 range as i31.
+assertThrows(
+ () => instance.exports.i31_id(kInt31MaxValue + 1), TypeError,
+ 'type incompatibility when transforming from/to JS');
+assertThrows(
+ () => instance.exports.i31_id(kInt31MinValue - 1), TypeError,
+ 'type incompatibility when transforming from/to JS');
+assertThrows(
+ () => instance.exports.i31_id(10.5), TypeError,
+ 'type incompatibility when transforming from/to JS');
+assertThrows(
+ () => instance.exports.i31_id(-0.0), TypeError,
+ 'type incompatibility when transforming from/to JS');
+// We cannot roundtrip a JS object as i31.
+assertThrows(
+ () => instance.exports.i31_id({}), TypeError,
+ 'type incompatibility when transforming from/to JS');
// We can roundtrip any null as any null supertype.
instance.exports.eq_id(instance.exports.struct_null());
instance.exports.eq_id(instance.exports.eq_null());
@@ -142,10 +256,36 @@ assertThrows(
TypeError,
'type incompatibility when transforming from/to JS');
+// We can roundtrip a subtype struct as its supertype, but not vice versa.
+instance.exports.raw_struct_id(instance.exports.sub_struct_producer());
+assertThrows(
+ () => instance.exports.raw_sub_struct_id(instance.exports.struct_producer()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+
+// We can roundtrip a struct as an exact type, but not its subtype.
+instance.exports.raw_struct_exact_id(instance.exports.struct_producer());
+assertThrows(
+ () => instance.exports.raw_struct_exact_id(
+ instance.exports.sub_struct_producer()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+
// We can roundtrip an extern.
assertEquals(null, instance.exports.extern_id(instance.exports.extern_null()));
-// We can roundtrip null typed as one of the three null types though wasm.
+// We can roundtrip null typed as one of the three null types though wasm...
for (const nullType of ["none", "nofunc", "noextern"]) {
instance.exports[`${nullType}_id`](instance.exports[`${nullType}_null`]());
}
+// ... but not their non-nullable (uninhabited) versions.
+for (const nullType of ["none", "nofunc", "noextern"]) {
+ assertThrows(
+ () => instance.exports[`${nullType}_non_null_id`](
+ instance.exports[`${nullType}_null`]()),
+ TypeError,
+ 'type incompatibility when transforming from/to JS');
+}
+
+assertThrows(() => instance.exports.multi_value_uninhabitable(null, 0),
+ TypeError, 'type incompatibility when transforming from/to JS');
diff --git a/deps/v8/test/mjsunit/wasm/wasm-interpreter.js b/deps/v8/test/mjsunit/wasm/wasm-interpreter.js
index d581b0c61d5..75b99d0811a 100644
--- a/deps/v8/test/mjsunit/wasm/wasm-interpreter.js
+++ b/deps/v8/test/mjsunit/wasm/wasm-interpreter.js
@@ -3558,6 +3558,272 @@ d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
assertEquals(42, instance.exports.main());
})();
+(function testStackResizing() {
+ print(arguments.callee.name);
+
+ const kParams = 1000;
+ const kBloat = 130600;
+ const kPayloadBase = 0x4141414141410000n;
+
+ const builder = new WasmModuleBuilder();
+
+ const reenter_sig = builder.addType(makeSig([], []));
+ const inner_sig = builder.addType(
+ makeSig(new Array(kParams).fill(kWasmI64), [kWasmI32]));
+
+ const reenter_index = builder.addImport('m', 'reenter', reenter_sig);
+
+ builder.addFunction('inner', inner_sig)
+ .addBody([
+ kExprI32Const, 7,
+ ])
+ .exportFunc();
+
+ const outer_body = [
+ kExprCallFunction, reenter_index,
+ kExprReturn,
+ ];
+ for (let i = 0; i < kBloat; i++) {
+ outer_body.push(...wasmI64Const(i + 1));
+ outer_body.push(kExprDrop);
+ }
+ builder.addFunction('outer', kSig_v_v)
+ .addBody(outer_body)
+ .exportFunc();
+
+ const args = Array.from({length: kParams},
+ (_, i) => kPayloadBase + BigInt(i));
+ let wasm;
+ const imports = {
+ m: {
+ reenter() {
+ // Re-enter inner from JS while outer is still on the interpreter
+ // stack. Ensure that the interpreter can handle the increased stack
+ // size.
+ assertEquals(7, wasm.inner(...args));
+ },
+ },
+ };
+
+ const instance = builder.instantiate(imports);
+ wasm = instance.exports;
+ wasm.outer();
+})();
+
+// Regression test for a call_indirect bug. The interpreter cached the
+// FunctionSig* derived from the first sig_index used on a given table entry.
+// A subsequent call_indirect on the same entry with a narrower subtype
+// signature passed the canonical subtype check but then used the stale cached
+// signature to coerce the JS import's return value. As a result, a JS value
+// returned from `() -> anyref` could end up on the typed Wasm stack as a
+// `(ref struct ...)` / `(ref array ...)`, causing later typed accesses to
+// observe the wrong type. The interpreter must instead coerce JS<->Wasm
+// values against the callee's declared signature, matching the behavior of
+// compiled wrappers, so that the narrow callsite still rejects a non-
+// conforming return value.
+(function testCallIndirectStaleSignature() {
+ print(arguments.callee.name);
+ const builder = new WasmModuleBuilder();
+ const array_type = builder.addArray(kWasmI32, {mutable: true});
+
+ // Wide cache-poisoning signature.
+ const sig_any =
+ builder.addType(makeSig([], [kWasmAnyRef]), kNoSuperType,
+ /* is_final */ false);
+ // Narrow signature: a subtype of sig_any.
+ const sig_array =
+ builder.addType(makeSig([], [wasmRefType(array_type)]), sig_any,
+ /* is_final */ false);
+
+ builder.addImport('m', 'imp', sig_array);
+ builder.addTable(kWasmFuncRef, 1, 1);
+ builder.addActiveElementSegment(0, wasmI32Const(0), [0]);
+
+ // First call: invoke the entry through the wider signature. Without the
+ // fix, this populates the interpreter's per-entry cache with sig_any's
+ // FunctionSig*.
+ builder.addFunction('warm_any', kSig_v_v).addBody([
+ kExprI32Const, 0,
+ kExprCallIndirect, sig_any, kTableZero,
+ kExprDrop,
+ ]).exportFunc();
+
+ // Second call: invoke the same entry through the narrower signature and
+ // immediately use the result as the typed array reference that the
+ // signature promises. With the bug present, the JS return value (a Smi)
+ // is coerced under the cached sig_any and reaches array.get unchecked.
+ builder.addFunction('trigger', kSig_i_v).addBody([
+ kExprI32Const, 0,
+ kExprCallIndirect, sig_array, kTableZero,
+ kExprI32Const, 0,
+ kGCPrefix, kExprArrayGet, array_type,
+ ]).exportFunc();
+
+ // The JS import advertises sig_array, but actually returns a Smi.
+ // The Wasm-to-JS boundary must reject this for sig_array, regardless of
+ // any sig_any-warmed cache state.
+ const instance = builder.instantiate({m: {imp() { return 13; }}});
+
+ // Attempt to warm the cache through the wider sig_any callsite. With the
+ // fix in place, JS<->Wasm coercion uses the callee's declared signature
+ // (sig_array), so returning a Smi here already throws. The test only
+ // requires that whatever cache state results cannot be used to bypass the
+ // type check at the narrow callsite below.
+ try {
+ instance.exports.warm_any();
+ } catch (e) {
+ // Ignore.
+ }
+
+ // Now invoke through sig_array. The runtime must coerce the JS return
+ // value against sig_array, so returning a Smi must trap with a typed-
+ // conversion error rather than smuggling a Smi onto the typed stack.
+ assertThrows(
+ () => instance.exports.trigger(),
+ TypeError);
+})();
+
+// The WasmInterpreterRuntime previously held its WasmInstanceObject through a
+// weak global handle (with a no-op finalizer). When the instance was collected,
+// the handle slot was freed and could be reused by an unrelated
+// WasmInstanceObject.
+// Subsequent interpreter calls would silently dereference the wrong instance's
+// trusted_data, aliasing globals across instances and corrupting memory. The fix
+// replaces the weak handle with a stack-rooted InstanceScope published at every
+// C++ entry into the runtime.
+//
+// The outer module uses Wasm exception handling (try/throw/catch with
+// return_call in the catch handler) because the interpreter's exception
+// unwinding path is what leaves the runtime in the stale state.
+// The host import re-enters the first instance (read) and the outer instance
+// (nop) before throwing a JS exception, creating nested activations that
+// exercise the problematic cleanup path.
+(function testRegressInterpreterInstanceUaf() {
+ print(arguments.callee.name);
+
+ const TARGET_REF_SLOT = 3669;
+ const ATTACKER_REF_GLOBALS = 0;
+ const ATTEMPTS = 128;
+ const keepAlive = [];
+ const refPayload = {marker: 0x41414141};
+
+ function buildVictimModule(targetRefSlot) {
+ const builder = new WasmModuleBuilder();
+ builder.addGlobal(kWasmI32, true, false, wasmI32Const(123));
+ for (let i = 0; i < targetRefSlot; i++) {
+ builder.addGlobal(kWasmExternRef, true);
+ }
+ const sinkGlobalIndex = 1 + targetRefSlot;
+ builder.addGlobal(kWasmExternRef, true);
+
+ builder.addFunction('read', kSig_i_v)
+ .addBody([kExprGlobalGet, ...wasmUnsignedLeb(0)])
+ .exportFunc();
+ builder.addFunction('write', kSig_v_i)
+ .addBody([kExprLocalGet, 0, kExprGlobalSet, ...wasmUnsignedLeb(0)])
+ .exportFunc();
+ builder.addFunction('writeControlledRef', kSig_v_r)
+ .addBody([
+ kExprLocalGet, 0,
+ kExprGlobalSet, ...wasmUnsignedLeb(sinkGlobalIndex),
+ ])
+ .exportFunc();
+
+ return builder.toModule();
+ }
+
+ function buildAttackerModule(refGlobals) {
+ const builder = new WasmModuleBuilder();
+ builder.addGlobal(kWasmI32, true, false, wasmI32Const(456));
+ for (let i = 0; i < refGlobals; i++) {
+ builder.addGlobal(kWasmExternRef, true);
+ }
+ builder.addFunction('read', kSig_i_v)
+ .addBody([kExprGlobalGet, ...wasmUnsignedLeb(0)])
+ .exportFunc();
+ return builder.toModule();
+ }
+
+ function buildOuterModule() {
+ const builder = new WasmModuleBuilder();
+ const hostImport = builder.addImport('m', 'host', kSig_v_v);
+ const tag = builder.addTag(kSig_v_v);
+ builder.addFunction('nop', kSig_i_v)
+ .addBody([kExprI32Const, 7])
+ .exportFunc();
+ builder.addFunction('outer', kSig_v_v)
+ .addBody([
+ kExprTry, kWasmVoid,
+ kExprThrow, tag,
+ kExprCatch, tag,
+ kExprReturnCall, hostImport,
+ kExprEnd,
+ ])
+ .exportFunc();
+ return builder.toModule();
+ }
+
+ const outerModule = buildOuterModule();
+ const victimModule = buildVictimModule(TARGET_REF_SLOT);
+ const attackerModule = buildAttackerModule(ATTACKER_REF_GLOBALS);
+
+ function fail(message) {
+ throw new Error(message);
+ }
+
+ function triggerStaleCleanup(victim) {
+ let outer = null;
+
+ function host() {
+ const first = victim.exports.read();
+ if (first !== 123) fail("unexpected victim first read " + first);
+
+ const nop = outer.exports.nop();
+ if (nop !== 7) fail("unexpected nop result " + nop);
+
+ throw 13;
+ }
+
+ outer = new WebAssembly.Instance(outerModule, {m: {host}});
+ try {
+ outer.exports.outer();
+ } catch (_) {}
+ }
+
+ function runAttempt(attempt) {
+ const victim = new WebAssembly.Instance(victimModule);
+ const attacker = new WebAssembly.Instance(attackerModule);
+ keepAlive.push(victim, attacker);
+
+ triggerStaleCleanup(victim);
+
+ attacker.exports.read();
+
+ const marker = 789 + attempt;
+ victim.exports.write(marker);
+
+ if (attacker.exports.read() !== marker) {
+ return false;
+ }
+
+ print("controlled write alias observed");
+ return true;
+ }
+
+ let bugDetected = false;
+ for (let attempt = 0; attempt < ATTEMPTS; attempt++) {
+ if (runAttempt(attempt)) {
+ bugDetected = true;
+ break;
+ }
+ }
+
+ // With the fix (InstanceScope), globals must remain isolated across instances.
+ if (bugDetected) {
+ throw new Error("FAIL: cross-instance globals aliasing detected");
+ }
+})();
+
// The WasmInterpreterRuntime previously held its WasmInstanceObject through a
// weak global handle (with a no-op finalizer). When the instance was collected,
// the handle slot was freed and could be reused by an unrelated
diff --git a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
index 62061b35d0d..38992879d48 100644
--- a/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
+++ b/deps/v8/test/mjsunit/wasm/wasm-module-builder.js
@@ -751,6 +751,7 @@ const kExprPause = 0x04;
const kExprStructWait = 0x05;
const kExprWaitqueueNotify = 0x06;
const kExprWaitqueueNew = 0x07;
+const kExprPublish = 0x0f;
const kExprStructAtomicGet = 0x5c;
const kExprStructAtomicGetS = 0x5d;
const kExprStructAtomicGetU = 0x5e;
diff --git a/deps/v8/test/mjsunit/wasm/wide-add.js b/deps/v8/test/mjsunit/wasm/wide-add.js
new file mode 100644
index 00000000000..fcbe7f85228
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/wide-add.js
@@ -0,0 +1,405 @@
+// 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-wide-arithmetic
+
+d8.file.execute("test/mjsunit/wasm/wasm-module-builder.js");
+
+// Tests pattern matching and carry behavior for chained 128-bit additions.
+// Verifies both left- and right-associative reduction patterns and all four
+// carry combinations (0, 1 from stage 1, 1 from stage 2, and 2 from both).
+function testAdd3Pattern() {
+ let builder = new WasmModuleBuilder();
+
+ // Pattern 1 (Left-associated): ((a + b) + c)
+ // Computes add128(add128(a, 0, b, 0), c, 0).
+ // Matches MachineOptimizationReducer:
+ // add128(add128(x, 0, y, 0), z, 0) -> Word64Add3(x, y, z)
+ builder.addFunction("add3_pattern", makeSig([kWasmI64, kWasmI64, kWasmI64], [kWasmI64, kWasmI64]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0, // a
+ kExprI64Const, 0,
+ kExprLocalGet, 1, // b
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128, // (a + b) -> (low, carry1)
+ kExprLocalGet, 2, // c
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128, // ((a + b) + c) -> (sum, carry_out)
+ ]);
+
+ // Pattern 2 (Right-associated): (a + (b + c))
+ // Computes add128(a, 0, add128(b, 0, c, 0)).
+ builder.addFunction("add3_pattern_alt", makeSig([kWasmI64, kWasmI64, kWasmI64], [kWasmI64, kWasmI64]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0, // a
+ kExprI64Const, 0,
+ kExprLocalGet, 1, // b
+ kExprI64Const, 0,
+ kExprLocalGet, 2, // c
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128, // (b + c) -> (low, carry1)
+ kNumericPrefix, kExprI64Add128, // (a + (b + c)) -> (sum, carry_out)
+ ]);
+
+ let instance = builder.instantiate();
+ let add3 = instance.exports.add3_pattern;
+ let add3_alt = instance.exports.add3_pattern_alt;
+
+ const max = 0xffffffffffffffffn;
+
+ for (let f of [add3, add3_alt]) {
+ // 1. No carry generated in either addition stage:
+ assertEquals([6n, 0n], f(1n, 2n, 3n));
+
+ // 2. Carry generated in the first addition stage (a + b), second does not carry:
+ assertEquals([4n, 1n], f(max, 2n, 3n));
+
+ // 3. Carry generated in the second addition stage, first stage does not carry:
+ assertEquals([1n, 1n], f(max - 1n, 1n, 2n));
+
+ // 4. Both addition stages generate a carry (2-bit carry-out):
+ assertEquals([0n, 2n], f(max, 2n, max));
+ }
+}
+
+// Tests pattern matching and code generation when one of the three operands
+// is an immediate / constant value.
+function testAdd3Constants() {
+ let builder = new WasmModuleBuilder();
+ // Tests different variants of const at different positions
+ // in the operation add128(add128(a, 0, 1, 0), c, 0).
+
+ // a is constant 1
+ builder.addFunction("add3_const_a", makeSig([kWasmI64, kWasmI64], [kWasmI64, kWasmI64]))
+ .exportFunc()
+ .addBody([
+ kExprI64Const, 1,
+ kExprI64Const, 0,
+ kExprLocalGet, 0, // b
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprLocalGet, 1, // c
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ ]);
+
+ // b is constant 1
+ builder.addFunction("add3_const_b", makeSig([kWasmI64, kWasmI64], [kWasmI64, kWasmI64]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0, // a
+ kExprI64Const, 0,
+ kExprI64Const, 1,
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprLocalGet, 1, // c
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ ]);
+
+ // c is constant 1
+ builder.addFunction("add3_const_c", makeSig([kWasmI64, kWasmI64], [kWasmI64, kWasmI64]))
+ .exportFunc()
+ .addBody([
+ kExprLocalGet, 0, // a
+ kExprI64Const, 0,
+ kExprLocalGet, 1, // b
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ kExprI64Const, 1,
+ kExprI64Const, 0,
+ kNumericPrefix, kExprI64Add128,
+ ]);
+
+ let instance = builder.instantiate();
+
+ assertEquals([6n, 0n], instance.exports.add3_const_a(2n, 3n));
+ assertEquals([4n, 1n], instance.exports.add3_const_a(0xffffffffffffffffn, 4n));
+
+ assertEquals([6n, 0n], instance.exports.add3_const_b(2n, 3n));
+ assertEquals([4n, 1n], instance.exports.add3_const_b(0xffffffffffffffffn, 4n));
+
+ assertEquals([6n, 0n], instance.exports.add3_const_c(2n, 3n));
+ assertEquals([0n, 1n], instance.exports.add3_const_c(0xffffffffffffffffn, 0n));
+}
+
+// Multi-limb BigInt addition loop variants:
+// These functions implement a full multi-precision addition loop (`res = a + b + carry`),
+// representing real-world cryptographic / bignum operations.
+
+// Variant 1: (a[i] + b[i]) + carry
+function addLoopVariant1(builder) {
+ builder.addFunction("loop_v1", makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], [kWasmI64]))
+ .exportFunc()
+ .addLocals(kWasmI32, 2) // i (local 4), limit (local 5)
+ .addLocals(kWasmI64, 1) // carry (local 6)
+ .addBody([
+ kExprLocalGet, 3, // count
+ kExprI32Const, 3,
+ kExprI32Shl, // byte limit = count * 8
+ kExprLocalSet, 5,
+ kExprI32Const, 0,
+ kExprLocalSet, 4, // i = 0
+ kExprI64Const, 0,
+ kExprLocalSet, 6, // carry = 0
+
+ kExprBlock, kWasmVoid,
+ kExprLoop, kWasmVoid,
+ kExprLocalGet, 4, // i
+ kExprLocalGet, 5, // limit
+ kExprI32GeS,
+ kExprBrIf, 1, // exit loop when i >= limit
+
+ // Compute destination address: res_ptr + i
+ kExprLocalGet, 2,
+ kExprLocalGet, 4,
+ kExprI32Add,
+
+ // Load a[i]
+ kExprLocalGet, 0,
+ kExprLocalGet, 4,
+ kExprI32Add,
+ kExprI64LoadMem, 3, 0,
+ kExprI64Const, 0,
+
+ // Load b[i]
+ kExprLocalGet, 1,
+ kExprLocalGet, 4,
+ kExprI32Add,
+ kExprI64LoadMem, 3, 0,
+ kExprI64Const, 0,
+
+ // (a[i] + b[i]) -> (temp_sum, temp_carry)
+ kNumericPrefix, kExprI64Add128,
+
+ // Get previous carry
+ kExprLocalGet, 6,
+ kExprI64Const, 0,
+
+ // ((a[i] + b[i]) + carry) -> (sum[i], next_carry)
+ kNumericPrefix, kExprI64Add128,
+
+ kExprLocalSet, 6, // next_carry
+ kExprI64StoreMem, 3, 0, // store sum[i] to res[i]
+
+ // i += 8
+ kExprLocalGet, 4,
+ kExprI32Const, 8,
+ kExprI32Add,
+ kExprLocalSet, 4,
+ kExprBr, 0,
+ kExprEnd,
+ kExprEnd,
+ kExprLocalGet, 6, // return final carry
+ ]);
+}
+
+// Variant 2: (a[i] + carry) + b[i]
+function addLoopVariant2(builder) {
+ builder.addFunction("loop_v2", makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], [kWasmI64]))
+ .exportFunc()
+ .addLocals(kWasmI32, 2) // i (local 4), limit (local 5)
+ .addLocals(kWasmI64, 1) // carry (local 6)
+ .addBody([
+ kExprLocalGet, 3,
+ kExprI32Const, 3,
+ kExprI32Shl,
+ kExprLocalSet, 5,
+ kExprI32Const, 0,
+ kExprLocalSet, 4,
+ kExprI64Const, 0,
+ kExprLocalSet, 6,
+
+ kExprBlock, kWasmVoid,
+ kExprLoop, kWasmVoid,
+ kExprLocalGet, 4,
+ kExprLocalGet, 5,
+ kExprI32GeS,
+ kExprBrIf, 1,
+
+ kExprLocalGet, 2,
+ kExprLocalGet, 4,
+ kExprI32Add,
+
+ // Load a[i]
+ kExprLocalGet, 0,
+ kExprLocalGet, 4,
+ kExprI32Add,
+ kExprI64LoadMem, 3, 0,
+ kExprI64Const, 0,
+
+ // Get previous carry
+ kExprLocalGet, 6,
+ kExprI64Const, 0,
+
+ // (a[i] + carry) -> (temp_sum, temp_carry)
+ kNumericPrefix, kExprI64Add128,
+
+ // Load b[i]
+ kExprLocalGet, 1,
+ kExprLocalGet, 4,
+ kExprI32Add,
+ kExprI64LoadMem, 3, 0,
+ kExprI64Const, 0,
+
+ // ((a[i] + carry) + b[i]) -> (sum[i], next_carry)
+ kNumericPrefix, kExprI64Add128,
+
+ kExprLocalSet, 6,
+ kExprI64StoreMem, 3, 0,
+
+ kExprLocalGet, 4,
+ kExprI32Const, 8,
+ kExprI32Add,
+ kExprLocalSet, 4,
+ kExprBr, 0,
+ kExprEnd,
+ kExprEnd,
+ kExprLocalGet, 6,
+ ]);
+}
+
+// Variant 3: (carry + b[i]) + a[i]
+function addLoopVariant3(builder) {
+ builder.addFunction("loop_v3", makeSig([kWasmI32, kWasmI32, kWasmI32, kWasmI32], [kWasmI64]))
+ .exportFunc()
+ .addLocals(kWasmI32, 2) // i (local 4), limit (local 5)
+ .addLocals(kWasmI64, 1) // carry (local 6)
+ .addBody([
+ kExprLocalGet, 3,
+ kExprI32Const, 3,
+ kExprI32Shl,
+ kExprLocalSet, 5,
+ kExprI32Const, 0,
+ kExprLocalSet, 4,
+ kExprI64Const, 0,
+ kExprLocalSet, 6,
+
+ kExprBlock, kWasmVoid,
+ kExprLoop, kWasmVoid,
+ kExprLocalGet, 4,
+ kExprLocalGet, 5,
+ kExprI32GeS,
+ kExprBrIf, 1,
+
+ kExprLocalGet, 2,
+ kExprLocalGet, 4,
+ kExprI32Add,
+
+ // Get previous carry
+ kExprLocalGet, 6,
+ kExprI64Const, 0,
+
+ // Load b[i]
+ kExprLocalGet, 1,
+ kExprLocalGet, 4,
+ kExprI32Add,
+ kExprI64LoadMem, 3, 0,
+ kExprI64Const, 0,
+
+ // (carry + b[i]) -> (temp_sum, temp_carry)
+ kNumericPrefix, kExprI64Add128,
+
+ // Load a[i]
+ kExprLocalGet, 0,
+ kExprLocalGet, 4,
+ kExprI32Add,
+ kExprI64LoadMem, 3, 0,
+ kExprI64Const, 0,
+
+ // ((carry + b[i]) + a[i]) -> (sum[i], next_carry)
+ kNumericPrefix, kExprI64Add128,
+
+ kExprLocalSet, 6,
+ kExprI64StoreMem, 3, 0,
+
+ kExprLocalGet, 4,
+ kExprI32Const, 8,
+ kExprI32Add,
+ kExprLocalSet, 4,
+ kExprBr, 0,
+ kExprEnd,
+ kExprEnd,
+ kExprLocalGet, 6,
+ ]);
+}
+
+function runLoopTest(loopFunc, memory, a_data, b_data, expected_res, expected_carry) {
+ let view = new DataView(memory.buffer);
+ let N = a_data.length;
+ for (let i = 0; i < N; i++) {
+ view.setBigUint64(i * 8, a_data[i], true);
+ }
+ for (let i = 0; i < N; i++) {
+ view.setBigUint64((N + i) * 8, b_data[i], true);
+ }
+ for (let i = 0; i < N; i++) {
+ view.setBigUint64((2 * N + i) * 8, 0n, true);
+ }
+
+ let carry = loopFunc(0, N * 8, 2 * N * 8, N);
+
+ assertEquals(expected_carry, carry);
+ for (let i = 0; i < N; i++) {
+ assertEquals(expected_res[i], view.getBigUint64((2 * N + i) * 8, true));
+ }
+}
+
+function testBigIntAddLoops() {
+ let builder = new WasmModuleBuilder();
+ builder.addMemory(1, 1);
+ builder.exportMemoryAs('memory');
+
+ addLoopVariant1(builder);
+ addLoopVariant2(builder);
+ addLoopVariant3(builder);
+
+ let instance = builder.instantiate();
+ let memory = instance.exports.memory;
+
+ const max = 0xffffffffffffffffn;
+
+ const test_cases = [
+ // Case 1: Multi-limb addition with no carries across any limbs.
+ {
+ a: [1n, 2n, 3n, 4n],
+ b: [5n, 6n, 7n, 8n],
+ expected_res: [6n, 8n, 10n, 12n],
+ expected_carry: 0n
+ },
+ // Case 2: Single-limb carry propagation from limb 0 to limb 1.
+ {
+ a: [max, 2n, 3n, 4n],
+ b: [2n, 6n, 7n, 8n],
+ expected_res: [1n, 9n, 10n, 12n],
+ expected_carry: 0n
+ },
+ // Case 3: Cascading / ripple carry across multiple saturated limbs.
+ {
+ a: [max, max, 3n, 4n],
+ b: [1n, 0n, 7n, 8n],
+ expected_res: [0n, 0n, 11n, 12n],
+ expected_carry: 0n
+ },
+ // Case 4: Full-width ripple carry through all 4 limbs with loop exit carry.
+ {
+ a: [max, max, max, max],
+ b: [1n, 0n, 0n, 0n],
+ expected_res: [0n, 0n, 0n, 0n],
+ expected_carry: 1n
+ }
+ ];
+
+ for (let loopFunc of [instance.exports.loop_v1, instance.exports.loop_v2, instance.exports.loop_v3]) {
+ for (let tc of test_cases) {
+ runLoopTest(loopFunc, memory, tc.a, tc.b, tc.expected_res, tc.expected_carry);
+ }
+ }
+}
+
+testAdd3Pattern();
+testAdd3Constants();
+testBigIntAddLoops();
diff --git a/deps/v8/test/mjsunit/wasm/wrapper-microbenchmark.js b/deps/v8/test/mjsunit/wasm/wrapper-microbenchmark.js
new file mode 100644
index 00000000000..0e2c1d2bbd4
--- /dev/null
+++ b/deps/v8/test/mjsunit/wasm/wrapper-microbenchmark.js
@@ -0,0 +1,218 @@
+// 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-wasm-generic-wrapper
+
+d8.file.execute('test/mjsunit/wasm/wasm-module-builder.js');
+
+const num_repetitions = 10_000_000;
+
+(function MeasureAbstractStructTypeWrapper() {
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct([makeField(kWasmI32, true)]);
+
+ builder.addFunction("producer", makeSig([], [kWasmStructRef]))
+ .addBody([kGCPrefix, kExprStructNewDefault, struct])
+ .exportFunc();
+
+ builder.addFunction("id", makeSig([kWasmStructRef], [kWasmStructRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let struct_obj = wasm.producer();
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(struct_obj);
+ }
+
+ print("Abstract type result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureIndexedStructTypeWrapper() {
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct([makeField(kWasmI32, true)]);
+
+ let struct_type = wasmRefNullType(struct);
+
+ builder.addFunction("producer", makeSig([], [struct_type]))
+ .addBody([kGCPrefix, kExprStructNewDefault, struct])
+ .exportFunc();
+
+ builder.addFunction("id", makeSig([struct_type], [struct_type]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let struct_obj = wasm.producer();
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(struct_obj);
+ }
+
+ print("Indexed type result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureIndexedStructSubtypeWrapper() {
+ let builder = new WasmModuleBuilder();
+
+ let super_struct = builder.addStruct([makeField(kWasmI32, true)]);
+ let sub_struct = builder.addStruct({
+ fields: [makeField(kWasmI32, true), makeField(kWasmI32, true)],
+ supertype: super_struct
+ });
+
+ builder.addFunction("producer", makeSig([], [wasmRefType(sub_struct)]))
+ .addBody([kGCPrefix, kExprStructNewDefault, sub_struct])
+ .exportFunc();
+
+ builder.addFunction("id", makeSig([wasmRefNullType(super_struct)],
+ [wasmRefNullType(super_struct)]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let struct_obj = wasm.producer();
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(struct_obj);
+ }
+
+ print("Indexed subtype result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureI31() {
+ let builder = new WasmModuleBuilder();
+
+ builder.addFunction("id", makeSig([kWasmI31Ref], [kWasmI31Ref]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(42);
+ }
+
+ print("i31 result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureEqI31() {
+ let builder = new WasmModuleBuilder();
+
+ builder.addFunction("id", makeSig([kWasmEqRef], [kWasmEqRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(42);
+ }
+
+ print("eq-i31 result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureEqWasmObject() {
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct({fields: [makeField(kWasmI32, true)]});
+
+ builder.addFunction("producer", makeSig([], [wasmRefType(struct)]))
+ .addBody([kGCPrefix, kExprStructNewDefault, struct])
+ .exportFunc();
+
+ builder.addFunction("id", makeSig([kWasmEqRef], [kWasmEqRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let start = Date.now();
+
+ let struct_obj = wasm.producer();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(struct_obj);
+ }
+
+ print("eq-wasm object result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureAnyI31() {
+ let builder = new WasmModuleBuilder();
+
+ builder.addFunction("id", makeSig([kWasmAnyRef], [kWasmAnyRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(42);
+ }
+
+ print("any-i31 result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureAnyWasmObject() {
+ let builder = new WasmModuleBuilder();
+
+ let struct = builder.addStruct({fields: [makeField(kWasmI32, true)]});
+
+ builder.addFunction("producer", makeSig([], [wasmRefType(struct)]))
+ .addBody([kGCPrefix, kExprStructNewDefault, struct])
+ .exportFunc();
+
+ builder.addFunction("id", makeSig([kWasmAnyRef], [kWasmAnyRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let start = Date.now();
+
+ let struct_obj = wasm.producer();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id(struct_obj);
+ }
+
+ print("any-wasm object result: " + (Date.now() - start) + "ms");
+})();
+
+(function MeasureAnyJSObject() {
+ let builder = new WasmModuleBuilder();
+
+ builder.addFunction("id", makeSig([kWasmAnyRef], [kWasmAnyRef]))
+ .addBody([kExprLocalGet, 0])
+ .exportFunc();
+
+ let wasm = builder.instantiate().exports;
+
+ let start = Date.now();
+
+ for (let i = 0; i < num_repetitions; i++) {
+ wasm.id({});
+ }
+
+ print("any-JS object result: " + (Date.now() - start) + "ms");
+})();
diff --git a/deps/v8/test/mkgrokdump/mkgrokdump.cc b/deps/v8/test/mkgrokdump/mkgrokdump.cc
index 7c8b452343c..3a8cc1d7ed7 100644
--- a/deps/v8/test/mkgrokdump/mkgrokdump.cc
+++ b/deps/v8/test/mkgrokdump/mkgrokdump.cc
@@ -146,6 +146,7 @@ static int DumpHeapConstants(FILE* out, const char* argv0) {
i::ReadOnlyHeapObjectIterator ro_iterator(read_only_heap);
for (i::Tagged<i::HeapObject> object = ro_iterator.Next();
!object.is_null(); object = ro_iterator.Next()) {
+ if (IsInaccessible(object)) continue;
if (!IsMap(object)) continue;
DumpKnownMap(out, heap, i::ToString(i::RO_SPACE), object);
}
@@ -168,7 +169,9 @@ static int DumpHeapConstants(FILE* out, const char* argv0) {
for (i::Tagged<i::HeapObject> object = ro_iterator.Next();
!object.is_null(); object = ro_iterator.Next()) {
// Skip read-only heap maps, they will be reported elsewhere.
- if (!IsAnyHole(object) && IsMap(object)) continue;
+ if (!IsInaccessible(object) && IsMap(object)) {
+ continue;
+ }
DumpKnownObject(out, heap, i::ToString(i::RO_SPACE), object);
}
diff --git a/deps/v8/test/test262/local-tests/test/staging/features.txt b/deps/v8/test/test262/local-tests/test/staging/features.txt
index 12320acb097..ac9cec96a5c 100644
--- a/deps/v8/test/test262/local-tests/test/staging/features.txt
+++ b/deps/v8/test/test262/local-tests/test/staging/features.txt
@@ -73,6 +73,10 @@ await-dictionary
# https://github.com/tc39/proposal-error-stack-accessor
error-stack-accessor
+# Iterator Join
+# https://github.com/tc39/proposal-iterator-join
+Iterator.prototype.join
+
## Standard language features
#
# Language features that have been included in a published version of the
@@ -145,7 +149,9 @@ globalThis
hashbang
import-attributes
import.meta
+iterator-chunking
iterator-helpers
+iterator-includes
iterator-sequencing
Int8Array
Int16Array
diff --git a/deps/v8/test/test262/test262.status b/deps/v8/test/test262/test262.status
index 1993adc5062..7af617325d1 100644
--- a/deps/v8/test/test262/test262.status
+++ b/deps/v8/test/test262/test262.status
@@ -702,9 +702,6 @@
####
# Roll-watcher patch
[ALWAYS, {
- 'annexB/language/comments/single-line-html-close-first-line-1': [SKIP],
- 'annexB/language/comments/single-line-html-close-first-line-2': [SKIP],
- 'annexB/language/comments/single-line-html-close-first-line-3': [SKIP],
'intl402/DateTimeFormat/timezone-legacy-non-iana': [SKIP],
}],
# End roll-watcher patch
@@ -862,15 +859,7 @@
####
-####
-# Roll-watcher patch
[ALWAYS, {
- 'built-ins/Atomics/notify/retrieve-length-before-index-coercion': [SKIP],
- 'built-ins/Atomics/notify/retrieve-length-before-index-coercion-non-shared': [SKIP],
- 'built-ins/Atomics/notify/retrieve-length-before-index-coercion-non-shared-detached': [SKIP],
- 'built-ins/Atomics/notify/retrieve-length-before-index-coercion-non-shared-resize-to-zero': [SKIP],
- 'built-ins/Atomics/wait/retrieve-length-before-index-coercion': [SKIP],
- 'built-ins/Atomics/waitAsync/retrieve-length-before-index-coercion': [SKIP],
'harness/verifyProperty-value-error': [SKIP],
}],
# End roll-watcher patch
@@ -900,14 +889,6 @@
# End roll-watcher patch
####
-####
-# Roll-watcher patch
-[ALWAYS, {
- 'built-ins/Iterator/concat/get-value-after-done': [SKIP],
-}],
-# End roll-watcher patch
-####
-
####
# Roll-watcher patch
[ALWAYS, {
@@ -1056,14 +1037,6 @@
# End roll-watcher patch
####
-####
-# Roll-watcher patch
-[ALWAYS, {
- 'built-ins/ArrayBuffer/prototype/sliceToImmutable/argument-coercion': [SKIP],
-}],
-# End roll-watcher patch
-####
-
####
# Roll-watcher patch
[ALWAYS, {
@@ -1102,7 +1075,6 @@
'built-ins/Error/prototype/stack/setter-receiver-is-proxy': [SKIP],
'built-ins/Error/prototype/stack/setter-this-not-object': [SKIP],
'built-ins/Error/prototype/stack/setter-via-assignment': [SKIP],
- 'built-ins/TypedArray/prototype/set/immutable-buffer': [SKIP],
'intl402/Temporal/ZonedDateTime/prototype/round/same-date-starts-twice': [SKIP],
'language/module-code/ambiguous-export-bindings/namespace-unambiguous-if-import-source-and-export': [SKIP],
'language/module-code/source-phase-import/reexport-source-binding-named-import': [SKIP],
@@ -1155,7 +1127,6 @@
####
# Roll-watcher patch
[ALWAYS, {
- 'built-ins/AsyncIteratorPrototype/Symbol.asyncDispose/invokes-return': [SKIP],
'built-ins/Promise/allKeyed/capability-resolve-throws-reject': [SKIP],
'built-ins/Promise/allKeyed/get-value-not-called-for-non-enumerable': [SKIP],
'built-ins/Promise/allKeyed/get-value-throws-reject': [SKIP],
@@ -1189,8 +1160,86 @@
####
# Roll-watcher patch
[ALWAYS, {
- 'intl402/Locale/prototype/getHourCycles/region-priority': [SKIP],
- 'intl402/Locale/prototype/getHourCycles/subdivision-region': [SKIP],
+ 'language/statements/await-using/initializer-Symbol.asyncDispose-disposed-at-end-of-imported-module': [SKIP],
+ 'language/statements/await-using/initializer-Symbol.dispose-disposed-at-end-of-imported-module': [SKIP],
+ 'language/statements/using/initializer-disposed-at-end-of-imported-module': [SKIP],
+}],
+# End roll-watcher patch
+####
+
+####
+# Roll-watcher patch
+[ALWAYS, {
+ 'built-ins/Iterator/prototype/chunks/argument-effect-order': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/argument-validation-failure-close-throws': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/argument-validation-failure-closes-underlying': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/callable': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/chunkSize-out-of-range': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/chunks-evenly-divisible': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/chunks-last-chunk-partial': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/chunks-size-1': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/chunks-size-larger-than-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/exhaustion-does-not-call-return': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/get-next-method-only-once': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/get-next-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/get-return-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/is-function': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/iterator-already-exhausted': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/iterator-return-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/length': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/name': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/next-method-returns-non-object': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/next-method-returns-throwing-done': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/next-method-returns-throwing-value': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/next-method-returns-throwing-value-done': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/next-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/prop-desc': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/proto': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/result-is-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/return-is-forwarded-to-underlying-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/return-is-not-forwarded-after-exhaustion': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/this-non-callable-next': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/this-plain-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/throws-typeerror-when-generator-is-running': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/underlying-iterator-advanced-in-parallel': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/underlying-iterator-closed-in-parallel': [SKIP],
+ 'built-ins/Iterator/prototype/chunks/yields-distinct-arrays': [SKIP],
+ 'built-ins/Iterator/prototype/windows/argument-effect-order': [SKIP],
+ 'built-ins/Iterator/prototype/windows/argument-validation-failure-close-throws': [SKIP],
+ 'built-ins/Iterator/prototype/windows/argument-validation-failure-closes-underlying': [SKIP],
+ 'built-ins/Iterator/prototype/windows/callable': [SKIP],
+ 'built-ins/Iterator/prototype/windows/exhaustion-does-not-call-return': [SKIP],
+ 'built-ins/Iterator/prototype/windows/get-next-method-only-once': [SKIP],
+ 'built-ins/Iterator/prototype/windows/get-next-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/windows/get-return-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/windows/is-function': [SKIP],
+ 'built-ins/Iterator/prototype/windows/iterator-already-exhausted': [SKIP],
+ 'built-ins/Iterator/prototype/windows/iterator-return-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/windows/length': [SKIP],
+ 'built-ins/Iterator/prototype/windows/name': [SKIP],
+ 'built-ins/Iterator/prototype/windows/next-method-returns-non-object': [SKIP],
+ 'built-ins/Iterator/prototype/windows/next-method-returns-throwing-done': [SKIP],
+ 'built-ins/Iterator/prototype/windows/next-method-returns-throwing-value': [SKIP],
+ 'built-ins/Iterator/prototype/windows/next-method-returns-throwing-value-done': [SKIP],
+ 'built-ins/Iterator/prototype/windows/next-method-throws': [SKIP],
+ 'built-ins/Iterator/prototype/windows/prop-desc': [SKIP],
+ 'built-ins/Iterator/prototype/windows/proto': [SKIP],
+ 'built-ins/Iterator/prototype/windows/result-is-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/windows/return-is-forwarded-to-underlying-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/windows/return-is-not-forwarded-after-exhaustion': [SKIP],
+ 'built-ins/Iterator/prototype/windows/this-non-callable-next': [SKIP],
+ 'built-ins/Iterator/prototype/windows/this-plain-iterator': [SKIP],
+ 'built-ins/Iterator/prototype/windows/throws-typeerror-when-generator-is-running': [SKIP],
+ 'built-ins/Iterator/prototype/windows/underlying-iterator-advanced-in-parallel': [SKIP],
+ 'built-ins/Iterator/prototype/windows/underlying-iterator-closed-in-parallel': [SKIP],
+ 'built-ins/Iterator/prototype/windows/undersized-default': [SKIP],
+ 'built-ins/Iterator/prototype/windows/windowSize-out-of-range': [SKIP],
+ 'built-ins/Iterator/prototype/windows/windows-allow-partial': [SKIP],
+ 'built-ins/Iterator/prototype/windows/windows-basic': [SKIP],
+ 'built-ins/Iterator/prototype/windows/windows-size-1': [SKIP],
+ 'built-ins/Iterator/prototype/windows/windows-size-3': [SKIP],
+ 'built-ins/Iterator/prototype/windows/yields-distinct-arrays': [SKIP],
+ 'staging/source-phase-imports/module-source-prototype-chain': [SKIP],
}],
# End roll-watcher patch
####
diff --git a/deps/v8/test/test262/testcfg.py b/deps/v8/test/test262/testcfg.py
index 99484c4e94a..30bd4b645d4 100644
--- a/deps/v8/test/test262/testcfg.py
+++ b/deps/v8/test/test262/testcfg.py
@@ -57,22 +57,12 @@ FEATURE_FLAGS = {
'iterator-helpers': '--harmony-iterator-helpers',
'set-methods': '--harmony-set-methods',
'import-attributes': '--harmony-import-attributes',
- 'regexp-duplicate-named-groups': '--js-regexp-duplicate-named-groups',
'regexp-modifiers': '--js-regexp-modifiers',
- 'explicit-resource-management': '--js-explicit-resource-management',
'decorators': '--js-decorators',
- 'promise-try': '--js-promise-try',
- 'Atomics.pause': '--js-atomics-pause',
'source-phase-imports': '--js-source-phase-imports --allow-natives-syntax',
- 'Error.isError': '--js-error-iserror',
- 'uint8array-base64': '--js-base-64',
- 'RegExp.escape': '--js-regexp-escape',
- 'upsert': '--js-upsert',
- 'Intl.Locale': '--js-intl-locale-variants',
'nonextensible-applies-to-private': '--js-nonextensible-applies-to-private',
'immutable-arraybuffer': '--js-immutable-arraybuffer',
'import-defer': '--js-defer-import-eval',
- 'Math.sumPrecise': '--js-sum-precise',
'Iterator.prototype.join': '--js-iterator-join',
'joint-iteration': '--js-joint-iteration',
'import-text': '--js-import-text',
diff --git a/deps/v8/test/test262/tools/v8_importer.py b/deps/v8/test/test262/tools/v8_importer.py
index 54dfdeb72b1..8c31b2eb58b 100644
--- a/deps/v8/test/test262/tools/v8_importer.py
+++ b/deps/v8/test/test262/tools/v8_importer.py
@@ -15,10 +15,10 @@ import sys
from blinkpy.common.system.log_utils import configure_logging
from blinkpy.w3c.common import read_credentials
-TEST_FILE_REFERENCE_IN_STATUS_FILE = re.compile("^\s*'(.*)':.*,$")
+TEST_FILE_REFERENCE_IN_STATUS_FILE = re.compile(r"^\s*'(.*)':.*,$")
TEST262_FAILURE_LINE = re.compile("=== test262/(.*) ===")
-TEST262_PATTERN = re.compile('^test/(.*)\.[^\s]*$')
-TEST262_RENAME_PATTERN = re.compile('^R[^\s]*\s*([^\s]*)\s*([^\s]*)$')
+TEST262_PATTERN = re.compile(r'^test/(.*)\.[^\s]*$')
+TEST262_RENAME_PATTERN = re.compile(r'^R[^\s]*\s*([^\s]*)\s*([^\s]*)$')
TEST262_REPO_URL = 'https://chromium.googlesource.com/external/github.com/tc39/test262'
V8_TEST262_ROLLS_META_BUG = 'v8:7834'
diff --git a/deps/v8/test/unittests/BUILD.gn b/deps/v8/test/unittests/BUILD.gn
index a4b8a7c3cc0..06428824029 100644
--- a/deps/v8/test/unittests/BUILD.gn
+++ b/deps/v8/test/unittests/BUILD.gn
@@ -5,12 +5,6 @@
import("../../gni/cluster_build.gni")
import("../../gni/v8.gni")
-if (v8_enable_webassembly) {
- if (!v8_target_is_simulator && v8_current_cpu == "x64") {
- v8_enable_wasm_simd256_revec = true
- }
-}
-
if (is_fuchsia) {
import("//build/config/fuchsia/generate_runner_scripts.gni")
import("//third_party/fuchsia-sdk/sdk/build/component.gni")
@@ -356,6 +350,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"date/date-cache-unittest.cc",
"date/date-unittest.cc",
"debug/debug-property-iterator-unittest.cc",
+ "debug/debug-scope-info-unittest.cc",
"deoptimizer/deoptimization-unittest.cc",
"diagnostics/eh-frame-iterator-unittest.cc",
"diagnostics/eh-frame-writer-unittest.cc",
@@ -507,6 +502,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"profiler/circular-queue-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",
@@ -523,6 +519,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"sandbox/sandbox-hardware-support-unittest.cc",
"sandbox/sandbox-unittest.cc",
"sandbox/sandbox-violation-unittest.cc",
+ "sandbox/segmented-table-unittest.cc",
"sandbox/trap-fuzzer-unittest.cc",
"strings/char-predicates-unittest.cc",
"strings/unicode-unittest.cc",
@@ -556,10 +553,10 @@ v8_cluster_source_set("v8_unittests_sources") {
exclude_from_cluster = [
"api/dictionary-template-unittest.cc",
+ "api/interceptor-unittest.cc",
"base/virtual-address-space-unittest.cc",
"base/hashing-unittest.cc",
"compiler/run-variables-unittest.cc",
- "compiler/linear-scheduler-unittest.cc",
"compiler/linkage-unittest.cc",
"heap/cppgc-js/cpp-heap-stack-start-marker-unittest.cc",
"heap/cppgc-js/embedder-roots-handler-unittest.cc",
@@ -718,6 +715,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"wasm/wasm-disassembler-unittest-too-many-ends.wasm.inc",
"wasm/wasm-disassembler-unittest-too-many-ends.wat.inc",
"wasm/wasm-disassembler-unittest.cc",
+ "wasm/wasm-interpreter-thread-unittest.cc",
"wasm/wasm-macro-gen-unittest.cc",
"wasm/wasm-module-builder-unittest.cc",
"wasm/wasm-module-sourcemap-unittest.cc",
@@ -730,13 +728,6 @@ v8_cluster_source_set("v8_unittests_sources") {
}
}
- if (v8_enable_wasm_simd256_revec) {
- sources += [
- "compiler/linear-scheduler-unittest.cc",
- "compiler/revec-unittest.cc",
- ]
- }
-
if (v8_enable_wasm_gdb_remote_debugging) {
sources += [ "wasm/wasm-gdbserver-unittest.cc" ]
}
@@ -833,6 +824,7 @@ v8_cluster_source_set("v8_unittests_sources") {
"assembler/assembler-x64-unittest.cc",
"assembler/disasm-x64-unittest.cc",
"assembler/macro-assembler-x64-unittest.cc",
+ "regress/regress-536954139-unittest.cc",
]
if (v8_enable_turbofan) {
sources +=
diff --git a/deps/v8/test/unittests/api/api-wasm-unittest.cc b/deps/v8/test/unittests/api/api-wasm-unittest.cc
index 00a2fdd8444..0eb4bd46614 100644
--- a/deps/v8/test/unittests/api/api-wasm-unittest.cc
+++ b/deps/v8/test/unittests/api/api-wasm-unittest.cc
@@ -14,6 +14,7 @@
#include "include/v8-wasm.h"
#include "src/api/api-inl.h"
#include "src/handles/global-handles.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/wasm/wasm-features.h"
#include "src/wasm/wasm-js.h"
#include "src/wasm/wasm-module.h"
@@ -49,6 +50,27 @@ class ApiWasmTest : public TestWithIsolate {
EmptyMessageQueues();
CHECK_EQ(expected_state, promise->State());
}
+
+ Local<WasmModuleObject> FinishModuleCompilation(
+ WasmModuleCompilation& compilation, std::span<const uint8_t> bytes) {
+ compilation.OnBytesReceived(bytes.data(), bytes.size());
+ // The resolution callback runs within a separate task with its own
+ // HandleScope, so persist the result in a Global.
+ Global<WasmModuleObject> module_object;
+ compilation.Finish(
+ isolate(), {},
+ [this,
+ &module_object](std::variant<Local<WasmModuleObject>, Local<Value>>
+ module_or_error) {
+ CHECK(
+ std::holds_alternative<Local<WasmModuleObject>>(module_or_error));
+ module_object.Reset(
+ isolate(), std::get<Local<WasmModuleObject>>(module_or_error));
+ });
+ EmptyMessageQueues();
+ CHECK(!module_object.IsEmpty());
+ return module_object.Get(isolate());
+ }
};
void WasmStreamingTestFinalizer(const WeakCallbackInfo<void>& data) {
@@ -211,8 +233,8 @@ TEST_F(ApiWasmTest, WasmCompileWithJsStringBuiltins) {
'-', 's', 't', 'r', 'i', 'n', 'g', 10, 'c', 'h', 'a', 'r', 'C',
'o', 'd', 'e', 'A', 't', kExternalFunction, 0)};
- WasmModuleObject::CompileTimeImports imports;
- imports.builtins = WasmModuleObject::CompileTimeImports::Builtins::kJsString;
+ WasmModuleObject::CompileOptions options{
+ .builtins = WasmModuleObject::CompileOptions::Builtins::kJsString};
// Without compile-time imports the "wasm:js-string" import is an ordinary
// import resolved at instantiation, so it is reflected and both modules
@@ -225,14 +247,14 @@ TEST_F(ApiWasmTest, WasmCompileWithJsStringBuiltins) {
// With the builtins enabled the valid import is bound at compile time, so it
// is no longer reflected.
Local<WasmModuleObject> bound =
- WasmModuleObject::Compile(isolate(), valid_module, imports)
+ WasmModuleObject::Compile(isolate(), valid_module, options)
.ToLocalChecked();
CHECK_EQ(0, ReflectedImportCount(isolate(), bound));
// The invalid signature is rejected at compile time.
{
TryCatch try_catch(isolate());
- CHECK(WasmModuleObject::Compile(isolate(), invalid_module, imports)
+ CHECK(WasmModuleObject::Compile(isolate(), invalid_module, options)
.IsEmpty());
CHECK(try_catch.HasCaught());
}
@@ -260,13 +282,33 @@ TEST_F(ApiWasmTest, WasmCompileWithImportedStringConstants) {
// Naming "strings" as the constants module binds the import at compile time,
// so it is no longer reflected.
- WasmModuleObject::CompileTimeImports imports;
- imports.imported_string_constants_module = "strings";
Local<WasmModuleObject> bound =
- WasmModuleObject::Compile(isolate(), module, imports).ToLocalChecked();
+ WasmModuleObject::Compile(isolate(), module,
+ {.imported_string_constants_module = "strings"})
+ .ToLocalChecked();
CHECK_EQ(0, ReflectedImportCount(isolate(), bound));
}
+TEST_F(ApiWasmTest, WasmCompileWithSourceUrl) {
+ Local<Context> context = Context::New(isolate());
+ Context::Scope context_scope(context);
+
+ constexpr std::string_view kUrl = "file:///test/module.wasm";
+ Local<WasmModuleObject> with_url =
+ WasmModuleObject::Compile(isolate(), kMinimalWasmModuleBytes,
+ {.source_url = kUrl})
+ .ToLocalChecked();
+ CHECK_EQ(kUrl, with_url->GetCompiledModule().source_url());
+
+ // A distinct module, since scripts (and their URLs) are cached per module
+ // per isolate. Without a source URL a wasm:// URL is synthesized.
+ const uint8_t distinct_module[] = {0x00, 0x61, 0x73, 0x6d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x01, 'x'};
+ Local<WasmModuleObject> plain =
+ WasmModuleObject::Compile(isolate(), distinct_module).ToLocalChecked();
+ CHECK_EQ(0u, plain->GetCompiledModule().source_url().find("wasm://wasm/"));
+}
+
TEST_F(ApiWasmTest, WasmStreamingSetCallback) {
TestWasmStreaming(WasmStreamingMoreFunctionsCanBeSerializedCallback,
Promise::kPending);
@@ -406,6 +448,66 @@ TEST_F(ApiWasmTest, WasmModuleCompilation_Basic) {
CHECK(!isolate()->HasPendingException());
}
+TEST_F(ApiWasmTest, WasmModuleCompilation_CompileOptions) {
+ using namespace internal::wasm; // NOLINT(build/namespaces)
+ Isolate::Scope iscope(isolate());
+ HandleScope scope(isolate());
+ Local<Context> context = Context::New(isolate());
+ Context::Scope cscope(context);
+ TryCatch try_catch(isolate());
+
+ // Imports `charCodeAt` from the "wasm:js-string" builtins module, matching
+ // the builtin signature, so it binds at compile time when enabled.
+ const uint8_t module_bytes[] = {
+ WASM_MODULE_HEADER,
+ SECTION(Type, ENTRY_COUNT(1),
+ SIG_ENTRY_x_xx(kI32Code, kExternRefCode, kI32Code)),
+ SECTION(Import, ENTRY_COUNT(1), 14, 'w', 'a', 's', 'm', ':', 'j', 's',
+ '-', 's', 't', 'r', 'i', 'n', 'g', 10, 'c', 'h', 'a', 'r', 'C',
+ 'o', 'd', 'e', 'A', 't', kExternalFunction, 0)};
+
+ constexpr std::string_view kUrl = "file:///test/async-module.wasm";
+ WasmModuleCompilation compilation(
+ {.builtins = WasmModuleObject::CompileOptions::Builtins::kJsString,
+ .source_url = kUrl});
+ Local<WasmModuleObject> module =
+ FinishModuleCompilation(compilation, module_bytes);
+ CHECK(!try_catch.HasCaught());
+ CHECK_EQ(0, ReflectedImportCount(isolate(), module));
+ CHECK_EQ(kUrl, module->GetCompiledModule().source_url());
+}
+
+TEST_F(ApiWasmTest, WasmModuleCompilation_SourceUrl) {
+ Isolate::Scope iscope(isolate());
+ HandleScope scope(isolate());
+ Local<Context> context = Context::New(isolate());
+ Context::Scope cscope(context);
+ TryCatch try_catch(isolate());
+
+ // SetUrl cleanly replaces a URL provided via compile options.
+ {
+ constexpr std::string_view kSetUrl = "file:///test/replaced.wasm";
+ WasmModuleCompilation compilation(
+ {.source_url = "file:///test/original.wasm"});
+ compilation.SetUrl(kSetUrl.data(), kSetUrl.size());
+ Local<WasmModuleObject> module =
+ FinishModuleCompilation(compilation, kMinimalWasmModuleBytes);
+ CHECK_EQ(kSetUrl, module->GetCompiledModule().source_url());
+ }
+
+ // Without a URL, a wasm:// URL is synthesized. A distinct module, since
+ // scripts (and their URLs) are cached per module per isolate.
+ {
+ const uint8_t distinct_module[] = {0x00, 0x61, 0x73, 0x6d, 0x01, 0x00,
+ 0x00, 0x00, 0x00, 0x02, 0x01, 'y'};
+ WasmModuleCompilation compilation;
+ Local<WasmModuleObject> module =
+ FinishModuleCompilation(compilation, distinct_module);
+ CHECK_EQ(0u, module->GetCompiledModule().source_url().find("wasm://wasm/"));
+ }
+ CHECK(!try_catch.HasCaught());
+}
+
TEST_F(ApiWasmTest, GetWasmMemoryReservationSizeInBytes) {
constexpr size_t kCapacity = 64 * 1024; // 64 KiB
size_t reservation = V8::GetWasmMemoryReservationSizeInBytes(
diff --git a/deps/v8/test/unittests/api/dictionary-template-unittest.cc b/deps/v8/test/unittests/api/dictionary-template-unittest.cc
index 7419ddde168..b264a591911 100644
--- a/deps/v8/test/unittests/api/dictionary-template-unittest.cc
+++ b/deps/v8/test/unittests/api/dictionary-template-unittest.cc
@@ -3,6 +3,8 @@
// found in the LICENSE file.
#include "include/v8-template.h"
+#include "src/base/macros.h"
+#include "src/common/globals.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -133,4 +135,41 @@ TEST_F(DictionaryTemplateTest, PrototypeContext) {
EXPECT_TRUE(instance2->GetPrototype() == instance3->GetPrototype());
}
+TEST_F(DictionaryTemplateTest, HoleNanCanonicalization) {
+ HandleScope handle_scope(isolate());
+
+ constexpr std::string_view property_names[] = {"a"};
+ Local<DictionaryTemplate> tpl =
+ DictionaryTemplate::New(isolate(), property_names);
+
+ // 1. Create first instance with a normal double to seed the map cache with
+ // double representation and const property details.
+ MaybeLocal<Value> values1[1] = {v8::Number::New(isolate(), 1.25)};
+ Local<Object> instance1 = tpl->NewInstance(context(), values1);
+ EXPECT_FALSE(instance1.IsEmpty());
+
+ // 2. Create second instance reusing cached map with the hole-NaN bit pattern.
+ const double hole_nan = base::bit_cast<double>(i::kHoleNanInt64);
+ MaybeLocal<Value> values2[1] = {v8::Number::New(isolate(), hole_nan)};
+ Local<Object> instance2 = tpl->NewInstance(context(), values2);
+ EXPECT_FALSE(instance2.IsEmpty());
+
+ // The stored HeapNumber value must not have the hole-NaN bit pattern.
+ auto value2 =
+ instance2->Get(context(), v8_str(isolate(), "a")).ToLocalChecked();
+ EXPECT_TRUE(value2->IsNumber());
+ double val2 = value2.As<v8::Number>()->Value();
+ EXPECT_TRUE(std::isnan(val2));
+ EXPECT_NE(base::bit_cast<uint64_t>(val2), i::kHoleNanInt64);
+
+ // The property must be mutable and not in Read-Only space.
+ EXPECT_TRUE(instance2
+ ->Set(context(), v8_str(isolate(), "a"),
+ v8::Number::New(isolate(), 42.5))
+ .ToChecked());
+ auto value2_mutated =
+ instance2->Get(context(), v8_str(isolate(), "a")).ToLocalChecked();
+ EXPECT_EQ(value2_mutated.As<v8::Number>()->Value(), 42.5);
+}
+
} // namespace v8
diff --git a/deps/v8/test/unittests/api/interceptor-unittest.cc b/deps/v8/test/unittests/api/interceptor-unittest.cc
index 7cabda34cb5..d0ae70df06c 100644
--- a/deps/v8/test/unittests/api/interceptor-unittest.cc
+++ b/deps/v8/test/unittests/api/interceptor-unittest.cc
@@ -331,6 +331,106 @@ TEST_F(InterceptorTest, IndexedInterceptorIterableToList_MissingCallback) {
false);
}
+TEST_F(InterceptorTest, IndexedInterceptorIterableToList_ValidityCellBypass) {
+ i::FlagScope<bool> enable_flag(&i::v8_flags.fast_api_iterable_to_list, true);
+ v8::HandleScope scope(isolate());
+ InterceptorData data;
+
+ Local<FunctionTemplate> tmpl =
+ CreateIterableToListInterceptorTemplate(isolate(), &data);
+ Local<Function> ctor = tmpl->GetFunction(context()).ToLocalChecked();
+ Local<Object> obj = ctor->NewInstance(context()).ToLocalChecked();
+ SetGlobalProperty("obj", obj);
+ ASSERT_EQ(data.call_count, 0);
+
+ // 1. Make sure the interceptor's prototype is still in setup mode.
+ Local<Object> prototype = obj->GetPrototype().As<Object>();
+ i::DirectHandle<i::JSObject> i_prototype =
+ i::Cast<i::JSObject>(v8::Utils::OpenDirectHandle(*prototype));
+ ASSERT_TRUE(i_prototype->map()->is_dictionary_map());
+
+ // 2. Make Symbol.iterator mutable but keep the value unchanged.
+ RunJS(R"(
+ var proto = Object.getPrototypeOf(obj);
+ proto[Symbol.iterator] = function() {};
+ proto[Symbol.iterator] = Array.prototype.values;
+ )");
+ data.call_count = 0;
+
+ // 3. Trigger fast path and let it switch the prototype to fast mode and
+ // perform the necessary checks.
+ RunJS("Array.from(obj);");
+ ASSERT_EQ(data.call_count, 1);
+
+ // 4. Modify Symbol.iterator again, the fast path shouldn't be taken.
+ RunJS("proto[Symbol.iterator] = function*() { yield 42; };");
+ data.call_count = 0;
+
+ // 5. Array.from should now use the custom iterator.
+ Local<Value> res = RunJS("Array.from(obj)");
+ ASSERT_EQ(data.call_count, 0);
+ ASSERT_TRUE(res->IsArray());
+ Local<Array> arr = res.As<Array>();
+
+ // With the bug, arr->Length() will be 3 and arr[0] will be 11.
+ // We want to write a failing test, so we assert what it SHOULD be,
+ // and the bug will cause the assertion to fail.
+ ASSERT_EQ(1u, arr->Length());
+ ASSERT_EQ(42, arr->Get(context(), 0).ToLocalChecked().As<Integer>()->Value());
+}
+
+TEST_F(InterceptorTest, IndexedInterceptorIterableToList_SetPrototypeBypass) {
+ i::FlagScope<bool> enable_flag(&i::v8_flags.fast_api_iterable_to_list, true);
+ v8::HandleScope scope(isolate());
+ InterceptorData data;
+
+ Local<FunctionTemplate> tmpl =
+ CreateIterableToListInterceptorTemplate(isolate(), &data);
+ Local<Function> ctor = tmpl->GetFunction(context()).ToLocalChecked();
+ Local<Object> obj = ctor->NewInstance(context()).ToLocalChecked();
+ SetGlobalProperty("obj", obj);
+
+ // 1. Trigger fast path and create validity cell.
+ RunJS("Array.from(obj);");
+ ASSERT_EQ(data.call_count, 1);
+
+ // 2. Change prototype to an object with a custom iterator.
+ RunJS(R"(
+ var custom_proto = {
+ [Symbol.iterator]: function*() { yield 99; }
+ };
+ Object.setPrototypeOf(obj, custom_proto);
+ )");
+ data.call_count = 0;
+
+ // 3. Array.from should not take the fast path and must use the custom
+ // iterator.
+ Local<Value> res = RunJS("Array.from(obj)");
+ ASSERT_EQ(data.call_count, 0);
+ ASSERT_TRUE(res->IsArray());
+ Local<Array> arr = res.As<Array>();
+ ASSERT_EQ(1u, arr->Length());
+ ASSERT_EQ(99, arr->Get(context(), 0).ToLocalChecked().As<Integer>()->Value());
+
+ // 4. Change prototype to null.
+ RunJS("Object.setPrototypeOf(obj, null);");
+ data.call_count = 0;
+ Local<Value> res_null = RunJS("Array.from(obj)");
+ ASSERT_EQ(data.call_count, 0);
+ ASSERT_TRUE(res_null->IsArray());
+ ASSERT_EQ(0u, res_null.As<Array>()->Length());
+
+ Local<Value> is_error = RunJS(R"(
+ try {
+ ((...args) => args)(...obj);
+ false;
+ } catch (e) {
+ e instanceof TypeError;
+ }
+ )");
+ ASSERT_TRUE(is_error->IsTrue());
+}
+
// namespace internal {
namespace {
diff --git a/deps/v8/test/unittests/api/v8-array-unittest.cc b/deps/v8/test/unittests/api/v8-array-unittest.cc
index b0166ebd381..55eb0d508d4 100644
--- a/deps/v8/test/unittests/api/v8-array-unittest.cc
+++ b/deps/v8/test/unittests/api/v8-array-unittest.cc
@@ -5,7 +5,11 @@
#include "include/v8-container.h"
#include "include/v8-primitive.h"
#include "include/v8-value.h"
+#include "src/api/api-inl.h"
#include "src/execution/protectors-inl.h"
+#include "src/heap/heap-inl.h"
+#include "src/objects/js-array-inl.h"
+#include "test/unittests/heap/heap-utils.h"
#include "test/unittests/interpreter/interpreter-tester.h"
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -241,5 +245,167 @@ TEST_F(ArrayTest, IteratorValueChangeShouldInvalidateArrayIteratorProtectCell) {
internal::Isolate::Current()));
}
+TEST_F(ArrayTest, IterateWithGC) {
+ i::v8_flags.expose_gc = true;
+ HandleScope scope(isolate());
+
+ struct ArrayTestCase {
+ const char* js_source;
+ internal::ElementsKind expected_kind;
+ std::vector<std::string> expected_values;
+ };
+
+ const ArrayTestCase test_cases[] = {
+ // PACKED_SMI_ELEMENTS
+ {"[10, 20, 30]", internal::PACKED_SMI_ELEMENTS, {"10", "20", "30"}},
+ // HOLEY_SMI_ELEMENTS
+ {"(() => { const a = [10, 20, 30]; delete a[1]; return a; })()",
+ internal::HOLEY_SMI_ELEMENTS,
+ {"10", "undefined", "30"}},
+ // PACKED_ELEMENTS
+ {"['foo', 'bar', 'baz']",
+ internal::PACKED_ELEMENTS,
+ {"foo", "bar", "baz"}},
+ // HOLEY_ELEMENTS
+ {"(() => { const a = ['foo', 'bar', 'baz']; delete a[1]; return a; })()",
+ internal::HOLEY_ELEMENTS,
+ {"foo", "undefined", "baz"}},
+ // PACKED_DOUBLE_ELEMENTS
+ {"[1.5, 2.5, 3.5]",
+ internal::PACKED_DOUBLE_ELEMENTS,
+ {"1.5", "2.5", "3.5"}},
+ // HOLEY_DOUBLE_ELEMENTS
+ {"(() => { const a = [1.5, 2.5, 3.5]; delete a[1]; return a; })()",
+ internal::HOLEY_DOUBLE_ELEMENTS,
+ {"1.5", "undefined", "3.5"}},
+ // PACKED_NONEXTENSIBLE_ELEMENTS (Object and Smi)
+ {"Object.preventExtensions(['a', 'b', 'c'])",
+ internal::PACKED_NONEXTENSIBLE_ELEMENTS,
+ {"a", "b", "c"}},
+ {"Object.preventExtensions([10, 20, 30])",
+ internal::PACKED_NONEXTENSIBLE_ELEMENTS,
+ {"10", "20", "30"}},
+ // HOLEY_NONEXTENSIBLE_ELEMENTS (Object and Smi)
+ {"(() => { const a = ['a', 'b', 'c']; delete a[1]; return "
+ "Object.preventExtensions(a); })()",
+ internal::HOLEY_NONEXTENSIBLE_ELEMENTS,
+ {"a", "undefined", "c"}},
+ {"(() => { const a = [10, 20, 30]; delete a[1]; return "
+ "Object.preventExtensions(a); })()",
+ internal::HOLEY_NONEXTENSIBLE_ELEMENTS,
+ {"10", "undefined", "30"}},
+ // PACKED_SEALED_ELEMENTS (Object and Smi)
+ {"Object.seal(['a', 'b', 'c'])",
+ internal::PACKED_SEALED_ELEMENTS,
+ {"a", "b", "c"}},
+ {"Object.seal([10, 20, 30])",
+ internal::PACKED_SEALED_ELEMENTS,
+ {"10", "20", "30"}},
+ // HOLEY_SEALED_ELEMENTS (Object and Smi)
+ {"(() => { const a = ['a', 'b', 'c']; delete a[1]; return "
+ "Object.seal(a); })()",
+ internal::HOLEY_SEALED_ELEMENTS,
+ {"a", "undefined", "c"}},
+ {"(() => { const a = [10, 20, 30]; delete a[1]; return "
+ "Object.seal(a); })()",
+ internal::HOLEY_SEALED_ELEMENTS,
+ {"10", "undefined", "30"}},
+ // PACKED_FROZEN_ELEMENTS (Object and Smi)
+ {"Object.freeze(['a', 'b', 'c'])",
+ internal::PACKED_FROZEN_ELEMENTS,
+ {"a", "b", "c"}},
+ {"Object.freeze([10, 20, 30])",
+ internal::PACKED_FROZEN_ELEMENTS,
+ {"10", "20", "30"}},
+ // HOLEY_FROZEN_ELEMENTS (Object and Smi)
+ {"(() => { const a = ['a', 'b', 'c']; delete a[1]; return "
+ "Object.freeze(a); })()",
+ internal::HOLEY_FROZEN_ELEMENTS,
+ {"a", "undefined", "c"}},
+ {"(() => { const a = [10, 20, 30]; delete a[1]; return "
+ "Object.freeze(a); })()",
+ internal::HOLEY_FROZEN_ELEMENTS,
+ {"10", "undefined", "30"}},
+ // DICTIONARY_ELEMENTS (Sparse array)
+ {"(() => { const a = []; a[0] = 'a'; a[10000] = 'b'; return a; })()",
+ internal::DICTIONARY_ELEMENTS,
+ {"a", "b"}},
+ // DICTIONARY_ELEMENTS (Dense array with reconfigured property)
+ {"(() => { const a = [10, 20, 30]; Object.defineProperty(a, '0', "
+ "{value: 10, configurable: false, writable: false}); return a; })()",
+ internal::DICTIONARY_ELEMENTS,
+ {"10", "20", "30"}},
+ // Empty array (PACKED_SMI_ELEMENTS, length 0)
+ {"[]", internal::PACKED_SMI_ELEMENTS, {}},
+ };
+
+ struct IterationData {
+ Isolate* isolate;
+ Local<Context> context;
+ std::vector<std::pair<uint32_t, std::string>> visited;
+ };
+
+ for (const auto& tc : test_cases) {
+ Local<Array> array = RunJS(tc.js_source).As<Array>();
+ CHECK(array->IsArray());
+ auto i_array = Utils::OpenDirectHandle(*array);
+ CHECK_EQ(i_array->GetElementsKind(), tc.expected_kind);
+
+ IterationData data{isolate(), context(), {}};
+ Array::IterationCallback callback = [](uint32_t index, Local<Value> element,
+ void* data_ptr) -> CbResult {
+ IterationData* d = static_cast<IterationData*>(data_ptr);
+ // Perform GC within the iteration callback.
+ d->isolate->RequestGarbageCollectionForTesting(
+ v8::Isolate::kFullGarbageCollection);
+
+ // Also allocate some new objects in the heap.
+ Local<String> allocated_str =
+ String::NewFromUtf8Literal(d->isolate, "test_alloc");
+ CHECK(!allocated_str.IsEmpty());
+
+ std::string val_str;
+ if (element->IsUndefined()) {
+ val_str = "undefined";
+ } else if (element->IsNumber()) {
+ double val = element.As<Number>()->Value();
+ if (val == static_cast<int64_t>(val)) {
+ val_str = std::to_string(static_cast<int64_t>(val));
+ } else {
+ val_str = std::to_string(val);
+ // Strip trailing zeroes for clean comparison with "1.5", "2.5", "3.5"
+ val_str.erase(val_str.find_last_not_of('0') + 1, std::string::npos);
+ if (val_str.back() == '.') val_str.pop_back();
+ }
+ } else if (element->IsString()) {
+ String::Utf8Value utf8(d->isolate, element.As<String>());
+ val_str = *utf8;
+ } else {
+ val_str = "unknown";
+ }
+ d->visited.emplace_back(index, val_str);
+ return CbResult::kContinue;
+ };
+
+ CHECK(array->Iterate(context(), callback, &data).IsJust());
+
+ if (tc.expected_kind == internal::DICTIONARY_ELEMENTS &&
+ tc.expected_values.size() == 2 && tc.expected_values[0] == "a" &&
+ tc.expected_values[1] == "b") {
+ CHECK_EQ(data.visited.size(), 2);
+ CHECK_EQ(data.visited[0].first, 0);
+ CHECK_EQ(data.visited[0].second, "a");
+ CHECK_EQ(data.visited[1].first, 10000);
+ CHECK_EQ(data.visited[1].second, "b");
+ } else {
+ CHECK_EQ(data.visited.size(), tc.expected_values.size());
+ for (size_t i = 0; i < tc.expected_values.size(); ++i) {
+ CHECK_EQ(data.visited[i].first, static_cast<uint32_t>(i));
+ CHECK_EQ(data.visited[i].second, tc.expected_values[i]);
+ }
+ }
+ }
+}
+
} // namespace
} // namespace v8
diff --git a/deps/v8/test/unittests/assembler/assembler-arm64-unittest.cc b/deps/v8/test/unittests/assembler/assembler-arm64-unittest.cc
index 1cf07e4dbe5..e5fd46a7f87 100644
--- a/deps/v8/test/unittests/assembler/assembler-arm64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/assembler-arm64-unittest.cc
@@ -280,6 +280,12 @@ using AtomicMemoryStoreSignature =
class AssemblerArm64Test : public i::TestWithIsolate {
public:
+ AssemblerArm64Test() {
+#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
+ v8_flags.validate_generated_code = false;
+#endif // V8_ENABLE_GENERATED_CODE_VALIDATOR
+ }
+
void SmullHelper(int64_t expected, int64_t a, int64_t b);
void BtiHelper(Register ipreg);
void LdrLiteralRangeHelper(size_t range, LiteralPoolEmitOutcome outcome,
@@ -321,6 +327,9 @@ class AssemblerArm64Test : public i::TestWithIsolate {
void AbsHelperW(int32_t value);
void MinMaxHelper(MinMaxOp op, bool is_signed, uint64_t a, uint64_t b,
uint32_t wexp, uint64_t xexp);
+
+ private:
+ SaveFlags save_flags_;
};
void AssemblerArm64Test::SmullHelper(int64_t expected, int64_t a, int64_t b) {
@@ -13967,207 +13976,6 @@ TEST_F(AssemblerArm64Test, cpureglist_utils_empty) {
CHECK(fpreg64.IsEmpty());
}
-TEST_F(AssemblerArm64Test, printf) {
-#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
- // Calling printf inlines the format string in a way the validator is not
- // expecting (since it's not generated by the JIT compilers).
- // TODO(523128533): support printf in the validator.
- v8_flags.validate_generated_code = false;
-#endif // V8_ENABLE_GENERATED_CODE_VALIDATOR
-
- SETUP_SIZE(BUF_SIZE * 2);
- START();
-
- char const* test_plain_string = "Printf with no arguments.\n";
- char const* test_substring = "'This is a substring.'";
- RegisterDump before;
-
- // Initialize x29 to the value of the stack pointer. We will use x29 as a
- // temporary stack pointer later, and initializing it in this way allows the
- // RegisterDump check to pass.
- __ Mov(x29, sp);
-
- // Test simple integer arguments.
- __ Mov(x0, 1234);
- __ Mov(x1, 0x1234);
-
- // Test simple floating-point arguments.
- __ Fmov(d0, 1.234);
-
- // Test pointer (string) arguments.
- __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
-
- // Test the maximum number of arguments, and sign extension.
- __ Mov(w3, 0xFFFFFFFF);
- __ Mov(w4, 0xFFFFFFFF);
- __ Mov(x5, 0xFFFFFFFFFFFFFFFF);
- __ Mov(x6, 0xFFFFFFFFFFFFFFFF);
- __ Fmov(s1, 1.234);
- __ Fmov(s2, 2.345);
- __ Fmov(d3, 3.456);
- __ Fmov(d4, 4.567);
-
- // Test printing callee-saved registers.
- __ Mov(x28, 0x123456789ABCDEF);
- __ Fmov(d10, 42.0);
-
- // Test with three arguments.
- __ Mov(x10, 3);
- __ Mov(x11, 40);
- __ Mov(x12, 500);
-
- // A single character.
- __ Mov(w13, 'x');
-
- // Check that we don't clobber any registers.
- before.Dump(&masm);
-
- __ Printf(test_plain_string); // NOLINT(runtime/printf)
- __ Printf("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
- __ Printf("w5: %" PRId32 ", x5: %" PRId64 "\n", w5, x5);
- __ Printf("d0: %f\n", d0);
- __ Printf("Test %%s: %s\n", x2);
- __ Printf("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32
- "\n"
- "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
- w3, w4, x5, x6);
- __ Printf("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
- __ Printf("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
- __ Printf("%g\n", d10);
- __ Printf("%%%%%s%%%c%%\n", x2, w13);
-
- // Print the stack pointer.
- __ Printf("StackPointer(sp): 0x%016" PRIx64 ", 0x%08" PRIx32 "\n", sp, wsp);
-
- // Test with three arguments.
- __ Printf("3=%u, 4=%u, 5=%u\n", x10, x11, x12);
-
- // Mixed argument types.
- __ Printf("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n", w3, s1, x5,
- d3);
- __ Printf("s1: %f, d3: %f, w3: %" PRId32 ", x5: %" PRId64 "\n", s1, d3, w3,
- x5);
-
- END();
- RUN();
-
- // We cannot easily test the output of the Printf sequences, and because
- // Printf preserves all registers by default, we can't look at the number of
- // bytes that were printed. However, the printf_no_preserve test should check
- // that, and here we just test that we didn't clobber any registers.
- CHECK_EQUAL_REGISTERS(before);
-}
-
-TEST_F(AssemblerArm64Test, printf_no_preserve) {
-#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
- // Calling printf_no_preserve inlines the format string in a way the validator
- // is not expecting (since it's not generated by the JIT compilers).
- // TODO(523128533): support printf_no_preserve in the validator.
- v8_flags.validate_generated_code = false;
-#endif // V8_ENABLE_GENERATED_CODE_VALIDATOR
-
- SETUP();
- START();
-
- char const* test_plain_string = "Printf with no arguments.\n";
- char const* test_substring = "'This is a substring.'";
-
- __ PrintfNoPreserve(test_plain_string);
- __ Mov(x19, x0);
-
- // Test simple integer arguments.
- __ Mov(x0, 1234);
- __ Mov(x1, 0x1234);
- __ PrintfNoPreserve("x0: %" PRId64 ", x1: 0x%08" PRIx64 "\n", x0, x1);
- __ Mov(x20, x0);
-
- // Test simple floating-point arguments.
- __ Fmov(d0, 1.234);
- __ PrintfNoPreserve("d0: %f\n", d0);
- __ Mov(x21, x0);
-
- // Test pointer (string) arguments.
- __ Mov(x2, reinterpret_cast<uintptr_t>(test_substring));
- __ PrintfNoPreserve("Test %%s: %s\n", x2);
- __ Mov(x22, x0);
-
- // Test the maximum number of arguments, and sign extension.
- __ Mov(w3, 0xFFFFFFFF);
- __ Mov(w4, 0xFFFFFFFF);
- __ Mov(x5, 0xFFFFFFFFFFFFFFFF);
- __ Mov(x6, 0xFFFFFFFFFFFFFFFF);
- __ PrintfNoPreserve("w3(uint32): %" PRIu32 "\nw4(int32): %" PRId32
- "\n"
- "x5(uint64): %" PRIu64 "\nx6(int64): %" PRId64 "\n",
- w3, w4, x5, x6);
- __ Mov(x23, x0);
-
- __ Fmov(s1, 1.234);
- __ Fmov(s2, 2.345);
- __ Fmov(d3, 3.456);
- __ Fmov(d4, 4.567);
- __ PrintfNoPreserve("%%f: %f\n%%g: %g\n%%e: %e\n%%E: %E\n", s1, s2, d3, d4);
- __ Mov(x24, x0);
-
- // Test printing callee-saved registers.
- __ Mov(x28, 0x123456789ABCDEF);
- __ PrintfNoPreserve("0x%" PRIx32 ", 0x%" PRIx64 "\n", w28, x28);
- __ Mov(x25, x0);
-
- __ Fmov(d10, 42.0);
- __ PrintfNoPreserve("%g\n", d10);
- __ Mov(x26, x0);
-
- // Test with three arguments.
- __ Mov(x3, 3);
- __ Mov(x4, 40);
- __ Mov(x5, 500);
- __ PrintfNoPreserve("3=%u, 4=%u, 5=%u\n", x3, x4, x5);
- __ Mov(x27, x0);
-
- // Mixed argument types.
- __ Mov(w3, 0xFFFFFFFF);
- __ Fmov(s1, 1.234);
- __ Mov(x5, 0xFFFFFFFFFFFFFFFF);
- __ Fmov(d3, 3.456);
- __ PrintfNoPreserve("w3: %" PRIu32 ", s1: %f, x5: %" PRIu64 ", d3: %f\n", w3,
- s1, x5, d3);
- __ Mov(x28, x0);
-
- END();
- RUN();
-
- // We cannot easily test the exact output of the Printf sequences, but we can
- // use the return code to check that the string length was correct.
-
- // Printf with no arguments.
- CHECK_EQUAL_64(strlen(test_plain_string), x19);
- // x0: 1234, x1: 0x00001234
- CHECK_EQUAL_64(25, x20);
- // d0: 1.234000
- CHECK_EQUAL_64(13, x21);
- // Test %s: 'This is a substring.'
- CHECK_EQUAL_64(32, x22);
- // w3(uint32): 4294967295
- // w4(int32): -1
- // x5(uint64): 18446744073709551615
- // x6(int64): -1
- CHECK_EQUAL_64(23 + 14 + 33 + 14, x23);
- // %f: 1.234000
- // %g: 2.345
- // %e: 3.456000e+00
- // %E: 4.567000E+00
- CHECK_EQUAL_64(13 + 10 + 17 + 17, x24);
- // 0x89ABCDEF, 0x123456789ABCDEF
- CHECK_EQUAL_64(30, x25);
- // 42
- CHECK_EQUAL_64(3, x26);
- // 3=3, 4=40, 5=500
- CHECK_EQUAL_64(17, x27);
- // w3: 4294967295, s1: 1.234000, x5: 18446744073709551615, d3: 3.456000
- CHECK_EQUAL_64(69, x28);
-}
-
TEST_F(AssemblerArm64Test, blr_lr) {
// A simple test to check that the simulator correcty handle "blr lr".
SETUP();
diff --git a/deps/v8/test/unittests/assembler/assembler-riscv64-unittest.cc b/deps/v8/test/unittests/assembler/assembler-riscv64-unittest.cc
index 8f717eab56c..bf86fdee3ca 100644
--- a/deps/v8/test/unittests/assembler/assembler-riscv64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/assembler-riscv64-unittest.cc
@@ -483,6 +483,16 @@ UTEST_AMO_WITH_RES(amominu_w, false, false, uint32_t, 0xFBB1A75C, 0xA75C0A9C,
UTEST_AMO_WITH_RES(amomaxu_w, false, false, uint32_t, 0xFBB1A75C, 0xA75C0A9C,
std::max((uint32_t)0xFBB1A75C, (uint32_t)0xA75C0A9C))
+TEST_F(AssemblerRISCV64Test, RISCV_UTEST_amo_w_sign_extends_result) {
+ auto fn = [](MacroAssembler& assm) {
+ __ amoswap_w(false, false, a1, a0, a2);
+ __ srli(a1, a1, 32);
+ __ sw(a1, a0, 0);
+ };
+ auto res = GenAndRunTestForAMO<uint32_t, int64_t>(0xFBB1A75C, 0xA75C0A9C, fn);
+ CHECK_EQ(-1, res);
+}
+
// -- RV64A Standard Extension (in addition to RV32A) --
UTEST_LR_SC(lr_d, sc_d, false, false, int64_t, 0xFBB10A9Cbfb76aa6)
UTEST_AMO_WITH_RES(amoswap_d, false, false, int64_t, 0xFBB10A9Cbfb76aa6,
@@ -3208,6 +3218,111 @@ TEST_F(AssemblerRISCV64Test, RVC_CB_BRANCH) {
CHECK_EQ(1, t.result);
}
+#ifdef USE_SIMULATOR // Remove it when v8 can detect zcb.
+TEST_F(AssemblerRISCV64Test, RVC_ZCB) {
+ // Test RV64C extension Zcb instructions.
+
+ Isolate* isolate = i_isolate();
+ HandleScope scope(isolate);
+
+ // Test c.lbu / c.sb.
+ {
+ uint8_t mem[4];
+ auto fn = [](MacroAssembler& assm) {
+ __ c_lbu(a1, a0, 0);
+ __ c_lbu(a2, a0, 3);
+ __ c_sb(a1, a0, 1);
+ __ c_sb(a2, a0, 2);
+ };
+ auto f = AssembleCode<F3>(isolate, fn);
+
+ mem[0] = 0xAB;
+ mem[1] = 0;
+ mem[2] = 0;
+ mem[3] = 0x80;
+ f.Call(mem, 0, 0, 0, 0);
+ CHECK_EQ(0xAB, mem[1]);
+ CHECK_EQ(0x80, mem[2]);
+ }
+
+ // Test c.lhu / c.lh / c.sh.
+ {
+ uint8_t mem[4];
+ auto fn = [](MacroAssembler& assm) {
+ __ c_lhu(a1, a0, 0); // a1 = zext(mem[0:1])
+ __ addi(a1, a1, 1);
+ __ c_sh(a1, a0, 0); // mem[0:1] = a1.
+ __ c_lh(a2, a0, 2); // a2 = sext(mem[2:3])
+ __ srli(a2, a2, 63); // a2 = 1 if sign-extended.
+ __ c_sb(a2, a0, 1);
+ };
+ auto f = AssembleCode<F3>(isolate, fn);
+
+ mem[0] = 0x34;
+ mem[1] = 0x12;
+ mem[2] = 0x00;
+ mem[3] = 0x80;
+ f.Call(mem, 0, 0, 0, 0);
+ CHECK_EQ(0x35, mem[0]);
+ CHECK_EQ(0x01, mem[1]);
+ CHECK_EQ(0x00, mem[2]);
+ CHECK_EQ(0x80, mem[3]);
+ }
+
+ // Test c.mul
+ {
+ auto fn = [](MacroAssembler& assm) {
+ __ RV_li(a1, 6);
+ __ c_mul(a0, a1);
+ };
+ auto res = GenAndRunTest<int64_t>(7, fn);
+ CHECK_EQ(42, res);
+ }
+
+ // Test c.zext.b
+ {
+ auto fn = [](MacroAssembler& assm) { __ c_zext_b(a0); };
+ auto res = GenAndRunTest<int64_t>(0x1234'5678'9ABC'DEFF, fn);
+ CHECK_EQ(0xFF, res);
+ }
+
+ // Test c.sext.b
+ {
+ auto fn = [](MacroAssembler& assm) { __ c_sext_b(a0); };
+ auto res = GenAndRunTest<int64_t>(0x80, fn);
+ CHECK_EQ(-128, res);
+ }
+
+ // Test c.zext.h
+ {
+ auto fn = [](MacroAssembler& assm) { __ c_zext_h(a0); };
+ auto res = GenAndRunTest<int64_t>(0x1234'5678'9ABC'DEFF, fn);
+ CHECK_EQ(0xDEFF, res);
+ }
+
+ // Test c.sext.h
+ {
+ auto fn = [](MacroAssembler& assm) { __ c_sext_h(a0); };
+ auto res = GenAndRunTest<int64_t>(0x1234'5678'9ABC'8000, fn);
+ CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFFFFF8000), res);
+ }
+
+ // Test c.zext.w
+ {
+ auto fn = [](MacroAssembler& assm) { __ c_zext_w(a0); };
+ auto res = GenAndRunTest<int64_t>(0x1234'5678'9ABC'DEFF, fn);
+ CHECK_EQ(static_cast<int64_t>(0x9ABCDEFF), res);
+ }
+
+ // Test c.not
+ {
+ auto fn = [](MacroAssembler& assm) { __ c_not(a0); };
+ auto res = GenAndRunTest<int64_t>(0x1234, fn);
+ CHECK_EQ(static_cast<int64_t>(0xFFFFFFFFFFFFEDCB), res);
+ }
+}
+#endif
+
TEST_F(AssemblerRISCV64Test, TARGET_ADDR) {
Isolate* isolate = i_isolate();
HandleScope scope(isolate);
diff --git a/deps/v8/test/unittests/assembler/assembler-x64-unittest.cc b/deps/v8/test/unittests/assembler/assembler-x64-unittest.cc
index 8e89043d795..96bbaa268e4 100644
--- a/deps/v8/test/unittests/assembler/assembler-x64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/assembler-x64-unittest.cc
@@ -3269,6 +3269,189 @@ TEST_F(AssemblerX64Test, AssemblerX64AVXVNNIINT8) {
CHECK_EQ(0, memcmp(expected, desc.buffer, sizeof(expected)));
}
+#ifdef V8_ENABLE_AVX10_1
+TEST_F(AssemblerX64Test, AVX10RegisterCodes) {
+ CHECK_EQ(16, xmm16.code());
+ CHECK_EQ(31, xmm31.code());
+ CHECK_EQ(1, xmm16.bit4()); // bit 4 set
+ CHECK_EQ(0, xmm15.bit4());
+ CHECK_EQ(0, xmm16.high_bit()); // bit 3 clear for code 16
+ CHECK_EQ(1, xmm24.high_bit()); // bit 3 set for code 24
+}
+#endif // V8_ENABLE_AVX10_1
+
+#ifdef V8_ENABLE_AVX10_1
+TEST_F(AssemblerX64Test, AVX10Vpmullq) {
+ auto buffer = AllocateAssemblerBuffer();
+ Isolate* isolate = i_isolate();
+ Assembler masm(AssemblerOptions{}, buffer->CreateView());
+ // Encoding-only test: force-enable AVX10_1 so it runs on any host.
+ CpuFeatureScope fscope(&masm, AVX10_1, CpuFeatureScope::kDontCheckSupported);
+
+ __ vpmullq(xmm3, xmm2, xmm1);
+ __ vpmullq(xmm19, xmm18, xmm17);
+ __ vpmullq(xmm3, xmm2, Operand(rbx, 64));
+ __ vpmullq(ymm3, ymm2, ymm1);
+ __ vpmullq(ymm3, ymm2, Operand(rbx, 128));
+ // CD8 edge cases (exercise Operand::to_evex_cd8 fallbacks):
+ __ vpmullq(xmm3, xmm2, Operand(rbx, 16)); // divisible -> compressed disp8
+ __ vpmullq(xmm3, xmm2, Operand(rbx, 20)); // not divisible -> disp32 fallback
+ __ vpmullq(xmm3, xmm2, Operand(rbx, 3200)); // cdisp8 out of int8 -> disp32
+ // SIB (base+index) memory operand: exercises the to_evex_cd8 path where a SIB
+ // byte precedes the displacement.
+ __ vpmullq(xmm3, xmm2, Operand(rbx, rcx, times_1, 64)); // CD8: 64/16 = 4
+ // RIP-relative (label) operand: must pass through to_evex_cd8 unchanged.
+ Label rip_label;
+ __ bind(&rip_label);
+ __ vpmullq(xmm3, xmm2, Operand(&rip_label));
+
+ // Capture the emitted instruction length before GetCode(): GetCode() pads the
+ // stream to kMetadataAlignment (desc.instr_size would include that padding).
+ int instruction_length = masm.pc_offset();
+ CodeDesc desc;
+ masm.GetCode(isolate, &desc);
+
+ uint8_t expected[] = {
+ // vpmullq xmm3, xmm2, xmm1
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0xd9,
+ // vpmullq xmm19, xmm18, xmm17 (high registers: R'/V'/B')
+ 0x62, 0xa2, 0xed, 0x00, 0x40, 0xd9,
+ // vpmullq xmm3, xmm2, [rbx+0x40] (CD8: 64/16 = 4)
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0x5b, 0x04,
+ // vpmullq ymm3, ymm2, ymm1
+ 0x62, 0xf2, 0xed, 0x28, 0x40, 0xd9,
+ // vpmullq ymm3, ymm2, [rbx+0x80] (CD8: 128/32 = 4)
+ 0x62, 0xf2, 0xed, 0x28, 0x40, 0x5b, 0x04,
+ // vpmullq xmm3, xmm2, [rbx+0x10] (CD8: 16/16 = 1, compressed disp8)
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0x5b, 0x01,
+ // vpmullq xmm3, xmm2, [rbx+0x14] (20 not divisible by 16 -> disp32)
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0x9b, 0x14, 0x00, 0x00, 0x00,
+ // vpmullq xmm3, xmm2, [rbx+0xc80] (3200/16=200 out of int8 -> disp32)
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0x9b, 0x80, 0x0c, 0x00, 0x00,
+ // vpmullq xmm3, xmm2, [rbx+rcx*1+0x40] (SIB; CD8: 64/16 = 4)
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0x5c, 0x0b, 0x04,
+ // vpmullq xmm3, xmm2, [rip-0xa] (RIP-relative disp32, no CD8 scaling)
+ 0x62, 0xf2, 0xed, 0x08, 0x40, 0x1d, 0xf6, 0xff, 0xff, 0xff};
+ CHECK_EQ(static_cast<int>(sizeof(expected)), instruction_length);
+ CHECK_EQ(0, memcmp(expected, desc.buffer, sizeof(expected)));
+}
+#endif // V8_ENABLE_AVX10_1
+
+#ifdef V8_ENABLE_AVX10_1
+TEST_F(AssemblerX64Test, AVX10IntegerArith) {
+ auto buffer = AllocateAssemblerBuffer();
+ Isolate* isolate = i_isolate();
+ Assembler masm(AssemblerOptions{}, buffer->CreateView());
+ CpuFeatureScope fscope(&masm, AVX10_1, CpuFeatureScope::kDontCheckSupported);
+
+ // vpsraq — variable count (xmm/m128)
+ __ vpsraq(xmm3, xmm2, xmm1);
+ __ vpsraq(xmm3, xmm2, Operand(rbx, 64));
+ // vpsraq — imm8
+ __ vpsraq(xmm3, xmm2, uint8_t{5});
+ __ vpsraq(ymm3, ymm2, uint8_t{5});
+ __ vpsraq(xmm3, Operand(rbx, 64), uint8_t{5});
+ // vpabsq — unary
+ __ vpabsq(xmm2, xmm1);
+ __ vpabsq(ymm2, ymm1);
+ __ vpabsq(xmm2, Operand(rbx, 64));
+ // vpminsq — binary
+ __ vpminsq(xmm3, xmm2, xmm1);
+ __ vpminsq(ymm3, ymm2, ymm1);
+ __ vpminsq(xmm3, xmm2, Operand(rbx, 64));
+ // vpopcntb — unary (W0)
+ __ vpopcntb(xmm2, xmm1);
+ __ vpopcntb(ymm18, ymm17);
+ __ vpopcntb(xmm2, Operand(rbx, 32));
+
+ // Capture the emitted instruction length before GetCode(): GetCode() pads the
+ // stream to kMetadataAlignment (desc.instr_size would include that padding).
+ int instruction_length = masm.pc_offset();
+ CodeDesc desc;
+ masm.GetCode(isolate, &desc);
+
+ uint8_t expected[] = {
+ // vpsraq xmm3, xmm2, xmm1
+ 0x62, 0xf1, 0xed, 0x08, 0xe2, 0xd9,
+ // vpsraq xmm3, xmm2, [rbx+0x40] (CD8: 64/16 = 4)
+ 0x62, 0xf1, 0xed, 0x08, 0xe2, 0x5b, 0x04,
+ // vpsraq xmm3, xmm2, 0x5
+ 0x62, 0xf1, 0xe5, 0x08, 0x72, 0xe2, 0x05,
+ // vpsraq ymm3, ymm2, 0x5
+ 0x62, 0xf1, 0xe5, 0x28, 0x72, 0xe2, 0x05,
+ // vpsraq xmm3, [rbx+0x40], 0x5 (CD8: 64/16 = 4)
+ 0x62, 0xf1, 0xe5, 0x08, 0x72, 0x63, 0x04, 0x05,
+ // vpabsq xmm2, xmm1
+ 0x62, 0xf2, 0xfd, 0x08, 0x1f, 0xd1,
+ // vpabsq ymm2, ymm1
+ 0x62, 0xf2, 0xfd, 0x28, 0x1f, 0xd1,
+ // vpabsq xmm2, [rbx+0x40] (CD8: 64/16 = 4)
+ 0x62, 0xf2, 0xfd, 0x08, 0x1f, 0x53, 0x04,
+ // vpminsq xmm3, xmm2, xmm1
+ 0x62, 0xf2, 0xed, 0x08, 0x39, 0xd9,
+ // vpminsq ymm3, ymm2, ymm1
+ 0x62, 0xf2, 0xed, 0x28, 0x39, 0xd9,
+ // vpminsq xmm3, xmm2, [rbx+0x40] (CD8: 64/16 = 4)
+ 0x62, 0xf2, 0xed, 0x08, 0x39, 0x5b, 0x04,
+ // vpopcntb xmm2, xmm1
+ 0x62, 0xf2, 0x7d, 0x08, 0x54, 0xd1,
+ // vpopcntb ymm18, ymm17 (high registers)
+ 0x62, 0xa2, 0x7d, 0x28, 0x54, 0xd1,
+ // vpopcntb xmm2, [rbx+0x20] (byte element, CD8: 32/16 = 2)
+ 0x62, 0xf2, 0x7d, 0x08, 0x54, 0x53, 0x02};
+ CHECK_EQ(static_cast<int>(sizeof(expected)), instruction_length);
+ CHECK_EQ(0, memcmp(expected, desc.buffer, sizeof(expected)));
+}
+#endif // V8_ENABLE_AVX10_1
+
+#ifdef V8_ENABLE_AVX10_1
+TEST_F(AssemblerX64Test, AVX10TernaryLogic) {
+ Isolate* isolate = i_isolate();
+ HandleScope scope(isolate);
+ uint8_t buffer[256];
+ Assembler masm(AssemblerOptions{},
+ ExternalAssemblerBuffer(buffer, sizeof(buffer)));
+ // Encoding-only test: force-enable AVX10_1 so it runs on any host.
+ CpuFeatureScope fscope(&masm, AVX10_1, CpuFeatureScope::kDontCheckSupported);
+
+ // vpternlogd — W0. reg-reg, high registers (R'/V'/B'), one reg-mem case.
+ __ vpternlogd(xmm3, xmm2, xmm1, 0x33);
+ __ vpternlogd(xmm19, xmm18, xmm17, 0x33);
+ __ vpternlogd(xmm3, xmm2, Operand(rbx, 64), 0x33);
+ __ vpternlogd(ymm3, ymm2, ymm1, 0x33);
+ // vpternlogq — W1.
+ __ vpternlogq(xmm3, xmm2, xmm1, 0xca);
+ __ vpternlogq(ymm3, ymm2, ymm1, 0xca);
+ // Masking: {k1} merging and {k1}{z} zeroing.
+ __ vpternlogd(xmm3, xmm2, xmm1, 0x33, Assembler::k1);
+ __ vpternlogd(xmm3, xmm2, xmm1, 0x33, Assembler::k1, Assembler::kZeroing);
+
+ int instruction_length = masm.pc_offset();
+ CodeDesc desc;
+ masm.GetCode(isolate, &desc);
+
+ uint8_t expected[] = {
+ // vpternlogd xmm3,xmm2,xmm1,0x33
+ 0x62, 0xf3, 0x6d, 0x08, 0x25, 0xd9, 0x33,
+ // vpternlogd xmm19,xmm18,xmm17,0x33 (high regs: R'/V'/B')
+ 0x62, 0xa3, 0x6d, 0x00, 0x25, 0xd9, 0x33,
+ // vpternlogd xmm3,xmm2,[rbx+0x40],0x33 (CD8: 64/16 = 4)
+ 0x62, 0xf3, 0x6d, 0x08, 0x25, 0x5b, 0x04, 0x33,
+ // vpternlogd ymm3,ymm2,ymm1,0x33
+ 0x62, 0xf3, 0x6d, 0x28, 0x25, 0xd9, 0x33,
+ // vpternlogq xmm3,xmm2,xmm1,0xca (W1)
+ 0x62, 0xf3, 0xed, 0x08, 0x25, 0xd9, 0xca,
+ // vpternlogq ymm3,ymm2,ymm1,0xca
+ 0x62, 0xf3, 0xed, 0x28, 0x25, 0xd9, 0xca,
+ // vpternlogd xmm3{k1},xmm2,xmm1,0x33 (masked, merging)
+ 0x62, 0xf3, 0x6d, 0x09, 0x25, 0xd9, 0x33,
+ // vpternlogd xmm3{k1}{z},xmm2,xmm1,0x33 (masked, zeroing)
+ 0x62, 0xf3, 0x6d, 0x89, 0x25, 0xd9, 0x33};
+ CHECK_EQ(static_cast<int>(sizeof(expected)), instruction_length);
+ CHECK_EQ(0, memcmp(expected, desc.buffer, sizeof(expected)));
+}
+#endif // V8_ENABLE_AVX10_1
+
TEST_F(AssemblerX64Test, CpuFeatures_ProbeImpl) {
// Support for a newer extension implies support for the older extensions.
CHECK_IMPLIES(CpuFeatures::IsSupported(FMA3), CpuFeatures::IsSupported(AVX));
diff --git a/deps/v8/test/unittests/assembler/disasm-riscv-unittest.cc b/deps/v8/test/unittests/assembler/disasm-riscv-unittest.cc
index ed73d116b5f..d9eeeb69329 100644
--- a/deps/v8/test/unittests/assembler/disasm-riscv-unittest.cc
+++ b/deps/v8/test/unittests/assembler/disasm-riscv-unittest.cc
@@ -658,6 +658,48 @@ TEST_F(DisasmRiscvTest, RV64C) {
VERIFY_RUN();
}
#endif
+#ifdef V8_TARGET_ARCH_RISCV64
+TEST_F(DisasmRiscvTest, Zcb) {
+ SET_UP();
+
+ // Zcb loads (CL format, funct3=100).
+ COMPARE(c_lbu(s1, a0, 3), "00008164 lbu s1, 3(a0)");
+ COMPARE(c_lbu(a0, a1, 1), "000081c8 lbu a0, 1(a1)");
+ COMPARE(c_lhu(s1, a0, 2), "00008524 lhu s1, 2(a0)");
+ COMPARE(c_lhu(a0, a1, 2), "000085a8 lhu a0, 2(a1)");
+ COMPARE(c_lh(s1, a0, 2), "00008564 lh s1, 2(a0)");
+ COMPARE(c_lh(a0, a1, 2), "000085e8 lh a0, 2(a1)");
+
+ // Zcb stores (CS format, funct3=100).
+ COMPARE(c_sb(s1, a0, 3), "00008964 sb s1, 3(a0)");
+ COMPARE(c_sb(a0, a1, 3), "000089e8 sb a0, 3(a1)");
+ COMPARE(c_sh(s1, a0, 2), "00008d24 sh s1, 2(a0)");
+ COMPARE(c_sh(a0, a1, 2), "00008da8 sh a0, 2(a1)");
+
+ // Zcb multiply (CA format).
+ COMPARE(c_mul(a0, s1), "00009d45 mul a0, a0, s1");
+ COMPARE(c_mul(s1, a0), "00009cc9 mul s1, s1, a0");
+
+ // Zcb unary instructions (CU format).
+ COMPARE(c_zext_b(a0), "00009d61 zext.b a0, a0");
+ COMPARE(c_zext_b(a1), "00009de1 zext.b a1, a1");
+
+ COMPARE(c_sext_b(a0), "00009d65 sext.b a0, a0");
+ COMPARE(c_sext_b(a2), "00009e65 sext.b a2, a2");
+
+ COMPARE(c_zext_h(a0), "00009d69 zext.h a0, a0");
+ COMPARE(c_zext_h(a3), "00009ee9 zext.h a3, a3");
+
+ COMPARE(c_sext_h(a0), "00009d6d sext.h a0, a0");
+ COMPARE(c_sext_h(a4), "00009f6d sext.h a4, a4");
+
+ COMPARE(c_zext_w(a0), "00009d71 zext.w a0, a0");
+ COMPARE(c_not(a0), "00009d75 not a0, a0");
+ COMPARE(c_not(a5), "00009ff5 not a5, a5");
+
+ VERIFY_RUN();
+}
+#endif
/*
TEST_F(DisasmRiscvTest, Previleged) {
SET_UP();
diff --git a/deps/v8/test/unittests/assembler/disasm-x64-unittest.cc b/deps/v8/test/unittests/assembler/disasm-x64-unittest.cc
index 7f766f5c4c8..5c7ecba9f55 100644
--- a/deps/v8/test/unittests/assembler/disasm-x64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/disasm-x64-unittest.cc
@@ -66,15 +66,15 @@ Handle<Code> CreateDummyCode(Isolate* isolate) {
TEST_F(DisasmX64Test, AVX512) {
uint8_t buffer[128];
- // vpcmpeqb (%rdi),%ymm16,%k0 -> 62 f3 7d 20 3f 07 00
+ // vpcmpb $0,(%rdi),%ymm16,%k0 -> 62 f3 7d 20 3f 07 00
// kmovd %k0,%eax -> c5 fb 93 c0
// kmovd %k0,%eax (malformed vex ~R) -> c5 7b 93 c0
- // vpcmpeqb %ymm17,%ymm16,%k0 -> 62 fb 7d 20 3f c1 00
+ // vpcmpb $0,%ymm17,%ymm16,%k0 -> 62 b3 7d 20 3f c1 00
memcpy(buffer,
"\x62\xf3\x7d\x20\x3f\x07\x00"
"\xc5\xfb\x93\xc0"
"\xc5\x7b\x93\xc0"
- "\x62\xfb\x7d\x20\x3f\xc1\x00",
+ "\x62\xb3\x7d\x20\x3f\xc1\x00",
22);
disasm::NameConverter converter;
@@ -85,7 +85,7 @@ TEST_F(DisasmX64Test, AVX512) {
int len = d.InstructionDecode(out_buffer, pc);
EXPECT_EQ(len, 7);
EXPECT_STREQ(out_buffer.begin(),
- "62f37d203f0700 vpcmpeqb k0,xmm16,[rdi],0x0");
+ "62f37d203f0700 vpcmpb k0,ymm16,[rdi],0x0");
pc += len;
len = d.InstructionDecode(out_buffer, pc);
@@ -99,12 +99,35 @@ TEST_F(DisasmX64Test, AVX512) {
EXPECT_EQ(len, 4);
EXPECT_STREQ(out_buffer.begin(), "c57b93c0 kmovd rax,k0");
- // Verify decoding of upper EVEX AVX-512 register (xmm17 / ymm17).
+ // Verify decoding of upper EVEX AVX-512 register (ymm17) and vector width.
pc += len;
len = d.InstructionDecode(out_buffer, pc);
EXPECT_EQ(len, 7);
EXPECT_STREQ(out_buffer.begin(),
- "62fb7d203fc100 vpcmpeqb k0,xmm16,xmm17,0x0");
+ "62b37d203fc100 vpcmpb k0,ymm16,ymm17,0x0");
+}
+
+TEST_F(DisasmX64Test, EVEXVectorW) {
+ uint8_t buffer[] = {
+ 0x62, 0xf1, 0x7e, 0x08, 0x2a, 0xc0, // vcvtlsi2ss xmm0,xmm0,rax
+ 0x62, 0xf1, 0xfe, 0x08, 0x2a, 0xc0, // vcvtqsi2ss xmm0,xmm0,rax
+ };
+
+ disasm::NameConverter converter;
+ disasm::Disassembler disassembler(converter);
+ v8::base::EmbeddedVector<char, 128> out_buffer;
+
+ uint8_t* pc = buffer;
+ int len = disassembler.InstructionDecode(out_buffer, pc);
+ EXPECT_EQ(len, 6);
+ EXPECT_STREQ(out_buffer.begin(),
+ "62f17e082ac0 vcvtlsi2ss xmm0,xmm0,rax");
+
+ pc += len;
+ len = disassembler.InstructionDecode(out_buffer, pc);
+ EXPECT_EQ(len, 6);
+ EXPECT_STREQ(out_buffer.begin(),
+ "62f1fe082ac0 vcvtqsi2ss xmm0,xmm0,rax");
}
TEST_F(DisasmX64Test, DisasmX64) {
@@ -623,6 +646,16 @@ TEST_F(DisasmX64Test, DisasmX64CheckOutput) {
COMPARE("48f7ac8b10270000 REX.W imulq [rbx+rcx*4+0x2710]",
imulq(Operand(rbx, rcx, times_4, 10000)));
+ Label imul_rip;
+ t.assm_.bind(&imul_rip);
+ COMPARE("48f72df9ffffff REX.W imulq [rip+0xfffffff9]",
+ imulq(Operand(&imul_rip)));
+ COMPARE("48f729 REX.W imulq [rcx]", imulq(Operand(rcx, 0)));
+ COMPARE("48f72c24 REX.W imulq [rsp]", imulq(Operand(rsp, 0)));
+ COMPARE("48f72c39 REX.W imulq [rcx+rdi*1]",
+ imulq(Operand(rcx, rdi, times_1, 0)));
+ COMPARE("48f72c7d00000000 REX.W imulq [rdi*2+0x0]",
+ imulq(Operand(rdi, times_2, 0)));
COMPARE("486bd10c REX.W imulq rdx,rcx,0xc",
imulq(rdx, rcx, Immediate(12)));
COMPARE("4869d1e8030000 REX.W imulq rdx,rcx,0x3e8",
@@ -1860,6 +1893,78 @@ TEST_F(DisasmX64Test, DisasmX64CheckOutputAPX) {
}
#endif // V8_ENABLE_APX_F
+#ifdef V8_ENABLE_AVX10_1
+TEST_F(DisasmX64Test, DisasmX64CheckOutputAVX10) {
+ DisassemblerTester t;
+ std::string actual;
+ CpuFeatureScope fscope(&t.assm_, AVX10_1,
+ CpuFeatureScope::kDontCheckSupported);
+
+ // vpmullq: reg-reg, high registers (R'/V'/B'), and reg-mem exercising the
+ // compressed-displacement (disp8*N) paths.
+ COMPARE_INSTR("vpmullq xmm3,xmm2,xmm1", vpmullq(xmm3, xmm2, xmm1));
+ COMPARE_INSTR("vpmullq xmm19,xmm18,xmm17", vpmullq(xmm19, xmm18, xmm17));
+ COMPARE_INSTR("vpmullq xmm3,xmm2,[rbx+0x40]",
+ vpmullq(xmm3, xmm2, Operand(rbx, 64)));
+ COMPARE_INSTR("vpmullq ymm3,ymm2,ymm1", vpmullq(ymm3, ymm2, ymm1));
+ COMPARE_INSTR("vpmullq ymm3,ymm2,[rbx+0x80]",
+ vpmullq(ymm3, ymm2, Operand(rbx, 128)));
+ COMPARE_INSTR(
+ "vpmullq xmm3,xmm2,[rbx+0x10]", // divisible -> compressed disp8
+ vpmullq(xmm3, xmm2, Operand(rbx, 16)));
+ COMPARE_INSTR("vpmullq xmm3,xmm2,[rbx+0x14]", // not divisible -> disp32
+ vpmullq(xmm3, xmm2, Operand(rbx, 20)));
+ COMPARE_INSTR("vpmullq xmm3,xmm2,[rbx+0xc80]", // out of int8 -> disp32
+ vpmullq(xmm3, xmm2, Operand(rbx, 3200)));
+ COMPARE_INSTR("vpmullq xmm3,xmm2,[rbx+rcx*1+0x40]", // SIB; CD8 64/16 = 4
+ vpmullq(xmm3, xmm2, Operand(rbx, rcx, times_1, 64)));
+
+ // vpsraq: variable count (xmm/m128) and imm8 (destination in EVEX.vvvv).
+ COMPARE_INSTR("vpsraq xmm3,xmm2,xmm1", vpsraq(xmm3, xmm2, xmm1));
+ COMPARE_INSTR("vpsraq xmm3,xmm2,[rbx+0x40]",
+ vpsraq(xmm3, xmm2, Operand(rbx, 64)));
+ COMPARE_INSTR("vpsraq xmm3,xmm2,5", vpsraq(xmm3, xmm2, uint8_t{5}));
+ COMPARE_INSTR("vpsraq ymm3,ymm2,5", vpsraq(ymm3, ymm2, uint8_t{5}));
+ COMPARE_INSTR("vpsraq xmm3,[rbx+0x40],5",
+ vpsraq(xmm3, Operand(rbx, 64), uint8_t{5}));
+
+ // vpabsq: unary.
+ COMPARE_INSTR("vpabsq xmm2,xmm1", vpabsq(xmm2, xmm1));
+ COMPARE_INSTR("vpabsq ymm2,ymm1", vpabsq(ymm2, ymm1));
+ COMPARE_INSTR("vpabsq xmm2,[rbx+0x40]", vpabsq(xmm2, Operand(rbx, 64)));
+
+ // vpminsq: binary.
+ COMPARE_INSTR("vpminsq xmm3,xmm2,xmm1", vpminsq(xmm3, xmm2, xmm1));
+ COMPARE_INSTR("vpminsq ymm3,ymm2,ymm1", vpminsq(ymm3, ymm2, ymm1));
+ COMPARE_INSTR("vpminsq xmm3,xmm2,[rbx+0x40]",
+ vpminsq(xmm3, xmm2, Operand(rbx, 64)));
+
+ // vpopcntb: unary (W0), including a high-register and a reg-mem case.
+ COMPARE_INSTR("vpopcntb xmm2,xmm1", vpopcntb(xmm2, xmm1));
+ COMPARE_INSTR("vpopcntb ymm18,ymm17", vpopcntb(ymm18, ymm17));
+ COMPARE_INSTR("vpopcntb xmm2,[rbx+0x20]", vpopcntb(xmm2, Operand(rbx, 32)));
+
+ // vpternlogd/q: reg-reg, high registers, reg-mem, imm8, and masking suffix.
+ COMPARE_INSTR("vpternlogd xmm3,xmm2,xmm1,0x33",
+ vpternlogd(xmm3, xmm2, xmm1, 0x33));
+ COMPARE_INSTR("vpternlogd xmm19,xmm18,xmm17,0x33",
+ vpternlogd(xmm19, xmm18, xmm17, 0x33));
+ COMPARE_INSTR("vpternlogd xmm3,xmm2,[rbx+0x40],0x33",
+ vpternlogd(xmm3, xmm2, Operand(rbx, 64), 0x33));
+ COMPARE_INSTR("vpternlogd ymm3,ymm2,ymm1,0x33",
+ vpternlogd(ymm3, ymm2, ymm1, 0x33));
+ COMPARE_INSTR("vpternlogq xmm3,xmm2,xmm1,0xca",
+ vpternlogq(xmm3, xmm2, xmm1, 0xca));
+ COMPARE_INSTR("vpternlogq ymm19,ymm18,ymm17,0xca",
+ vpternlogq(ymm19, ymm18, ymm17, 0xca));
+ COMPARE_INSTR("vpternlogd xmm3{k1},xmm2,xmm1,0x33",
+ vpternlogd(xmm3, xmm2, xmm1, 0x33, Assembler::k1));
+ COMPARE_INSTR(
+ "vpternlogd xmm3{k1}{z},xmm2,xmm1,0x33",
+ vpternlogd(xmm3, xmm2, xmm1, 0x33, Assembler::k1, Assembler::kZeroing));
+}
+#endif // V8_ENABLE_AVX10_1
+
#undef __
} // namespace internal
diff --git a/deps/v8/test/unittests/assembler/macro-assembler-loong64-unittest.cc b/deps/v8/test/unittests/assembler/macro-assembler-loong64-unittest.cc
index c1b532d13b3..903df258fde 100644
--- a/deps/v8/test/unittests/assembler/macro-assembler-loong64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/macro-assembler-loong64-unittest.cc
@@ -764,9 +764,9 @@ TEST_F(MacroAssemblerTest, OverflowInstructions) {
expected_mul_ovf =
base::bits::SignedMulOverflow32(ii32, jj32, &expected_mul);
- CHECK_EQ(expected_add_ovf, t.overflow_add1 < 0);
- CHECK_EQ(expected_sub_ovf, t.overflow_sub1 < 0);
- CHECK_EQ(expected_mul_ovf, t.overflow_mul1 != 0);
+ CHECK_EQ(expected_add_ovf, t.overflow_add1);
+ CHECK_EQ(expected_sub_ovf, t.overflow_sub1);
+ CHECK_EQ(expected_mul_ovf, t.overflow_mul1);
CHECK_EQ(t.overflow_add1, t.overflow_add2);
CHECK_EQ(t.overflow_sub1, t.overflow_sub2);
diff --git a/deps/v8/test/unittests/assembler/macro-assembler-x64-unittest.cc b/deps/v8/test/unittests/assembler/macro-assembler-x64-unittest.cc
index 877beaf1b27..9b550abe8fa 100644
--- a/deps/v8/test/unittests/assembler/macro-assembler-x64-unittest.cc
+++ b/deps/v8/test/unittests/assembler/macro-assembler-x64-unittest.cc
@@ -43,6 +43,7 @@
#include "src/objects/smi.h"
#include "src/utils/ostreams.h"
#include "test/common/assembler-tester.h"
+#include "test/common/flag-utils.h"
#include "test/common/value-helper.h"
#include "test/unittests/test-utils.h"
#include "third_party/fp16/src/include/fp16.h"
@@ -1328,9 +1329,12 @@ TEST_F(MacroAssemblerX64Test, SIMDMacros) {
CHECK_EQ(0, result);
}
+// Test the pre-AVX10 path.
TEST_F(MacroAssemblerX64Test, S256Select) {
if (!CpuFeatures::IsSupported(AVX) || !CpuFeatures::IsSupported(AVX2)) return;
-
+#ifdef V8_ENABLE_AVX10_1
+ FlagScope<bool> avx10_scope(&v8_flags.enable_avx10_1, false);
+#endif
Isolate* isolate = i_isolate();
HandleScope handles(isolate);
auto buffer = AllocateAssemblerBuffer();
@@ -1414,6 +1418,231 @@ TEST_F(MacroAssemblerX64Test, S256Select) {
}
}
+#ifdef V8_ENABLE_AVX10_1
+// End-to-end execution tests for the AVX10.1 (vpternlogd) lowerings of
+// s128.not/select and s256.not/select.
+
+TEST_F(MacroAssemblerX64Test, S128NotAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ Isolate* isolate = i_isolate();
+ HandleScope handles(isolate);
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler assembler(isolate, v8::internal::CodeObjectRequired{true},
+ buffer->CreateView());
+ MacroAssembler* masm = &assembler;
+
+ const XMMRegister dst = xmm0;
+ const XMMRegister src = xmm1;
+
+ CpuFeatureScope avx_scope(masm, AVX);
+
+ __ vmovdqu(src, Operand(kCArgRegs[0], 0));
+ __ S128Not(dst, src, kScratchDoubleReg);
+ __ vmovdqu(Operand(kCArgRegs[1], 0), dst);
+ __ ret(0);
+
+ CodeDesc desc;
+ __ GetCode(i_isolate(), &desc);
+ buffer->MakeExecutable();
+ auto f = GeneratedCode<F1>::FromBuffer(i_isolate(), buffer->start());
+
+ std::vector<std::array<uint64_t, 2>> test_cases = {
+ {0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
+ {0x0123456789ABCDEF, 0xFEDCBA9876543210},
+ {0xAAAAAAAAAAAAAAAA, 0x5555555555555555}};
+
+ uint64_t input[2];
+ uint64_t output[2];
+
+ for (const auto& arr : test_cases) {
+ input[0] = arr[0];
+ input[1] = arr[1];
+
+ f.Call(input, output, nullptr);
+
+ for (int i = 0; i < 2; i++) {
+ CHECK_EQ(output[i], ~input[i]);
+ }
+ }
+}
+
+TEST_F(MacroAssemblerX64Test, S128SelectAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ Isolate* isolate = i_isolate();
+ HandleScope handles(isolate);
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler assembler(isolate, v8::internal::CodeObjectRequired{true},
+ buffer->CreateView());
+ MacroAssembler* masm = &assembler;
+
+ // The AVX10.1 lowering requires dst == mask.
+ const XMMRegister dst = xmm0;
+ const XMMRegister mask = xmm0;
+ const XMMRegister src1 = xmm1;
+ const XMMRegister src2 = xmm2;
+
+ CpuFeatureScope avx_scope(masm, AVX);
+
+ __ vmovdqu(src1, Operand(kCArgRegs[0], 0));
+ __ vmovdqu(src2, Operand(kCArgRegs[1], 0));
+ __ vmovdqu(mask, Operand(kCArgRegs[2], 0));
+ __ S128Select(dst, mask, src1, src2, kScratchDoubleReg);
+ __ vmovdqu(Operand(kCArgRegs[3], 0), dst);
+ __ ret(0);
+
+ CodeDesc desc;
+ __ GetCode(i_isolate(), &desc);
+ buffer->MakeExecutable();
+ auto f = GeneratedCode<F2>::FromBuffer(i_isolate(), buffer->start());
+
+ std::vector<std::array<uint64_t, 6>> test_cases = {
+ // {src1[0], src1[1], src2[0], src2[1], mask[0], mask[1]}
+ {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xBBBBBBBBBBBBBBBB,
+ 0xBBBBBBBBBBBBBBBB, 0x00112345F00FFFFF, 0x10112021BBAABBAA},
+ {0x0123456789ABCDEF, 0xFEDCBA9876543210, 0xFEDCBA9876543210,
+ 0x0123456789ABCDEF, 0x0000000000000000, 0xFFFFFFFFFFFFFFFF},
+ {0x0123456789ABCDEF, 0xFEDCBA9876543210, 0x55555555AAAAAAAA,
+ 0x00000000FFFFFFFF, 0xAAAAAAAA55555555, 0xFFFFFFFF00000000}};
+
+ uint64_t v1[2];
+ uint64_t v2[2];
+ uint64_t c[2];
+ uint64_t output[2];
+
+ for (const auto& arr : test_cases) {
+ v1[0] = arr[0];
+ v1[1] = arr[1];
+ v2[0] = arr[2];
+ v2[1] = arr[3];
+ c[0] = arr[4];
+ c[1] = arr[5];
+
+ f.Call(v1, v2, c, output);
+
+ for (int i = 0; i < 2; i++) {
+ CHECK_EQ(output[i], (v1[i] & c[i]) | (v2[i] & ~c[i]));
+ }
+ }
+}
+
+TEST_F(MacroAssemblerX64Test, S256NotAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ Isolate* isolate = i_isolate();
+ HandleScope handles(isolate);
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler assembler(isolate, v8::internal::CodeObjectRequired{true},
+ buffer->CreateView());
+ MacroAssembler* masm = &assembler;
+
+ const YMMRegister dst = ymm0;
+ const YMMRegister src = ymm1;
+
+ CpuFeatureScope avx_scope(masm, AVX);
+ CpuFeatureScope avx2_scope(masm, AVX2);
+
+ __ vmovdqu(src, Operand(kCArgRegs[0], 0));
+ __ S256Not(dst, src, kScratchSimd256Reg);
+ __ vmovdqu(Operand(kCArgRegs[1], 0), dst);
+ __ ret(0);
+
+ CodeDesc desc;
+ __ GetCode(i_isolate(), &desc);
+ buffer->MakeExecutable();
+ auto f = GeneratedCode<F1>::FromBuffer(i_isolate(), buffer->start());
+
+ std::vector<std::array<uint64_t, 4>> test_cases = {
+ {0x0000000000000000, 0xFFFFFFFFFFFFFFFF, 0xAAAAAAAAAAAAAAAA,
+ 0x5555555555555555},
+ {0x0123456789ABCDEF, 0xFEDCBA9876543210, 0x00112345F00FFFFF,
+ 0x10112021BBAABBAA}};
+
+ uint64_t input[4];
+ uint64_t output[4];
+
+ for (const auto& arr : test_cases) {
+ for (int i = 0; i < 4; i++) input[i] = arr[i];
+
+ f.Call(input, output, nullptr);
+
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(output[i], ~input[i]);
+ }
+ }
+}
+
+TEST_F(MacroAssemblerX64Test, S256SelectAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ Isolate* isolate = i_isolate();
+ HandleScope handles(isolate);
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler assembler(isolate, v8::internal::CodeObjectRequired{true},
+ buffer->CreateView());
+ MacroAssembler* masm = &assembler;
+
+ // The AVX10.1 lowering requires dst == mask.
+ const YMMRegister dst = ymm0;
+ const YMMRegister mask = ymm0;
+ const YMMRegister src1 = ymm1;
+ const YMMRegister src2 = ymm2;
+
+ CpuFeatureScope avx_scope(masm, AVX);
+ CpuFeatureScope avx2_scope(masm, AVX2);
+
+ __ vmovdqu(src1, Operand(kCArgRegs[0], 0));
+ __ vmovdqu(src2, Operand(kCArgRegs[1], 0));
+ __ vmovdqu(mask, Operand(kCArgRegs[2], 0));
+ __ S256Select(dst, mask, src1, src2, kScratchSimd256Reg);
+ __ vmovdqu(Operand(kCArgRegs[3], 0), dst);
+ __ ret(0);
+
+ CodeDesc desc;
+ __ GetCode(i_isolate(), &desc);
+ buffer->MakeExecutable();
+ auto f = GeneratedCode<F2>::FromBuffer(i_isolate(), buffer->start());
+
+ std::vector<std::array<uint64_t, 12>> test_cases = {
+ {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA,
+ 0xAAAAAAAAAAAAAAAA, 0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB,
+ 0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB, 0x00112345F00FFFFF,
+ 0x10112021BBAABBAA, 0x0000000000000000, 0x0000000000000000},
+ {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA,
+ 0xAAAAAAAAAAAAAAAA, 0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB,
+ 0xBBBBBBBBBBBBBBBB, 0xBBBBBBBBBBBBBBBB, 0x1111111111111111,
+ 0x1111111111111111, 0x0123456789ABCDEF, 0xFEDCBA9876543210},
+ {0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA, 0xAAAAAAAAAAAAAAAA,
+ 0xAAAAAAAAAAAAAAAA, 0x5555555555555555, 0x5555555555555555,
+ 0x5555555555555555, 0x5555555555555555, 0x0123456789ABCDEF,
+ 0xFEDCBA9876543210, 0x55555555AAAAAAAA, 0x00000000FFFFFFFF},
+ {0x499602D2499602D2, 0x499602D2499602D2, 0x1234567812345678,
+ 0x1234567812345678, 0xB669FD2EB669FD2E, 0xB669FD2EB669FD2E,
+ 0x90ABCDEF90ABCDEF, 0x90ABCDEF90ABCDEF, 0xCDEFCDEFCDEFCDEF,
+ 0xCDEFCDEFCDEFCDEF, 0xCDEFCDEFCDEFCDEF, 0xCDEFCDEFCDEFCDEF}};
+
+ uint64_t v1[4];
+ uint64_t v2[4];
+ uint64_t c[4];
+ uint64_t output[4];
+
+ for (const auto& arr : test_cases) {
+ for (int i = 0; i < 4; i++) {
+ v1[i] = arr[i];
+ v2[i] = arr[i + 4];
+ c[i] = arr[i + 8];
+ }
+
+ f.Call(v1, v2, c, output);
+
+ for (int i = 0; i < 4; i++) {
+ CHECK_EQ(output[i], (v1[i] & c[i]) | (v2[i] & ~c[i]));
+ }
+ }
+}
+#endif // V8_ENABLE_AVX10_1
+
TEST_F(MacroAssemblerX64Test, AreAliased) {
DCHECK(!AreAliased(rax));
DCHECK(!AreAliased(rax, no_reg));
@@ -1455,6 +1684,7 @@ TEST_F(MacroAssemblerX64Test, DeoptExitSizeIsFixed) {
}
}
+// Test the pre-AVX10 path.
TEST_F(MacroAssemblerX64Test, I64x2Mul) {
Isolate* isolate = i_isolate();
HandleScope handles(isolate);
@@ -1473,7 +1703,7 @@ TEST_F(MacroAssemblerX64Test, I64x2Mul) {
__ movdqu(lhs, Operand(kCArgRegs[0], 0));
__ movdqu(rhs, Operand(kCArgRegs[1], 0));
// Calculation
- __ I64x2Mul(dst, lhs, rhs, tmp1, tmp2);
+ __ I64x2MulPreAvx10(dst, lhs, rhs, tmp1, tmp2);
// Store result array
__ movdqu(Operand(kCArgRegs[2], 0), dst);
__ ret(0);
@@ -1512,8 +1742,12 @@ TEST_F(MacroAssemblerX64Test, I64x2Mul) {
}
}
+// Test the pre-AVX10 path.
TEST_F(MacroAssemblerX64Test, I64x4Mul) {
if (!CpuFeatures::IsSupported(AVX) || !CpuFeatures::IsSupported(AVX2)) return;
+#ifdef V8_ENABLE_AVX10_1
+ FlagScope<bool> avx10_scope(&v8_flags.enable_avx10_1, false);
+#endif
Isolate* isolate = i_isolate();
HandleScope handles(isolate);
auto buffer = AllocateAssemblerBuffer();
@@ -2691,7 +2925,7 @@ TEST_F(MacroAssemblerX64Test, I64x2ShrS_SignReplication_63) {
MacroAssembler masm(isolate, v8::internal::CodeObjectRequired{true},
buffer->CreateView());
masm.movdqu(xmm0, Operand(kCArgRegs[0], 0));
- masm.I64x2ShrS(xmm0, xmm0, 63, xmm1);
+ masm.I64x2ShrSPreAvx10(xmm0, xmm0, 63, xmm1);
masm.movdqu(Operand(kCArgRegs[1], 0), xmm0);
masm.ret(0);
@@ -2716,7 +2950,7 @@ TEST_F(MacroAssemblerX64Test, I64x2ShrS_SignReplication_63) {
MacroAssembler masm(isolate, v8::internal::CodeObjectRequired{true},
buffer->CreateView());
masm.movdqu(xmm0, Operand(kCArgRegs[0], 0));
- masm.I64x2ShrS(xmm0, xmm0, 13, xmm1);
+ masm.I64x2ShrSPreAvx10(xmm0, xmm0, 13, xmm1);
masm.movdqu(Operand(kCArgRegs[1], 0), xmm0);
masm.ret(0);
@@ -2739,6 +2973,157 @@ TEST_F(MacroAssemblerX64Test, I64x2ShrS_SignReplication_63) {
CHECK_LT(size_63, size_other);
}
+TEST_F(MacroAssemblerX64Test, I8x16ShrS_SignReplication_7) {
+ Isolate* isolate = i_isolate();
+ HandleScope handles(isolate);
+
+ // Expected Optimal Codegen for I8x16ShrS with shift count 7:
+ // - x64: instruction sequence: pxor/vpxor + pcmpgtb/vpcmpgtb +
+ // (if necessary based on register choices) movaps/vmovaps
+ auto run_test = [this, isolate](uint8_t shift) {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(isolate, v8::internal::CodeObjectRequired{true},
+ buffer->CreateView());
+ masm.movdqu(xmm0, Operand(kCArgRegs[0], 0));
+ masm.I8x16ShrS(xmm0, xmm0, shift, xmm1);
+ masm.movdqu(Operand(kCArgRegs[1], 0), xmm0);
+ masm.ret(0);
+
+ CodeDesc desc;
+ masm.GetCode(isolate, &desc);
+
+ // Run and assert correctness
+ buffer->MakeExecutable();
+ using F = int(int8_t*, int8_t*);
+ auto f = GeneratedCode<F>::FromBuffer(i_isolate(), buffer->start());
+ int8_t input[16] = {1, -2, 127, -128, 0, -1, 42, -42,
+ 10, -20, 30, -40, 50, -60, 70, -80};
+ int8_t output[16] = {0};
+ f.Call(input, output);
+ for (int i = 0; i < 16; ++i) {
+ CHECK_EQ(output[i], static_cast<int8_t>(input[i] >> shift));
+ }
+ return desc.instr_size;
+ };
+
+ CHECK_LT(run_test(7), run_test(3));
+}
+
+TEST_F(MacroAssemblerX64Test, PshufdOptimization) {
+ if (!CpuFeatures::IsSupported(AVX2)) return;
+
+ Isolate* isolate = i_isolate();
+ HandleScope handles(isolate);
+
+ const XMMRegister xmm_regs[] = {xmm0, xmm1, xmm2, xmm3, xmm4, xmm5,
+ xmm6, xmm7, xmm8, xmm9, xmm10, xmm11,
+ xmm12, xmm13, xmm14, xmm15};
+
+ for (XMMRegister dst : xmm_regs) {
+ for (XMMRegister src : xmm_regs) {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(isolate, v8::internal::CodeObjectRequired{false},
+ buffer->CreateView());
+ CpuFeatureScope avx2_scope(&masm, AVX2);
+
+ int size_before = masm.pc_offset();
+ masm.Pshufd(dst, src, 0);
+ int size = masm.pc_offset() - size_before;
+
+ uint8_t* code = masm.buffer_start() + size_before;
+
+ EXPECT_EQ(size, 5);
+
+ if (src.code() > 7) {
+ // When src is in xmm8-xmm15, VPBROADCASTD is 5 bytes:
+ // 3-byte VEX prefix (0xC4) + opcode 0x58 + ModR/M
+ EXPECT_EQ(code[0], 0xC4);
+ EXPECT_EQ(code[3], 0x58);
+ } else {
+ // When src is in xmm0-xmm7, VPSHUFD is 5 bytes:
+ // 2-byte VEX prefix (0xC5) + opcode 0x70 + ModR/M + imm8(0x00)
+ EXPECT_EQ(code[0], 0xC5);
+ EXPECT_EQ(code[2], 0x70);
+ EXPECT_EQ(code[4], 0x00);
+ }
+ }
+ }
+
+ // Non-zero shuffle should always emit VPSHUFD
+ for (XMMRegister dst : xmm_regs) {
+ for (XMMRegister src : xmm_regs) {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(isolate, v8::internal::CodeObjectRequired{false},
+ buffer->CreateView());
+ CpuFeatureScope avx2_scope(&masm, AVX2);
+
+ int size_before = masm.pc_offset();
+ masm.Pshufd(dst, src, 0x55);
+ int size = masm.pc_offset() - size_before;
+
+ uint8_t* code = masm.buffer_start() + size_before;
+
+ if (src.code() > 7) {
+ // 3-byte VEX (0xC4) + opcode 0x70 + ModR/M + imm8
+ EXPECT_EQ(size, 6);
+ EXPECT_EQ(code[0], 0xC4);
+ EXPECT_EQ(code[3], 0x70);
+ EXPECT_EQ(code[5], 0x55);
+ } else {
+ // 2-byte VEX (0xC5) + opcode 0x70 + ModR/M + imm8
+ EXPECT_EQ(size, 5);
+ EXPECT_EQ(code[0], 0xC5);
+ EXPECT_EQ(code[2], 0x70);
+ EXPECT_EQ(code[4], 0x55);
+ }
+ }
+ }
+
+ // Verify functional execution correctness of Pshufd(dst, src, 0)
+ {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(isolate, v8::internal::CodeObjectRequired{false},
+ buffer->CreateView());
+ CpuFeatureScope avx2_scope(&masm, AVX2);
+
+ // Save callee-saved registers on Windows x64 (xmm6-xmm15 are non-volatile).
+ masm.AllocateStackSpace(3 * kSimd128Size);
+ masm.movdqu(Operand(rsp, 0 * kSimd128Size), xmm8);
+ masm.movdqu(Operand(rsp, 1 * kSimd128Size), xmm9);
+ masm.movdqu(Operand(rsp, 2 * kSimd128Size), xmm10);
+
+ // Test combinations: high-high, high-low, low-high, low-low
+ masm.movdqu(xmm8, Operand(kCArgRegs[0], 0));
+ masm.Pshufd(xmm9, xmm8, 0); // src > 7: vpbroadcastd
+ masm.Pshufd(xmm0, xmm8, 0); // src > 7: vpbroadcastd
+ masm.Pshufd(xmm10, xmm0, 0); // src <= 7: vpshufd
+ masm.Pshufd(xmm1, xmm0, 0); // src <= 7: vpshufd
+ masm.movdqu(Operand(kCArgRegs[1], 0), xmm9);
+ masm.movdqu(Operand(kCArgRegs[1], 16), xmm0);
+ masm.movdqu(Operand(kCArgRegs[1], 32), xmm10);
+ masm.movdqu(Operand(kCArgRegs[1], 48), xmm1);
+
+ // Restore callee-saved registers.
+ masm.movdqu(xmm8, Operand(rsp, 0 * kSimd128Size));
+ masm.movdqu(xmm9, Operand(rsp, 1 * kSimd128Size));
+ masm.movdqu(xmm10, Operand(rsp, 2 * kSimd128Size));
+ masm.addq(rsp, Immediate(3 * kSimd128Size));
+ masm.ret(0);
+
+ buffer->MakeExecutable();
+ using F = void(const uint32_t*, uint32_t*);
+ auto f = GeneratedCode<F>::FromBuffer(isolate, buffer->start());
+
+ uint32_t input[4] = {0x12345678, 0x9ABCDEF0, 0x13579BDF, 0x2468ACE0};
+ uint32_t output[16] = {0};
+ f.Call(input, output);
+
+ for (int i = 0; i < 16; ++i) {
+ EXPECT_EQ(output[i], input[0]);
+ }
+ }
+}
+
#undef __
} // namespace test_macro_assembler_x64
diff --git a/deps/v8/test/unittests/base/atomic-utils-unittest.cc b/deps/v8/test/unittests/base/atomic-utils-unittest.cc
index a4e4694f5c1..5b58f145a9c 100644
--- a/deps/v8/test/unittests/base/atomic-utils-unittest.cc
+++ b/deps/v8/test/unittests/base/atomic-utils-unittest.cc
@@ -2,9 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/base/atomic-utils.h"
+
#include <limits.h>
-#include "src/base/atomic-utils.h"
+#include "src/base/memcopy.h"
#include "src/base/platform/platform.h"
#include "testing/gtest/include/gtest/gtest.h"
@@ -236,5 +238,70 @@ TEST(AsAtomicWord, SetBits_Concurrent) {
}
}
+template <typename T>
+void TestRelaxedMemsetHelper(T value, T sentinel) {
+ constexpr int kBufferSize = 64;
+ for (int offset = 0; offset < 8; ++offset) {
+ for (int count = 0; count < 32; ++count) {
+ if (offset + count > kBufferSize) continue;
+ alignas(8) T buffer[kBufferSize];
+ for (int i = 0; i < kBufferSize; ++i) {
+ buffer[i] = sentinel;
+ }
+ Relaxed_Memset(&buffer[offset], value, count);
+ for (int i = 0; i < kBufferSize; ++i) {
+ if (i >= offset && i < offset + count) {
+ EXPECT_EQ(value, buffer[i])
+ << "offset=" << offset << " count=" << count << " i=" << i;
+ } else {
+ EXPECT_EQ(sentinel, buffer[i])
+ << "offset=" << offset << " count=" << count << " i=" << i;
+ }
+ }
+ }
+ }
+}
+
+TEST(RelaxedMemset, VariousTypesAndAlignments) {
+ TestRelaxedMemsetHelper<uint8_t>(0xAB, 0x12);
+ TestRelaxedMemsetHelper<uint16_t>(0xABCD, 0x1234);
+ TestRelaxedMemsetHelper<uint32_t>(0xABCDEF01u, 0x12345678u);
+ TestRelaxedMemsetHelper<uint64_t>(0xABCDEF0123456789ULL,
+ 0x1111222233334444ULL);
+ TestRelaxedMemsetHelper<int8_t>(-1, 0);
+ TestRelaxedMemsetHelper<int32_t>(-123456, 789);
+}
+
+TEST(RelaxedMemset, ConstexprReplicatedWord) {
+ static_assert(ReplicateValueWord<uint8_t>(0xAB) ==
+#if V8_HOST_ARCH_64_BIT
+ 0xABABABABABABABABULL
+#else
+ 0xABABABABu
+#endif
+ );
+ static_assert(ReplicateValueWord<uint16_t>(0x1234) ==
+#if V8_HOST_ARCH_64_BIT
+ 0x1234123412341234ULL
+#else
+ 0x12341234u
+#endif
+ );
+
+ constexpr int kBufferSize = 32;
+ alignas(8) uint8_t buffer[kBufferSize];
+ for (int i = 0; i < kBufferSize; ++i) {
+ buffer[i] = 0xFF;
+ }
+ Relaxed_Memset<uint8_t>(&buffer[1], 0x42, 15);
+ EXPECT_EQ(0xFF, buffer[0]);
+ for (int i = 1; i < 16; ++i) {
+ EXPECT_EQ(0x42, buffer[i]);
+ }
+ for (int i = 16; i < kBufferSize; ++i) {
+ EXPECT_EQ(0xFF, buffer[i]);
+ }
+}
+
} // namespace base
} // namespace v8
diff --git a/deps/v8/test/unittests/base/cpu-unittest.cc b/deps/v8/test/unittests/base/cpu-unittest.cc
index 15b24f178fb..380198eaa7f 100644
--- a/deps/v8/test/unittests/base/cpu-unittest.cc
+++ b/deps/v8/test/unittests/base/cpu-unittest.cc
@@ -47,6 +47,7 @@ TEST(CPUTest, FeatureImplications) {
EXPECT_TRUE(!cpu.has_avx() || cpu.has_sse2());
EXPECT_TRUE(!cpu.has_fma3() || cpu.has_avx());
EXPECT_TRUE(!cpu.has_avx2() || cpu.has_avx());
+ EXPECT_TRUE(!cpu.has_avx10_1() || cpu.has_avx2());
// arm features
EXPECT_TRUE(!cpu.has_vfp3_d32() || cpu.has_vfp3());
diff --git a/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-scheduler-arm64-unittest.cc b/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-scheduler-arm64-unittest.cc
index 6ceb0149d32..ca7828482e0 100644
--- a/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-scheduler-arm64-unittest.cc
+++ b/deps/v8/test/unittests/compiler/arm64/turboshaft-instruction-scheduler-arm64-unittest.cc
@@ -2,6 +2,7 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/flags/flags.h"
#include "test/common/flag-utils.h"
#include "test/unittests/compiler/backend/turboshaft-instruction-selector-unittest.h"
@@ -58,14 +59,14 @@ TEST_F(InstructionSchedulerTurboshaftArm64Test, ParallelLdrQFmulStrQ) {
constexpr int32_t kArithBase = kNumLoads;
EXPECT_EQ(kArm64FMul, s[kArithBase]->arch_opcode());
EXPECT_EQ(kArm64FMul, s[kArithBase + 1]->arch_opcode());
- EXPECT_EQ(kArm64StrQ, s[kArithBase + 2]->arch_opcode());
+ EXPECT_EQ(kArm64FMul, s[kArithBase + 2]->arch_opcode());
EXPECT_EQ(kArm64FMul, s[kArithBase + 3]->arch_opcode());
- EXPECT_EQ(kArm64StrQ, s[kArithBase + 4]->arch_opcode());
- EXPECT_EQ(kArm64FMul, s[kArithBase + 5]->arch_opcode());
- EXPECT_EQ(kArm64StrQ, s[kArithBase + 6]->arch_opcode());
- EXPECT_EQ(kArm64FMul, s[kArithBase + 7]->arch_opcode());
+ EXPECT_EQ(kArm64FMul, s[kArithBase + 4]->arch_opcode());
+ EXPECT_EQ(kArm64StrQ, s[kArithBase + 5]->arch_opcode());
+ EXPECT_EQ(kArm64FMul, s[kArithBase + 6]->arch_opcode());
+ EXPECT_EQ(kArm64StrQ, s[kArithBase + 7]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 8]->arch_opcode());
- EXPECT_EQ(kArm64FMul, s[kArithBase + 9]->arch_opcode());
+ EXPECT_EQ(kArm64StrQ, s[kArithBase + 9]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 10]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 11]->arch_opcode());
}
@@ -99,34 +100,27 @@ TEST_F(InstructionSchedulerTurboshaftArm64Test, LdrQIntoFMA) {
InstructionSelector::kEnableScheduling);
// First loads.
- EXPECT_EQ(kArm64LdrQ, s[0]->arch_opcode());
- EXPECT_EQ(kArm64LdrQ, s[1]->arch_opcode());
- EXPECT_EQ(kArm64LdrQ, s[2]->arch_opcode());
- EXPECT_EQ(kArm64LdrQ, s[3]->arch_opcode());
- EXPECT_EQ(kArm64LdrQ, s[4]->arch_opcode());
+ for (int i = 0; i < 6; ++i) {
+ EXPECT_EQ(kArm64LdrQ, s[i]->arch_opcode());
+ }
// Then one fma.
- EXPECT_EQ(kArm64Ffma, s[5]->arch_opcode());
+ EXPECT_EQ(kArm64Ffma, s[6]->arch_opcode());
- // Then two loads.
- EXPECT_EQ(kArm64LdrQ, s[6]->arch_opcode());
+ // Then three loads.
EXPECT_EQ(kArm64LdrQ, s[7]->arch_opcode());
-
- // Then one fma.
- EXPECT_EQ(kArm64Ffma, s[8]->arch_opcode());
-
- // Then two loads.
+ EXPECT_EQ(kArm64LdrQ, s[8]->arch_opcode());
EXPECT_EQ(kArm64LdrQ, s[9]->arch_opcode());
- EXPECT_EQ(kArm64LdrQ, s[10]->arch_opcode());
// Then one fma.
- EXPECT_EQ(kArm64Ffma, s[11]->arch_opcode());
+ EXPECT_EQ(kArm64Ffma, s[10]->arch_opcode());
- // Final two loads.
+ // Then two loads.
+ EXPECT_EQ(kArm64LdrQ, s[11]->arch_opcode());
EXPECT_EQ(kArm64LdrQ, s[12]->arch_opcode());
- EXPECT_EQ(kArm64LdrQ, s[13]->arch_opcode());
- // Final two fmas.
+ // Final three fmas.
+ EXPECT_EQ(kArm64Ffma, s[13]->arch_opcode());
EXPECT_EQ(kArm64Ffma, s[14]->arch_opcode());
EXPECT_EQ(kArm64Ffma, s[15]->arch_opcode());
}
@@ -167,22 +161,31 @@ TEST_F(InstructionSchedulerTurboshaftArm64Test, LdrQIntoFixedFP) {
InstructionSelector::kAllSourcePositions,
InstructionSelector::kEnableScheduling);
- // The loads are the longest latency.
- for (unsigned i = 0; i < kNumLoads; ++i) {
- EXPECT_EQ(kArm64LdrQ, s[i]->arch_opcode());
+ // The divide is longer than the loads and is scheduled once its inputs are
+ // available.
+ int early_loads = 0;
+ int early_divides = 0;
+ for (unsigned i = 0; i <= kNumLoads; ++i) {
+ if (s[i]->arch_opcode() == kArm64LdrQ) {
+ ++early_loads;
+ } else {
+ EXPECT_EQ(kArm64FDiv, s[i]->arch_opcode());
+ ++early_divides;
+ }
}
+ EXPECT_EQ(kNumLoads, early_loads);
+ EXPECT_EQ(1, early_divides);
constexpr int32_t kArithBase = kNumLoads;
- EXPECT_EQ(kArm64FMul, s[kArithBase]->arch_opcode());
- EXPECT_EQ(kArm64FAdd, s[kArithBase + 1]->arch_opcode());
- EXPECT_EQ(kArm64StrQ, s[kArithBase + 2]->arch_opcode());
+ EXPECT_EQ(kArm64FMul, s[kArithBase + 1]->arch_opcode());
+ EXPECT_EQ(kArm64FAdd, s[kArithBase + 2]->arch_opcode());
EXPECT_EQ(kArm64FSub, s[kArithBase + 3]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 4]->arch_opcode());
EXPECT_EQ(kArm64FMin, s[kArithBase + 5]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 6]->arch_opcode());
EXPECT_EQ(kArm64FMax, s[kArithBase + 7]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 8]->arch_opcode());
- EXPECT_EQ(kArm64FDiv, s[kArithBase + 9]->arch_opcode());
+ EXPECT_EQ(kArm64StrQ, s[kArithBase + 9]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 10]->arch_opcode());
EXPECT_EQ(kArm64StrQ, s[kArithBase + 11]->arch_opcode());
}
@@ -224,21 +227,34 @@ TEST_F(InstructionSchedulerTurboshaftArm64Test, LdrSIntoFixedFP) {
InstructionSelector::kAllSourcePositions,
InstructionSelector::kEnableScheduling);
- // All the loads happen first.
- for (unsigned i = 0; i < kNumLoads; ++i) {
- EXPECT_EQ(kArm64LdrS, s[i]->arch_opcode());
+ // The divide is longer than the loads and is scheduled once its inputs are
+ // available.
+ int early_loads = 0;
+ int early_divides = 0;
+ for (unsigned i = 0; i <= kNumLoads; ++i) {
+ if (s[i]->arch_opcode() == kArm64LdrS) {
+ ++early_loads;
+ } else {
+ EXPECT_EQ(kArm64Float32Div, s[i]->arch_opcode());
+ ++early_divides;
+ }
}
+ EXPECT_EQ(kNumLoads, early_loads);
+ EXPECT_EQ(1, early_divides);
constexpr int32_t kArithBase = kNumLoads;
- // The divide has been scheduled earlier than the other arith ops.
- EXPECT_EQ(kArm64Float32Div, s[kArithBase]->arch_opcode());
- EXPECT_EQ(kArm64Float32Add, s[kArithBase + 1]->arch_opcode());
- EXPECT_EQ(kArm64Float32Sub, s[kArithBase + 2]->arch_opcode());
- EXPECT_EQ(kArm64Float32Mul, s[kArithBase + 3]->arch_opcode());
+ if (v8_flags.experimental_turbo_instruction_scheduling) {
+ EXPECT_EQ(kArm64Float32Mul, s[kArithBase + 1]->arch_opcode());
+ EXPECT_EQ(kArm64Float32Add, s[kArithBase + 2]->arch_opcode());
+ } else {
+ EXPECT_EQ(kArm64Float32Add, s[kArithBase + 1]->arch_opcode());
+ EXPECT_EQ(kArm64Float32Mul, s[kArithBase + 2]->arch_opcode());
+ }
+ EXPECT_EQ(kArm64Float32Sub, s[kArithBase + 3]->arch_opcode());
EXPECT_EQ(kArm64Float32Min, s[kArithBase + 4]->arch_opcode());
EXPECT_EQ(kArm64StrS, s[kArithBase + 5]->arch_opcode());
- EXPECT_EQ(kArm64StrS, s[kArithBase + 6]->arch_opcode());
- EXPECT_EQ(kArm64Float32Max, s[kArithBase + 7]->arch_opcode());
+ EXPECT_EQ(kArm64Float32Max, s[kArithBase + 6]->arch_opcode());
+ EXPECT_EQ(kArm64StrS, s[kArithBase + 7]->arch_opcode());
EXPECT_EQ(kArm64StrS, s[kArithBase + 8]->arch_opcode());
EXPECT_EQ(kArm64StrS, s[kArithBase + 9]->arch_opcode());
EXPECT_EQ(kArm64StrS, s[kArithBase + 10]->arch_opcode());
@@ -273,16 +289,16 @@ TEST_F(InstructionSchedulerTurboshaftArm64Test, ScheduleBackwards) {
InstructionSelector::kAllSourcePositions,
InstructionSelector::kEnableScheduling);
- // The address-calculation chain is scheduled before the independent divide
- // feeding the store. Backward scheduling should pull the divide/store chain
- // first, saving cycles, but we need to be using 'data' predecessors to
- // calculate the latency accurately.
+ // The divide feeding the store is scheduled before the address-calculation
+ // chain. Backward scheduling should pull this long-latency chain first,
+ // saving cycles, but we need to be using 'data' predecessors to calculate
+ // the latency accurately.
ASSERT_GE(s.size(), 7U);
- EXPECT_EQ(kArm64Add, s[0]->arch_opcode());
- EXPECT_EQ(kArm64Sub, s[1]->arch_opcode());
+ EXPECT_EQ(kArm64Udiv, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Add, s[1]->arch_opcode());
EXPECT_EQ(kArm64Sub, s[2]->arch_opcode());
- EXPECT_EQ(kArm64Ldr, s[3]->arch_opcode());
- EXPECT_EQ(kArm64Udiv, s[4]->arch_opcode());
+ EXPECT_EQ(kArm64Sub, s[3]->arch_opcode());
+ EXPECT_EQ(kArm64Ldr, s[4]->arch_opcode());
EXPECT_EQ(kArm64LdrW, s[5]->arch_opcode());
EXPECT_EQ(kArm64Str, s[6]->arch_opcode());
}
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 01e7dc90245..dfd84c8f8e4 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
@@ -157,7 +157,7 @@ const MachInst2 kDPFlagSetInstructions[] = {
MachineType::Int32()},
{TSBinop::kWord32Add, "Word32Add", kArm64Cmn32, MachineType::Int32()},
{TSBinop::kWord32Sub, "Int32Sub", kArm64Cmp32, MachineType::Int32()},
- {TSBinop::kWord64BitwiseAnd, "Word64BitwiseAnd", kArm64Tst,
+ {TSBinop::kWord64BitwiseAnd, "Word64BitwiseAnd", kArm64Tst32,
MachineType::Int64()}};
// ARM64 arithmetic with overflow instructions.
@@ -1088,9 +1088,9 @@ TEST_F(TurboshaftInstructionSelectorTest, Word32AndBranchWithImmediateOnRight) {
}
TEST_F(TurboshaftInstructionSelectorTest, Word64AndBranchWithImmediateOnRight) {
- TRACED_FOREACH(int64_t, imm, kLogical64Immediates) {
+ TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
// Skip the cases where the instruction selector would use tbz/tbnz.
- if (base::bits::CountPopulation(static_cast<uint64_t>(imm)) == 1) continue;
+ if (base::bits::CountPopulation(static_cast<uint32_t>(imm)) == 1) continue;
StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
Block *a = m.NewBlock(), *b = m.NewBlock();
@@ -1103,9 +1103,10 @@ TEST_F(TurboshaftInstructionSelectorTest, Word64AndBranchWithImmediateOnRight) {
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
EXPECT_EQ(4U, s[0]->InputCount());
EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
EXPECT_EQ(kNotEqual, s[0]->flags_condition());
}
@@ -1170,9 +1171,9 @@ TEST_F(TurboshaftInstructionSelectorTest, Word32AndBranchWithImmediateOnLeft) {
}
TEST_F(TurboshaftInstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) {
- TRACED_FOREACH(int64_t, imm, kLogical64Immediates) {
+ TRACED_FOREACH(int32_t, imm, kLogical32Immediates) {
// Skip the cases where the instruction selector would use tbz/tbnz.
- if (base::bits::CountPopulation(static_cast<uint64_t>(imm)) == 1) continue;
+ if (base::bits::CountPopulation(static_cast<uint32_t>(imm)) == 1) continue;
StreamBuilder m(this, MachineType::Int64(), MachineType::Int64());
Block *a = m.NewBlock(), *b = m.NewBlock();
@@ -1185,9 +1186,10 @@ TEST_F(TurboshaftInstructionSelectorTest, Word64AndBranchWithImmediateOnLeft) {
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kArm64Tst, s[0]->arch_opcode());
+ EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
EXPECT_EQ(4U, s[0]->InputCount());
EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(imm, s.ToInt32(s[0]->InputAt(1)));
ASSERT_LE(1U, s[0]->InputCount());
EXPECT_EQ(kFlags_branch, s[0]->flags_mode());
EXPECT_EQ(kNotEqual, s[0]->flags_condition());
@@ -1308,7 +1310,7 @@ const TestAndBranch kTestAndBranchMatchers64[] = {
return m.TruncateWord64ToWord32(
m.Word64BitwiseAnd(x, m.Int64Constant(mask)));
},
- "if (x and mask)", kArm64TestAndBranch, MachineType::Int64()},
+ "if (x and mask)", kArm64TestAndBranch32, MachineType::Int64()},
kNotEqual},
{{[](TurboshaftInstructionSelectorTest::StreamBuilder& m, OpIndex x,
uint64_t mask) -> V<Word32> {
@@ -1378,11 +1380,20 @@ TEST_F(TurboshaftInstructionSelectorTest,
m.Return(m.Int32Constant(0));
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
- EXPECT_EQ(kNotEqual, s[0]->flags_condition());
- EXPECT_EQ(4U, s[0]->InputCount());
- EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
- EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+ // Only bits 0-31 can be encoded as an immediate to tbz/tbnz instructions.
+ // For higher bits the bit will never be set. As this eliminates the branch,
+ // such optimization should have happened prior to instruction selection.
+ if (bit < 32) {
+ EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(bit, s.ToInt64(s[0]->InputAt(1)));
+ } else {
+ EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
+ EXPECT_EQ(kNotEqual, s[0]->flags_condition());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ }
}
}
@@ -1428,9 +1439,17 @@ TEST_F(TurboshaftInstructionSelectorTest, TestAndBranch64AndWhenCanCoverFalse) {
Stream s = m.Build();
ASSERT_EQ(1U, s.size());
- EXPECT_EQ(kArm64TestAndBranch, s[0]->arch_opcode());
- EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
- EXPECT_EQ(4U, s[0]->InputCount());
+ // Only bits 0-31 can be encoded as an immediate to tbz/tbnz instructions.
+ // For higher bits the bit will never be set. As this eliminates the branch,
+ // such optimization should have happened prior to instruction selection.
+ if (bit < 32) {
+ EXPECT_EQ(kArm64TestAndBranch32, s[0]->arch_opcode());
+ EXPECT_EQ(InstructionOperand::IMMEDIATE, s[0]->InputAt(1)->kind());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ } else {
+ EXPECT_EQ(kArm64Tst32, s[0]->arch_opcode());
+ EXPECT_EQ(4U, s[0]->InputCount());
+ }
}
}
@@ -1935,6 +1954,236 @@ TEST_F(TurboshaftInstructionSelectorTest, ConditionalBranches) {
}
}
+// -----------------------------------------------------------------------------
+// CCMP branch-cascade fusion.
+
+namespace {
+// Returns the fused cascade instruction, or nullptr if the cascade was not
+// fused. The fused instruction is the one with a conditional-branch flags-mode.
+const Instruction* FindFusedCcmpBranch(
+ const TurboshaftInstructionSelectorTest::Stream& s) {
+ const Instruction* found = nullptr;
+ for (size_t i = 0; i < s.size(); ++i) {
+ if (s[i]->flags_mode() == kFlags_conditional_branch) {
+ EXPECT_EQ(nullptr, found);
+ found = s[i];
+ }
+ }
+ return found;
+}
+} // namespace
+
+TEST_F(TurboshaftInstructionSelectorTest, CcmpBranchCascadeEligible) {
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ const Instruction* ccmp = FindFusedCcmpBranch(s);
+ ASSERT_NE(nullptr, ccmp);
+ EXPECT_EQ(kArm64Cmp32, ccmp->arch_opcode());
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex shared = m.Parameter(1);
+ Block *t1 = m.NewBlock(), *t2 = m.NewBlock(), *b = m.NewBlock();
+ Block *merge = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(3)), t1, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(4)), t2, f);
+ m.Bind(t1);
+ m.Goto(merge);
+ m.Bind(t2);
+ m.Goto(merge);
+ m.Bind(merge);
+ OpIndex phi = m.Phi(MachineRepresentation::kWord32, shared, shared);
+ m.Return(phi);
+ m.Bind(f);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ EXPECT_NE(nullptr, FindFusedCcmpBranch(s));
+ }
+ {
+ // Immediate-range asymmetry. The head compare is a regular cmp with a
+ // 12-bit immediate range. The fused compare is a ccmp with a 5-bit
+ // immediate range.
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(100)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(5)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_NE(nullptr, FindFusedCcmpBranch(s));
+ }
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, CcmpBranchCascadeIneligible) {
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex y = m.Parameter(1);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(y, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "different variables";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Int32LessThan(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "non-equality compare";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word64Equal(x, m.Int64Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word64Equal(x, m.Int64Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "word64 representation";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ V<Word32> cond_a = m.Word32Equal(x, m.Int32Constant(1));
+ m.Branch(cond_a, t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(cond_a);
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "head compare has extra use";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(100)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s))
+ << "fused constant outside ccmp immediate range";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t1 = m.NewBlock(), *t2 = m.NewBlock(), *b = m.NewBlock();
+ Block* f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t1, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t2, f);
+ m.Bind(t1);
+ m.Return(m.Int32Constant(11));
+ m.Bind(t2);
+ m.Return(m.Int32Constant(33));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "true edges do not merge";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex v1 = m.Parameter(1);
+ OpIndex v2 = m.Parameter(2);
+ Block *t1 = m.NewBlock(), *t2 = m.NewBlock(), *b = m.NewBlock();
+ Block *merge = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t1, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t2, f);
+ m.Bind(t1);
+ m.Goto(merge);
+ m.Bind(t2);
+ m.Goto(merge);
+ m.Bind(merge);
+ OpIndex phi = m.Phi(MachineRepresentation::kWord32, v1, v2);
+ m.Return(phi);
+ m.Bind(f);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "merge phi inputs differ";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *head = m.NewBlock(), *t = m.NewBlock(), *b = m.NewBlock();
+ Block* f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(5)), head, b);
+ m.Bind(head);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s))
+ << "fused block has multiple predecessors";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Pointer());
+ OpIndex x = m.Parameter(0);
+ OpIndex mem = m.Parameter(1);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Store(MachineRepresentation::kWord32, mem, m.Int32Constant(0), x,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "side effect in fused block";
+ }
+}
+
// -----------------------------------------------------------------------------
// Add and subtract instructions with overflow.
@@ -2565,6 +2814,46 @@ TEST_F(TurboshaftInstructionSelectorTest, Word64ShlWithChangeUint32ToUint64) {
}
}
+TEST_F(TurboshaftInstructionSelectorTest,
+ Word64ShlBelow32WithChangeInt32ToInt64) {
+ TRACED_FORRANGE(int32_t, x, 1, 31) {
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Int32());
+ OpIndex const p0 = m.Parameter(0);
+ OpIndex const n =
+ m.Word64ShiftLeft(m.ChangeInt32ToInt64(p0), m.Int32Constant(x));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Sbfiz, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
+ EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ }
+}
+
+TEST_F(TurboshaftInstructionSelectorTest,
+ Word64ShlBelow32WithChangeUint32ToUint64) {
+ TRACED_FORRANGE(int32_t, x, 1, 31) {
+ StreamBuilder m(this, MachineType::Int64(), MachineType::Uint32());
+ OpIndex const p0 = m.Parameter(0);
+ OpIndex const n =
+ m.Word64ShiftLeft(m.ChangeUint32ToUint64(p0), m.Int32Constant(x));
+ m.Return(n);
+ Stream s = m.Build();
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kArm64Ubfiz, s[0]->arch_opcode());
+ ASSERT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(s.ToVreg(p0), s.ToVreg(s[0]->InputAt(0)));
+ EXPECT_EQ(x, s.ToInt32(s[0]->InputAt(1)));
+ EXPECT_EQ(32, s.ToInt32(s[0]->InputAt(2)));
+ ASSERT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(s.ToVreg(n), s.ToVreg(s[0]->Output()));
+ }
+}
+
TEST_F(TurboshaftInstructionSelectorTest, TruncateWord64ToWord32WithWord64Sar) {
StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
OpIndex const p = m.Parameter(0);
@@ -6957,6 +7246,24 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
TurboshaftInstructionSelectorStoreWithBarrierTest,
::testing::ValuesIn(kWriteBarrierKinds));
+TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
+ if (v8_flags.disable_write_barriers) return;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int64(),
+ MachineType::Int64(), MachineType::AnyTagged());
+ m.Store(m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ StoreOp::Kind::Aligned(BaseTaggedness::kTaggedBase).Atomic(),
+ MemoryRepresentation::TaggedPointer(),
+ WriteBarrierKind::kFullWriteBarrier, AtomicMemoryOrder::kSeqCst);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build(kAllExceptNopInstructions);
+ ASSERT_EQ(3U, s.size());
+ 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()),
+ RecordWriteMode::kValueIsAny);
+}
+
// -----------------------------------------------------------------------------
// Comparison instructions.
@@ -10332,4 +10639,26 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
TurboshaftInstructionSelectorAddSub128Test,
::testing::ValuesIn(kAddOrSub128));
+TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
+ if (!V8_STATIC_ROOTS_BOOL &&
+ (!COMPRESS_POINTERS_BOOL || isolate()->bootstrapper())) {
+ return;
+ }
+
+ StreamBuilder m(this, MachineType::Int32(), MachineType::AnyTagged());
+ Handle<HeapObject> undefined_value = isolate()->factory()->undefined_value();
+
+ OpIndex param = m.Parameter(0);
+ OpIndex heap_constant = m.HeapConstant(undefined_value);
+ OpIndex eq = m.Word32Equal(param, heap_constant);
+
+ m.Return(eq);
+ Stream s = m.Build();
+
+ ASSERT_EQ(1u, s.size());
+ EXPECT_EQ(kArm64Cmp32, s[0]->arch_opcode());
+ ASSERT_EQ(2u, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/compiler/compiler-unittest.cc b/deps/v8/test/unittests/compiler/compiler-unittest.cc
index 5b189e34020..e03d1c961f1 100644
--- a/deps/v8/test/unittests/compiler/compiler-unittest.cc
+++ b/deps/v8/test/unittests/compiler/compiler-unittest.cc
@@ -19,6 +19,7 @@
#include "src/codegen/script-details.h"
#include "src/heap/factory.h"
#include "src/objects/allocation-site-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/shared-function-info.h"
#include "test/unittests/heap/heap-utils.h" // For ManualGCScope.
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 84b0b0a8402..1f5fc7e309b 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
@@ -968,4 +968,22 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
::testing::ValuesIn(kSwizzleConstants));
#endif // V8_ENABLE_WEBASSEMBLY
+TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
+ if (v8_flags.disable_write_barriers) return;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Pointer(), MachineType::AnyTagged());
+ m.Store(m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ StoreOp::Kind::Aligned(BaseTaggedness::kTaggedBase).Atomic(),
+ MemoryRepresentation::TaggedPointer(),
+ WriteBarrierKind::kFullWriteBarrier, AtomicMemoryOrder::kSeqCst);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build(kAllExceptNopInstructions);
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[0]->arch_opcode());
+ EXPECT_EQ(AtomicMemoryOrderField::decode(s[0]->opcode()),
+ AtomicMemoryOrder::kSeqCst);
+ EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[0]->opcode()),
+ RecordWriteMode::kValueIsAny);
+}
+
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/compiler/linear-scheduler-unittest.cc b/deps/v8/test/unittests/compiler/linear-scheduler-unittest.cc
deleted file mode 100644
index 7e3f7b93077..00000000000
--- a/deps/v8/test/unittests/compiler/linear-scheduler-unittest.cc
+++ /dev/null
@@ -1,177 +0,0 @@
-// Copyright 2015 the V8 project authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "src/compiler/linear-scheduler.h"
-
-#include "src/compiler/access-builder.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/node.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/simplified-operator.h"
-#include "src/compiler/turbofan-graph.h"
-#include "test/unittests/compiler/compiler-test-utils.h"
-#include "test/unittests/test-utils.h"
-#include "testing/gmock/include/gmock/gmock.h"
-
-using testing::AnyOf;
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-class LinearSchedulerTest : public TestWithIsolateAndZone {
- public:
- LinearSchedulerTest()
- : graph_(zone()), common_(zone()), simplified_(zone()) {}
-
- TFGraph* graph() { return &graph_; }
- CommonOperatorBuilder* common() { return &common_; }
- SimplifiedOperatorBuilder* simplified() { return &simplified_; }
-
- private:
- TFGraph graph_;
- CommonOperatorBuilder common_;
- SimplifiedOperatorBuilder simplified_;
-};
-
-namespace {
-
-const Operator kIntAdd(IrOpcode::kInt32Add, Operator::kPure, "Int32Add", 2, 0,
- 0, 1, 0, 0);
-
-} // namespace
-
-TEST_F(LinearSchedulerTest, BuildSimpleScheduleEmpty) {
- Node* start = graph()->NewNode(common()->Start(0));
- graph()->SetStart(start);
-
- Node* end = graph()->NewNode(common()->End(1), graph()->start());
- graph()->SetEnd(end);
-
- LinearScheduler simple_scheduler(zone(), graph());
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(start, end));
-}
-
-TEST_F(LinearSchedulerTest, BuildSimpleScheduleOneParameter) {
- graph()->SetStart(graph()->NewNode(common()->Start(0)));
-
- Node* p1 = graph()->NewNode(common()->Parameter(0), graph()->start());
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* ret = graph()->NewNode(common()->Return(), zero, p1, graph()->start(),
- graph()->start());
-
- graph()->SetEnd(graph()->NewNode(common()->End(1), ret));
-
- LinearScheduler simple_scheduler(zone(), graph());
- EXPECT_TRUE(simple_scheduler.SameBasicBlock(p1, zero));
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(zero, ret));
-}
-
-TARGET_TEST_F(LinearSchedulerTest, FloatingDiamond) {
- Node* start = graph()->NewNode(common()->Start(1));
- graph()->SetStart(start);
-
- Node* cond = graph()->NewNode(common()->Parameter(0), start);
- Node* tv = graph()->NewNode(common()->Int32Constant(6));
- Node* fv = graph()->NewNode(common()->Int32Constant(7));
- Node* br = graph()->NewNode(common()->Branch(), cond, start);
- Node* t = graph()->NewNode(common()->IfTrue(), br);
- Node* f = graph()->NewNode(common()->IfFalse(), br);
- Node* m = graph()->NewNode(common()->Merge(2), t, f);
- Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
- tv, fv, m);
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* ret = graph()->NewNode(common()->Return(), zero, phi, start, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
-
- graph()->SetEnd(end);
-
- LinearScheduler simple_scheduler(zone(), graph());
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(t, f));
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(phi, t));
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(phi, f));
-}
-
-TARGET_TEST_F(LinearSchedulerTest, NestedFloatingDiamonds) {
- Node* start = graph()->NewNode(common()->Start(2));
- graph()->SetStart(start);
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
-
- Node* tv = graph()->NewNode(common()->Int32Constant(7));
- Node* br = graph()->NewNode(common()->Branch(), p0, graph()->start());
- Node* t = graph()->NewNode(common()->IfTrue(), br);
- Node* f = graph()->NewNode(common()->IfFalse(), br);
-
- Node* map = graph()->NewNode(
- simplified()->LoadElement(AccessBuilder::ForFixedArrayElement()), p0, p0,
- start, f);
- Node* br1 = graph()->NewNode(common()->Branch(), map, graph()->start());
- Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
- Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
- Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
- Node* ttrue = graph()->NewNode(common()->Int32Constant(1));
- Node* ffalse = graph()->NewNode(common()->Int32Constant(0));
- Node* phi1 = graph()->NewNode(
- common()->Phi(MachineRepresentation::kTagged, 2), ttrue, ffalse, m1);
-
- Node* m = graph()->NewNode(common()->Merge(2), t, f);
- Node* phi = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
- tv, phi1, m);
- Node* ephi1 = graph()->NewNode(common()->EffectPhi(2), start, map, m);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* ret = graph()->NewNode(common()->Return(), zero, phi, ephi1, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
-
- graph()->SetEnd(end);
-
- LinearScheduler simple_scheduler(zone(), graph());
- EXPECT_TRUE(simple_scheduler.SameBasicBlock(map, f));
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(map, br1));
- EXPECT_TRUE(simple_scheduler.SameBasicBlock(ephi1, phi));
-}
-
-TARGET_TEST_F(LinearSchedulerTest, LoopedFloatingDiamond) {
- Node* start = graph()->NewNode(common()->Start(2));
- graph()->SetStart(start);
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
-
- Node* c = graph()->NewNode(common()->Int32Constant(7));
- Node* loop = graph()->NewNode(common()->Loop(2), start, start);
- Node* ind = graph()->NewNode(common()->Phi(MachineRepresentation::kTagged, 2),
- p0, p0, loop);
- Node* add = graph()->NewNode(&kIntAdd, ind, c);
-
- Node* br = graph()->NewNode(common()->Branch(), add, loop);
- Node* t = graph()->NewNode(common()->IfTrue(), br);
- Node* f = graph()->NewNode(common()->IfFalse(), br);
-
- Node* br1 = graph()->NewNode(common()->Branch(), p0, graph()->start());
- Node* t1 = graph()->NewNode(common()->IfTrue(), br1);
- Node* f1 = graph()->NewNode(common()->IfFalse(), br1);
- Node* m1 = graph()->NewNode(common()->Merge(2), t1, f1);
- Node* phi1 = graph()->NewNode(
- common()->Phi(MachineRepresentation::kTagged, 2), add, p0, m1);
-
- loop->ReplaceInput(1, t); // close loop.
- ind->ReplaceInput(1, phi1); // close induction variable.
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* ret = graph()->NewNode(common()->Return(), zero, ind, start, f);
- Node* end = graph()->NewNode(common()->End(2), ret, f);
-
- graph()->SetEnd(end);
-
- LinearScheduler simple_scheduler(zone(), graph());
- EXPECT_TRUE(simple_scheduler.SameBasicBlock(ind, loop));
- EXPECT_TRUE(simple_scheduler.SameBasicBlock(phi1, m1));
- EXPECT_FALSE(simple_scheduler.SameBasicBlock(loop, m1));
-}
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
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 7b7f6271911..4fe0f84690a 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
@@ -1770,12 +1770,12 @@ std::ostream& operator<<(std::ostream& os, const OverflowBinopOp& bop) {
// Note that multiplication isn't tested because multiplication doesn't set
// flags on Arm64, and thus BranchIfOverflow fusion cannot happen.
const OverflowBinopOp kOverflowBinaryOperationsForBranchFusion[] = {
- {TSBinop::kInt32AddCheckOverflow, "Int32AddCheckOverflow", kLoong64Add_d,
+ {TSBinop::kInt32AddCheckOverflow, "Int32AddCheckOverflow", kLoong64AddOvf_w,
false},
{TSBinop::kInt64AddCheckOverflow, "Int64AddCheckOverflow", kLoong64AddOvf_d,
true},
- {TSBinop::kInt32SubCheckOverflow, "kInt32SubCheckOverflow", kLoong64Sub_d,
- false},
+ {TSBinop::kInt32SubCheckOverflow, "kInt32SubCheckOverflow",
+ kLoong64SubOvf_w, false},
{TSBinop::kInt64SubCheckOverflow, "kInt64SubCheckOverflow",
kLoong64SubOvf_d, true},
{TSBinop::kInt32MulCheckOverflow, "Int32MulCheckOverflow", kLoong64MulOvf_w,
@@ -2131,4 +2131,45 @@ TEST_P(TurboshaftInstructionSelectorAddSub128Test,
INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
TurboshaftInstructionSelectorAddSub128Test,
::testing::ValuesIn(kAddOrSub128));
+
+TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
+ if (v8_flags.disable_write_barriers) return;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int64(),
+ MachineType::Int64(), MachineType::AnyTagged());
+ m.Store(m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ StoreOp::Kind::Aligned(BaseTaggedness::kTaggedBase).Atomic(),
+ MemoryRepresentation::TaggedPointer(),
+ WriteBarrierKind::kFullWriteBarrier, AtomicMemoryOrder::kSeqCst);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build(kAllExceptNopInstructions);
+ ASSERT_EQ(3U, s.size());
+ 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()),
+ RecordWriteMode::kValueIsAny);
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
+ if (!V8_STATIC_ROOTS_BOOL &&
+ (!COMPRESS_POINTERS_BOOL || isolate()->bootstrapper())) {
+ return;
+ }
+
+ StreamBuilder m(this, MachineType::Int32(), MachineType::AnyTagged());
+ Handle<HeapObject> undefined_value = isolate()->factory()->undefined_value();
+
+ OpIndex param = m.Parameter(0);
+ OpIndex heap_constant = m.HeapConstant(undefined_value);
+ OpIndex eq = m.Word32Equal(param, heap_constant);
+
+ m.Return(eq);
+ Stream s = m.Build();
+
+ ASSERT_EQ(1u, s.size());
+ EXPECT_EQ(kLoong64Cmp32Eq, s[0]->arch_opcode());
+ ASSERT_EQ(2u, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
} // 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 30c8712d431..b16c21d1968 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
@@ -2094,6 +2094,24 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
TurboshaftInstructionSelectorAddSub128Test,
::testing::ValuesIn(kAddOrSub128));
+TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
+ if (v8_flags.disable_write_barriers) return;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int64(),
+ MachineType::Int64(), MachineType::AnyTagged());
+ m.Store(m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ StoreOp::Kind::Aligned(BaseTaggedness::kTaggedBase).Atomic(),
+ MemoryRepresentation::TaggedPointer(),
+ WriteBarrierKind::kFullWriteBarrier, AtomicMemoryOrder::kSeqCst);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build(kAllExceptNopInstructions);
+ ASSERT_EQ(3U, s.size());
+ 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()),
+ RecordWriteMode::kValueIsAny);
+}
+
} // namespace turboshaft
} // namespace compiler
} // namespace internal
diff --git a/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc b/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc
index 709ec6601b9..17077204b0e 100644
--- a/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/regalloc/move-optimizer-unittest.cc
@@ -22,6 +22,16 @@ class MoveOptimizerTest : public InstructionSequenceTest {
Instruction* LastInstruction() { return sequence()->instructions().back(); }
+ // Unlike Const(), which encodes the virtual register only, this registers
+ // an actual constant value for it, as required by paths that inspect the
+ // value (such as the one-instruction-constant heuristic on arm64). Unlike
+ // InstructionSequenceTest::DefineConstant(), it emits no instruction.
+ TestOperand ConstWithValue(int32_t value) {
+ int virtual_register = sequence()->NextVirtualRegister();
+ sequence()->AddConstant(virtual_register, Constant(value));
+ return Const(virtual_register);
+ }
+
void AddMove(Instruction* instr, TestOperand from, TestOperand to,
Instruction::GapPosition pos = Instruction::START) {
auto parallel_move = instr->GetOrCreateParallelMove(pos, zone());
@@ -141,6 +151,56 @@ TEST_F(MoveOptimizerTest, SplitsConstants) {
CHECK(Contains(move, Reg(0), Slot(2)));
}
+TEST_F(MoveOptimizerTest, KeepsCheapConstantsIndependent) {
+ StartBlock();
+ EndBlock(Last());
+
+ auto gap = LastInstruction();
+ TestOperand cheap = ConstWithValue(1);
+ AddMove(gap, cheap, Reg(0));
+ AddMove(gap, cheap, Reg(1));
+
+ Optimize();
+
+ auto move = gap->parallel_moves()[0];
+#if V8_TARGET_ARCH_ARM64
+ // A one-instruction constant rematerializes into each register; grouping
+ // would only make the second move depend on the first.
+ CHECK_EQ(2, NonRedundantSize(move));
+ CHECK(Contains(move, cheap, Reg(0)));
+ CHECK(Contains(move, cheap, Reg(1)));
+ auto follow = gap->parallel_moves()[1];
+ CHECK(follow == nullptr || NonRedundantSize(follow) == 0);
+#else
+ CHECK_EQ(1, NonRedundantSize(move));
+ CHECK(Contains(move, cheap, Reg(0)));
+ auto follow = gap->parallel_moves()[1];
+ CHECK_EQ(1, NonRedundantSize(follow));
+ CHECK(Contains(follow, Reg(0), Reg(1)));
+#endif
+}
+
+TEST_F(MoveOptimizerTest, GroupsExpensiveConstants) {
+ StartBlock();
+ EndBlock(Last());
+
+ auto gap = LastInstruction();
+ // 0x12345678 is no single MOVZ/MOVN/ORR-immediate on arm64, so grouping
+ // still pays off: materialize once, then copy.
+ TestOperand expensive = ConstWithValue(0x12345678);
+ AddMove(gap, expensive, Reg(0));
+ AddMove(gap, expensive, Reg(1));
+
+ Optimize();
+
+ auto move = gap->parallel_moves()[0];
+ CHECK_EQ(1, NonRedundantSize(move));
+ CHECK(Contains(move, expensive, Reg(0)));
+ auto follow = gap->parallel_moves()[1];
+ CHECK_EQ(1, NonRedundantSize(follow));
+ CHECK(Contains(follow, Reg(0), Reg(1)));
+}
+
TEST_F(MoveOptimizerTest, SimpleMerge) {
StartBlock();
EndBlock(Branch(Imm(), 1, 2));
diff --git a/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc b/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc
index cf14b5d96f6..875088a20cd 100644
--- a/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc
+++ b/deps/v8/test/unittests/compiler/regalloc/register-allocator-unittest.cc
@@ -115,6 +115,31 @@ TEST_F(RegisterAllocatorTest, CanAllocateThreeRegisters) {
Allocate();
}
+TEST_F(RegisterAllocatorTest, CombineFPAliasingSimd128InactiveDouble) {
+ if (kFPAliasing != AliasingKind::kCombine) return;
+ // Four double registers give two Simd128 registers under combine aliasing;
+ // the second Simd128 register aliases the two upper double registers.
+ SetNumRegs(4, 4);
+
+ StartBlock();
+ // Occupy the first Simd128 register for the whole block.
+ auto blocker = Define(FPReg(0, kSimd128));
+ // The Simd128 value below has to share resources with the fixed double
+ // definition that follows, since that double aliases the only remaining
+ // Simd128 register.
+ auto simd = EmitOI(FPReg(kNoValue, kSimd128));
+ EmitOI(FPReg(2, kFloat64));
+ Instruction* use = EmitI(Reg(simd));
+ EmitI(Reg(blocker, 0));
+ EndBlock(Last());
+
+ Allocate();
+
+ AllocatedOperand d2(LocationOperand::REGISTER, kFloat64, 2);
+ EXPECT_TRUE(use->InputAt(0)->IsAnyLocationOperand());
+ EXPECT_FALSE(use->InputAt(0)->InterferesWith(d2));
+}
+
TEST_F(RegisterAllocatorTest, CanAllocateFPRegisters) {
StartBlock();
TestOperand inputs[] = {
diff --git a/deps/v8/test/unittests/compiler/revec-unittest.cc b/deps/v8/test/unittests/compiler/revec-unittest.cc
deleted file mode 100644
index c48d75cd912..00000000000
--- a/deps/v8/test/unittests/compiler/revec-unittest.cc
+++ /dev/null
@@ -1,697 +0,0 @@
-// Copyright 2022 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/codegen/machine-type.h"
-#include "src/compiler/backend/instruction-selector.h"
-#include "src/compiler/common-operator.h"
-#include "src/compiler/machine-graph.h"
-#include "src/compiler/machine-operator.h"
-#include "src/compiler/node-properties.h"
-#include "src/compiler/node.h"
-#include "src/compiler/opcodes.h"
-#include "src/compiler/operator.h"
-#include "src/compiler/revectorizer.h"
-#include "src/compiler/wasm-compiler.h"
-#include "src/wasm/wasm-module.h"
-#include "test/unittests/compiler/graph-unittest.h"
-#include "test/unittests/compiler/node-test-utils.h"
-#include "testing/gmock-support.h"
-
-using testing::AllOf;
-using testing::Capture;
-using testing::CaptureEq;
-
-namespace v8 {
-namespace internal {
-namespace compiler {
-
-// REVIEW: Looks like this entire file still uses the Turbofan implementation.
-// It should be ported to Turboshaft.
-
-class RevecTest : public TestWithIsolateAndZone {
- public:
- RevecTest()
- : graph_(zone()),
- common_(zone()),
- machine_(zone(), MachineRepresentation::kWord64,
- InstructionSelector::SupportedMachineOperatorFlags()),
- mcgraph_(&graph_, &common_, &machine_),
- source_positions_(
- mcgraph()->zone()->New<SourcePositionTable>(mcgraph()->graph())) {}
-
- void TestBinOp(const Operator* bin_op,
- const IrOpcode::Value expected_simd256_op_code);
- void TestShiftOp(const Operator* shift_op,
- const IrOpcode::Value expected_simd256_op_code);
- void TestSplatOp(const Operator* splat_op,
- MachineType splat_input_machine_type,
- const IrOpcode::Value expected_simd256_op_code);
- void TestLoadSplat(LoadTransformation transform, const Operator* bin_op,
- LoadTransformation expected_transform);
-
- TFGraph* graph() { return &graph_; }
- CommonOperatorBuilder* common() { return &common_; }
- MachineOperatorBuilder* machine() { return &machine_; }
- MachineGraph* mcgraph() { return &mcgraph_; }
- SourcePositionTable* source_positions() { return source_positions_; }
-
- private:
- TFGraph graph_;
- CommonOperatorBuilder common_;
- MachineOperatorBuilder machine_;
- MachineGraph mcgraph_;
- SourcePositionTable* source_positions_;
-};
-
-// Create a graph which perform binary operation on two 256 bit vectors(a, b),
-// store the result in c: simd128 *a,*b,*c; *c = *a bin_op *b;
-// *(c+1) = *(a+1) bin_op *(b+1);
-// In Revectorization, two simd 128 nodes can be combined into one 256 node:
-// simd256 *d, *e, *f;
-// *f = *d bin_op *e;
-void RevecTest::TestBinOp(const Operator* bin_op,
- const IrOpcode::Value expected_simd256_op_code) {
- if (!CpuFeatures::IsSupported(AVX2)) return;
- Node* start = graph()->NewNode(common()->Start(5));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- // offset of memory start field in WASM instance object.
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- Node* p2 = graph()->NewNode(common()->Parameter(2), start);
- Node* p3 = graph()->NewNode(common()->Parameter(3), start);
-
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- LoadRepresentation load_rep(MachineType::Simd128());
- Node* load0 = graph()->NewNode(machine()->Load(MachineType::Int64()), p0,
- offset, start, start);
- Node* mem_buffer1 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_buffer2 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_store = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* load1 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p1,
- load0, start);
- Node* load2 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer1,
- p1, load1, start);
- Node* load3 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p2,
- load2, start);
- Node* load4 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer2,
- p2, load3, start);
- Node* bin_op1 = graph()->NewNode(bin_op, load1, load3);
- Node* bin_op2 = graph()->NewNode(bin_op, load2, load4);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), load0, p3,
- bin_op1, load4, start);
- Node* store2 = graph()->NewNode(machine()->Store(store_rep), mem_store, p3,
- bin_op2, store1, start);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store2, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store1);
- graph()->RecordSimdStore(store2);
- graph()->SetSimd(true);
-
- // Test whether the graph can be revectorized
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- EXPECT_TRUE(revec.TryRevectorize(nullptr));
-
- // Test whether the graph has been revectorized
- Node* store_256 = ret->InputAt(1);
- EXPECT_EQ(StoreRepresentationOf(store_256->op()).representation(),
- MachineRepresentation::kSimd256);
- EXPECT_EQ(store_256->InputAt(2)->opcode(), expected_simd256_op_code);
-}
-
-#define BIN_OP_LIST(V) \
- V(F64x2Add, F64x4Add) \
- V(F32x4Add, F32x8Add) \
- V(I64x2Add, I64x4Add) \
- V(I32x4Add, I32x8Add) \
- V(I16x8Add, I16x16Add) \
- V(I8x16Add, I8x32Add) \
- V(F64x2Sub, F64x4Sub) \
- V(F32x4Sub, F32x8Sub) \
- V(I64x2Sub, I64x4Sub) \
- V(I32x4Sub, I32x8Sub) \
- V(I16x8Sub, I16x16Sub) \
- V(I8x16Sub, I8x32Sub) \
- V(F64x2Mul, F64x4Mul) \
- V(F32x4Mul, F32x8Mul) \
- V(I64x2Mul, I64x4Mul) \
- V(I32x4Mul, I32x8Mul) \
- V(I16x8Mul, I16x16Mul) \
- V(F64x2Div, F64x4Div) \
- V(F32x4Div, F32x8Div) \
- V(F64x2Eq, F64x4Eq) \
- V(F32x4Eq, F32x8Eq) \
- V(I64x2Eq, I64x4Eq) \
- V(I32x4Eq, I32x8Eq) \
- V(I16x8Eq, I16x16Eq) \
- V(I8x16Eq, I8x32Eq) \
- V(F64x2Ne, F64x4Ne) \
- V(F32x4Ne, F32x8Ne) \
- V(I64x2GtS, I64x4GtS) \
- V(I32x4GtS, I32x8GtS) \
- V(I16x8GtS, I16x16GtS) \
- V(I8x16GtS, I8x32GtS) \
- V(F64x2Lt, F64x4Lt) \
- V(F32x4Lt, F32x8Lt) \
- V(F64x2Le, F64x4Le) \
- V(F32x4Le, F32x8Le) \
- V(I32x4MinS, I32x8MinS) \
- V(I16x8MinS, I16x16MinS) \
- V(I8x16MinS, I8x32MinS) \
- V(I32x4MinU, I32x8MinU) \
- V(I16x8MinU, I16x16MinU) \
- V(I8x16MinU, I8x32MinU) \
- V(I32x4MaxS, I32x8MaxS) \
- V(I16x8MaxS, I16x16MaxS) \
- V(I8x16MaxS, I8x32MaxS) \
- V(I32x4MaxU, I32x8MaxU) \
- V(I16x8MaxU, I16x16MaxU) \
- V(I8x16MaxU, I8x32MaxU) \
- V(F64x2Min, F64x4Min) \
- V(F64x2Max, F64x4Max) \
- V(F32x4Min, F32x8Min) \
- V(F32x4Max, F32x8Max)
-
-#define TEST_BIN_OP(op128, op256) \
- TEST_F(RevecTest, op256) { \
- TestBinOp(machine()->op128(), IrOpcode::k##op256); \
- }
-
-BIN_OP_LIST(TEST_BIN_OP)
-
-#undef TEST_BIN_OP
-#undef BIN_OP_LIST
-
-// Create a graph with load chain that can not be packed due to effect
-// dependency:
-// [Load4] -> [Load3] -> [Load2] -> [Irrelevant Load] -> [Load1]
-//
-// After reordering, no effect dependency will be broken so the graph can be
-// revectorized:
-// [Load4] -> [Load3] -> [Load2] -> [Load1] -> [Irrelevant Load]
-TEST_F(RevecTest, ReorderLoadChain1) {
- if (!CpuFeatures::IsSupported(AVX2)) return;
-
- Node* start = graph()->NewNode(common()->Start(5));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- // offset of memory start field in Wasm instance object.
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- Node* p2 = graph()->NewNode(common()->Parameter(2), start);
- Node* p3 = graph()->NewNode(common()->Parameter(3), start);
-
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- LoadRepresentation load_rep(MachineType::Simd128());
- Node* load0 = graph()->NewNode(machine()->Load(MachineType::Int64()), p0,
- offset, start, start);
- Node* mem_buffer1 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_buffer2 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_store = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* load1 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p1,
- load0, start);
- Node* irrelevant_load = graph()->NewNode(machine()->TrappingLoad(load_rep),
- mem_buffer1, p1, load1, start);
- Node* load2 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer1,
- p1, irrelevant_load, start);
- Node* load3 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p2,
- load2, start);
- Node* load4 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer2,
- p2, load3, start);
- Node* add1 = graph()->NewNode(machine()->F32x4Add(), load1, load3);
- Node* add2 = graph()->NewNode(machine()->F32x4Add(), load2, load4);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), load0, p3, add1,
- load4, start);
- Node* store2 = graph()->NewNode(machine()->Store(store_rep), mem_store, p3,
- add2, store1, start);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store2, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store1);
- graph()->RecordSimdStore(store2);
- graph()->SetSimd(true);
-
- // Test whether the graph can be revectorized
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- EXPECT_TRUE(revec.TryRevectorize(nullptr));
-}
-
-// Create a graph with load chain that can not be packed due to effect
-// dependency:
-// [Load4] -> [Load2] -> [Load1] -> [Irrelevant Load] -> [Load3]
-//
-// After reordering, no effect dependency will be broken so the graph can be
-// revectorized:
-// [Load4] -> [Load3] -> [Load2] -> [Load1] -> [Irrelevant Load]
-TEST_F(RevecTest, ReorderLoadChain2) {
- if (!CpuFeatures::IsSupported(AVX2)) return;
-
- Node* start = graph()->NewNode(common()->Start(5));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- // offset of memory start field in Wasm instance object.
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- Node* p2 = graph()->NewNode(common()->Parameter(2), start);
- Node* p3 = graph()->NewNode(common()->Parameter(3), start);
-
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- LoadRepresentation load_rep(MachineType::Simd128());
- Node* load0 = graph()->NewNode(machine()->Load(MachineType::Int64()), p0,
- offset, start, start);
- Node* mem_buffer1 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_buffer2 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_store = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* load3 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p2,
- load0, start);
- Node* irrelevant_load = graph()->NewNode(machine()->TrappingLoad(load_rep),
- mem_buffer1, p1, load3, start);
- Node* load1 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p1,
- irrelevant_load, start);
- Node* load2 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer1,
- p1, load1, start);
- Node* load4 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer2,
- p2, load2, start);
- Node* add1 = graph()->NewNode(machine()->F32x4Add(), load1, load3);
- Node* add2 = graph()->NewNode(machine()->F32x4Add(), load2, load4);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), load0, p3, add1,
- load4, start);
- Node* store2 = graph()->NewNode(machine()->Store(store_rep), mem_store, p3,
- add2, store1, start);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store2, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store1);
- graph()->RecordSimdStore(store2);
- graph()->SetSimd(true);
-
- // Test whether the graph can be revectorized
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- EXPECT_TRUE(revec.TryRevectorize(nullptr));
-}
-
-// Test shift using an immediate and a value loaded from memory (b) on a 256-bit
-// vector a and store the result in another 256-bit vector c:
-// simd128 *a, *c;
-// int32 *b;
-// *c = (*a shift_op 1) shift_op *b;
-// *(c+1) = (*(a+1) shift_op 1) shift_op *b;
-// In Revectorization, two simd128 nodes can be coalesced into one simd256 node
-// as below:
-// simd256 *a, *c; *c = (*a shift_op 1) shift_op *b;
-void RevecTest::TestShiftOp(const Operator* shift_op,
- const IrOpcode::Value expected_simd256_op_code) {
- Node* start = graph()->NewNode(common()->Start(4));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* one = graph()->NewNode(common()->Int32Constant(1));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- // Wasm array base address
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* a = graph()->NewNode(common()->Parameter(1), start);
- Node* b = graph()->NewNode(common()->Parameter(2), start);
- Node* c = graph()->NewNode(common()->Parameter(3), start);
-
- LoadRepresentation load_rep(MachineType::Simd128());
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- Node* base = graph()->NewNode(machine()->Load(MachineType::Int64()), p0,
- offset, start, start);
- Node* base16 = graph()->NewNode(machine()->Int64Add(), base, sixteen);
- Node* load0 =
- graph()->NewNode(machine()->TrappingLoad(load_rep), base, a, base, start);
- Node* load1 = graph()->NewNode(machine()->TrappingLoad(load_rep), base16, a,
- load0, start);
- Node* shift0 = graph()->NewNode(shift_op, load0, one);
- Node* shift1 = graph()->NewNode(shift_op, load1, one);
- Node* load2 =
- graph()->NewNode(machine()->TrappingLoad(LoadRepresentation::Int32()),
- base, b, load1, start);
- Node* store0 =
- graph()->NewNode(machine()->Store(store_rep), base, c,
- graph()->NewNode(shift_op, shift0, load2), load2, start);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), base16, c,
- graph()->NewNode(shift_op, shift1, load2),
- store0, start);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store1, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store0);
- graph()->RecordSimdStore(store1);
- graph()->SetSimd(true);
-
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- bool result = revec.TryRevectorize(nullptr);
-
- if (CpuFeatures::IsSupported(AVX2)) {
- EXPECT_TRUE(result);
- Node* store_256 = ret->InputAt(1);
- EXPECT_EQ(StoreRepresentationOf(store_256->op()).representation(),
- MachineRepresentation::kSimd256);
- EXPECT_EQ(store_256->InputAt(2)->opcode(), expected_simd256_op_code);
- return;
- }
-
- EXPECT_FALSE(result);
-}
-
-TEST_F(RevecTest, I64x4Shl) {
- TestShiftOp(machine()->I64x2Shl(), IrOpcode::kI64x4Shl);
-}
-TEST_F(RevecTest, I32x8ShrS) {
- TestShiftOp(machine()->I32x4Shl(), IrOpcode::kI32x8Shl);
-}
-TEST_F(RevecTest, I16x16ShrU) {
- TestShiftOp(machine()->I16x8Shl(), IrOpcode::kI16x16Shl);
-}
-
-void RevecTest::TestSplatOp(const Operator* splat_op,
- MachineType splat_input_machine_type,
- const IrOpcode::Value expected_simd256_op_code) {
- if (!CpuFeatures::IsSupported(AVX2)) {
- return;
- }
- Node* start = graph()->NewNode(common()->Start(3));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- Node* p2 = graph()->NewNode(common()->Parameter(2), start);
-
- Node* base = graph()->NewNode(machine()->Load(MachineType::Uint64()), p0,
- offset, start, start);
-
- Node* load = graph()->NewNode(
- machine()->TrappingLoad(splat_input_machine_type), base, p1, base, start);
- Node* splat0 = graph()->NewNode(splat_op, load);
- Node* splat1 = graph()->NewNode(splat_op, load);
-
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
-
- Node* store0 = graph()->NewNode(machine()->Store(store_rep), base, p2, splat0,
- load, start);
- Node* store1 =
- graph()->NewNode(machine()->Store(store_rep),
- graph()->NewNode(machine()->Int64Add(), base, sixteen),
- p2, splat1, store0, start);
-
- Node* ret = graph()->NewNode(common()->Return(0), zero, store0, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store0);
- graph()->RecordSimdStore(store1);
- graph()->SetSimd(true);
-
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- bool result = revec.TryRevectorize(nullptr);
-
- EXPECT_TRUE(result);
- Node* store_256 = ret->InputAt(1);
- EXPECT_EQ(StoreRepresentationOf(store_256->op()).representation(),
- MachineRepresentation::kSimd256);
- EXPECT_EQ(store_256->InputAt(2)->opcode(), expected_simd256_op_code);
- return;
-}
-
-#define SPLAT_OP_LIST(V) \
- V(I8x16Splat, I8x32Splat, Int8) \
- V(I16x8Splat, I16x16Splat, Int16) \
- V(I32x4Splat, I32x8Splat, Int32) \
- V(I64x2Splat, I64x4Splat, Int64)
-
-#define TEST_SPLAT(op128, op256, machine_type) \
- TEST_F(RevecTest, op256) { \
- TestSplatOp(machine()->op128(), MachineType::machine_type(), \
- IrOpcode::k##op256); \
- }
-
-SPLAT_OP_LIST(TEST_SPLAT)
-
-#undef TEST_SPLAT
-#undef SPLAT_OP_LIST
-
-// Create a graph which multiplies a F32x8 vector with a shuffle splat vector.
-// float *a, *b, *c;
-// c[0123] = a[0123] * b[1111];
-// c[4567] = a[4567] * b[1111];
-//
-// After the revectorization phase, two consecutive 128-bit loads and multiplies
-// can be coalesced using 256-bit operators:
-// c[01234567] = a[01234567] * b[11111111];
-TEST_F(RevecTest, ShuffleForSplat) {
- if (!CpuFeatures::IsSupported(AVX2)) return;
-
- Node* start = graph()->NewNode(common()->Start(4));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- // Wasm array base address
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- // Load base address a*
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- // Load for shuffle base address b*
- Node* p2 = graph()->NewNode(common()->Parameter(2), start);
- // Store base address c*
- Node* p3 = graph()->NewNode(common()->Parameter(3), start);
-
- LoadRepresentation load_rep(MachineType::Simd128());
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- Node* base = graph()->NewNode(machine()->Load(MachineType::Int64()), p0,
- offset, start, start);
- Node* load0 = graph()->NewNode(machine()->TrappingLoad(load_rep), base, p1,
- base, start);
- Node* base16 = graph()->NewNode(machine()->Int64Add(), base, sixteen);
- Node* load1 = graph()->NewNode(machine()->TrappingLoad(load_rep), base16, p1,
- load0, start);
-
- // Load and shuffle for splat
- Node* load2 = graph()->NewNode(machine()->TrappingLoad(load_rep), base, p2,
- load1, start);
- const uint8_t mask[16] = {4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7, 4, 5, 6, 7};
- Node* shuffle = graph()->NewNode(machine()->I8x16Shuffle(mask), load2, load2);
-
- Node* mul0 = graph()->NewNode(machine()->F32x4Mul(), load0, shuffle);
- Node* mul1 = graph()->NewNode(machine()->F32x4Mul(), load1, shuffle);
- Node* store0 = graph()->NewNode(machine()->Store(store_rep), base, p3, mul0,
- load2, start);
- Node* base16_store = graph()->NewNode(machine()->Int64Add(), base, sixteen);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), base16_store, p3,
- mul1, store0, start);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store1, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store0);
- graph()->RecordSimdStore(store1);
- graph()->SetSimd(true);
-
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- EXPECT_TRUE(revec.TryRevectorize(nullptr));
-
- // Test whether the graph has been revectorized
- Node* store_256 = ret->InputAt(1);
- EXPECT_EQ(StoreRepresentationOf(store_256->op()).representation(),
- MachineRepresentation::kSimd256);
-}
-
-void RevecTest::TestLoadSplat(
- const LoadTransformation load_transform, const Operator* bin_op,
- const LoadTransformation expected_load_transform) {
- if (!CpuFeatures::IsSupported(AVX2)) {
- return;
- }
- Node* start = graph()->NewNode(common()->Start(3));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* a = graph()->NewNode(common()->Parameter(1), start);
- Node* b = graph()->NewNode(common()->Parameter(2), start);
- Node* c = graph()->NewNode(common()->Parameter(3), start);
-
- Node* base = graph()->NewNode(machine()->Load(MachineType::Uint64()), p0,
- offset, start, start);
-
- Node* loadSplat = graph()->NewNode(
- machine()->LoadTransform(MemoryAccessKind::kTrapping, load_transform),
- base, a, base, start);
-
- LoadRepresentation load_rep(MachineType::Simd128());
- Node* load0 = graph()->NewNode(machine()->TrappingLoad(load_rep), base, b,
- loadSplat, start);
- Node* load1 = graph()->NewNode(
- machine()->TrappingLoad(load_rep),
- graph()->NewNode(machine()->Int64Add(), base, sixteen), b, load0, start);
-
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- Node* store0 = graph()->NewNode(machine()->Store(store_rep), base, c,
- graph()->NewNode(bin_op, load0, loadSplat),
- load1, start);
- Node* store1 = graph()->NewNode(
- machine()->Store(store_rep),
- graph()->NewNode(machine()->Int64Add(), base, sixteen), c,
- graph()->NewNode(bin_op, load1, loadSplat), store0, start);
-
- Node* ret = graph()->NewNode(common()->Return(0), zero, store0, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store0);
- graph()->RecordSimdStore(store1);
- graph()->SetSimd(true);
-
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- bool result = revec.TryRevectorize(nullptr);
-
- EXPECT_TRUE(result);
- Node* store_256 = ret->InputAt(1);
- EXPECT_EQ(StoreRepresentationOf(store_256->op()).representation(),
- MachineRepresentation::kSimd256);
- EXPECT_EQ(LoadTransformParametersOf(store_256->InputAt(2)->InputAt(1)->op())
- .transformation,
- expected_load_transform);
-}
-
-TEST_F(RevecTest, Load8Splat) {
- TestLoadSplat(LoadTransformation::kS128Load8Splat, machine()->I8x16Add(),
- LoadTransformation::kS256Load8Splat);
-}
-TEST_F(RevecTest, Load64Splat) {
- TestLoadSplat(LoadTransformation::kS128Load64Splat, machine()->I64x2Add(),
- LoadTransformation::kS256Load64Splat);
-}
-
-// Create a graph with Store nodes that can not be packed due to effect
-// intermediate:
-// [Store0] -> [Load] -> [Store1]
-TEST_F(RevecTest, StoreDependencyCheck) {
- if (!CpuFeatures::IsSupported(AVX2)) return;
-
- Node* start = graph()->NewNode(common()->Start(5));
- graph()->SetStart(start);
-
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- // offset of memory start field in WASM instance object.
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- Node* p2 = graph()->NewNode(common()->Parameter(2), start);
- Node* p3 = graph()->NewNode(common()->Parameter(3), start);
-
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- LoadRepresentation load_rep(MachineType::Simd128());
- Node* load0 = graph()->NewNode(machine()->Load(MachineType::Int64()), p0,
- offset, start, start);
- Node* mem_buffer1 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_buffer2 = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* mem_store = graph()->NewNode(machine()->Int64Add(), load0, sixteen);
- Node* load1 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p1,
- load0, start);
- Node* load2 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer1,
- p1, load1, start);
- Node* load3 = graph()->NewNode(machine()->TrappingLoad(load_rep), load0, p2,
- load2, start);
- Node* load4 = graph()->NewNode(machine()->TrappingLoad(load_rep), mem_buffer2,
- p2, load3, start);
- Node* add1 = graph()->NewNode(machine()->F32x4Add(), load1, load3);
- Node* add2 = graph()->NewNode(machine()->F32x4Add(), load2, load4);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), load0, p3, add1,
- load4, start);
- Node* effect_intermediate = graph()->NewNode(
- machine()->TrappingLoad(load_rep), mem_buffer2, p2, store1, start);
- Node* store2 = graph()->NewNode(machine()->Store(store_rep), mem_store, p3,
- add2, effect_intermediate, start);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store2, start);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store1);
- graph()->RecordSimdStore(store2);
- graph()->SetSimd(true);
-
- // Test whether the graph can be revectorized
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- EXPECT_FALSE(revec.TryRevectorize(nullptr));
-}
-
-TEST_F(RevecTest, S128Zero) {
- if (!CpuFeatures::IsSupported(AVX) || !CpuFeatures::IsSupported(AVX2)) return;
-
- Node* start = graph()->NewNode(common()->Start(5));
- graph()->SetStart(start);
-
- Node* control = graph()->start();
- Node* zero = graph()->NewNode(common()->Int32Constant(0));
- Node* sixteen = graph()->NewNode(common()->Int64Constant(16));
- Node* zero128 = graph()->NewNode(machine()->S128Zero());
- // offset of memory start field in WASM instance object.
- Node* offset = graph()->NewNode(common()->Int64Constant(23));
-
- Node* p0 = graph()->NewNode(common()->Parameter(0), start);
- Node* p1 = graph()->NewNode(common()->Parameter(1), start);
- Node* base = graph()->NewNode(machine()->Load(MachineType::Uint64()), p0,
- offset, start, control);
- StoreRepresentation store_rep(MachineRepresentation::kSimd128,
- WriteBarrierKind::kNoWriteBarrier);
- Node* store1 = graph()->NewNode(machine()->Store(store_rep), base, p1,
- zero128, base, control);
- Node* object = graph()->NewNode(machine()->Int64Add(), base, sixteen);
- Node* store2 = graph()->NewNode(machine()->Store(store_rep), object, p1,
- zero128, store1, control);
- Node* ret = graph()->NewNode(common()->Return(0), zero, store2, control);
- Node* end = graph()->NewNode(common()->End(1), ret);
- graph()->SetEnd(end);
-
- graph()->RecordSimdStore(store1);
- graph()->RecordSimdStore(store2);
- graph()->SetSimd(true);
-
- // Test whether the graph can be revectorized
- Revectorizer revec(zone(), graph(), mcgraph(), source_positions());
- EXPECT_TRUE(revec.TryRevectorize(nullptr));
-}
-
-} // namespace compiler
-} // namespace internal
-} // namespace v8
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 623c8bf13d2..39f0b82e219 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
@@ -1812,6 +1812,28 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
TurboshaftInstructionSelectorAddSub128Test,
::testing::ValuesIn(kAddOrSub128));
+TEST_F(TurboshaftInstructionSelectorTest, Word32EqualWithReadOnlyRoot) {
+ if (!V8_STATIC_ROOTS_BOOL &&
+ (!COMPRESS_POINTERS_BOOL || isolate()->bootstrapper())) {
+ return;
+ }
+
+ StreamBuilder m(this, MachineType::Int32(), MachineType::AnyTagged());
+ Handle<HeapObject> undefined_value = isolate()->factory()->undefined_value();
+
+ OpIndex param = m.Parameter(0);
+ OpIndex heap_constant = m.HeapConstant(undefined_value);
+ OpIndex eq = m.Word32Equal(param, heap_constant);
+
+ m.Return(eq);
+ Stream s = m.Build();
+
+ ASSERT_EQ(1u, s.size());
+ EXPECT_EQ(kRiscvCmp32, s[0]->arch_opcode());
+ ASSERT_EQ(2u, s[0]->InputCount());
+ EXPECT_TRUE(s[0]->InputAt(1)->IsImmediate());
+}
+
} // namespace turboshaft
} // namespace compiler
} // namespace internal
diff --git a/deps/v8/test/unittests/compiler/run-jsobjects-unittest.cc b/deps/v8/test/unittests/compiler/run-jsobjects-unittest.cc
index 28cf68e87a6..0d6342ff7db 100644
--- a/deps/v8/test/unittests/compiler/run-jsobjects-unittest.cc
+++ b/deps/v8/test/unittests/compiler/run-jsobjects-unittest.cc
@@ -4,6 +4,7 @@
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "test/unittests/compiler/function-tester.h"
#include "test/unittests/test-utils.h"
diff --git a/deps/v8/test/unittests/compiler/run-unwinding-info-unittest.cc b/deps/v8/test/unittests/compiler/run-unwinding-info-unittest.cc
index d19160d22b3..f533cab7400 100644
--- a/deps/v8/test/unittests/compiler/run-unwinding-info-unittest.cc
+++ b/deps/v8/test/unittests/compiler/run-unwinding-info-unittest.cc
@@ -18,13 +18,19 @@
namespace v8::internal::compiler {
-using RunUnwindingInfoTest = TestWithContext;
+using RunUnwindingInfoTest = TestWithPlatform;
TEST_F(RunUnwindingInfoTest, RunUnwindingInfo) {
+ SaveFlags save_flags;
v8_flags.perf_prof_unwinding_info = true;
v8_flags.jit_fuzzing = true;
+ v8_flags.concurrent_recompilation = false;
+ FlagList::EnforceFlagImplications();
- FunctionTester tester(i_isolate(),
+ IsolateWithContextWrapper isolate_wrapper;
+ i::Isolate* i_isolate = isolate_wrapper.isolate();
+
+ FunctionTester tester(i_isolate,
"(function (x) {\n"
" function f(x) { return x*x; }\n"
" return x > 0 ? x+1 : f(x);\n"
@@ -34,7 +40,7 @@ TEST_F(RunUnwindingInfoTest, RunUnwindingInfo) {
tester.Call(tester.NewNumber(-1));
}
- EXPECT_TRUE(tester.function->code(i_isolate())->has_unwinding_info());
+ EXPECT_TRUE(tester.function->code(i_isolate)->has_unwinding_info());
}
// TODO(ssanfilippo) Build low-level graph and check that state is correctly
diff --git a/deps/v8/test/unittests/compiler/turboshaft/late-load-elimination-reducer-unittest.cc b/deps/v8/test/unittests/compiler/turboshaft/late-load-elimination-reducer-unittest.cc
index c7f09484af3..56dacca7d57 100644
--- a/deps/v8/test/unittests/compiler/turboshaft/late-load-elimination-reducer-unittest.cc
+++ b/deps/v8/test/unittests/compiler/turboshaft/late-load-elimination-reducer-unittest.cc
@@ -491,6 +491,43 @@ TEST_F(LateLoadEliminationReducerTest,
#endif
}
+TEST_F(LateLoadEliminationReducerTest,
+ IndexedStore_Invalidates_Offset_On_Other_Object) {
+ auto test = CreateFromGraph(
+ base::VectorOf({RegisterRepresentation::Tagged(),
+ RegisterRepresentation::Tagged(),
+ RegisterRepresentation::WordPtr()}),
+ [](auto& Asm) {
+ V<HeapObject> obj1 = V<HeapObject>::Cast(Asm.GetParameter(0));
+ V<HeapObject> obj2 = V<HeapObject>::Cast(Asm.GetParameter(1));
+ V<WordPtr> index = Asm.template GetParameter<WordPtr>(2);
+
+ // Initial load from obj2 at offset 8.
+ constexpr int kOffset = 8;
+ constexpr MemoryRepresentation kRep = MemoryRepresentation::Int32();
+ V<Word32> C(load0) = __ Load(obj2, {}, LoadOp::Kind::TaggedBase(), kRep,
+ RegisterRepresentation::Word32(), kOffset);
+
+ // Indexed store to obj1 (which may alias obj2).
+ __ Store(obj1, index, __ Word32Constant(42),
+ StoreOp::Kind::TaggedBase(), kRep,
+ WriteBarrierKind::kNoWriteBarrier, /* offset= */ 0,
+ kRep.SizeInBytesLog2());
+
+ // Second load from obj2 at offset 8.
+ V<Word32> C(load1) = __ Load(obj2, {}, LoadOp::Kind::TaggedBase(), kRep,
+ RegisterRepresentation::Word32(), kOffset);
+
+ __ Return(__ Word32Constant(0), base::VectorOf({load0, load1}));
+ });
+
+ test.Run<LateLoadEliminationReducer>();
+
+ // load1 MUST NOT be eliminated because obj1 may alias obj2 at runtime!
+ const LoadOp* load1 = test.GetCapturedAs<LoadOp>("load1");
+ ASSERT_NE(load1, nullptr);
+}
+
#if V8_ENABLE_WEBASSEMBLY
class WasmLateLoadEliminationReducerTest
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 6988c51ec93..18782ae8173 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
@@ -8,6 +8,7 @@
#include "src/compiler/turboshaft/assembler.h"
#include "src/compiler/turboshaft/copying-phase.h"
#include "src/compiler/turboshaft/dead-code-elimination-reducer.h"
+#include "src/compiler/turboshaft/loop-unrolling-reducer.h"
#include "src/compiler/turboshaft/operations.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/compiler/turboshaft/required-optimization-reducer.h"
@@ -727,6 +728,119 @@ TEST_F(ReducerTest, ShuffleOfShuffleRejectsRoundedWindowPastInputEnd) {
EXPECT_EQ(reduced_inner->kind, Simd128ShuffleOp::Kind::kI8x16);
}
+TEST_F(ReducerTest, ShuffleOfShuffleShiftsOnce) {
+ // Test that the analysis is only run once.
+ constexpr std::array<uint8_t, kSimd128Size> shuffle0 = {
+ 24, 13, 2, 30, 28, 31, 13, 31, 17, 27, 2, 0, 19, 31, 31, 0};
+ constexpr std::array<uint8_t, kSimd128Size> shuffle1 = {
+ 2, 28, 0, 31, 24, 31, 5, 25, 30, 26, 0, 5, 0, 11, 6, 18};
+ constexpr std::array<uint8_t, kSimd128Size> shuffle2 = {
+ 31, 31, 28, 4, 31, 11, 19, 22, 31, 20, 0, 3, 15, 30, 3, 0};
+ constexpr std::array<uint8_t, kSimd128Size> shuffle5 = {
+ 3, 1, 21, 31, 16, 2, 9, 10, 22, 0, 31, 29, 0, 1, 0, 1};
+
+ auto test = CreateFromGraph(1, [&](auto& Asm) {
+ auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ auto a =
+ __ Simd128Splat(__ Word32Constant(0), Simd128SplatOp::Kind::kI32x4);
+ auto b =
+ __ Simd128Splat(__ Word32Constant(1), Simd128SplatOp::Kind::kI32x4);
+ auto c =
+ __ Simd128Splat(__ Word32Constant(2), Simd128SplatOp::Kind::kI32x4);
+ auto d =
+ __ Simd128Splat(__ Word32Constant(3), Simd128SplatOp::Kind::kI32x4);
+
+ OpIndex x0 = Asm.Capture(
+ __ Simd128Shuffle(a, b, ShuffleKind, shuffle0.data()), "x0");
+ OpIndex y0 = __ Simd128Shuffle(c, d, ShuffleKind, shuffle1.data());
+ OpIndex z0 = Asm.Capture(
+ __ Simd128Shuffle(x0, y0, ShuffleKind, shuffle2.data()), "z0");
+
+ OpIndex x1 = Asm.Capture(
+ __ Simd128Shuffle(b, c, ShuffleKind, shuffle0.data()), "x1");
+ OpIndex y1 = __ Simd128Shuffle(d, a, ShuffleKind, shuffle1.data());
+ OpIndex z1 = Asm.Capture(
+ __ Simd128Shuffle(x1, y1, ShuffleKind, shuffle5.data()), "z1");
+
+ OpIndex extmul =
+ __ Simd128Binop(z0, z1, Simd128BinopOp::Kind::kI64x2ExtMulLowI32x4S);
+ __ Return(
+ __ Simd128Unary(extmul, Simd128UnaryOp::Kind::kI32x4UConvertI16x8Low));
+ });
+
+ test.Run<WasmShuffleReducer>();
+
+ const Simd128ShuffleOp* reduced_x0 =
+ test.GetCapture("x0").GetAs<Simd128ShuffleOp>();
+ ASSERT_TRUE(reduced_x0);
+ const Simd128ShuffleOp* reduced_z0 =
+ test.GetCapture("z0").GetAs<Simd128ShuffleOp>();
+ ASSERT_TRUE(reduced_z0);
+ const Simd128ShuffleOp* reduced_x1 =
+ test.GetCapture("x1").GetAs<Simd128ShuffleOp>();
+ ASSERT_TRUE(reduced_x1);
+ const Simd128ShuffleOp* reduced_z1 =
+ test.GetCapture("z1").GetAs<Simd128ShuffleOp>();
+ ASSERT_TRUE(reduced_z1);
+
+ if (v8_flags.future_wasm_simd_opt) {
+ // z0 only needs bytes {31, 31, 28, 4} from x0/y0. Since byte 28 comes from
+ // x0, x0 can be shifted once to expose that byte as its byte zero.
+ EXPECT_EQ(reduced_x0->kind, Simd128ShuffleOp::Kind::kI8x1);
+ EXPECT_EQ(reduced_x0->shuffle[0], 28);
+
+ EXPECT_EQ(reduced_z0->kind, Simd128ShuffleOp::Kind::kI8x4);
+ EXPECT_EQ(reduced_z0->shuffle[0], 31);
+ EXPECT_EQ(reduced_z0->shuffle[1], 31);
+ EXPECT_EQ(reduced_z0->shuffle[2], 28);
+ EXPECT_EQ(reduced_z0->shuffle[3], 0);
+
+ // z1 needs a four-byte window from x1, so x1 is shifted once and z1 is
+ // rewritten to address the shifted x1 bytes. If the analysis runs twice,
+ // x1 is incorrectly shifted a second time to {2, 30, 28, 28}, while z1 is
+ // still written for the once-shifted producer.
+ EXPECT_EQ(reduced_x1->kind, Simd128ShuffleOp::Kind::kI8x4);
+ EXPECT_EQ(reduced_x1->shuffle[0], 13);
+ EXPECT_EQ(reduced_x1->shuffle[1], 2);
+ EXPECT_EQ(reduced_x1->shuffle[2], 30);
+ EXPECT_EQ(reduced_x1->shuffle[3], 28);
+
+ EXPECT_EQ(reduced_z1->kind, Simd128ShuffleOp::Kind::kI8x4);
+ EXPECT_EQ(reduced_z1->shuffle[0], 2);
+ EXPECT_EQ(reduced_z1->shuffle[1], 0);
+ EXPECT_EQ(reduced_z1->shuffle[2], 21);
+ EXPECT_EQ(reduced_z1->shuffle[3], 31);
+ } else {
+ EXPECT_EQ(reduced_x0->kind, Simd128ShuffleOp::Kind::kI8x8);
+ EXPECT_EQ(reduced_x0->shuffle[0], 24);
+ EXPECT_EQ(reduced_x0->shuffle[1], 13);
+ EXPECT_EQ(reduced_x0->shuffle[2], 2);
+ EXPECT_EQ(reduced_x0->shuffle[3], 30);
+ EXPECT_EQ(reduced_x0->shuffle[4], 28);
+ EXPECT_EQ(reduced_x0->shuffle[5], 31);
+ EXPECT_EQ(reduced_x0->shuffle[6], 13);
+ EXPECT_EQ(reduced_x0->shuffle[7], 31);
+
+ EXPECT_EQ(reduced_z0->kind, Simd128ShuffleOp::Kind::kI8x4);
+ EXPECT_EQ(reduced_z0->shuffle[0], 31);
+ EXPECT_EQ(reduced_z0->shuffle[1], 31);
+ EXPECT_EQ(reduced_z0->shuffle[2], 28);
+ EXPECT_EQ(reduced_z0->shuffle[3], 4);
+
+ EXPECT_EQ(reduced_x1->kind, Simd128ShuffleOp::Kind::kI8x4);
+ EXPECT_EQ(reduced_x1->shuffle[0], 24);
+ EXPECT_EQ(reduced_x1->shuffle[1], 13);
+ EXPECT_EQ(reduced_x1->shuffle[2], 2);
+ EXPECT_EQ(reduced_x1->shuffle[3], 30);
+
+ EXPECT_EQ(reduced_z1->kind, Simd128ShuffleOp::Kind::kI8x4);
+ EXPECT_EQ(reduced_z1->shuffle[0], 3);
+ EXPECT_EQ(reduced_z1->shuffle[1], 1);
+ EXPECT_EQ(reduced_z1->shuffle[2], 21);
+ EXPECT_EQ(reduced_z1->shuffle[3], 31);
+ }
+}
+
TEST_F(ReducerTest, ExtractLaneNarrowsShuffle) {
using ExtractCase = std::tuple<Simd128ExtractLaneOp::Kind, uint8_t,
Simd128ShuffleOp::Kind, DemandedBytes>;
@@ -974,6 +1088,465 @@ TEST_F(ReducerTest, ShuffleTwoShuffles) {
}
}
+TEST_F(ReducerTest, I32x4AddReduceOfDotI8x16S) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr auto SplatKind = Simd128SplatOp::Kind::kI8x16;
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr auto AddKind = Simd128BinopOp::Kind::kI32x4Add;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {
+ 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15};
+
+ V<Simd128> left_input0 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(16), SplatKind), "left_input0");
+ V<Simd128> right_input0 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(17), SplatKind), "right_input0");
+ V<Simd128> left_input1 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(18), SplatKind), "left_input1");
+ V<Simd128> right_input1 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(19), SplatKind), "right_input1");
+ V<Simd128> left_input2 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(20), SplatKind), "left_input2");
+ V<Simd128> right_input2 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(21), SplatKind), "right_input2");
+ V<Simd128> initial_accumulator =
+ __ Simd128Splat(__ Word32Constant(0), Simd128SplatOp::Kind::kI32x4);
+
+ Block* loop = __ NewLoopHeader();
+ Block *done = __ NewBlock(), *backedge = __ NewBlock();
+ V<Word32> initial_iteration = __ Word32Constant(0);
+
+ __ Goto(loop);
+ __ Bind(loop);
+ OpIndex accumulator_phi = __ PendingLoopPhi(
+ initial_accumulator, RegisterRepresentation::Simd128());
+ OpIndex iteration_phi =
+ __ PendingLoopPhi(initial_iteration, RegisterRepresentation::Word32());
+
+ V<Simd128> left_shuffle0 =
+ __ Simd128Shuffle(left_input0, left_input0, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle0 = __ Simd128Shuffle(right_input0, right_input0,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot0 = Asm.Capture(
+ __ Simd128Binop(left_shuffle0, right_shuffle0, DotKind), "dot0");
+
+ V<Simd128> left_shuffle1 =
+ __ Simd128Shuffle(left_input1, left_input1, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle1 = __ Simd128Shuffle(right_input1, right_input1,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot1 = Asm.Capture(
+ __ Simd128Binop(left_shuffle1, right_shuffle1, DotKind), "dot1");
+
+ V<Simd128> left_shuffle2 =
+ __ Simd128Shuffle(left_input2, left_input2, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle2 = __ Simd128Shuffle(right_input2, right_input2,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot2 = Asm.Capture(
+ __ Simd128Binop(left_shuffle2, right_shuffle2, DotKind), "dot2");
+
+ V<Simd128> dot_chain =
+ __ Simd128Binop(__ Simd128Binop(dot0, dot1, AddKind), dot2, AddKind);
+ V<Simd128> next_accumulator =
+ __ Simd128Binop(V<Simd128>::Cast(accumulator_phi), dot_chain, AddKind);
+ V<Word32> next_iteration = __ Word32Add(V<Word32>::Cast(iteration_phi), 1);
+ __ Branch(__ Word32Equal(next_iteration, 4), done, backedge);
+
+ __ Bind(backedge);
+ __ Goto(loop);
+
+ __ Bind(done);
+ V<Simd128> reduce = __ Simd128Reduce(
+ next_accumulator, Simd128ReduceOp::Kind::kI32x4AddReduce);
+ __ Return(
+ __ Simd128ExtractLane(reduce, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+
+ __ output_graph().template Replace<PhiOp>(
+ accumulator_phi,
+ base::VectorOf<OpIndex>({initial_accumulator, next_accumulator}),
+ RegisterRepresentation::Simd128());
+ __ output_graph().template Replace<PhiOp>(
+ iteration_phi,
+ base::VectorOf<OpIndex>({initial_iteration, next_iteration}),
+ RegisterRepresentation::Word32());
+ });
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 1u);
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 0u);
+
+ struct DotExpectation {
+ const char* dot;
+ const char* left;
+ const char* right;
+ };
+ for (const DotExpectation expectation :
+ {DotExpectation{"dot0", "left_input0", "right_input0"},
+ DotExpectation{"dot1", "left_input1", "right_input1"},
+ DotExpectation{"dot2", "left_input2", "right_input2"}}) {
+ const Simd128BinopOp* dot =
+ test.GetCapture(expectation.dot).GetAs<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ EXPECT_FALSE(test.graph().Get(dot->left()).Is<Simd128ShuffleOp>());
+ EXPECT_FALSE(test.graph().Get(dot->right()).Is<Simd128ShuffleOp>());
+ EXPECT_TRUE(test.GetCapture(expectation.left).Is(dot->left()));
+ EXPECT_TRUE(test.GetCapture(expectation.right).Is(dot->right()));
+ }
+}
+
+TEST_F(ReducerTest, I32x4AddReduceOfDotI8x16SInUnrolledLoop) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr auto SplatKind = Simd128SplatOp::Kind::kI8x16;
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr auto AddKind = Simd128BinopOp::Kind::kI32x4Add;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {
+ 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15};
+
+ V<Simd128> left_input = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(16), SplatKind), "left_input");
+ V<Simd128> right_input = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(17), SplatKind), "right_input");
+ V<Simd128> initial_accumulator =
+ __ Simd128Splat(__ Word32Constant(0), Simd128SplatOp::Kind::kI32x4);
+
+ Block* loop = __ NewLoopHeader();
+ Block* done = __ NewBlock();
+ V<Word32> initial_iteration = __ Word32Constant(0);
+
+ __ Goto(loop);
+ __ Bind(loop);
+ OpIndex accumulator_phi = __ PendingLoopPhi(
+ initial_accumulator, RegisterRepresentation::Simd128());
+ OpIndex iteration_phi =
+ __ PendingLoopPhi(initial_iteration, RegisterRepresentation::Word32());
+
+ V<Simd128> left_shuffle =
+ __ Simd128Shuffle(left_input, left_input, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle =
+ __ Simd128Shuffle(right_input, right_input, ShuffleKind, shuffle_bytes);
+ V<Simd128> dot = Asm.Capture(
+ __ Simd128Binop(left_shuffle, right_shuffle, DotKind), "dot");
+
+ V<Simd128> next_accumulator =
+ __ Simd128Binop(V<Simd128>::Cast(accumulator_phi), dot, AddKind);
+ V<Word32> next_iteration = __ Word32Add(V<Word32>::Cast(iteration_phi), 1);
+ __ Branch(__ Word32Equal(next_iteration, 4), done, loop);
+
+ __ Bind(done);
+ V<Simd128> reduce = __ Simd128Reduce(
+ next_accumulator, Simd128ReduceOp::Kind::kI32x4AddReduce);
+ __ Return(
+ __ Simd128ExtractLane(reduce, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+
+ __ output_graph().template Replace<PhiOp>(
+ accumulator_phi,
+ base::VectorOf<OpIndex>({initial_accumulator, next_accumulator}),
+ RegisterRepresentation::Simd128());
+ __ output_graph().template Replace<PhiOp>(
+ iteration_phi,
+ base::VectorOf<OpIndex>({initial_iteration, next_iteration}),
+ RegisterRepresentation::Word32());
+ });
+
+ LoopUnrollingAnalyzer analyzer(test.zone(), &test.graph(), true);
+ ASSERT_TRUE(analyzer.CanUnrollAtLeastOneLoop());
+ test.graph().set_loop_unrolling_analyzer(&analyzer);
+ test.Run<LoopUnrollingReducer>();
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 1u);
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 0u);
+
+ const auto& dots = test.GetCapture("dot").generated_output;
+ ASSERT_FALSE(dots.empty());
+ for (OpIndex dot_index : dots) {
+ const Simd128BinopOp* dot =
+ test.graph().Get(dot_index).TryCast<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ EXPECT_FALSE(test.graph().Get(dot->left()).Is<Simd128ShuffleOp>());
+ EXPECT_FALSE(test.graph().Get(dot->right()).Is<Simd128ShuffleOp>());
+ EXPECT_TRUE(
+ test.GetCapture("left_input").generated_output.contains(dot->left()));
+ EXPECT_TRUE(
+ test.GetCapture("right_input").generated_output.contains(dot->right()));
+ }
+}
+
+TEST_F(ReducerTest, I32x4AddReduceOfDotI8x16SWithoutPhi) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr auto SplatKind = Simd128SplatOp::Kind::kI8x16;
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {
+ 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15};
+
+ V<Simd128> left_input = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(16), SplatKind), "left_input");
+ V<Simd128> right_input = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(17), SplatKind), "right_input");
+ V<Simd128> left_shuffle =
+ __ Simd128Shuffle(left_input, left_input, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle =
+ __ Simd128Shuffle(right_input, right_input, ShuffleKind, shuffle_bytes);
+ V<Simd128> dot = Asm.Capture(
+ __ Simd128Binop(left_shuffle, right_shuffle, DotKind), "dot");
+ V<Simd128> reduce =
+ __ Simd128Reduce(dot, Simd128ReduceOp::Kind::kI32x4AddReduce);
+ __ Return(
+ __ Simd128ExtractLane(reduce, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ });
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 1u);
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 0u);
+
+ const Simd128BinopOp* dot = test.GetCapture("dot").GetAs<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ EXPECT_FALSE(test.graph().Get(dot->left()).Is<Simd128ShuffleOp>());
+ EXPECT_FALSE(test.graph().Get(dot->right()).Is<Simd128ShuffleOp>());
+ EXPECT_TRUE(test.GetCapture("left_input").Is(dot->left()));
+ EXPECT_TRUE(test.GetCapture("right_input").Is(dot->right()));
+}
+
+TEST_F(ReducerTest, I32x4AddReduceOfDotI8x16SWithUnsafeShuffle) {
+ const RegisterRepresentation simd128 = RegisterRepresentation::Simd128();
+ std::array reps = {simd128, simd128};
+ auto test = CreateFromGraph(base::VectorOf(reps), [](auto& Asm) {
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 0, 0, 0, 0, 0, 0, 0, 0};
+
+ V<Simd128> left_input = Asm.template GetParameter<Simd128>(0);
+ V<Simd128> right_input = Asm.template GetParameter<Simd128>(1);
+ V<Simd128> left_shuffle = Asm.Capture(
+ __ Simd128Shuffle(left_input, left_input, ShuffleKind, shuffle_bytes),
+ "left_shuffle");
+ V<Simd128> right_shuffle = Asm.Capture(
+ __ Simd128Shuffle(right_input, right_input, ShuffleKind, shuffle_bytes),
+ "right_shuffle");
+ V<Simd128> dot = Asm.Capture(
+ __ Simd128Binop(left_shuffle, right_shuffle, DotKind), "dot");
+ V<Simd128> reduce =
+ __ Simd128Reduce(dot, Simd128ReduceOp::Kind::kI32x4AddReduce);
+ __ Return(
+ __ Simd128ExtractLane(reduce, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ });
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 1u);
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 2u);
+
+ const Simd128BinopOp* dot = test.GetCapture("dot").GetAs<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ EXPECT_TRUE(test.GetCapture("left_shuffle").Is(dot->left()));
+ EXPECT_TRUE(test.GetCapture("right_shuffle").Is(dot->right()));
+}
+
+TEST_F(ReducerTest, I32x4AddReduceOfTwoDotsWithoutPhi) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr auto SplatKind = Simd128SplatOp::Kind::kI8x16;
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr auto AddKind = Simd128BinopOp::Kind::kI32x4Add;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {
+ 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15};
+
+ V<Simd128> left_input0 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(16), SplatKind), "left_input0");
+ V<Simd128> right_input0 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(17), SplatKind), "right_input0");
+ V<Simd128> left_input1 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(18), SplatKind), "left_input1");
+ V<Simd128> right_input1 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(19), SplatKind), "right_input1");
+
+ V<Simd128> left_shuffle0 =
+ __ Simd128Shuffle(left_input0, left_input0, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle0 = __ Simd128Shuffle(right_input0, right_input0,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot0 = Asm.Capture(
+ __ Simd128Binop(left_shuffle0, right_shuffle0, DotKind), "dot0");
+
+ V<Simd128> left_shuffle1 =
+ __ Simd128Shuffle(left_input1, left_input1, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle1 = __ Simd128Shuffle(right_input1, right_input1,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot1 = Asm.Capture(
+ __ Simd128Binop(left_shuffle1, right_shuffle1, DotKind), "dot1");
+
+ V<Simd128> reduce =
+ __ Simd128Reduce(__ Simd128Binop(dot0, dot1, AddKind),
+ Simd128ReduceOp::Kind::kI32x4AddReduce);
+ __ Return(
+ __ Simd128ExtractLane(reduce, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ });
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 1u);
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 0u);
+
+ struct DotExpectation {
+ const char* dot;
+ const char* left;
+ const char* right;
+ };
+ for (const DotExpectation expectation :
+ {DotExpectation{"dot0", "left_input0", "right_input0"},
+ DotExpectation{"dot1", "left_input1", "right_input1"}}) {
+ const Simd128BinopOp* dot =
+ test.GetCapture(expectation.dot).GetAs<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ EXPECT_FALSE(test.graph().Get(dot->left()).Is<Simd128ShuffleOp>());
+ EXPECT_FALSE(test.graph().Get(dot->right()).Is<Simd128ShuffleOp>());
+ EXPECT_TRUE(test.GetCapture(expectation.left).Is(dot->left()));
+ EXPECT_TRUE(test.GetCapture(expectation.right).Is(dot->right()));
+ }
+}
+
+TEST_F(ReducerTest, I32x4AddReduceOfTwoDotsWithSideReduce) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr auto SplatKind = Simd128SplatOp::Kind::kI8x16;
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr auto AddKind = Simd128BinopOp::Kind::kI32x4Add;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {
+ 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15};
+
+ V<Simd128> left_input0 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(16), SplatKind), "left_input0");
+ V<Simd128> right_input0 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(17), SplatKind), "right_input0");
+ V<Simd128> left_input1 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(18), SplatKind), "left_input1");
+ V<Simd128> right_input1 = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(19), SplatKind), "right_input1");
+
+ V<Simd128> left_shuffle0 =
+ __ Simd128Shuffle(left_input0, left_input0, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle0 = __ Simd128Shuffle(right_input0, right_input0,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot0 = Asm.Capture(
+ __ Simd128Binop(left_shuffle0, right_shuffle0, DotKind), "dot0");
+
+ V<Simd128> left_shuffle1 =
+ __ Simd128Shuffle(left_input1, left_input1, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle1 = __ Simd128Shuffle(right_input1, right_input1,
+ ShuffleKind, shuffle_bytes);
+ V<Simd128> dot1 = Asm.Capture(
+ __ Simd128Binop(left_shuffle1, right_shuffle1, DotKind), "dot1");
+
+ V<Simd128> reduce0 =
+ __ Simd128Reduce(__ Simd128Binop(dot0, dot1, AddKind),
+ Simd128ReduceOp::Kind::kI32x4AddReduce);
+ V<Simd128> reduce1 =
+ __ Simd128Reduce(dot0, Simd128ReduceOp::Kind::kI32x4AddReduce);
+ V<Word32> extract0 = V<Word32>::Cast(
+ __ Simd128ExtractLane(reduce0, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ V<Word32> extract1 = V<Word32>::Cast(
+ __ Simd128ExtractLane(reduce1, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ __ Return(__ Word32Add(extract0, extract1));
+ });
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 2u);
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 0u);
+
+ struct DotExpectation {
+ const char* dot;
+ const char* left;
+ const char* right;
+ };
+ for (const DotExpectation expectation :
+ {DotExpectation{"dot0", "left_input0", "right_input0"},
+ DotExpectation{"dot1", "left_input1", "right_input1"}}) {
+ const Simd128BinopOp* dot =
+ test.GetCapture(expectation.dot).GetAs<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ EXPECT_FALSE(test.graph().Get(dot->left()).Is<Simd128ShuffleOp>());
+ EXPECT_FALSE(test.graph().Get(dot->right()).Is<Simd128ShuffleOp>());
+ EXPECT_TRUE(test.GetCapture(expectation.left).Is(dot->left()));
+ EXPECT_TRUE(test.GetCapture(expectation.right).Is(dot->right()));
+ }
+}
+
+TEST_F(ReducerTest, I32x4AddReduceOfSharedDotThroughTwoAdds) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr auto SplatKind = Simd128SplatOp::Kind::kI8x16;
+ constexpr auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ constexpr auto DotKind = Simd128BinopOp::Kind::kI32x4DotI8x16S;
+ constexpr auto AddKind = Simd128BinopOp::Kind::kI32x4Add;
+ constexpr uint8_t shuffle_bytes[kSimd128Size] = {
+ 0, 1, 8, 9, 2, 3, 10, 11, 4, 5, 12, 13, 6, 7, 14, 15};
+
+ V<Simd128> left_input = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(16), SplatKind), "left_input");
+ V<Simd128> right_input = Asm.Capture(
+ __ Simd128Splat(__ Word32Constant(17), SplatKind), "right_input");
+ V<Simd128> acc0 =
+ __ Simd128Splat(__ Word32Constant(18), Simd128SplatOp::Kind::kI32x4);
+ V<Simd128> acc1 =
+ __ Simd128Splat(__ Word32Constant(19), Simd128SplatOp::Kind::kI32x4);
+
+ V<Simd128> left_shuffle =
+ __ Simd128Shuffle(left_input, left_input, ShuffleKind, shuffle_bytes);
+ V<Simd128> right_shuffle =
+ __ Simd128Shuffle(right_input, right_input, ShuffleKind, shuffle_bytes);
+ V<Simd128> dot = Asm.Capture(
+ __ Simd128Binop(left_shuffle, right_shuffle, DotKind), "dot");
+
+ V<Simd128> reduce0 =
+ __ Simd128Reduce(__ Simd128Binop(dot, acc0, AddKind),
+ Simd128ReduceOp::Kind::kI32x4AddReduce);
+ V<Simd128> reduce1 =
+ __ Simd128Reduce(__ Simd128Binop(dot, acc1, AddKind),
+ Simd128ReduceOp::Kind::kI32x4AddReduce);
+ V<Word32> extract0 = V<Word32>::Cast(
+ __ Simd128ExtractLane(reduce0, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ V<Word32> extract1 = V<Word32>::Cast(
+ __ Simd128ExtractLane(reduce1, Simd128ExtractLaneOp::Kind::kI32x4, 0));
+ __ Return(__ Word32Add(extract0, extract1));
+ });
+
+ test.Run<WasmShuffleReducer>();
+ test.Run<DeadCodeEliminationReducer>();
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Reduce), 2u);
+ // The Dot is used by two Adds and our current checks only directly test for
+ // other AddReduce users so the analysis can't prove the legality.
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 2u);
+
+ const Simd128BinopOp* dot = test.GetCapture("dot").GetAs<Simd128BinopOp>();
+ ASSERT_TRUE(dot);
+ EXPECT_EQ(dot->kind, Simd128BinopOp::Kind::kI32x4DotI8x16S);
+ const Simd128ShuffleOp* left_shuffle =
+ test.graph().Get(dot->left()).TryCast<Simd128ShuffleOp>();
+ const Simd128ShuffleOp* right_shuffle =
+ test.graph().Get(dot->right()).TryCast<Simd128ShuffleOp>();
+ ASSERT_TRUE(left_shuffle);
+ ASSERT_TRUE(right_shuffle);
+ EXPECT_TRUE(test.GetCapture("left_input").Is(left_shuffle->left()));
+ EXPECT_TRUE(test.GetCapture("right_input").Is(right_shuffle->left()));
+}
+
namespace {
auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
constexpr uint8_t shuffle_bytes_even[kSimd128Size] = {
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 408536e7b47..c6e3dd24e27 100644
--- a/deps/v8/test/unittests/compiler/turboshaft/wasm-simd-unittest.cc
+++ b/deps/v8/test/unittests/compiler/turboshaft/wasm-simd-unittest.cc
@@ -11,6 +11,7 @@
#include "src/compiler/turboshaft/operations.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/compiler/turboshaft/required-optimization-reducer.h"
+#include "src/compiler/turboshaft/value-numbering-reducer.h"
#include "src/compiler/turboshaft/wasm-shuffle-reducer.h"
#include "test/common/flag-utils.h"
#include "test/unittests/compiler/turboshaft/reducer-test.h"
@@ -513,6 +514,80 @@ TEST_F(WasmSimdTest, FailureCaseMixedInputsI32x4AddReduce) {
#endif
}
+// GVN has to see through the member arrays of {Simd128ConstantOp},
+// {Simd128ShuffleOp} and {Simd256ConstantOp}.
+
+TEST_F(WasmSimdTest, Simd128ConstantValueNumbering) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr uint8_t kValue[kSimd128Size] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16};
+ V<Simd128> a = __ Simd128Constant(kValue);
+ V<Simd128> b = __ Simd128Constant(kValue);
+ __ Return(__ Simd128Binop(a, b, Simd128BinopOp::Kind::kS128Xor));
+ });
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Constant), 2u);
+ test.Run<ValueNumberingReducer>();
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Constant), 1u);
+}
+
+// Counterpart to the test above: distinct constants must not collapse.
+TEST_F(WasmSimdTest, Simd128ConstantValueNumberingDistinctValues) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr uint8_t kValue[kSimd128Size] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 16};
+ // Differs from {kValue} in the last byte only.
+ constexpr uint8_t kOther[kSimd128Size] = {1, 2, 3, 4, 5, 6, 7, 8,
+ 9, 10, 11, 12, 13, 14, 15, 17};
+ V<Simd128> a = __ Simd128Constant(kValue);
+ V<Simd128> b = __ Simd128Constant(kOther);
+ __ Return(__ Simd128Binop(a, b, Simd128BinopOp::Kind::kS128Xor));
+ });
+
+ test.Run<ValueNumberingReducer>();
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Constant), 2u);
+}
+
+TEST_F(WasmSimdTest, Simd128ShuffleValueNumbering) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr uint8_t kShuffle[kSimd128Size] = {0, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15};
+ // Differs in the first byte, which selects from the second operand.
+ constexpr uint8_t kOther[kSimd128Size] = {16, 1, 2, 3, 4, 5, 6, 7,
+ 8, 9, 10, 11, 12, 13, 14, 15};
+ auto ShuffleKind = Simd128ShuffleOp::Kind::kI8x16;
+ V<Simd128> input =
+ __ Simd128Splat(__ Float32Constant(1.0), Simd128SplatOp::Kind::kF32x4);
+ V<Simd128> a = __ Simd128Shuffle(input, input, ShuffleKind, kShuffle);
+ V<Simd128> b = __ Simd128Shuffle(input, input, ShuffleKind, kShuffle);
+ V<Simd128> c = __ Simd128Shuffle(input, input, ShuffleKind, kOther);
+ V<Simd128> ab = __ Simd128Binop(a, b, Simd128BinopOp::Kind::kS128Xor);
+ __ Return(__ Simd128Binop(ab, c, Simd128BinopOp::Kind::kS128Xor));
+ });
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 3u);
+ test.Run<ValueNumberingReducer>();
+ // {a} and {b} collapse; {c} has a different shuffle and stays.
+ ASSERT_EQ(test.CountOp(Opcode::kSimd128Shuffle), 2u);
+}
+
+#ifdef V8_ENABLE_WASM_SIMD256_REVEC
+TEST_F(WasmSimdTest, Simd256ConstantValueNumbering) {
+ auto test = CreateFromGraph(1, [](auto& Asm) {
+ constexpr uint8_t kValue[kSimd256Size] = {
+ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
+ 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32};
+ V<Simd256> a = __ Simd256Constant(kValue);
+ V<Simd256> b = __ Simd256Constant(kValue);
+ __ Return(__ Simd256Binop(a, b, Simd256BinopOp::Kind::kS256Xor));
+ });
+
+ ASSERT_EQ(test.CountOp(Opcode::kSimd256Constant), 2u);
+ test.Run<ValueNumberingReducer>();
+ ASSERT_EQ(test.CountOp(Opcode::kSimd256Constant), 1u);
+}
+#endif // V8_ENABLE_WASM_SIMD256_REVEC
+
#include "src/compiler/turboshaft/undef-assembler-macros.inc"
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/compiler/types-unittest.cc b/deps/v8/test/unittests/compiler/types-unittest.cc
index 8f45448b670..e5785916a84 100644
--- a/deps/v8/test/unittests/compiler/types-unittest.cc
+++ b/deps/v8/test/unittests/compiler/types-unittest.cc
@@ -8,6 +8,7 @@
#include "src/compiler/turbofan-types.h"
#include "src/execution/isolate.h"
#include "src/heap/factory-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects.h"
#include "test/common/types-fuzz.h"
#include "test/unittests/test-utils.h"
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 e278163927b..8560d6f2b74 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
@@ -9,6 +9,7 @@
#include "src/compiler/backend/instruction-codes.h"
#include "src/compiler/turboshaft/representations.h"
#include "src/objects/objects-inl.h"
+#include "test/common/flag-utils.h"
#include "test/unittests/compiler/backend/turboshaft-instruction-selector-unittest.h"
#if V8_ENABLE_WEBASSEMBLY
@@ -2289,6 +2290,245 @@ INSTANTIATE_TEST_SUITE_P(TurboshaftInstructionSelectorTest,
TurboshaftInstructionSelectorAddSub128Test,
::testing::ValuesIn(kAddOrSub128));
+// -----------------------------------------------------------------------------
+// CCMP branch-cascade fusion.
+
+namespace {
+// Returns the fused cascade instruction, or nullptr if the cascade was not
+// fused. The fused instruction is the one with a conditional-branch flags-mode.
+const Instruction* FindFusedCcmpBranch(
+ const TurboshaftInstructionSelectorTest::Stream& s) {
+ const Instruction* found = nullptr;
+ for (size_t i = 0; i < s.size(); ++i) {
+ if (s[i]->flags_mode() == kFlags_conditional_branch) {
+ EXPECT_EQ(nullptr, found);
+ found = s[i];
+ }
+ }
+ return found;
+}
+} // namespace
+
+TEST_F(TurboshaftInstructionSelectorTest, CcmpBranchCascadeEligible) {
+#ifdef V8_ENABLE_APX_F
+ FlagScope<bool> ccmp(&v8_flags.enable_apx_f_ccmp, true);
+ CpuFeatures::SetSupported(APX_F);
+#endif
+ if (!UseApxCcmp()) return;
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ const Instruction* ccmp_insn = FindFusedCcmpBranch(s);
+ ASSERT_NE(nullptr, ccmp_insn);
+ EXPECT_EQ(kX64Cmp32, ccmp_insn->arch_opcode());
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex shared = m.Parameter(1);
+ Block *t1 = m.NewBlock(), *t2 = m.NewBlock(), *b = m.NewBlock();
+ Block *merge = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(3)), t1, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(4)), t2, f);
+ m.Bind(t1);
+ m.Goto(merge);
+ m.Bind(t2);
+ m.Goto(merge);
+ m.Bind(merge);
+ OpIndex phi = m.Phi(MachineRepresentation::kWord32, shared, shared);
+ m.Return(phi);
+ m.Bind(f);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ EXPECT_NE(nullptr, FindFusedCcmpBranch(s));
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(100)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_NE(nullptr, FindFusedCcmpBranch(s));
+ }
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, CcmpBranchCascadeIneligible) {
+#ifdef V8_ENABLE_APX_F
+ FlagScope<bool> ccmp(&v8_flags.enable_apx_f_ccmp, true);
+ CpuFeatures::SetSupported(APX_F);
+#endif
+ if (!UseApxCcmp()) return;
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex y = m.Parameter(1);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(y, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "different variables";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Int32LessThan(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "non-equality compare";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int64());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word64Equal(x, m.Int64Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word64Equal(x, m.Int64Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "word64 representation";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ V<Word32> cond_a = m.Word32Equal(x, m.Int32Constant(1));
+ m.Branch(cond_a, t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(cond_a);
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "head compare has extra use";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex y = m.Parameter(1);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, y), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s))
+ << "fused rhs is not an immediate";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *t1 = m.NewBlock(), *t2 = m.NewBlock(), *b = m.NewBlock();
+ Block* f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t1, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t2, f);
+ m.Bind(t1);
+ m.Return(m.Int32Constant(11));
+ m.Bind(t2);
+ m.Return(m.Int32Constant(33));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "true edges do not merge";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ OpIndex v1 = m.Parameter(1);
+ OpIndex v2 = m.Parameter(2);
+ Block *t1 = m.NewBlock(), *t2 = m.NewBlock(), *b = m.NewBlock();
+ Block *merge = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t1, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t2, f);
+ m.Bind(t1);
+ m.Goto(merge);
+ m.Bind(t2);
+ m.Goto(merge);
+ m.Bind(merge);
+ OpIndex phi = m.Phi(MachineRepresentation::kWord32, v1, v2);
+ m.Return(phi);
+ m.Bind(f);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "merge phi inputs differ";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32());
+ OpIndex x = m.Parameter(0);
+ Block *head = m.NewBlock(), *t = m.NewBlock(), *b = m.NewBlock();
+ Block* f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(5)), head, b);
+ m.Bind(head);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s))
+ << "fused block has multiple predecessors";
+ }
+ {
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Int32(),
+ MachineType::Pointer());
+ OpIndex x = m.Parameter(0);
+ OpIndex mem = m.Parameter(1);
+ Block *t = m.NewBlock(), *b = m.NewBlock(), *f = m.NewBlock();
+ m.Branch(m.Word32Equal(x, m.Int32Constant(1)), t, b);
+ m.Bind(b);
+ m.Store(MachineRepresentation::kWord32, mem, m.Int32Constant(0), x,
+ WriteBarrierKind::kNoWriteBarrier);
+ m.Branch(m.Word32Equal(x, m.Int32Constant(2)), t, f);
+ m.Bind(t);
+ m.Return(m.Int32Constant(11));
+ m.Bind(f);
+ m.Return(m.Int32Constant(22));
+ Stream s = m.Build();
+ EXPECT_EQ(nullptr, FindFusedCcmpBranch(s)) << "side effect in fused block";
+ }
+}
+
#if V8_ENABLE_WEBASSEMBLY
// -----------------------------------------------------------------------------
// SIMD.
@@ -2744,6 +2984,171 @@ TEST_F(TurboshaftInstructionSelectorTest, SIMDF32x4SConvert) {
EXPECT_EQ(1U, s[2]->OutputCount());
}
+#ifdef V8_ENABLE_AVX10_1
+TEST_F(TurboshaftInstructionSelectorTest, I64x2MulAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128(),
+ MachineType::Simd128());
+ V<Simd128> lhs = m.Parameter<Simd128>(0);
+ V<Simd128> rhs = m.Parameter<Simd128>(1);
+ m.Return(m.I64x2Mul(lhs, rhs));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64IMul, s[0]->arch_opcode());
+ EXPECT_EQ(LaneSize::kL64, LaneSizeField::decode(s[0]->opcode()));
+ EXPECT_EQ(VectorLength::kV128, VectorLengthField::decode(s[0]->opcode()));
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(0))->IsUsedAtStart());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(1))->IsUsedAtStart());
+}
+
+#ifdef V8_ENABLE_SIMD256
+TEST_F(TurboshaftInstructionSelectorTest, I64x4MulAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd256(), MachineType::Simd256(),
+ MachineType::Simd256());
+ V<Simd256> lhs = m.Parameter<Simd256>(0);
+ V<Simd256> rhs = m.Parameter<Simd256>(1);
+ m.Return(m.Simd256Binop(lhs, rhs, Simd256BinopOp::Kind::kI64x4Mul));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64IMul, s[0]->arch_opcode());
+ EXPECT_EQ(LaneSize::kL64, LaneSizeField::decode(s[0]->opcode()));
+ EXPECT_EQ(VectorLength::kV256, VectorLengthField::decode(s[0]->opcode()));
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(0))->IsUsedAtStart());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(1))->IsUsedAtStart());
+}
+#endif // V8_ENABLE_SIMD256
+
+TEST_F(TurboshaftInstructionSelectorTest, I64x2ShrSAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128(),
+ MachineType::Int32());
+ V<Simd128> input = m.Parameter<Simd128>(0);
+ V<Word32> shift = m.Parameter<Word32>(1);
+ m.Return(m.I64x2ShrS(input, shift));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64IShrS, s[0]->arch_opcode());
+ EXPECT_EQ(LaneSize::kL64, LaneSizeField::decode(s[0]->opcode()));
+ EXPECT_EQ(VectorLength::kV128, VectorLengthField::decode(s[0]->opcode()));
+ EXPECT_EQ(2U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(0))->IsUsedAtStart());
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, I8x16PopcntAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
+ V<Simd128> input = m.Parameter<Simd128>(0);
+ m.Return(m.I8x16Popcnt(input));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64I8x16Popcnt, s[0]->arch_opcode());
+ EXPECT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(0))->IsUsedAtStart());
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, I64x2AbsAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128());
+ V<Simd128> input = m.Parameter<Simd128>(0);
+ m.Return(m.I64x2Abs(input));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64IAbs, s[0]->arch_opcode());
+ EXPECT_EQ(LaneSize::kL64, LaneSizeField::decode(s[0]->opcode()));
+ EXPECT_EQ(VectorLength::kV128, VectorLengthField::decode(s[0]->opcode()));
+ EXPECT_EQ(1U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->InputAt(0))->IsUsedAtStart());
+}
+
+TEST_F(TurboshaftInstructionSelectorTest, S128SelectAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd128(), MachineType::Simd128(),
+ MachineType::Simd128(), MachineType::Simd128());
+ V<Simd128> mask = m.Parameter<Simd128>(0);
+ V<Simd128> a = m.Parameter<Simd128>(1);
+ V<Simd128> b = m.Parameter<Simd128>(2);
+ m.Return(m.S128Select(mask, a, b));
+ // Build with AVX enabled: without AVX10.1 the AVX path uses DefineAsRegister
+ // (dst != mask), so this is the configuration where pinning dst to the mask
+ // is an observable AVX10.1-specific choice.
+ Stream s = m.Build(AVX);
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64SSelect, s[0]->arch_opcode());
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ // vpternlogd needs dst == mask: the output is tied to input 0.
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+}
+
+#ifdef V8_ENABLE_SIMD256
+TEST_F(TurboshaftInstructionSelectorTest, S256SelectAVX10_1) {
+ if (!UseAvx10_1()) return;
+
+ StreamBuilder m(this, MachineType::Simd256(), MachineType::Simd256(),
+ MachineType::Simd256(), MachineType::Simd256());
+ V<Simd256> mask = m.Parameter<Simd256>(0);
+ V<Simd256> a = m.Parameter<Simd256>(1);
+ V<Simd256> b = m.Parameter<Simd256>(2);
+ m.Return(m.Simd256Ternary(mask, a, b, Simd256TernaryOp::Kind::kS256Select));
+ Stream s = m.Build();
+
+ ASSERT_EQ(1U, s.size());
+ EXPECT_EQ(kX64SSelect, s[0]->arch_opcode());
+ EXPECT_EQ(VectorLength::kV256, VectorLengthField::decode(s[0]->opcode()));
+ EXPECT_EQ(3U, s[0]->InputCount());
+ EXPECT_EQ(1U, s[0]->OutputCount());
+ EXPECT_EQ(0U, s[0]->TempCount());
+ // vpternlogd needs dst == mask: the output is tied to input 0.
+ EXPECT_TRUE(UnallocatedOperand::cast(s[0]->Output())->HasSameAsInputPolicy());
+}
+
+#endif // V8_ENABLE_SIMD256
+#endif // V8_ENABLE_AVX10_1
+
#endif // V8_ENABLE_WEBASSEMBLY
+TEST_F(TurboshaftInstructionSelectorTest, AtomicStoreWithWriteBarrier) {
+ if (v8_flags.disable_write_barriers) return;
+ StreamBuilder m(this, MachineType::Int32(), MachineType::Pointer(),
+ MachineType::Pointer(), MachineType::AnyTagged());
+ m.Store(m.Parameter(0), m.Parameter(1), m.Parameter(2),
+ StoreOp::Kind::Aligned(BaseTaggedness::kTaggedBase).Atomic(),
+ MemoryRepresentation::TaggedPointer(),
+ WriteBarrierKind::kFullWriteBarrier, AtomicMemoryOrder::kSeqCst);
+ m.Return(m.Int32Constant(0));
+ Stream s = m.Build(kAllExceptNopInstructions);
+ ASSERT_EQ(2U, s.size());
+ EXPECT_EQ(kArchAtomicStoreWithWriteBarrier, s[0]->arch_opcode());
+ EXPECT_EQ(AtomicMemoryOrderField::decode(s[0]->opcode()),
+ AtomicMemoryOrder::kSeqCst);
+ EXPECT_EQ(AtomicStoreRecordWriteModeField::decode(s[0]->opcode()),
+ RecordWriteMode::kValueIsAny);
+}
+
} // namespace v8::internal::compiler::turboshaft
diff --git a/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc b/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc
new file mode 100644
index 00000000000..c8d3b10a17a
--- /dev/null
+++ b/deps/v8/test/unittests/debug/debug-scope-info-unittest.cc
@@ -0,0 +1,1335 @@
+// 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-scope-info.h"
+
+#include <iterator>
+
+#include "include/v8-function.h"
+#include "src/api/api-inl.h"
+#include "src/ast/scopes.h"
+#include "src/debug/debug-interface.h"
+#include "src/debug/debug.h"
+#include "src/execution/isolate-inl.h"
+#include "src/heap/factory.h"
+#include "src/objects/debug-objects-inl.h"
+#include "src/objects/scope-info.h"
+#include "src/parsing/parse-info.h"
+#include "src/parsing/parsing.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8 {
+namespace internal {
+
+class DebugScopeInfoTest : public TestWithNativeContext {
+ public:
+ struct ParsedScript {
+ std::unique_ptr<UnoptimizedCompileState> compile_state;
+ std::unique_ptr<ReusableUnoptimizedCompileState> reusable_state;
+ std::unique_ptr<ParseInfo> info;
+ Handle<DebugScriptScopeInfo> scope_info;
+
+ DeclarationScope* script_scope() const { return info->literal()->scope(); }
+ };
+
+ ParsedScript ParseAndSerialize(const char* source) {
+ ParsedScript result;
+ result.compile_state = std::make_unique<UnoptimizedCompileState>();
+ result.reusable_state =
+ std::make_unique<ReusableUnoptimizedCompileState>(isolate());
+ Handle<String> source_str =
+ isolate()->factory()->NewStringFromAsciiChecked(source);
+ Handle<Script> script = isolate()->factory()->NewScript(source_str);
+ UnoptimizedCompileFlags flags =
+ UnoptimizedCompileFlags::ForScriptCompile(isolate(), *script)
+ .set_is_eager(true);
+ result.info = std::make_unique<ParseInfo>(isolate(), flags,
+ result.compile_state.get(),
+ result.reusable_state.get());
+ CHECK(parsing::ParseProgram(result.info.get(), script, isolate(),
+ parsing::ReportStatisticsMode{false}));
+ result.scope_info = SerializeDebugScriptScopeInfo(
+ isolate(), result.info->literal()->scope());
+ return result;
+ }
+};
+
+namespace {
+
+void VerifyScopeTreeParity(Scope* ast_scope, DebugScriptScope debug_scope) {
+ EXPECT_EQ(ast_scope->start_position(), debug_scope.start_position());
+ EXPECT_EQ(ast_scope->end_position(), debug_scope.end_position());
+ EXPECT_EQ(ast_scope->scope_type(), debug_scope.scope_type());
+ EXPECT_EQ(ast_scope->is_script_scope(), debug_scope.is_script_scope());
+ EXPECT_EQ(ast_scope->is_function_scope(), debug_scope.is_function_scope());
+ EXPECT_EQ(ast_scope->is_block_scope(), debug_scope.is_block_scope());
+ EXPECT_EQ(ast_scope->is_declaration_scope(),
+ debug_scope.is_declaration_scope());
+ EXPECT_EQ(ast_scope->is_class_scope(), debug_scope.is_class_scope());
+ EXPECT_EQ(ast_scope->is_with_scope(), debug_scope.is_with_scope());
+ EXPECT_EQ(ast_scope->is_module_scope(), debug_scope.is_module_scope());
+ EXPECT_EQ(ast_scope->is_eval_scope(), debug_scope.is_eval_scope());
+ EXPECT_EQ(ast_scope->is_catch_scope(), debug_scope.is_catch_scope());
+ EXPECT_EQ(ast_scope->is_repl_mode_scope(), debug_scope.is_repl_mode_scope());
+ EXPECT_EQ(ast_scope->is_hidden(), debug_scope.is_hidden());
+ EXPECT_EQ(ast_scope->language_mode(), debug_scope.language_mode());
+ EXPECT_EQ(ast_scope->HasThisReference(), debug_scope.has_this_reference());
+ EXPECT_EQ(ast_scope->NeedsContext(), debug_scope.needs_context());
+ if (ast_scope->NeedsContext()) {
+ EXPECT_EQ(ast_scope->UniqueIdInScript(), debug_scope.unique_id_in_script());
+ } else {
+ EXPECT_EQ(-3, debug_scope.unique_id_in_script());
+ }
+ if (ast_scope->is_declaration_scope()) {
+ DeclarationScope* decl = ast_scope->AsDeclarationScope();
+ EXPECT_EQ(decl->is_arrow_scope(), debug_scope.is_arrow_scope());
+ EXPECT_EQ(decl->has_this_declaration(), debug_scope.has_this_declaration());
+ EXPECT_EQ(decl->has_simple_parameters(),
+ debug_scope.has_simple_parameters());
+ EXPECT_EQ(decl->sloppy_eval_can_extend_vars(),
+ debug_scope.sloppy_eval_can_extend_vars());
+ if (decl->has_this_declaration()) {
+ Variable* var = decl->receiver();
+ VariableAllocationInfo expected_info =
+ var->location() == VariableLocation::CONTEXT
+ ? VariableAllocationInfo::CONTEXT
+ : VariableAllocationInfo::STACK;
+ EXPECT_EQ(debug_scope.receiver_info(),
+ (std::pair{expected_info, var->index()}));
+ }
+ if (decl->arguments() != nullptr) {
+ EXPECT_TRUE(debug_scope.has_arguments());
+ Variable* var = decl->arguments();
+ VariableAllocationInfo expected_info =
+ var->location() == VariableLocation::CONTEXT
+ ? VariableAllocationInfo::CONTEXT
+ : VariableAllocationInfo::STACK;
+ EXPECT_EQ(debug_scope.arguments_info(),
+ (std::pair{expected_info, var->index()}));
+ } else {
+ EXPECT_FALSE(debug_scope.has_arguments());
+ EXPECT_EQ(debug_scope.arguments_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ }
+ if (decl->function_var() != nullptr) {
+ EXPECT_TRUE(debug_scope.has_function_variable());
+ Variable* var = decl->function_var();
+ VariableAllocationInfo expected_info =
+ var->location() == VariableLocation::CONTEXT
+ ? VariableAllocationInfo::CONTEXT
+ : VariableAllocationInfo::STACK;
+ EXPECT_EQ(debug_scope.function_variable_info(),
+ (std::pair{expected_info, var->index()}));
+ EXPECT_TRUE(debug_scope.function_variable_name()->Equals(*var->name()));
+ } else {
+ EXPECT_FALSE(debug_scope.has_function_variable());
+ EXPECT_EQ(debug_scope.function_variable_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ EXPECT_TRUE(debug_scope.function_variable_name().is_null());
+ }
+ } else {
+ EXPECT_FALSE(debug_scope.is_arrow_scope());
+ EXPECT_FALSE(debug_scope.has_this_declaration());
+ EXPECT_FALSE(debug_scope.has_simple_parameters());
+ EXPECT_FALSE(debug_scope.has_arguments());
+ EXPECT_FALSE(debug_scope.has_function_variable());
+ EXPECT_FALSE(debug_scope.sloppy_eval_can_extend_vars());
+ EXPECT_EQ(debug_scope.receiver_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ EXPECT_EQ(debug_scope.arguments_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ EXPECT_EQ(debug_scope.function_variable_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ EXPECT_TRUE(debug_scope.function_variable_name().is_null());
+ }
+
+ int ast_var_count = base::checked_cast<int>(
+ std::distance(ast_scope->locals()->begin(), ast_scope->locals()->end()));
+ EXPECT_EQ(ast_var_count, debug_scope.variable_count());
+
+ int var_idx = 0;
+ for (Variable* ast_var : *ast_scope->locals()) {
+ DebugVariableInfo debug_var = debug_scope.variable(var_idx++);
+ EXPECT_EQ(ast_var->location(), debug_var.location);
+ EXPECT_EQ(ast_var->mode(), debug_var.mode);
+ EXPECT_EQ(ast_var->index(), debug_var.index);
+ EXPECT_EQ(ast_var->initializer_position(), debug_var.initializer_position);
+ const AstRawString* raw = ast_var->raw_name();
+ // Keep in sync with ScopeInfo::VariableIsSynthetic() in
+ // src/objects/scope-info.cc.
+ bool expected_synthetic =
+ raw != nullptr &&
+ (raw->IsEmpty() || raw->FirstCharacter() == '.' ||
+ raw->IsPrivateName() || raw->IsOneByteEqualTo("this"));
+ EXPECT_EQ(expected_synthetic, debug_var.is_synthetic);
+ // Keep in sync with Variable::IsReceiver() in src/ast/variables.h.
+ bool expected_receiver = ast_var->IsParameter() && ast_var->IsReceiver();
+ EXPECT_EQ(expected_receiver, debug_var.is_receiver);
+ if (raw != nullptr) {
+ ASSERT_FALSE(debug_var.name.is_null());
+ EXPECT_TRUE(debug_var.name->Equals(*ast_var->name()));
+ } else {
+ EXPECT_TRUE(debug_var.name.is_null());
+ }
+ }
+
+ Scope* ast_child = ast_scope->inner_scope();
+ auto debug_child = debug_scope.first_child();
+
+ while (ast_child != nullptr) {
+ ASSERT_TRUE(debug_child.has_value());
+ EXPECT_TRUE(debug_child->parent().has_value());
+ EXPECT_EQ(debug_child->parent()->scope_index(), debug_scope.scope_index());
+ VerifyScopeTreeParity(ast_child, *debug_child);
+ ast_child = ast_child->sibling();
+ debug_child = debug_child->next_sibling();
+ }
+ EXPECT_FALSE(debug_child.has_value());
+}
+
+} // namespace
+
+TEST_F(DebugScopeInfoTest, EmptyScript) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope root = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(root.scope_index(), 0);
+ EXPECT_EQ(root.start_position(), 0);
+ EXPECT_EQ(root.end_position(), 0);
+ EXPECT_EQ(root.scope_type(), ScopeType::SCRIPT_SCOPE);
+ EXPECT_TRUE(root.is_script_scope());
+ EXPECT_FALSE(root.is_function_scope());
+ EXPECT_FALSE(root.is_block_scope());
+ EXPECT_TRUE(root.is_declaration_scope());
+ EXPECT_FALSE(root.parent().has_value());
+ EXPECT_FALSE(root.first_child().has_value());
+ EXPECT_FALSE(root.next_sibling().has_value());
+
+ VerifyScopeTreeParity(parsed.script_scope(), root);
+}
+
+TEST_F(DebugScopeInfoTest, SingleScriptScope) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("let x = 1;");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope root = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(root.scope_index(), 0);
+ EXPECT_EQ(root.start_position(), 0);
+ EXPECT_EQ(root.end_position(), 10);
+ EXPECT_EQ(root.scope_type(), ScopeType::SCRIPT_SCOPE);
+ EXPECT_TRUE(root.is_script_scope());
+ EXPECT_FALSE(root.is_function_scope());
+ EXPECT_FALSE(root.is_block_scope());
+ EXPECT_TRUE(root.is_declaration_scope());
+ EXPECT_FALSE(root.parent().has_value());
+ EXPECT_FALSE(root.first_child().has_value());
+ EXPECT_FALSE(root.next_sibling().has_value());
+
+ VerifyScopeTreeParity(parsed.script_scope(), root);
+}
+
+TEST_F(DebugScopeInfoTest, NestedBlockScopes) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("{ let a = 1; } { let b = 2; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ // Script scope (0)
+ DebugScriptScope s0 = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(s0.scope_index(), 0);
+ EXPECT_EQ(s0.start_position(), 0);
+ EXPECT_EQ(s0.end_position(), 29);
+ EXPECT_EQ(s0.scope_type(), ScopeType::SCRIPT_SCOPE);
+ EXPECT_TRUE(s0.is_script_scope());
+ EXPECT_FALSE(s0.is_block_scope());
+ EXPECT_FALSE(s0.parent().has_value());
+ EXPECT_FALSE(s0.next_sibling().has_value());
+ ASSERT_TRUE(s0.first_child().has_value());
+ EXPECT_EQ(s0.first_child()->scope_index(), 1);
+
+ // Block 2 scope (1)
+ DebugScriptScope s1 = DebugScriptScope::FromIndex(info, 1);
+ EXPECT_EQ(s1.scope_index(), 1);
+ EXPECT_EQ(s1.start_position(), 15);
+ EXPECT_EQ(s1.end_position(), 29);
+ EXPECT_EQ(s1.scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(s1.is_block_scope());
+ EXPECT_FALSE(s1.is_script_scope());
+ ASSERT_TRUE(s1.parent().has_value());
+ EXPECT_EQ(s1.parent()->scope_index(), 0);
+ EXPECT_FALSE(s1.first_child().has_value());
+ ASSERT_TRUE(s1.next_sibling().has_value());
+ EXPECT_EQ(s1.next_sibling()->scope_index(), 2);
+
+ // Block 1 scope (2)
+ DebugScriptScope s2 = DebugScriptScope::FromIndex(info, 2);
+ EXPECT_EQ(s2.scope_index(), 2);
+ EXPECT_EQ(s2.start_position(), 0);
+ EXPECT_EQ(s2.end_position(), 14);
+ EXPECT_EQ(s2.scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(s2.is_block_scope());
+ EXPECT_FALSE(s2.is_script_scope());
+ ASSERT_TRUE(s2.parent().has_value());
+ EXPECT_EQ(s2.parent()->scope_index(), 0);
+ EXPECT_FALSE(s2.first_child().has_value());
+ EXPECT_FALSE(s2.next_sibling().has_value());
+
+ VerifyScopeTreeParity(parsed.script_scope(), s0);
+}
+
+TEST_F(DebugScopeInfoTest, NestedFunctionScopes) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("function foo() { { let x = 1; } }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ // Script scope (0)
+ DebugScriptScope s0 = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(s0.scope_index(), 0);
+ EXPECT_EQ(s0.start_position(), 0);
+ EXPECT_EQ(s0.end_position(), 33);
+ EXPECT_EQ(s0.scope_type(), ScopeType::SCRIPT_SCOPE);
+ EXPECT_TRUE(s0.is_script_scope());
+ EXPECT_FALSE(s0.parent().has_value());
+ EXPECT_FALSE(s0.next_sibling().has_value());
+ ASSERT_TRUE(s0.first_child().has_value());
+ EXPECT_EQ(s0.first_child()->scope_index(), 1);
+
+ // Function foo scope (1)
+ DebugScriptScope s1 = DebugScriptScope::FromIndex(info, 1);
+ EXPECT_EQ(s1.scope_index(), 1);
+ EXPECT_EQ(s1.start_position(), 12);
+ EXPECT_EQ(s1.end_position(), 33);
+ EXPECT_EQ(s1.scope_type(), ScopeType::FUNCTION_SCOPE);
+ EXPECT_TRUE(s1.is_function_scope());
+ EXPECT_TRUE(s1.is_declaration_scope());
+ ASSERT_TRUE(s1.parent().has_value());
+ EXPECT_EQ(s1.parent()->scope_index(), 0);
+ EXPECT_FALSE(s1.next_sibling().has_value());
+ ASSERT_TRUE(s1.first_child().has_value());
+ EXPECT_EQ(s1.first_child()->scope_index(), 2);
+
+ // Inner block scope (2)
+ DebugScriptScope s2 = DebugScriptScope::FromIndex(info, 2);
+ EXPECT_EQ(s2.scope_index(), 2);
+ EXPECT_EQ(s2.start_position(), 17);
+ EXPECT_EQ(s2.end_position(), 31);
+ EXPECT_EQ(s2.scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(s2.is_block_scope());
+ EXPECT_FALSE(s2.is_declaration_scope());
+ ASSERT_TRUE(s2.parent().has_value());
+ EXPECT_EQ(s2.parent()->scope_index(), 1);
+ EXPECT_FALSE(s2.first_child().has_value());
+ EXPECT_FALSE(s2.next_sibling().has_value());
+
+ VerifyScopeTreeParity(parsed.script_scope(), s0);
+}
+
+TEST_F(DebugScopeInfoTest, DeeplyNestedScopes) {
+ HandleScope scope(isolate());
+ // Scopes: 0 = Script, 1 = Function outer, 2 = Block 1, 3 = Block 2
+ ParsedScript parsed = ParseAndSerialize(
+ "function outer() { { let a = 1; { let nested = 42; } } }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(script.scope_type(), ScopeType::SCRIPT_SCOPE);
+ EXPECT_FALSE(script.parent().has_value());
+
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+ EXPECT_EQ(func->scope_index(), 1);
+ EXPECT_EQ(func->scope_type(), ScopeType::FUNCTION_SCOPE);
+ EXPECT_TRUE(func->parent().has_value());
+ EXPECT_EQ(func->parent()->scope_index(), 0);
+
+ auto block1 = func->first_child();
+ ASSERT_TRUE(block1.has_value());
+ EXPECT_EQ(block1->scope_index(), 2);
+ EXPECT_EQ(block1->scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(block1->parent().has_value());
+ EXPECT_EQ(block1->parent()->scope_index(), 1);
+
+ auto block2 = block1->first_child();
+ ASSERT_TRUE(block2.has_value());
+ EXPECT_EQ(block2->scope_index(), 3);
+ EXPECT_EQ(block2->scope_type(), ScopeType::BLOCK_SCOPE);
+ EXPECT_TRUE(block2->parent().has_value());
+ EXPECT_EQ(block2->parent()->scope_index(), 2);
+ EXPECT_FALSE(block2->first_child().has_value());
+ EXPECT_FALSE(block2->next_sibling().has_value());
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+TEST_F(DebugScopeInfoTest, MultipleFunctionsAndSiblings) {
+ HandleScope scope(isolate());
+ // Scopes: 0 = Script, 1 = Function f1, 2 = Function f2
+ ParsedScript parsed = ParseAndSerialize(
+ "function f1() { let a = 1; } function f2() { let b = 2; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(script.scope_type(), ScopeType::SCRIPT_SCOPE);
+
+ auto f1 = script.first_child();
+ ASSERT_TRUE(f1.has_value());
+ EXPECT_EQ(f1->scope_index(), 1);
+ EXPECT_EQ(f1->scope_type(), ScopeType::FUNCTION_SCOPE);
+ EXPECT_TRUE(f1->parent().has_value());
+ EXPECT_EQ(f1->parent()->scope_index(), 0);
+
+ auto f2 = f1->next_sibling();
+ ASSERT_TRUE(f2.has_value());
+ EXPECT_EQ(f2->scope_index(), 2);
+ EXPECT_EQ(f2->scope_type(), ScopeType::FUNCTION_SCOPE);
+ EXPECT_TRUE(f2->parent().has_value());
+ EXPECT_EQ(f2->parent()->scope_index(), 0);
+ EXPECT_FALSE(f2->next_sibling().has_value());
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+TEST_F(DebugScopeInfoTest, ArrowAndNormalFunctionScope) {
+ HandleScope scope(isolate());
+ ParsedScript parsed =
+ ParseAndSerialize("let fn = (x) => { return x + 1; }; function g() {}");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(script.is_script_scope());
+ EXPECT_FALSE(script.is_arrow_scope());
+ EXPECT_FALSE(script.has_this_declaration());
+
+ // Function g scope (1) - child scopes are prepended in AST
+ auto normal = script.first_child();
+ ASSERT_TRUE(normal.has_value());
+ EXPECT_TRUE(normal->is_function_scope());
+ EXPECT_FALSE(normal->is_arrow_scope());
+ EXPECT_TRUE(normal->has_this_declaration());
+
+ // Arrow function fn scope (2)
+ auto arrow = normal->next_sibling();
+ ASSERT_TRUE(arrow.has_value());
+ EXPECT_TRUE(arrow->is_function_scope());
+ EXPECT_TRUE(arrow->is_arrow_scope());
+ EXPECT_FALSE(arrow->has_this_declaration());
+ EXPECT_TRUE(arrow->has_simple_parameters());
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+TEST_F(DebugScopeInfoTest, StrictAndNonSimpleParams) {
+ HandleScope scope(isolate());
+ ParsedScript parsed =
+ ParseAndSerialize("\"use strict\"; function f(a = 1) { eval(\"\"); }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_EQ(script.language_mode(), LanguageMode::kStrict);
+
+ auto func = script.first_child();
+ ASSERT_TRUE(func.has_value());
+ EXPECT_EQ(func->language_mode(), LanguageMode::kStrict);
+ EXPECT_FALSE(func->has_simple_parameters());
+ EXPECT_FALSE(func->sloppy_eval_can_extend_vars());
+
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+TEST_F(DebugScopeInfoTest, ComplexScopeTypes) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "class C { m() {} }\n"
+ "try { } catch (e) { }\n"
+ "with ({}) { }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+}
+
+TEST_F(DebugScopeInfoTest, NeedsContextAndUniqueId) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "function outer() {\n"
+ " let x = 1;\n"
+ " { let y = 2; return () => x + y; }\n"
+ "}\n"
+ "function noContext() { let a = 1; return a; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+
+ // Function noContext (1)
+ auto no_ctx = script.first_child();
+ ASSERT_TRUE(no_ctx.has_value());
+ EXPECT_FALSE(no_ctx->needs_context());
+ EXPECT_EQ(no_ctx->unique_id_in_script(), -3);
+
+ // Function outer (2)
+ auto outer = no_ctx->next_sibling();
+ ASSERT_TRUE(outer.has_value());
+ EXPECT_TRUE(outer->needs_context());
+ EXPECT_GE(outer->unique_id_in_script(), 0);
+
+ // Inner block scope (3) inside outer
+ auto block = outer->first_child();
+ ASSERT_TRUE(block.has_value());
+ EXPECT_TRUE(block->needs_context());
+ EXPECT_GE(block->unique_id_in_script(), 0);
+ EXPECT_NE(block->unique_id_in_script(), outer->unique_id_in_script());
+}
+
+TEST_F(DebugScopeInfoTest, ReceiverAllocationInfo) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "function withThisContext() { return () => this; }\n"
+ "function normalFunc() { return 1; }\n"
+ "const arrow = () => 42;");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+
+ // Arrow function (1)
+ auto arrow_scope = script.first_child();
+ ASSERT_TRUE(arrow_scope.has_value());
+ EXPECT_FALSE(arrow_scope->has_this_declaration());
+ EXPECT_EQ(arrow_scope->receiver_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+
+ // normalFunc (2)
+ auto normal_scope = arrow_scope->next_sibling();
+ ASSERT_TRUE(normal_scope.has_value());
+ EXPECT_TRUE(normal_scope->has_this_declaration());
+ EXPECT_EQ(normal_scope->receiver_info(),
+ (std::pair{VariableAllocationInfo::STACK, -1}));
+
+ // withThisContext (3)
+ auto with_this = normal_scope->next_sibling();
+ ASSERT_TRUE(with_this.has_value());
+ EXPECT_TRUE(with_this->has_this_declaration());
+ auto [this_loc, this_idx] = with_this->receiver_info();
+ EXPECT_EQ(this_loc, VariableAllocationInfo::CONTEXT);
+ EXPECT_GE(this_idx, 0);
+}
+
+TEST_F(DebugScopeInfoTest, ArgumentsAllocationInfo) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "function withArgsContext() { return () => arguments[0]; }\n"
+ "function withArgsStack() { return arguments[0]; }\n"
+ "function noArgs() { return 1; }\n"
+ "const arrow = () => 42;");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+
+ // Arrow function (1)
+ auto arrow_scope = script.first_child();
+ ASSERT_TRUE(arrow_scope.has_value());
+ EXPECT_FALSE(arrow_scope->has_arguments());
+ EXPECT_EQ(arrow_scope->arguments_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+
+ // noArgs (2)
+ auto no_args = arrow_scope->next_sibling();
+ ASSERT_TRUE(no_args.has_value());
+ EXPECT_FALSE(no_args->has_arguments());
+ EXPECT_EQ(no_args->arguments_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+
+ // withArgsStack (3)
+ auto with_args_stack = no_args->next_sibling();
+ ASSERT_TRUE(with_args_stack.has_value());
+ EXPECT_TRUE(with_args_stack->has_arguments());
+ auto [stack_loc, stack_idx] = with_args_stack->arguments_info();
+ EXPECT_EQ(stack_loc, VariableAllocationInfo::STACK);
+ EXPECT_GE(stack_idx, 0);
+
+ // withArgsContext (4)
+ auto with_args_context = with_args_stack->next_sibling();
+ ASSERT_TRUE(with_args_context.has_value());
+ EXPECT_TRUE(with_args_context->has_arguments());
+ auto [ctx_loc, ctx_idx] = with_args_context->arguments_info();
+ EXPECT_EQ(ctx_loc, VariableAllocationInfo::CONTEXT);
+ EXPECT_GE(ctx_idx, 0);
+}
+
+TEST_F(DebugScopeInfoTest, FunctionVariableInfo) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "const withFuncContext = function f1() { return () => f1; };\n"
+ "const withFuncStack = function f2() { return f2; };\n"
+ "const withFuncDup = function f1() { return f1; };\n"
+ "const unusedName = function f3() { return 1; };\n"
+ "function normalDecl() { return 1; }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+ EXPECT_TRUE(IsFixedArray(info->string_table()));
+ EXPECT_EQ(info->string_table()->length().value(), 11u);
+
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+
+ // normalDecl (1)
+ auto normal_decl = script.first_child();
+ ASSERT_TRUE(normal_decl.has_value());
+ EXPECT_FALSE(normal_decl->has_function_variable());
+ EXPECT_EQ(normal_decl->function_variable_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ EXPECT_TRUE(normal_decl->function_variable_name().is_null());
+
+ // unusedName (2)
+ auto unused_name = normal_decl->next_sibling();
+ ASSERT_TRUE(unused_name.has_value());
+ EXPECT_FALSE(unused_name->has_function_variable());
+ EXPECT_EQ(unused_name->function_variable_info(),
+ (std::pair{VariableAllocationInfo::NONE, -1}));
+ EXPECT_TRUE(unused_name->function_variable_name().is_null());
+
+ // withFuncDup (3)
+ auto with_func_dup = unused_name->next_sibling();
+ ASSERT_TRUE(with_func_dup.has_value());
+ EXPECT_TRUE(with_func_dup->has_function_variable());
+ auto [dup_loc, dup_idx] = with_func_dup->function_variable_info();
+ EXPECT_EQ(dup_loc, VariableAllocationInfo::STACK);
+ EXPECT_GE(dup_idx, 0);
+ EXPECT_TRUE(with_func_dup->function_variable_name()->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("f1")));
+
+ // withFuncStack (4)
+ auto with_func_stack = with_func_dup->next_sibling();
+ ASSERT_TRUE(with_func_stack.has_value());
+ EXPECT_TRUE(with_func_stack->has_function_variable());
+ auto [stack_loc, stack_idx] = with_func_stack->function_variable_info();
+ EXPECT_EQ(stack_loc, VariableAllocationInfo::STACK);
+ EXPECT_GE(stack_idx, 0);
+ EXPECT_TRUE(with_func_stack->function_variable_name()->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("f2")));
+
+ // withFuncContext (5)
+ auto with_func_context = with_func_stack->next_sibling();
+ ASSERT_TRUE(with_func_context.has_value());
+ EXPECT_TRUE(with_func_context->has_function_variable());
+ auto [ctx_loc, ctx_idx] = with_func_context->function_variable_info();
+ EXPECT_EQ(ctx_loc, VariableAllocationInfo::CONTEXT);
+ EXPECT_GE(ctx_idx, 0);
+ EXPECT_TRUE(with_func_context->function_variable_name()->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("f1")));
+ EXPECT_EQ(with_func_context->function_variable_name(),
+ with_func_dup->function_variable_name());
+}
+
+TEST_F(DebugScopeInfoTest, ScopeVariables) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "let x = 1;\n"
+ "const y = 2;\n"
+ "var z = 3;\n"
+ "function foo(param1, param2) {\n"
+ " let inner = () => x + param1;\n"
+ " { let blockVar = 4; }\n"
+ "}");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+
+ EXPECT_GE(script.variable_count(), 4);
+ bool found_x = false, found_y = false, found_z = false, found_foo = false;
+ for (int i = 0; i < script.variable_count(); ++i) {
+ DebugVariableInfo var = script.variable(i);
+ if (!var.name.is_null()) {
+ if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("x"))) {
+ found_x = true;
+ EXPECT_EQ(var.mode, VariableMode::kLet);
+ } else if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("y"))) {
+ found_y = true;
+ EXPECT_EQ(var.mode, VariableMode::kConst);
+ } else if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("z"))) {
+ found_z = true;
+ EXPECT_EQ(var.mode, VariableMode::kVar);
+ } else if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("foo"))) {
+ found_foo = true;
+ }
+ }
+ }
+ EXPECT_TRUE(found_x);
+ EXPECT_TRUE(found_y);
+ EXPECT_TRUE(found_z);
+ EXPECT_TRUE(found_foo);
+
+ // foo function scope
+ auto foo_scope = script.first_child();
+ ASSERT_TRUE(foo_scope.has_value());
+ EXPECT_GE(foo_scope->variable_count(), 3);
+ bool found_param1 = false, found_param2 = false, found_inner = false;
+ for (int i = 0; i < foo_scope->variable_count(); ++i) {
+ DebugVariableInfo var = foo_scope->variable(i);
+ if (!var.name.is_null()) {
+ if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("param1"))) {
+ found_param1 = true;
+ EXPECT_EQ(var.location, VariableLocation::CONTEXT);
+ } else if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked(
+ "param2"))) {
+ found_param2 = true;
+ EXPECT_EQ(var.location, VariableLocation::PARAMETER);
+ } else if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked(
+ "inner"))) {
+ found_inner = true;
+ EXPECT_EQ(var.mode, VariableMode::kLet);
+ }
+ }
+ }
+ EXPECT_TRUE(found_param1);
+ EXPECT_TRUE(found_param2);
+ EXPECT_TRUE(found_inner);
+}
+
+TEST_F(DebugScopeInfoTest, SyntheticAndReceiverVariables) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize(
+ "let normalVar = 1;\n"
+ "function normalFunc(param) { return this; }\n"
+ "function withThisContext() { return () => this; }\n"
+ "const arrowFunc = () => 42;\n"
+ "function* gen() { yield 1; }\n"
+ "class C { #priv() {} }");
+ DirectHandle<DebugScriptScopeInfo> info = parsed.scope_info;
+ DebugScriptScope script = DebugScriptScope::FromIndex(info, 0);
+ VerifyScopeTreeParity(parsed.script_scope(), script);
+
+ // Verify normal script variable is neither synthetic nor receiver.
+ bool found_normal_var = false;
+ for (int i = 0; i < script.variable_count(); ++i) {
+ DebugVariableInfo var = script.variable(i);
+ if (!var.name.is_null() &&
+ var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("normalVar"))) {
+ found_normal_var = true;
+ EXPECT_FALSE(var.is_synthetic);
+ EXPECT_FALSE(var.is_receiver);
+ }
+ }
+ EXPECT_TRUE(found_normal_var);
+
+ bool found_normal_this = false;
+ bool found_param = false;
+ bool found_context_this = false;
+ bool arrow_has_receiver = false;
+ bool found_generator_obj = false;
+ bool found_private_member = false;
+
+ auto inspect_scope = [&](auto& self,
+ const DebugScriptScope& current) -> void {
+ for (int i = 0; i < current.variable_count(); ++i) {
+ DebugVariableInfo var = current.variable(i);
+ if (var.name.is_null()) continue;
+
+ if (var.name->Equals(*isolate()->factory()->this_string())) {
+ EXPECT_TRUE(var.is_synthetic);
+ if (var.is_receiver) {
+ EXPECT_EQ(var.location, VariableLocation::PARAMETER);
+ EXPECT_EQ(var.index, -1);
+ found_normal_this = true;
+ } else if (var.location == VariableLocation::CONTEXT) {
+ EXPECT_GE(var.index, 0);
+ found_context_this = true;
+ }
+ }
+
+ if (var.name->Equals(
+ *isolate()->factory()->NewStringFromAsciiChecked("param"))) {
+ found_param = true;
+ EXPECT_FALSE(var.is_synthetic);
+ EXPECT_FALSE(var.is_receiver);
+ }
+
+ if (var.name->Equals(*isolate()->factory()->NewStringFromAsciiChecked(
+ ".generator_object"))) {
+ found_generator_obj = true;
+ EXPECT_TRUE(var.is_synthetic);
+ EXPECT_FALSE(var.is_receiver);
+ }
+
+ if (var.name->length() > 0 &&
+ (var.name->Get(0) == '#' || var.name->Get(0) == '.')) {
+ EXPECT_TRUE(var.is_synthetic);
+ EXPECT_FALSE(var.is_receiver);
+ if (var.name->Get(0) == '#') {
+ found_private_member = true;
+ }
+ }
+ }
+
+ if (current.is_arrow_scope()) {
+ for (int i = 0; i < current.variable_count(); ++i) {
+ if (current.variable(i).is_receiver) {
+ arrow_has_receiver = true;
+ }
+ }
+ }
+
+ for (auto child = current.first_child(); child.has_value();
+ child = child->next_sibling()) {
+ self(self, *child);
+ }
+ };
+
+ inspect_scope(inspect_scope, script);
+
+ EXPECT_TRUE(found_normal_this);
+ EXPECT_TRUE(found_param);
+ EXPECT_TRUE(found_context_this);
+ EXPECT_FALSE(arrow_has_receiver);
+ EXPECT_TRUE(found_generator_obj);
+ EXPECT_TRUE(found_private_member);
+}
+
+TEST_F(DebugScopeInfoTest, DebugScriptScopeInfoSideTable) {
+ HandleScope scope(isolate());
+ ParsedScript parsed1 = ParseAndSerialize("let a = 1;");
+ ParsedScript parsed2 = ParseAndSerialize("let b = 2;");
+
+ Handle<String> src1 =
+ isolate()->factory()->NewStringFromAsciiChecked("let a = 1;");
+ Handle<Script> script1 = isolate()->factory()->NewScript(src1);
+
+ Handle<String> src2 =
+ isolate()->factory()->NewStringFromAsciiChecked("let b = 2;");
+ Handle<Script> script2 = isolate()->factory()->NewScript(src2);
+
+ Debug* debug = isolate()->debug();
+
+ // Initially, no scope info in the debug side table.
+ EXPECT_TRUE(debug->GetScriptScopeInfo(script1).is_null());
+ EXPECT_TRUE(debug->GetScriptScopeInfo(script2).is_null());
+
+ // Set scope infos.
+ debug->SetScriptScopeInfo(script1, parsed1.scope_info);
+ debug->SetScriptScopeInfo(script2, parsed2.scope_info);
+
+ // Retrieve and verify cached scope infos.
+ auto cached1 = debug->GetScriptScopeInfo(script1);
+ ASSERT_FALSE(cached1.is_null());
+ EXPECT_EQ(*cached1, *parsed1.scope_info);
+
+ auto cached2 = debug->GetScriptScopeInfo(script2);
+ ASSERT_FALSE(cached2.is_null());
+ EXPECT_EQ(*cached2, *parsed2.scope_info);
+
+ // Update existing entry.
+ debug->SetScriptScopeInfo(script1, parsed2.scope_info);
+ auto updated1 = debug->GetScriptScopeInfo(script1);
+ ASSERT_FALSE(updated1.is_null());
+ EXPECT_EQ(*updated1, *parsed2.scope_info);
+
+ // ClearScriptScopeInfos clears all entries.
+ debug->ClearScriptScopeInfos();
+ EXPECT_TRUE(debug->GetScriptScopeInfo(script1).is_null());
+ EXPECT_TRUE(debug->GetScriptScopeInfo(script2).is_null());
+}
+
+TEST_F(DebugScopeInfoTest, SideTableClearedOnUnload) {
+ HandleScope scope(isolate());
+ ParsedScript parsed = ParseAndSerialize("let x = 42;");
+ Handle<String> src =
+ isolate()->factory()->NewStringFromAsciiChecked("let x = 42;");
+ Handle<Script> script = isolate()->factory()->NewScript(src);
+
+ Debug* debug = isolate()->debug();
+ debug->SetScriptScopeInfo(script, parsed.scope_info);
+ EXPECT_FALSE(debug->GetScriptScopeInfo(script).is_null());
+
+ struct EmptyDelegate : public v8::debug::DebugDelegate {
+ } delegate;
+ v8::debug::SetDebugDelegate(v8_isolate(), &delegate);
+ v8::debug::SetDebugDelegate(v8_isolate(), nullptr);
+
+ EXPECT_TRUE(debug->GetScriptScopeInfo(script).is_null());
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> foo = RunJS<JSFunction>(
+ "function foo() { let a = 1; function bar() { return a; } return bar; } "
+ "foo;");
+ DirectHandle<Script> script(Cast<Script>(foo->shared()->script()), isolate());
+
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+
+ EXPECT_EQ(*info, *EnsureDebugScriptScopeInfo(isolate(), script));
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_DirectEval) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "function outer() {\n"
+ " 'use strict';\n"
+ " let outer_lexical = 42;\n"
+ " return eval('function inner() { return outer_lexical; } inner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_IndirectEval) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> indirect_fn = RunJS<JSFunction>(
+ "function outer() {\n"
+ " 'use strict';\n"
+ " return (0, eval)('function indirectInner() { return 1; } "
+ "indirectInner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(
+ Cast<Script>(indirect_fn->shared()->script()), isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kSloppy);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest,
+ EnsureDebugScriptScopeInfo_DirectEval_StrictCallerNoContext) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "'use strict';\n"
+ "eval('function inner() { return 1; } inner;');");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+ EXPECT_FALSE(eval_script->has_eval_from_scope_info());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest,
+ EnsureDebugScriptScopeInfo_DirectEval_StrictFunctionNoContext) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "function outer() {\n"
+ " 'use strict';\n"
+ " return eval('function inner() { return 1; } inner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest,
+ EnsureDebugScriptScopeInfo_DirectEval_SloppyCallerSloppyEval) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "function outer() {\n"
+ " var x = 1;\n"
+ " return eval('function inner() { return x; } inner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kSloppy);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest,
+ EnsureDebugScriptScopeInfo_DirectEval_SloppyCallerStrictEval) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "function outer() {\n"
+ " var x = 1;\n"
+ " return eval('\"use strict\"; function inner() { return x; } "
+ "inner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_IndirectEval_StrictBody) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> indirect_fn = RunJS<JSFunction>(
+ "(0, eval)('\"use strict\"; function indirectInner() { return 1; } "
+ "indirectInner;');");
+ DirectHandle<Script> eval_script(
+ Cast<Script>(indirect_fn->shared()->script()), isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(eval_script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_DirectEval_PostGC) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "function outer() {\n"
+ " 'use strict';\n"
+ " let outer_lexical = 42;\n"
+ " return eval('function inner() { return outer_lexical; } inner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ isolate()->heap()->CollectAllGarbage(i::GCFlag::kNoFlags,
+ i::GarbageCollectionReason::kTesting);
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_WrappedScript) {
+ v8::HandleScope scope(v8_isolate());
+ v8::ScriptCompiler::Source script_source(
+ NewString("let wrapped_x = 10; return wrapped_x;"));
+ v8::Local<v8::Function> fun =
+ v8::ScriptCompiler::CompileFunction(context(), &script_source)
+ .ToLocalChecked();
+ Handle<JSFunction> function = Cast<JSFunction>(Utils::OpenHandle(*fun));
+ DirectHandle<Script> script(Cast<Script>(function->shared()->script()),
+ isolate());
+ EXPECT_TRUE(script->is_wrapped());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kSloppy);
+
+ auto inner_scope = root_scope.first_child();
+ ASSERT_TRUE(inner_scope.has_value());
+ EXPECT_TRUE(inner_scope->is_function_scope());
+ EXPECT_EQ(inner_scope->language_mode(), LanguageMode::kSloppy);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest,
+ EnsureDebugScriptScopeInfo_WrappedScript_StrictMode) {
+ v8::HandleScope scope(v8_isolate());
+ v8::ScriptCompiler::Source script_source(
+ NewString("'use strict'; let wrapped_x = 10; return wrapped_x;"));
+ v8::Local<v8::Function> fun =
+ v8::ScriptCompiler::CompileFunction(context(), &script_source)
+ .ToLocalChecked();
+ Handle<JSFunction> function = Cast<JSFunction>(Utils::OpenHandle(*fun));
+ DirectHandle<Script> script(Cast<Script>(function->shared()->script()),
+ isolate());
+ EXPECT_TRUE(script->is_wrapped());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ // The outer wrapper declaration scope (eval scope) is always sloppy mode.
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kSloppy);
+
+ // The inner wrapped function inherits the 'use strict' directive.
+ auto inner_scope = root_scope.first_child();
+ ASSERT_TRUE(inner_scope.has_value());
+ EXPECT_TRUE(inner_scope->is_function_scope());
+ EXPECT_EQ(inner_scope->language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest,
+ EnsureDebugScriptScopeInfo_WrappedScript_ContextExtension) {
+ v8::HandleScope scope(v8_isolate());
+ RunJS("var ext_obj = {x: 42};");
+ v8::Local<v8::Object> ext[1];
+ ext[0] =
+ v8::Local<v8::Object>::Cast(context()
+ ->Global()
+ ->Get(context(), NewString("ext_obj"))
+ .ToLocalChecked());
+ v8::ScriptCompiler::Source script_source(
+ NewString("let local_y = 100; return x + local_y;"));
+ v8::Local<v8::Function> fun =
+ v8::ScriptCompiler::CompileFunction(context(), &script_source, 0, nullptr,
+ 1, ext)
+ .ToLocalChecked();
+ Handle<JSFunction> function = Cast<JSFunction>(Utils::OpenHandle(*fun));
+ DirectHandle<Script> script(Cast<Script>(function->shared()->script()),
+ isolate());
+ EXPECT_TRUE(script->is_wrapped());
+
+ DirectHandle<Context> fn_context(function->context(), isolate());
+ EXPECT_FALSE(IsNativeContext(*fn_context));
+
+ // Verify runtime execution resolves `x` from the context extension.
+ v8::Local<v8::Value> call_result =
+ fun->Call(context(), context()->Global(), 0, nullptr).ToLocalChecked();
+ EXPECT_EQ(142, call_result->Int32Value(context()).ToChecked());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+
+ // Reparsing does not require the runtime context extension; it faithfully
+ // extracts internal AST scope topology and local variables without it.
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kSloppy);
+
+ auto inner_scope = root_scope.first_child();
+ ASSERT_TRUE(inner_scope.has_value());
+ EXPECT_TRUE(inner_scope->is_function_scope());
+ EXPECT_EQ(inner_scope->language_mode(), LanguageMode::kSloppy);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_CacheMissDefaultArgs) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> foo = RunJS<JSFunction>(
+ "function foo() { let a = 1; function bar() { return a; } return bar; } "
+ "foo;");
+ DirectHandle<Script> script(Cast<Script>(foo->shared()->script()), isolate());
+
+ // Verify on regular script without any handles.
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+
+ // Also verify cache miss with default args on direct eval script.
+ Handle<JSFunction> inner = RunJS<JSFunction>(
+ "function outer() {\n"
+ " 'use strict';\n"
+ " let outer_lexical = 42;\n"
+ " return eval('function inner() { return outer_lexical; } inner;');\n"
+ "}\n"
+ "outer();");
+ DirectHandle<Script> eval_script(Cast<Script>(inner->shared()->script()),
+ isolate());
+ EXPECT_TRUE(eval_script->is_eval());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(eval_script).is_null());
+
+ Handle<DebugScriptScopeInfo> eval_info =
+ EnsureDebugScriptScopeInfo(isolate(), eval_script);
+ ASSERT_FALSE(eval_info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(eval_info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_FunctionConstructor) {
+ HandleScope scope(isolate());
+ Handle<JSFunction> fun =
+ RunJS<JSFunction>("new Function('a', 'let b = 2; return a + b;');");
+ DirectHandle<Script> script(Cast<Script>(fun->shared()->script()), isolate());
+ EXPECT_EQ(script->compilation_kind(),
+ Script::CompilationKind::kFunctionConstructor);
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_eval_scope());
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+TEST_F(DebugScopeInfoTest, EnsureDebugScriptScopeInfo_Module) {
+ 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());
+ EXPECT_TRUE(script->origin_options().IsModule());
+
+ isolate()->debug()->ClearScriptScopeInfos();
+ EXPECT_TRUE(isolate()->debug()->GetScriptScopeInfo(script).is_null());
+
+ Handle<DebugScriptScopeInfo> info =
+ EnsureDebugScriptScopeInfo(isolate(), script);
+ ASSERT_FALSE(info.is_null());
+
+ DebugScriptScope root_scope = DebugScriptScope::FromIndex(info, 0);
+ EXPECT_TRUE(root_scope.is_module_scope());
+ EXPECT_EQ(root_scope.language_mode(), LanguageMode::kStrict);
+
+ auto inner_scope = root_scope.first_child();
+ ASSERT_TRUE(inner_scope.has_value());
+ EXPECT_TRUE(inner_scope->is_function_scope());
+ EXPECT_EQ(inner_scope->language_mode(), LanguageMode::kStrict);
+
+ auto cached_info = isolate()->debug()->GetScriptScopeInfo(script);
+ ASSERT_FALSE(cached_info.is_null());
+ EXPECT_EQ(*info, *cached_info);
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/execution/microtask-queue-unittest.cc b/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
index da7091a7ca3..5b98d617d87 100644
--- a/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
+++ b/deps/v8/test/unittests/execution/microtask-queue-unittest.cc
@@ -29,17 +29,10 @@ namespace internal {
using Closure = std::function<void()>;
-template <typename T>
-T* GetRaw(const std::unique_ptr<T>& ptr) {
- return ptr.get();
-}
-
-#ifdef V8_CPPGC_MICROTASK_QUEUE
template <typename T>
T* GetRaw(const cppgc::Persistent<T>& ptr) {
return ptr.Get();
}
-#endif // V8_CPPGC_MICROTASK_QUEUE
void RunStdFunction(void* data) {
std::unique_ptr<Closure> f(static_cast<Closure*>(data));
@@ -174,11 +167,7 @@ class MicrotaskQueueTest
}
private:
-#ifdef V8_CPPGC_MICROTASK_QUEUE
cppgc::Persistent<MicrotaskQueue> microtask_queue_;
-#else
- std::unique_ptr<MicrotaskQueue> microtask_queue_;
-#endif // V8_CPPGC_MICROTASK_QUEUE
};
class RecordingVisitor : public RootVisitor {
@@ -247,38 +236,6 @@ TEST_P(MicrotaskQueueTest, BufferGrowth) {
EXPECT_EQ(MicrotaskQueue::kMinimumCapacity + 2, count);
}
-#ifndef V8_CPPGC_MICROTASK_QUEUE
-// MicrotaskQueue instances form a doubly linked list.
-TEST_P(MicrotaskQueueTest, InstanceChain) {
- ClearTestMicrotaskQueue();
-
- MicrotaskQueue* default_mtq = isolate()->default_microtask_queue();
- ASSERT_TRUE(default_mtq);
- EXPECT_EQ(default_mtq, default_mtq->next());
- EXPECT_EQ(default_mtq, default_mtq->prev());
-
- // Create two instances, and check their connection.
- // The list contains all instances in the creation order, and the next of the
- // last instance is the first instance:
- // default_mtq -> mtq1 -> mtq2 -> default_mtq.
- std::unique_ptr<MicrotaskQueue> mtq1 = MicrotaskQueue::New(isolate());
- std::unique_ptr<MicrotaskQueue> mtq2 = MicrotaskQueue::New(isolate());
- EXPECT_EQ(default_mtq->next(), mtq1.get());
- EXPECT_EQ(mtq1->next(), mtq2.get());
- EXPECT_EQ(mtq2->next(), default_mtq);
- EXPECT_EQ(default_mtq, mtq1->prev());
- EXPECT_EQ(mtq1.get(), mtq2->prev());
- EXPECT_EQ(mtq2.get(), default_mtq->prev());
-
- // Deleted item should be also removed from the list.
- mtq1 = nullptr;
- EXPECT_EQ(default_mtq->next(), mtq2.get());
- EXPECT_EQ(mtq2->next(), default_mtq);
- EXPECT_EQ(default_mtq, mtq2->prev());
- EXPECT_EQ(mtq2.get(), default_mtq->prev());
-}
-#endif // V8_CPPGC_MICROTASK_QUEUE
-
// Pending Microtasks in MicrotaskQueues are strong roots. Ensure they are
// visited exactly once.
TEST_P(MicrotaskQueueTest, VisitRoot) {
@@ -491,13 +448,8 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableForeignThen) {
{
// Create a context with its own microtask queue.
-#ifdef V8_CPPGC_MICROTASK_QUEUE
cppgc::Persistent<MicrotaskQueue> sub_microtask_queue =
MicrotaskQueue::New(isolate());
-#else
- std::unique_ptr<MicrotaskQueue> sub_microtask_queue =
- MicrotaskQueue::New(isolate());
-#endif // V8_CPPGC_MICROTASK_QUEUE
sub_microtask_queue->set_microtasks_policy(MicrotasksPolicy::kExplicit);
Local<v8::Context> sub_context = v8::Context::New(
@@ -558,13 +510,8 @@ TEST_P(MicrotaskQueueTest, DetachGlobal_ResolveThenableNativeThen) {
{
// Create a context with its own microtask queue.
-#ifdef V8_CPPGC_MICROTASK_QUEUE
cppgc::Persistent<MicrotaskQueue> sub_microtask_queue =
MicrotaskQueue::New(isolate());
-#else
- std::unique_ptr<MicrotaskQueue> sub_microtask_queue =
- MicrotaskQueue::New(isolate());
-#endif
sub_microtask_queue->set_microtasks_policy(MicrotasksPolicy::kExplicit);
Local<v8::Context> sub_context = v8::Context::New(
v8_isolate(),
diff --git a/deps/v8/test/unittests/flags/flag-definitions-unittest.cc b/deps/v8/test/unittests/flags/flag-definitions-unittest.cc
index 70960ace971..2e06620b5d3 100644
--- a/deps/v8/test/unittests/flags/flag-definitions-unittest.cc
+++ b/deps/v8/test/unittests/flags/flag-definitions-unittest.cc
@@ -240,22 +240,6 @@ TEST_F(FlagDefinitionsTest, FreezeFlags) {
CHECK_EQ(42, *direct_testing_int_ptr);
}
-// Stress implications after setting a flag. We only set one flag, as multiple
-// might just lead to known flag contradictions.
-void StressFlagImplications(const std::string& s1) {
- int result = FlagList::SetFlagsFromString(s1.c_str(), s1.length());
- // Only process implications if a flag was set successfully (which happens
- // only in a small portion of fuzz runs).
- if (result == 0) FlagList::EnforceFlagImplications();
- // Ensure a clean state in each iteration.
- for (Flag& flag : Flags()) {
- if (!flag.IsReadOnly()) flag.Reset();
- }
-}
-
-V8_FUZZ_TEST(FlagDefinitionsFuzzTest, StressFlagImplications)
- .WithDomains(fuzztest::InRegexp("^--(\\w|\\-){1,50}(=\\w{1,5})?$"));
-
struct FlagAndName {
FlagValue<bool>* value;
const char* name;
@@ -346,19 +330,35 @@ TEST(FlagContradictionsTest, ResolvesContradictions) {
TEST(FlagContradictionsTest, ResolvesNegContradictions) {
#ifdef V8_ENABLE_MAGLEV
- int argc = 4;
- const char* argv[] = {"Test", "--fuzzing", "--no-turbofan",
- "--always-osr-from-maglev"};
- FlagList::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), false);
- CHECK(v8_flags.fuzzing);
- CHECK(!v8_flags.turbofan);
- CHECK(v8_flags.always_osr_from_maglev);
- CHECK(!v8_flags.osr_from_maglev);
- FlagList::ResolveContradictionsWhenFuzzing();
- FlagList::EnforceFlagImplications();
- CHECK(v8_flags.fuzzing);
- CHECK(!v8_flags.turbofan);
- CHECK(!v8_flags.osr_from_maglev);
+ {
+ int argc = 4;
+ const char* argv[] = {"Test", "--fuzzing", "--no-turbofan",
+ "--always-osr-from-maglev"};
+ FlagList::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), false);
+ CHECK(v8_flags.fuzzing);
+ CHECK(!v8_flags.turbofan);
+ CHECK(v8_flags.always_osr_from_maglev);
+ FlagList::ResolveContradictionsWhenFuzzing();
+ FlagList::EnforceFlagImplications();
+ CHECK(v8_flags.fuzzing);
+ CHECK(!v8_flags.turbofan);
+ CHECK(!v8_flags.always_osr_from_maglev);
+ CHECK_EQ(v8_flags.osr_from_maglev, 0);
+ }
+ {
+ int argc = 4;
+ const char* argv[] = {"Test", "--fuzzing", "--no-turbofan",
+ "--osr-from-maglev=4"};
+ FlagList::SetFlagsFromCommandLine(&argc, const_cast<char**>(argv), false);
+ CHECK(v8_flags.fuzzing);
+ CHECK(!v8_flags.turbofan);
+ CHECK_EQ(v8_flags.osr_from_maglev, 4);
+ FlagList::ResolveContradictionsWhenFuzzing();
+ FlagList::EnforceFlagImplications();
+ CHECK(v8_flags.fuzzing);
+ CHECK(!v8_flags.turbofan);
+ CHECK_EQ(v8_flags.osr_from_maglev, 0);
+ }
#endif
}
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 f0b90696f76..9e172c18ae6 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
@@ -25,6 +25,7 @@
#include "src/heap/cppgc-internal/sweeper.h"
#include "src/heap/cppgc-js/cpp-heap.h"
#include "src/heap/gc-tracer-inl.h"
+#include "src/heap/heap-controller.h"
#include "src/objects/objects-inl.h"
#include "test/unittests/heap/cppgc-js/unified-heap-utils.h"
#include "test/unittests/heap/heap-utils.h"
@@ -966,4 +967,32 @@ TEST_F(UnifiedHeapTest, WrappedWithConservativeGCInCtor) {
CHECK(name->IsString());
}
+TEST_F(UnifiedHeapTest, TriggerGCWithNoIncrementalMarking) {
+ if (v8_flags.stress_incremental_marking) return;
+ if (v8_flags.stress_concurrent_allocation) return;
+ // This test should ensure that we trigger GC on cppgc allocations even when
+ // incremental marking is disabled.
+ v8_flags.incremental_marking = false;
+ const int initial_gc_count = heap()->ms_count();
+
+ // Set the allocation limits close to current consumption to trigger GC
+ // quickly.
+ const size_t current_old = heap()->OldGenerationConsumedBytes();
+ const size_t current_global = heap()->GlobalConsumedBytes();
+ heap()->limits()->SetAllocationLimit(current_old + 512 * KB,
+ current_global + 512 * KB);
+
+ static constexpr size_t kAllocationSize = 16 * KB;
+ static constexpr size_t kMaxAllocations = KB;
+ for (size_t i = 0;
+ i < kMaxAllocations && heap()->ms_count() == initial_gc_count; ++i) {
+ cppgc::MakeGarbageCollected<Wrappable>(
+ allocation_handle(), cppgc::AdditionalBytes(kAllocationSize));
+ }
+
+ EXPECT_GT(heap()->ms_count(), initial_gc_count)
+ << "GC should have been triggered when allocation limits are reached "
+ "even without incremental marking";
+}
+
} // namespace v8::internal
diff --git a/deps/v8/test/unittests/heap/cppgc/explicit-management-unittest.cc b/deps/v8/test/unittests/heap/cppgc/explicit-management-unittest.cc
index d340f81e116..f0f63f91c71 100644
--- a/deps/v8/test/unittests/heap/cppgc/explicit-management-unittest.cc
+++ b/deps/v8/test/unittests/heap/cppgc/explicit-management-unittest.cc
@@ -139,6 +139,14 @@ TEST_F(ExplicitManagementTest, GrowAtLAB) {
header.ObjectSize());
}
+TEST_F(ExplicitManagementTest, GrowPastLargeObjectThreshold) {
+ auto* o =
+ MakeGarbageCollected<DynamicallySized>(GetHeap()->GetAllocationHandle());
+ auto& header = HeapObjectHeader::FromObject(o);
+ ASSERT_TRUE(!header.IsLargeObject());
+ EXPECT_FALSE(subtle::Resize(*o, AdditionalBytes(kLargeObjectSizeThreshold)));
+}
+
TEST_F(ExplicitManagementTest, GrowShrinkAtLAB) {
auto* o =
MakeGarbageCollected<DynamicallySized>(GetHeap()->GetAllocationHandle());
diff --git a/deps/v8/test/unittests/heap/direct-handles-unittest.cc b/deps/v8/test/unittests/heap/direct-handles-unittest.cc
index e77359df5aa..3115d1ed2b3 100644
--- a/deps/v8/test/unittests/heap/direct-handles-unittest.cc
+++ b/deps/v8/test/unittests/heap/direct-handles-unittest.cc
@@ -25,6 +25,13 @@ TEST_F(DirectHandlesTest, CreateDirectHandleFromLocal) {
EXPECT_EQ(*direct, *handle);
}
+TEST_F(DirectHandlesTest, HandleNull) {
+ HandleScope scope(isolate());
+ i::DirectHandle<i::Object> n(i::Tagged<i::Object>(i::kNullAddress),
+ i_isolate());
+ EXPECT_FALSE(n.is_null());
+}
+
TEST_F(DirectHandlesTest, CreateLocalFromDirectHandle) {
HandleScope scope(isolate());
i::IndirectHandle<i::String> handle =
diff --git a/deps/v8/test/unittests/heap/global-handles-unittest.cc b/deps/v8/test/unittests/heap/global-handles-unittest.cc
index 8d9d8c7e8ef..181da207f0f 100644
--- a/deps/v8/test/unittests/heap/global-handles-unittest.cc
+++ b/deps/v8/test/unittests/heap/global-handles-unittest.cc
@@ -258,6 +258,45 @@ TEST_F(GlobalHandlesTest, EternalHandles) {
CHECK_EQ(2 * kArrayLength + 1, eternal_handles->handles_count());
}
+TEST_F(GlobalHandlesTest, StrongGlobalHandles) {
+ Isolate* isolate = i_isolate();
+ Factory* factory = isolate->factory();
+ GlobalHandles* global_handles = isolate->global_handles();
+
+ Handle<Object> h1;
+ Handle<Object> h2;
+ Handle<Object> h3;
+ Handle<Object> h4;
+
+ {
+ HandleScope scope(isolate);
+
+ DirectHandle<Object> i = factory->NewStringFromStaticChars("fisk");
+ DirectHandle<Object> u = factory->NewNumber(1.12344);
+
+ h1 = global_handles->Create(*i);
+ h2 = global_handles->Create(*u);
+ h3 = global_handles->Create(*i);
+ h4 = global_handles->Create(*u);
+ }
+
+ // After GC, objects should survive.
+ InvokeMinorGC();
+
+ EXPECT_TRUE(IsString(*h1));
+ EXPECT_TRUE(IsHeapNumber(*h2));
+ EXPECT_TRUE(IsString(*h3));
+ EXPECT_TRUE(IsHeapNumber(*h4));
+
+ EXPECT_EQ(*h3, *h1);
+ GlobalHandles::Destroy(h1.location());
+ GlobalHandles::Destroy(h3.location());
+
+ EXPECT_EQ(*h4, *h2);
+ GlobalHandles::Destroy(h2.location());
+ GlobalHandles::Destroy(h4.location());
+}
+
TEST_F(GlobalHandlesTest, PersistentBaseGetLocal) {
v8::Isolate* isolate = v8_isolate();
diff --git a/deps/v8/test/unittests/heap/heap-unittest.cc b/deps/v8/test/unittests/heap/heap-unittest.cc
index 9f7218d0568..1dbbb2b1b8f 100644
--- a/deps/v8/test/unittests/heap/heap-unittest.cc
+++ b/deps/v8/test/unittests/heap/heap-unittest.cc
@@ -19,18 +19,25 @@
#include <vector>
#include "include/v8-callbacks.h"
+#include "include/v8-function.h"
#include "include/v8-initialization.h"
#include "include/v8-isolate.h"
#include "include/v8-object.h"
#include "src/base/bounded-page-allocator.h"
+#include "src/codegen/assembler-inl.h"
+#include "src/codegen/compilation-cache.h"
+#include "src/codegen/compiler.h"
+#include "src/codegen/script-details.h"
#include "src/common/globals.h"
#include "src/flags/flags.h"
#include "src/handles/handles-inl.h"
+#include "src/heap/factory.h"
#include "src/heap/gc-tracer-inl.h"
#include "src/heap/gc-tracer.h"
#include "src/heap/heap-controller.h"
#include "src/heap/heap-layout-inl.h"
#include "src/heap/heap-layout.h"
+#include "src/heap/main-allocator-inl.h"
#include "src/heap/marking-state-inl.h"
#include "src/heap/minor-mark-sweep.h"
#include "src/heap/mutable-page.h"
@@ -38,12 +45,20 @@
#include "src/heap/safepoint.h"
#include "src/heap/spaces-inl.h"
#include "src/heap/trusted-range.h"
+#include "src/objects/bytecode-array-inl.h"
+#include "src/objects/feedback-vector-inl.h"
#include "src/objects/fixed-array.h"
#include "src/objects/free-space-inl.h"
+#include "src/objects/instruction-stream-inl.h"
#include "src/objects/internal-index.h"
#include "src/objects/js-array-buffer-inl.h"
#include "src/objects/js-collection-inl.h"
+#include "src/objects/script-inl.h"
+#include "src/objects/shared-function-info-inl.h"
+#include "src/objects/transitions-inl.h"
+#include "src/regexp/regexp.h"
#include "src/sandbox/external-pointer-table.h"
+#include "test/common/noop-bytecode-verifier.h"
#include "test/unittests/heap/heap-utils.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -1431,5 +1446,2956 @@ TEST_F(HeapTest, CheckCrashKeysAreReportedInOOM) {
g_crash_key_store_for_oom = nullptr;
}
+TEST_F(HeapTest, FindCodeForInnerPointer) {
+#define __ assm.
+
+ Assembler assm(i_isolate()->allocator(), AssemblerOptions{});
+
+ __ nop(); // supported on all architectures
+
+ CodeDesc desc;
+ assm.GetCode(i_isolate(), &desc);
+ DirectHandle<InstructionStream> code(
+ Factory::CodeBuilder(i_isolate(), desc, CodeKind::FOR_TESTING)
+ .Build()
+ ->instruction_stream(),
+ i_isolate());
+ EXPECT_TRUE(IsInstructionStream(*code));
+
+ Tagged<HeapObject> obj = Cast<HeapObject>(*code);
+ Address obj_addr = obj.address();
+
+ for (int i = 0; i < obj->Size(); i += kTaggedSize) {
+ Tagged<Code> lookup_result = heap()->FindCodeForInnerPointer(obj_addr + i);
+ EXPECT_EQ(*code, lookup_result->instruction_stream());
+ }
+
+ DirectHandle<InstructionStream> copy(
+ Factory::CodeBuilder(i_isolate(), desc, CodeKind::FOR_TESTING)
+ .Build()
+ ->instruction_stream(),
+ i_isolate());
+ Tagged<HeapObject> obj_copy = Cast<HeapObject>(*copy);
+ Tagged<Code> not_right = heap()->FindCodeForInnerPointer(
+ obj_copy.address() + obj_copy->Size() / 2);
+ EXPECT_NE(not_right->instruction_stream(), *code);
+ EXPECT_EQ(not_right->instruction_stream(), *copy);
+#undef __
+}
+
+TEST_F(HeapTest, BytecodeArray) {
+ if (!v8_flags.compact) return;
+ if (v8_flags.precise_object_pinning) return;
+ static const uint8_t kRawBytes[] = {0xC3, 0x7E, 0xA5, 0x5A};
+ static const int kRawBytesSize = sizeof(kRawBytes);
+ static const int32_t kFrameSize = 32;
+ static const uint16_t kParameterCount = 2;
+ static const uint16_t kMaxArguments = 0;
+
+ v8_flags.manual_evacuation_candidates_selection = true;
+ ManualGCScope manual_gc_scope(isolate());
+ Factory* factory = i_isolate()->factory();
+ HandleScope scope(i_isolate());
+
+ SimulateFullSpace(heap()->trusted_space());
+
+ IndirectHandle<TrustedFixedArray> constant_pool =
+ factory->NewTrustedFixedArray(5);
+ for (int i = 0; i < 5; i++) {
+ IndirectHandle<Object> number = factory->NewHeapNumber(i);
+ constant_pool->set(i, *number);
+ }
+
+ IndirectHandle<TrustedByteArray> handler_table =
+ factory->NewTrustedByteArray(3);
+
+ // Allocate and initialize BytecodeArray
+ IndirectHandle<BytecodeArray> array = factory->NewBytecodeArray(
+ kRawBytesSize, kRawBytes, kFrameSize, kParameterCount, kMaxArguments,
+ constant_pool, handler_table);
+
+ EXPECT_TRUE(IsBytecodeArray(*array));
+
+#ifdef V8_ENABLE_SANDBOX
+ // BytecodeArrays are not exposed to the sandbox ("published") immediately
+ // after allocation. Instead, this only happens once the bytecode has been
+ // verified. This way, we ensure that we only execute safe bytecode.
+ EXPECT_FALSE(array->IsPublished(i_isolate()));
+ NoOpBytecodeVerifier::Verify(i_isolate(), array);
+ EXPECT_TRUE(array->IsPublished(i_isolate()));
+#endif // V8_ENABLE_SANDBOX
+
+ EXPECT_EQ(array->length(), (int)sizeof(kRawBytes));
+ EXPECT_EQ(array->frame_size(), kFrameSize);
+ EXPECT_EQ(array->parameter_count(), kParameterCount);
+ EXPECT_EQ(array->constant_pool(), *constant_pool);
+ EXPECT_EQ(array->handler_table(), *handler_table);
+ EXPECT_LE(array->address(), array->GetFirstBytecodeAddress());
+ EXPECT_GE(array->address() + array->BytecodeArraySize(),
+ array->GetFirstBytecodeAddress() + array->length());
+ for (int i = 0; i < kRawBytesSize; i++) {
+ EXPECT_EQ(Memory<uint8_t>(array->GetFirstBytecodeAddress() + i),
+ kRawBytes[i]);
+ EXPECT_EQ(array->get(i), kRawBytes[i]);
+ }
+
+ Tagged<TrustedFixedArray> old_constant_pool_address = *constant_pool;
+
+ // Perform a full garbage collection and force the constant pool to be on an
+ // evacuation candidate.
+ i::MutablePage::FromHeapObject(isolate(), *constant_pool)
+ ->set_forced_evacuation_candidate_for_testing(true);
+ {
+ // We need to invoke GC without stack, otherwise no compaction is performed.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+
+ // BytecodeArray should survive.
+ EXPECT_EQ(array->length(), kRawBytesSize);
+ EXPECT_EQ(array->frame_size(), kFrameSize);
+ for (int i = 0; i < kRawBytesSize; i++) {
+ EXPECT_EQ(array->get(i), kRawBytes[i]);
+ EXPECT_EQ(Memory<uint8_t>(array->GetFirstBytecodeAddress() + i),
+ kRawBytes[i]);
+ }
+
+ // Constant pool should have been migrated.
+ EXPECT_EQ(array->constant_pool().ptr(), constant_pool->ptr());
+ EXPECT_NE(array->constant_pool().ptr(), old_constant_pool_address.ptr());
+}
+
+TEST_F(HeapTest, BytecodeFlushing) {
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ v8_flags.turbofan = false;
+ i::v8_flags.optimize_for_size = false;
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+#ifdef V8_ENABLE_SPARKPLUG
+ v8_flags.always_sparkplug = false;
+#endif // V8_ENABLE_SPARKPLUG
+ i::v8_flags.flush_bytecode = true;
+ i::v8_flags.allow_natives_syntax = true;
+
+ ManualGCScope manual_gc_scope(i_isolate());
+ v8::HandleScope scope(v8_isolate());
+ const char* source =
+ "function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "};"
+ "foo()";
+ DirectHandle<String> foo_name = factory()->InternalizeUtf8String("foo");
+
+ // This compile will add the code to the compilation cache.
+ {
+ v8::HandleScope new_scope(v8_isolate());
+ RunJS(source);
+ }
+
+ // Check function is compiled.
+ DirectHandle<Object> func_value =
+ Object::GetProperty(i_isolate(), i_isolate()->global_object(), foo_name)
+ .ToHandleChecked();
+ EXPECT_TRUE(IsJSFunction(*func_value));
+ DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
+ EXPECT_TRUE(function->shared()->is_compiled());
+
+ // The code will survive at least two GCs.
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ InvokeMajorGC();
+ }
+ EXPECT_TRUE(function->shared()->is_compiled());
+
+ i::SharedFunctionInfo::EnsureOldForTesting(function->shared());
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+
+ // foo should no longer be compiled
+ EXPECT_FALSE(function->shared()->is_compiled());
+ EXPECT_FALSE(function->is_compiled(i_isolate()));
+ // Call foo to get it recompiled.
+ RunJS("foo()");
+ EXPECT_TRUE(function->shared()->is_compiled());
+ EXPECT_TRUE(function->is_compiled(i_isolate()));
+}
+
+namespace {
+void RunMultiReferencedBytecodeFlushingTest(HeapTest* test,
+ bool sparkplug_compile) {
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ v8_flags.turbofan = false;
+ i::v8_flags.optimize_for_size = false;
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+#ifdef V8_ENABLE_SPARKPLUG
+ v8_flags.always_sparkplug = false;
+ v8_flags.flush_baseline_code = true;
+#else
+ if (sparkplug_compile) return;
+#endif // V8_ENABLE_SPARKPLUG
+ i::v8_flags.flush_bytecode = true;
+ i::v8_flags.allow_natives_syntax = true;
+
+ ManualGCScope manual_gc_scope(test->i_isolate());
+ v8::HandleScope scope(test->v8_isolate());
+ const char* source =
+ "function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "};"
+ "foo()";
+ DirectHandle<String> foo_name = test->factory()->InternalizeUtf8String("foo");
+
+ // This compile will add the code to the compilation cache.
+ {
+ v8::HandleScope new_scope(test->v8_isolate());
+ test->RunJS(source);
+ }
+
+ // Check function is compiled.
+ DirectHandle<Object> func_value =
+ Object::GetProperty(test->i_isolate(), test->i_isolate()->global_object(),
+ foo_name)
+ .ToHandleChecked();
+ EXPECT_TRUE(IsJSFunction(*func_value));
+ DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
+ DirectHandle<SharedFunctionInfo> shared(function->shared(),
+ test->i_isolate());
+ EXPECT_TRUE(shared->is_compiled());
+
+ // Make a copy of the SharedFunctionInfo which points to the same bytecode.
+ Handle<SharedFunctionInfo> copy =
+ test->factory()->CloneSharedFunctionInfo(shared);
+
+ if (sparkplug_compile) {
+ v8::HandleScope baseline_compilation_scope(test->v8_isolate());
+ IsCompiledScope is_compiled_scope =
+ copy->is_compiled_scope(test->i_isolate());
+ Compiler::CompileSharedWithBaseline(
+ test->i_isolate(), copy, Compiler::CLEAR_EXCEPTION, &is_compiled_scope);
+ }
+
+ i::SharedFunctionInfo::EnsureOldForTesting(*shared);
+ {
+ // We need to invoke GC without stack, otherwise some objects may not be
+ // reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ test->heap());
+ test->InvokeMajorGC();
+ }
+
+ // shared SFI is marked old but BytecodeArray is kept alive by copy.
+ EXPECT_TRUE(shared->is_compiled());
+ EXPECT_TRUE(copy->is_compiled());
+ EXPECT_TRUE(function->is_compiled(test->i_isolate()));
+
+ // The feedback metadata for both SharedFunctionInfo instances should have
+ // been reset.
+ EXPECT_TRUE(shared->HasFeedbackMetadata());
+ EXPECT_TRUE(copy->HasFeedbackMetadata());
+}
+} // namespace
+
+TEST_F(HeapTest, MultiReferencedBytecodeFlushing) {
+ RunMultiReferencedBytecodeFlushingTest(this, /*sparkplug_compile=*/false);
+}
+
+TEST_F(HeapTest, MultiReferencedBytecodeFlushingWithSparkplug) {
+ RunMultiReferencedBytecodeFlushingTest(this, /*sparkplug_compile=*/true);
+}
+
+TEST_F(HeapTest, JSInterceptorMap) {
+ DirectHandle<InterceptorInfo> named_interceptor =
+ factory()->NewInterceptorInfo(InterceptorKind::kNamed);
+ DirectHandle<InterceptorInfo> indexed_interceptor =
+ factory()->NewInterceptorInfo(InterceptorKind::kIndexed);
+
+ DirectHandle<Map> last_map;
+ {
+ HandleScope sc1(isolate());
+
+ const size_t N = 100;
+ DirectHandleVector<JSObject> objects(isolate());
+ objects.reserve(N);
+ DirectHandle<JSInterceptorMap> map;
+
+ for (size_t i = 0; i < N; i++) {
+ if (i % 10 == 0) {
+ // Create a fresh map every now and then.
+ const int inobject_properties = 2;
+ map = Cast<JSInterceptorMap>(factory()->NewExtendedMapWithMetaMap(
+ isolate()->meta_map(), ExtendedMapKind::kJSInterceptorMap,
+ JS_OBJECT_TYPE,
+ JSObject::kHeaderSize + inobject_properties * kTaggedSize,
+ TERMINAL_FAST_ELEMENTS_KIND, inobject_properties));
+ map->init_flags_and_clear_extended_padding();
+ map->set_named_interceptor(*named_interceptor);
+ map->set_indexed_interceptor(*indexed_interceptor);
+ map->set_fast_case_validity_cell(
+ ReadOnlyRoots(isolate()).invalid_prototype_validity_cell());
+ }
+
+ Handle<JSObject> obj = factory()->NewJSObjectFromMap(map);
+ Object::SetProperty(isolate(), obj, factory()->a_string(), obj).Check();
+ Object::SetProperty(isolate(), obj, factory()->b_string(), obj).Check();
+ Object::SetProperty(isolate(), obj, factory()->c_string(), obj).Check();
+ Object::SetProperty(isolate(), obj, factory()->d_string(), obj).Check();
+
+#ifdef VERIFY_HEAP
+ obj->HeapObjectVerify(isolate());
+ obj->map()->HeapObjectVerify(isolate());
+#endif // VERIFY_HEAP
+ objects.emplace_back(obj);
+ if (i == N / 2) {
+ InvokeMajorGC();
+ InvokeMajorGC();
+ }
+ }
+
+ InvokeMajorGC();
+ InvokeMajorGC();
+ last_map = sc1.CloseAndEscape(map);
+ }
+ InvokeMajorGC();
+ InvokeMajorGC();
+
+ EXPECT_TRUE(IsJSObjectMap(*last_map));
+ EXPECT_TRUE(last_map->is_extended_map());
+
+ EXPECT_EQ(UncheckedCast<ExtendedMap>(last_map)->map_kind(),
+ ExtendedMapKind::kJSInterceptorMap);
+ DirectHandle<JSInterceptorMap> map = Cast<JSInterceptorMap>(last_map);
+ EXPECT_EQ(map->named_interceptor(), *named_interceptor);
+ EXPECT_EQ(map->indexed_interceptor(), *indexed_interceptor);
+}
+
+namespace {
+void RunCompilationCacheCachingBehaviorTest(HeapTest* test,
+ bool retain_script) {
+ // If we do not have the compilation cache turned off, this test is invalid.
+ if (!v8_flags.compilation_cache) {
+ return;
+ }
+ if (!v8_flags.flush_bytecode ||
+ (v8_flags.always_sparkplug && !v8_flags.flush_baseline_code)) {
+ return;
+ }
+ Isolate* isolate = test->i_isolate();
+ Factory* factory = test->factory();
+ CompilationCache* compilation_cache = isolate->compilation_cache();
+ LanguageMode language_mode = LanguageMode::kSloppy;
+
+ v8::HandleScope outer_scope(test->v8_isolate());
+ const char* raw_source = retain_script ? "function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "};"
+ "foo();"
+ : "(function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "})();";
+ Handle<String> source =
+ Cast<String>(factory->InternalizeUtf8String(raw_source));
+
+ {
+ v8::HandleScope scope(test->v8_isolate());
+ test->RunJS(raw_source);
+ }
+
+ // The script should be in the cache now.
+ {
+ v8::HandleScope scope(test->v8_isolate());
+ ScriptDetails script_details(Handle<Object>(),
+ v8::ScriptOriginOptions(true, false));
+ auto lookup_result =
+ compilation_cache->LookupScript(source, script_details, language_mode);
+ EXPECT_FALSE(lookup_result.toplevel_sfi().is_null());
+ }
+
+ // Check that the code cache entry survives at least one GC.
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ test->heap());
+ test->InvokeMajorGC();
+ }
+ {
+ v8::HandleScope scope(test->v8_isolate());
+ ScriptDetails script_details(Handle<Object>(),
+ v8::ScriptOriginOptions(true, false));
+ auto lookup_result =
+ compilation_cache->LookupScript(source, script_details, language_mode);
+ EXPECT_FALSE(lookup_result.toplevel_sfi().is_null());
+
+ // Progress code age until it's old and ready for GC.
+ DirectHandle<SharedFunctionInfo> shared =
+ lookup_result.toplevel_sfi().ToHandleChecked();
+ EXPECT_TRUE(shared->HasBytecodeArray());
+ SharedFunctionInfo::EnsureOldForTesting(*shared);
+ }
+
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ test->heap());
+ // The first GC flushes the BytecodeArray from the SFI.
+ test->InvokeMajorGC();
+ // The second GC removes the SFI from the compilation cache.
+ test->InvokeMajorGC();
+ }
+
+ {
+ v8::HandleScope scope(test->v8_isolate());
+ // Ensure code aging cleared the entry from the cache.
+ ScriptDetails script_details(Handle<Object>(),
+ v8::ScriptOriginOptions(true, false));
+ auto lookup_result =
+ compilation_cache->LookupScript(source, script_details, language_mode);
+ EXPECT_TRUE(lookup_result.toplevel_sfi().is_null());
+ EXPECT_EQ(retain_script, !lookup_result.script().is_null());
+ }
+}
+} // namespace
+
+TEST_F(HeapTest, CompilationCacheCachingBehaviorDiscardScript) {
+ RunCompilationCacheCachingBehaviorTest(this, false);
+}
+
+TEST_F(HeapTest, CompilationCacheCachingBehaviorRetainScript) {
+ RunCompilationCacheCachingBehaviorTest(this, true);
+}
+
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+TEST_F(HeapTest, OptimizeAfterBytecodeFlushingCandidate) {
+ if (v8_flags.single_generation) return;
+ v8_flags.turbofan = true;
+#ifdef V8_ENABLE_SPARKPLUG
+ v8_flags.always_sparkplug = false;
+#endif // V8_ENABLE_SPARKPLUG
+ i::v8_flags.optimize_for_size = false;
+ i::v8_flags.incremental_marking = true;
+ i::v8_flags.flush_bytecode = true;
+ i::v8_flags.allow_natives_syntax = true;
+ ManualGCScope manual_gc_scope(i_isolate());
+
+ v8::HandleScope outer_scope(v8_isolate());
+ const char* source =
+ "function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "};"
+ "foo()";
+ DirectHandle<String> foo_name = factory()->InternalizeUtf8String("foo");
+
+ // This compile will add the code to the compilation cache.
+ {
+ v8::HandleScope scope(v8_isolate());
+ RunJS(source);
+ }
+
+ // Check function is compiled.
+ DirectHandle<Object> func_value =
+ Object::GetProperty(i_isolate(), i_isolate()->global_object(), foo_name)
+ .ToHandleChecked();
+ EXPECT_TRUE(IsJSFunction(*func_value));
+ DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
+ EXPECT_TRUE(function->shared()->is_compiled());
+
+ // The code will survive at least two GCs.
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ InvokeMajorGC();
+ }
+ EXPECT_TRUE(function->shared()->is_compiled());
+
+ i::SharedFunctionInfo::EnsureOldForTesting(function->shared());
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+
+ EXPECT_FALSE(function->shared()->is_compiled());
+ EXPECT_FALSE(function->is_compiled(i_isolate()));
+
+ // This compile will compile the function again.
+ {
+ v8::HandleScope scope(v8_isolate());
+ RunJS("foo();");
+ }
+
+ SharedFunctionInfo::EnsureOldForTesting(function->shared());
+ SimulateIncrementalMarking();
+
+ // Force optimization while incremental marking is active and while
+ // the function is enqueued as a candidate.
+ {
+ v8::HandleScope scope(v8_isolate());
+ RunJS(
+ "%PrepareFunctionForOptimization(foo); foo();"
+ "%OptimizeFunctionOnNextCall(foo); foo();");
+ }
+
+ // Simulate one final GC and make sure the candidate wasn't flushed.
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+ EXPECT_TRUE(function->shared()->is_compiled());
+ EXPECT_TRUE(function->is_compiled(i_isolate()));
+}
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+
+TEST_F(HeapTest, MultiReferencedBytecodeFlushingBothOld) {
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ v8_flags.turbofan = false;
+ i::v8_flags.optimize_for_size = false;
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+#ifdef V8_ENABLE_SPARKPLUG
+ v8_flags.always_sparkplug = false;
+ v8_flags.flush_baseline_code = true;
+#endif // V8_ENABLE_SPARKPLUG
+ i::v8_flags.flush_bytecode = true;
+ i::v8_flags.allow_natives_syntax = true;
+
+ ManualGCScope manual_gc_scope(i_isolate());
+ v8::HandleScope scope(v8_isolate());
+ const char* source =
+ "function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "};"
+ "foo()";
+ DirectHandle<String> foo_name = factory()->InternalizeUtf8String("foo");
+
+ // This compile will add the code to the compilation cache.
+ {
+ v8::HandleScope new_scope(v8_isolate());
+ RunJS(source);
+ }
+
+ // Check function is compiled.
+ DirectHandle<Object> func_value =
+ Object::GetProperty(i_isolate(), i_isolate()->global_object(), foo_name)
+ .ToHandleChecked();
+ EXPECT_TRUE(IsJSFunction(*func_value));
+ DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
+ DirectHandle<SharedFunctionInfo> shared(function->shared(), i_isolate());
+ EXPECT_TRUE(shared->is_compiled());
+
+ // Make a copy of the SharedFunctionInfo which points to the same bytecode.
+ Handle<SharedFunctionInfo> copy = factory()->CloneSharedFunctionInfo(shared);
+
+ // Verify that both SFIs share the same BytecodeArray.
+ EXPECT_EQ(shared->GetBytecodeArray(i_isolate()),
+ copy->GetBytecodeArray(i_isolate()));
+
+ i::SharedFunctionInfo::EnsureOldForTesting(*shared);
+ i::SharedFunctionInfo::EnsureOldForTesting(*copy);
+
+ {
+ // We need to invoke GC without stack, otherwise some objects may not be
+ // reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+
+ // Both should be decompiled (flushed) because both were old.
+ EXPECT_FALSE(shared->is_compiled());
+ EXPECT_FALSE(copy->is_compiled());
+}
+
+TEST_F(HeapTest, Regress10843) {
+ v8_flags.max_semi_space_size = 2;
+ v8_flags.min_semi_space_size = 2;
+ v8_flags.max_old_space_size = 8;
+ v8_flags.compact_on_every_full_gc = true;
+ v8::Isolate::CreateParams create_params;
+ std::unique_ptr<v8::ArrayBuffer::Allocator> allocator(
+ v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+ create_params.array_buffer_allocator = allocator.get();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
+ Factory* factory = i_isolate->factory();
+ Heap* heap = i_isolate->heap();
+ bool callback_was_invoked = false;
+
+ heap->AddNearHeapLimitCallback(
+ [](void* data, size_t current_heap_limit,
+ size_t initial_heap_limit) -> size_t {
+ *reinterpret_cast<bool*>(data) = true;
+ return current_heap_limit * 2;
+ },
+ &callback_was_invoked);
+
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ PtrComprCageAccessScope ptr_compr_cage_access_scope(i_isolate);
+ HandleScope scope(i_isolate);
+ std::vector<Handle<FixedArray>> arrays;
+ for (int i = 0; i < 140; i++) {
+ arrays.push_back(factory->NewFixedArray(10000));
+ }
+ i::InvokeMajorGC(i_isolate);
+ i::InvokeMajorGC(i_isolate);
+ for (int i = 0; i < 40; i++) {
+ arrays.push_back(factory->NewFixedArray(10000));
+ }
+ i::InvokeMajorGC(i_isolate);
+ for (int i = 0; i < 100; i++) {
+ arrays.push_back(factory->NewFixedArray(10000));
+ }
+ i::InvokeMajorGC(i_isolate);
+ EXPECT_TRUE(callback_was_invoked);
+ }
+ isolate->Dispose();
+}
+
+TEST_F(HeapTest, Regress10560) {
+ i::v8_flags.flush_bytecode = true;
+ i::v8_flags.allow_natives_syntax = true;
+ // Disable flags that allocate a feedback vector eagerly.
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ i::v8_flags.turbofan = false;
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+#ifdef V8_ENABLE_SPARKPLUG
+ v8_flags.always_sparkplug = false;
+#endif // V8_ENABLE_SPARKPLUG
+ i::v8_flags.lazy_feedback_allocation = true;
+
+ ManualGCScope manual_gc_scope(i_isolate());
+ v8::HandleScope scope(v8_isolate());
+ const char* source =
+ "function foo() {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ "};"
+ "foo()";
+ DirectHandle<String> foo_name = factory()->InternalizeUtf8String("foo");
+ RunJS(source);
+
+ // Check function is compiled.
+ DirectHandle<Object> func_value =
+ Object::GetProperty(i_isolate(), i_isolate()->global_object(), foo_name)
+ .ToHandleChecked();
+ EXPECT_TRUE(IsJSFunction(*func_value));
+ DirectHandle<JSFunction> function = Cast<JSFunction>(func_value);
+ EXPECT_TRUE(function->shared()->is_compiled());
+ EXPECT_FALSE(function->has_feedback_vector());
+
+ // Pre-age bytecode so it will be flushed on next run.
+ EXPECT_TRUE(function->shared()->HasBytecodeArray());
+ SharedFunctionInfo::EnsureOldForTesting(function->shared());
+
+ SimulateFullSpace(heap()->old_space());
+
+ // Just check bytecode isn't flushed still
+ EXPECT_TRUE(function->shared()->is_compiled());
+
+ heap()->set_force_gc_on_next_allocation(true);
+
+ // Allocate feedback vector.
+ IsCompiledScope is_compiled_scope(
+ function->shared()->is_compiled_scope(i_isolate()));
+ JSFunction::EnsureFeedbackVector(i_isolate(), function, &is_compiled_scope);
+
+ EXPECT_TRUE(function->has_feedback_vector());
+ EXPECT_TRUE(function->shared()->is_compiled());
+ EXPECT_TRUE(function->is_compiled(i_isolate()));
+}
+
+using LeakNativeContextViaMapKeyedTest = TestWithHeapInternals;
+
+TEST_F(LeakNativeContextViaMapKeyedTest, LeakNativeContextViaMapKeyed) {
+ v8_flags.allow_natives_syntax = true;
+ v8::Isolate* isolate = v8_isolate();
+ Heap* heap_instance = heap();
+ v8::HandleScope outer_scope(isolate);
+ v8::Persistent<v8::Context> ctx1p;
+ v8::Persistent<v8::Context> ctx2p;
+ {
+ v8::HandleScope scope(isolate);
+ ctx1p.Reset(isolate, v8::Context::New(isolate));
+ ctx2p.Reset(isolate, v8::Context::New(isolate));
+ v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
+ }
+
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(2, NumberOfGlobalObjects());
+
+ {
+ v8::HandleScope inner_scope(isolate);
+ v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
+ v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
+ RunJS(ctx1, "var v = [42, 43];");
+ v8::Local<v8::Value> v =
+ ctx1->Global()
+ ->Get(ctx1, v8::String::NewFromUtf8Literal(isolate, "v"))
+ .ToLocalChecked();
+ ctx2->Enter();
+ EXPECT_TRUE(ctx2->Global()
+ ->Set(ctx2, v8::String::NewFromUtf8Literal(isolate, "o"), v)
+ .FromJust());
+ Handle<Object> res = RunJS(ctx2,
+ "function f() { return o[0]; }"
+ "%PrepareFunctionForOptimization(f);"
+ "for (var i = 0; i < 10; ++i) f();"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ EXPECT_EQ(42, Object::NumberValue(*res));
+ EXPECT_TRUE(ctx2->Global()
+ ->Set(ctx2, v8::String::NewFromUtf8Literal(isolate, "o"),
+ v8::Int32::New(isolate, 0))
+ .FromJust());
+ ctx2->Exit();
+ v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
+ ctx1p.Reset();
+ isolate->ContextDisposedNotification(
+ v8::ContextDependants::kSomeDependants);
+ }
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(1, NumberOfGlobalObjects());
+ ctx2p.Reset();
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(0, NumberOfGlobalObjects());
+}
+
+namespace {
+size_t near_heap_limit_invocation_count = 0;
+size_t InvokeGCNearHeapLimitCallback(void* data, size_t current_heap_limit,
+ size_t initial_heap_limit) {
+ near_heap_limit_invocation_count++;
+ if (near_heap_limit_invocation_count > 1) {
+ // We are already in a GC triggered in this callback, raise the limit
+ // to avoid an OOM.
+ return current_heap_limit * 5;
+ }
+
+ DCHECK_EQ(near_heap_limit_invocation_count, 1);
+ // Operations that may cause GC (e.g. taking heap snapshots) in the
+ // near heap limit callback should not hit the AllowGarbageCollection
+ // assertion.
+ static_cast<v8::Isolate*>(data)->GetHeapProfiler()->TakeHeapSnapshot();
+ return current_heap_limit * 5;
+}
+} // namespace
+
+TEST_F(HeapTest, Regress12777) {
+ v8::Isolate::CreateParams create_params;
+ create_params.constraints.set_max_old_generation_size_in_bytes(10 * i::MB);
+ std::unique_ptr<v8::ArrayBuffer::Allocator> allocator(
+ v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+ create_params.array_buffer_allocator = allocator.get();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+
+ near_heap_limit_invocation_count = 0;
+ isolate->AddNearHeapLimitCallback(InvokeGCNearHeapLimitCallback, isolate);
+
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+
+ Isolate* i_isolate = reinterpret_cast<Isolate*>(isolate);
+ // Allocate data to trigger the NearHeapLimitCallback.
+ HandleScope scope(i_isolate);
+ int length = 2 * i::MB / i::kTaggedSize;
+ std::vector<Handle<FixedArray>> arrays;
+ for (int i = 0; i < 5; i++) {
+ arrays.push_back(i_isolate->factory()->NewFixedArray(length));
+ }
+ i::InvokeMajorGC(i_isolate);
+ for (int i = 0; i < 5; i++) {
+ arrays.push_back(i_isolate->factory()->NewFixedArray(length));
+ }
+ i::InvokeMajorGC(i_isolate);
+ for (int i = 0; i < 5; i++) {
+ arrays.push_back(i_isolate->factory()->NewFixedArray(length));
+ }
+ i::InvokeMajorGC(i_isolate);
+ EXPECT_GT(near_heap_limit_invocation_count, 0u);
+ }
+ isolate->Dispose();
+}
+
+TEST_F(HeapTest, LeakNativeContextViaMap) {
+ v8_flags.allow_natives_syntax = true;
+ v8::Isolate* isolate = v8_isolate();
+ Heap* heap_instance = heap();
+ v8::HandleScope outer_scope(isolate);
+ v8::Persistent<v8::Context> ctx1p;
+ v8::Persistent<v8::Context> ctx2p;
+ {
+ v8::HandleScope scope(isolate);
+ ctx1p.Reset(isolate, v8::Context::New(isolate));
+ ctx2p.Reset(isolate, v8::Context::New(isolate));
+ v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
+ }
+
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ // HeapTest creates and enters a default context (context 0) which is
+ // unaffected by the test, so there are 3 global objects initially (default
+ // context + ctx1 + ctx2).
+ EXPECT_EQ(3, NumberOfGlobalObjects());
+
+ {
+ v8::HandleScope inner_scope(isolate);
+ v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
+ v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
+ RunJS(ctx1, "var v = {x: 42};");
+ v8::Local<v8::Value> v =
+ ctx1->Global()
+ ->Get(ctx1, v8::String::NewFromUtf8Literal(isolate, "v"))
+ .ToLocalChecked();
+ ctx2->Enter();
+ EXPECT_TRUE(ctx2->Global()
+ ->Set(ctx2, v8::String::NewFromUtf8Literal(isolate, "o"), v)
+ .FromJust());
+ Handle<Object> res = RunJS(ctx2,
+ "function f() { return o.x; }"
+ "%PrepareFunctionForOptimization(f);"
+ "for (var i = 0; i < 10; ++i) f();"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ EXPECT_EQ(42, Object::NumberValue(*res));
+ EXPECT_TRUE(ctx2->Global()
+ ->Set(ctx2, v8::String::NewFromUtf8Literal(isolate, "o"),
+ v8::Int32::New(isolate, 0))
+ .FromJust());
+ ctx2->Exit();
+ v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
+ ctx1p.Reset();
+ isolate->ContextDisposedNotification(
+ v8::ContextDependants::kSomeDependants);
+ }
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(2, NumberOfGlobalObjects());
+ ctx2p.Reset();
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(1, NumberOfGlobalObjects());
+}
+
+TEST_F(HeapTest, LeakNativeContextViaMapProto) {
+ v8_flags.allow_natives_syntax = true;
+ v8::Isolate* isolate = v8_isolate();
+ Heap* heap_instance = heap();
+ v8::HandleScope outer_scope(isolate);
+ v8::Persistent<v8::Context> ctx1p;
+ v8::Persistent<v8::Context> ctx2p;
+ {
+ v8::HandleScope scope(isolate);
+ ctx1p.Reset(isolate, v8::Context::New(isolate));
+ ctx2p.Reset(isolate, v8::Context::New(isolate));
+ v8::Local<v8::Context>::New(isolate, ctx1p)->Enter();
+ }
+
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(3, NumberOfGlobalObjects());
+
+ {
+ v8::HandleScope inner_scope(isolate);
+ v8::Local<v8::Context> ctx1 = v8::Local<v8::Context>::New(isolate, ctx1p);
+ v8::Local<v8::Context> ctx2 = v8::Local<v8::Context>::New(isolate, ctx2p);
+ RunJS(ctx1, "var v = { y: 42};");
+ v8::Local<v8::Value> v =
+ ctx1->Global()
+ ->Get(ctx1, v8::String::NewFromUtf8Literal(isolate, "v"))
+ .ToLocalChecked();
+ ctx2->Enter();
+ EXPECT_TRUE(ctx2->Global()
+ ->Set(ctx2, v8::String::NewFromUtf8Literal(isolate, "o"), v)
+ .FromJust());
+ Handle<Object> res = RunJS(ctx2,
+ "function f() {"
+ " var p = {x: 42};"
+ " p.__proto__ = o;"
+ " return p.x;"
+ "}"
+ "%PrepareFunctionForOptimization(f);"
+ "for (var i = 0; i < 10; ++i) f();"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ EXPECT_EQ(42, Object::NumberValue(*res));
+ EXPECT_TRUE(ctx2->Global()
+ ->Set(ctx2, v8::String::NewFromUtf8Literal(isolate, "o"),
+ v8::Int32::New(isolate, 0))
+ .FromJust());
+ ctx2->Exit();
+ v8::Local<v8::Context>::New(isolate, ctx1)->Exit();
+ ctx1p.Reset();
+ isolate->ContextDisposedNotification(
+ v8::ContextDependants::kSomeDependants);
+ }
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(2, NumberOfGlobalObjects());
+ ctx2p.Reset();
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ heap_instance);
+ InvokeMemoryReducingMajorGCs();
+ }
+ EXPECT_EQ(1, NumberOfGlobalObjects());
+}
+
+TEST_F(HeapTest, OptimizedPretenuringNestedDoubleLiterals) {
+ v8_flags.allow_natives_syntax = true;
+ v8_flags.expose_gc = true;
+ if (!i_isolate()->use_optimizer()) return;
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
+ return;
+ }
+ v8::HandleScope scope(v8_isolate());
+ const char* extension_names[] = {"v8/gc"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Local<v8::Context> ctx = v8::Context::New(v8_isolate(), &extensions);
+ v8::Context::Scope context_scope(ctx);
+ ManualGCScope manual_gc_scope(i_isolate());
+ GrowNewSpaceToMaximumCapacity();
+
+ static const int kPretenureCreationCount =
+ PretenuringHandler::GetMinMementoCountForTesting() + 1;
+
+ auto source = base::OwnedVector<char>::NewForOverwrite(1024);
+ base::SNPrintF(source.as_vector(),
+ "var number_elements = %d;"
+ "var elements = new Array(number_elements);"
+ "function f() {"
+ " for (var i = 0; i < number_elements; i++) {"
+ " elements[i] = [[1.1, 1.2, 1.3],[2.1, 2.2, 2.3]];"
+ " }"
+ " return elements[number_elements - 1];"
+ "};"
+ "%%PrepareFunctionForOptimization(f);"
+ "f(); gc({type: 'minor'});"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ kPretenureCreationCount);
+
+ Handle<JSObject> o = Cast<JSObject>(RunJS(ctx, source.begin()));
+
+ DirectHandle<JSObject> double_array_handle_1 = Cast<JSObject>(
+ JSReceiver::GetElement(i_isolate(), o, 0).ToHandleChecked());
+ DirectHandle<JSObject> double_array_handle_2 = Cast<JSObject>(
+ JSReceiver::GetElement(i_isolate(), o, 1).ToHandleChecked());
+
+ EXPECT_TRUE(heap()->InOldSpace(*o));
+ EXPECT_TRUE(heap()->InOldSpace(*double_array_handle_1));
+ EXPECT_TRUE(heap()->InOldSpace(double_array_handle_1->elements()));
+ EXPECT_TRUE(heap()->InOldSpace(*double_array_handle_2));
+ EXPECT_TRUE(heap()->InOldSpace(double_array_handle_2->elements()));
+}
+TEST_F(HeapTest, OptimizedPretenuringNestedInObjectProperties) {
+ v8_flags.allow_natives_syntax = true;
+ v8_flags.expose_gc = true;
+ if (!i_isolate()->use_optimizer()) return;
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
+ return;
+ }
+ v8::HandleScope scope(v8_isolate());
+ const char* extension_names[] = {"v8/gc"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Local<v8::Context> ctx = v8::Context::New(v8_isolate(), &extensions);
+ v8::Context::Scope context_scope(ctx);
+ ManualGCScope manual_gc_scope(i_isolate());
+ GrowNewSpaceToMaximumCapacity();
+
+ static const int kPretenureCreationCount =
+ PretenuringHandler::GetMinMementoCountForTesting() + 1;
+
+ auto source = base::OwnedVector<char>::NewForOverwrite(1024);
+ base::SNPrintF(
+ source.as_vector(),
+ "let number_elements = %d;"
+ "let elements = new Array(number_elements);"
+ "function f() {"
+ " for (let i = 0; i < number_elements; i++) {"
+ " let l = {a: {b: {c: {d: {e: 2.2}, e: 3.3}, g: {h: 1.1}}}}; "
+ " elements[i] = l.a.b.c.d;"
+ " }"
+ " return elements[number_elements-1];"
+ "};"
+ "%%PrepareFunctionForOptimization(f);"
+ "f(); gc({type: 'minor'}); gc({type: 'minor'});"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ kPretenureCreationCount);
+
+ Handle<JSObject> o = Cast<JSObject>(RunJS(ctx, source.begin()));
+
+ EXPECT_TRUE(HeapLayout::InYoungGeneration(*o));
+}
+TEST_F(HeapTest, OptimizedPretenuringNestedObjectLiterals) {
+ v8_flags.allow_natives_syntax = true;
+ v8_flags.expose_gc = true;
+ if (!i_isolate()->use_optimizer()) return;
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
+ return;
+ }
+ v8::HandleScope scope(v8_isolate());
+ const char* extension_names[] = {"v8/gc"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Local<v8::Context> ctx = v8::Context::New(v8_isolate(), &extensions);
+ v8::Context::Scope context_scope(ctx);
+ ManualGCScope manual_gc_scope(i_isolate());
+ GrowNewSpaceToMaximumCapacity();
+
+ static const int kPretenureCreationCount =
+ PretenuringHandler::GetMinMementoCountForTesting() + 1;
+
+ auto source = base::OwnedVector<char>::NewForOverwrite(1024);
+ base::SNPrintF(source.as_vector(),
+ "var number_elements = %d;"
+ "var elements = new Array(number_elements);"
+ "function f() {"
+ " for (var i = 0; i < number_elements; i++) {"
+ " elements[i] = [[{}, {}, {}],[{}, {}, {}]];"
+ " }"
+ " return elements[number_elements - 1];"
+ "};"
+ "%%PrepareFunctionForOptimization(f);"
+ "f(); gc({type: 'minor'});"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ kPretenureCreationCount);
+
+ Handle<JSObject> o = Cast<JSObject>(RunJS(ctx, source.begin()));
+
+ DirectHandle<JSObject> int_array_handle_1 = Cast<JSObject>(
+ JSReceiver::GetElement(i_isolate(), o, 0).ToHandleChecked());
+ DirectHandle<JSObject> int_array_handle_2 = Cast<JSObject>(
+ JSReceiver::GetElement(i_isolate(), o, 1).ToHandleChecked());
+
+ EXPECT_TRUE(heap()->InOldSpace(*o));
+ EXPECT_TRUE(heap()->InOldSpace(*int_array_handle_1));
+ EXPECT_TRUE(heap()->InOldSpace(int_array_handle_1->elements()));
+ EXPECT_TRUE(heap()->InOldSpace(*int_array_handle_2));
+ EXPECT_TRUE(heap()->InOldSpace(int_array_handle_2->elements()));
+}
+TEST_F(HeapTest, OptimizedPretenuringMixedInObjectProperties) {
+ v8_flags.allow_natives_syntax = true;
+ v8_flags.expose_gc = true;
+ if (!i_isolate()->use_optimizer()) return;
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
+ return;
+ }
+ v8::HandleScope scope(v8_isolate());
+ const char* extension_names[] = {"v8/gc"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Local<v8::Context> ctx = v8::Context::New(v8_isolate(), &extensions);
+ v8::Context::Scope context_scope(ctx);
+ ManualGCScope manual_gc_scope(i_isolate());
+ GrowNewSpaceToMaximumCapacity();
+
+ static const int kPretenureCreationCount =
+ PretenuringHandler::GetMinMementoCountForTesting() + 1;
+
+ auto source = base::OwnedVector<char>::NewForOverwrite(1024);
+ base::SNPrintF(source.as_vector(),
+ "var number_elements = %d;"
+ "var elements = new Array(number_elements);"
+ "function f() {"
+ " for (var i = 0; i < number_elements; i++) {"
+ " elements[i] = {a: {c: 2.2, d: {}}, b: 1.1};"
+ " }"
+ " return elements[number_elements - 1];"
+ "};"
+ "%%PrepareFunctionForOptimization(f);"
+ "f(); gc({type: 'minor'});"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ kPretenureCreationCount);
+
+ Handle<JSObject> o = Cast<JSObject>(RunJS(ctx, source.begin()));
+
+ EXPECT_TRUE(heap()->InOldSpace(*o));
+ FieldIndex idx1 = FieldIndex::ForPropertyIndex(o->map(), 0);
+ FieldIndex idx2 = FieldIndex::ForPropertyIndex(o->map(), 1);
+ EXPECT_TRUE(heap()->InOldSpace(o->RawFastPropertyAt(idx1)));
+ EXPECT_TRUE(heap()->InOldSpace(o->RawFastPropertyAt(idx2)));
+
+ Tagged<JSObject> inner_object = Cast<JSObject>(o->RawFastPropertyAt(idx1));
+ EXPECT_TRUE(heap()->InOldSpace(inner_object));
+ EXPECT_TRUE(heap()->InOldSpace(inner_object->RawFastPropertyAt(idx1)));
+ EXPECT_TRUE(heap()->InOldSpace(inner_object->RawFastPropertyAt(idx2)));
+}
+
+TEST_F(HeapTest, OptimizedPretenuringDoubleArrayLiterals) {
+ v8_flags.allow_natives_syntax = true;
+ v8_flags.expose_gc = true;
+ if (!i_isolate()->use_optimizer()) return;
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
+ return;
+ }
+ v8::HandleScope scope(v8_isolate());
+ const char* extension_names[] = {"v8/gc"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Local<v8::Context> ctx = v8::Context::New(v8_isolate(), &extensions);
+ v8::Context::Scope context_scope(ctx);
+ ManualGCScope manual_gc_scope(i_isolate());
+ GrowNewSpaceToMaximumCapacity();
+
+ static const int kPretenureCreationCount =
+ PretenuringHandler::GetMinMementoCountForTesting() + 1;
+
+ auto source = base::OwnedVector<char>::NewForOverwrite(1024);
+ base::SNPrintF(source.as_vector(),
+ "var number_elements = %d;"
+ "var elements = new Array(number_elements);"
+ "function f() {"
+ " for (var i = 0; i < number_elements; i++) {"
+ " elements[i] = [1.1, 2.2, 3.3];"
+ " }"
+ " return elements[number_elements - 1];"
+ "};"
+ "%%PrepareFunctionForOptimization(f);"
+ "f(); gc({type: 'minor'});"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ kPretenureCreationCount);
+
+ Handle<JSObject> o = Cast<JSObject>(RunJS(ctx, source.begin()));
+
+ EXPECT_TRUE(heap()->InOldSpace(o->elements()));
+ EXPECT_TRUE(heap()->InOldSpace(*o));
+}
+
+TEST_F(HeapTest, OptimizedPretenuringNestedMixedArrayLiterals) {
+ v8_flags.allow_natives_syntax = true;
+ v8_flags.expose_gc = true;
+ if (!i_isolate()->use_optimizer()) return;
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.stress_concurrent_allocation || v8_flags.scavenger_chaos_mode) {
+ return;
+ }
+ v8::HandleScope scope(v8_isolate());
+ const char* extension_names[] = {"v8/gc"};
+ v8::ExtensionConfiguration extensions(1, extension_names);
+ v8::Local<v8::Context> ctx = v8::Context::New(v8_isolate(), &extensions);
+ v8::Context::Scope context_scope(ctx);
+ ManualGCScope manual_gc_scope(i_isolate());
+ GrowNewSpaceToMaximumCapacity();
+
+ static const int kPretenureCreationCount =
+ PretenuringHandler::GetMinMementoCountForTesting() + 1;
+
+ auto source = base::OwnedVector<char>::NewForOverwrite(1024);
+ base::SNPrintF(source.as_vector(),
+ "var number_elements = %d;"
+ "var elements = new Array(number_elements);"
+ "function f() {"
+ " for (var i = 0; i < number_elements; i++) {"
+ " elements[i] = [[{}, {}, {}], [1.1, 2.2, 3.3]];"
+ " }"
+ " return elements[number_elements - 1];"
+ "};"
+ "%%PrepareFunctionForOptimization(f);"
+ "f(); gc({type: 'minor'});"
+ "f(); f();"
+ "%%OptimizeFunctionOnNextCall(f);"
+ "f();",
+ kPretenureCreationCount);
+
+ Handle<JSObject> o = Cast<JSObject>(RunJS(ctx, source.begin()));
+
+ v8::Local<v8::Value> int_array = v8::Utils::ToLocal(o)
+ ->ToObject(ctx)
+ .ToLocalChecked()
+ ->Get(ctx, NewString("0"))
+ .ToLocalChecked();
+ i::DirectHandle<JSObject> int_array_handle = i::Cast<JSObject>(
+ v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(int_array)));
+ v8::Local<v8::Value> double_array = v8::Utils::ToLocal(o)
+ ->ToObject(ctx)
+ .ToLocalChecked()
+ ->Get(ctx, NewString("1"))
+ .ToLocalChecked();
+ i::DirectHandle<JSObject> double_array_handle = i::Cast<JSObject>(
+ v8::Utils::OpenDirectHandle(*v8::Local<v8::Object>::Cast(double_array)));
+
+ EXPECT_TRUE(heap()->InOldSpace(*o));
+ EXPECT_TRUE(heap()->InOldSpace(*int_array_handle));
+ EXPECT_TRUE(heap()->InOldSpace(int_array_handle->elements()));
+ EXPECT_TRUE(heap()->InOldSpace(*double_array_handle));
+ EXPECT_TRUE(heap()->InOldSpace(double_array_handle->elements()));
+}
+
+TEST_F(HeapTest, IncrementalMarkingPreservesMonomorphicConstructor) {
+ if (!v8_flags.incremental_marking) return;
+ v8_flags.allow_natives_syntax = true;
+ v8::HandleScope scope(v8_isolate());
+ v8::Local<v8::Context> ctx = v8_isolate()->GetCurrentContext();
+ // Prepare function f that contains a monomorphic IC for object
+ // originating from the same native context.
+ RunJS(ctx,
+ "function fun() { this.x = 1; };"
+ "function f(o) { return new o(); }"
+ "%EnsureFeedbackVectorForFunction(f);"
+ "f(fun); f(fun);");
+ DirectHandle<JSFunction> f = Cast<JSFunction>(
+ v8::Utils::OpenDirectHandle(*v8::Local<v8::Function>::Cast(
+ ctx->Global()
+ ->Get(ctx, v8::String::NewFromUtf8Literal(v8_isolate(), "f"))
+ .ToLocalChecked())));
+
+ DirectHandle<FeedbackVector> vector(f->feedback_vector(), i_isolate());
+ EXPECT_TRUE(vector->Get(FeedbackSlot(0)).IsWeakOrCleared());
+
+ SimulateIncrementalMarking();
+ InvokeMajorGC();
+
+ EXPECT_TRUE(vector->Get(FeedbackSlot(0)).IsWeakOrCleared());
+}
+namespace {
+
+template <typename T>
+DirectHandle<SharedFunctionInfo> GetSharedFunctionInfo(
+ v8::Local<T> function_or_script, Isolate* isolate) {
+ DirectHandle<JSFunction> i_function =
+ Cast<JSFunction>(v8::Utils::OpenDirectHandle(*function_or_script));
+ return direct_handle(i_function->shared(), isolate);
+}
+
+template <typename T>
+void AgeBytecode(v8::Local<T> function_or_script, Isolate* isolate) {
+ DirectHandle<SharedFunctionInfo> shared =
+ GetSharedFunctionInfo(function_or_script, isolate);
+ EXPECT_TRUE(shared->HasBytecodeArray());
+ SharedFunctionInfo::EnsureOldForTesting(*shared);
+}
+
+void RunCompilationCacheRegenerationTest(HeapTest* test, bool retain_root_sfi,
+ bool flush_root_sfi,
+ bool flush_eager_sfi) {
+ // If the compilation cache is turned off, this test is invalid.
+ if (!v8_flags.compilation_cache) {
+ return;
+ }
+
+ // Skip test if code flushing was disabled.
+ if (!v8_flags.flush_bytecode ||
+ (v8_flags.always_sparkplug && !v8_flags.flush_baseline_code)) {
+ return;
+ }
+
+ Isolate* isolate = test->i_isolate();
+ Heap* heap = test->heap();
+ v8::Isolate* v8_isolate = test->v8_isolate();
+
+ const char* source =
+ "({"
+ " lazyFunction: function () {"
+ " var x = 42;"
+ " var y = 42;"
+ " var z = x + y;"
+ " },"
+ " eagerFunction: (function () {"
+ " var x = 43;"
+ " var y = 43;"
+ " var z = x + y;"
+ " })"
+ "})";
+
+ v8::Global<v8::Script> outer_function;
+ v8::Global<v8::Function> lazy_function;
+ v8::Global<v8::Function> eager_function;
+
+ {
+ v8::HandleScope scope(v8_isolate);
+ v8::Local<v8::Context> context = test->context();
+ v8::Local<v8::String> source_str =
+ v8::String::NewFromUtf8(v8_isolate, source).ToLocalChecked();
+ v8::Local<v8::Script> script =
+ v8::Script::Compile(context, source_str).ToLocalChecked();
+ outer_function.Reset(v8_isolate, script);
+
+ // Even though the script has not executed, it should already be parsed.
+ DirectHandle<SharedFunctionInfo> script_sfi =
+ GetSharedFunctionInfo(script, isolate);
+ EXPECT_TRUE(script_sfi->is_compiled());
+
+ v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
+
+ // Now that the script has run, we can get references to the inner
+ // functions, and verify that the eager parsing heuristics are behaving as
+ // expected.
+ v8::Local<v8::Object> result_obj =
+ result->ToObject(context).ToLocalChecked();
+ v8::Local<v8::Value> lazy_function_value =
+ result_obj
+ ->GetRealNamedProperty(
+ context, v8::String::NewFromUtf8(v8_isolate, "lazyFunction")
+ .ToLocalChecked())
+ .ToLocalChecked();
+ EXPECT_TRUE(lazy_function_value->IsFunction());
+ EXPECT_FALSE(
+ GetSharedFunctionInfo(lazy_function_value, isolate)->is_compiled());
+ lazy_function.Reset(v8_isolate, lazy_function_value.As<v8::Function>());
+ v8::Local<v8::Value> eager_function_value =
+ result_obj
+ ->GetRealNamedProperty(
+ context, v8::String::NewFromUtf8(v8_isolate, "eagerFunction")
+ .ToLocalChecked())
+ .ToLocalChecked();
+ EXPECT_TRUE(eager_function_value->IsFunction());
+ eager_function.Reset(v8_isolate, eager_function_value.As<v8::Function>());
+ EXPECT_TRUE(
+ GetSharedFunctionInfo(eager_function_value, isolate)->is_compiled());
+ }
+
+ {
+ v8::HandleScope scope(v8_isolate);
+
+ // Progress code age until it's old and ready for GC.
+ if (flush_root_sfi) {
+ v8::Local<v8::Script> outer_function_value =
+ outer_function.Get(v8_isolate);
+ AgeBytecode(outer_function_value, isolate);
+ }
+ if (flush_eager_sfi) {
+ v8::Local<v8::Function> eager_function_value =
+ eager_function.Get(v8_isolate);
+ AgeBytecode(eager_function_value, isolate);
+ }
+ if (!retain_root_sfi) {
+ outer_function.Reset();
+ }
+ }
+
+ {
+ // In these tests, we need to invoke GC without stack, otherwise some
+ // objects may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+
+ if (v8_flags.stress_incremental_marking) {
+ // This GC finishes incremental marking if it is already running. If
+ // incremental marking was already running we would not flush the code
+ // right away.
+ test->InvokeMajorGC();
+ }
+
+ // The first GC performs code flushing.
+ test->InvokeMajorGC();
+ // The second GC clears the entry from the compilation cache.
+ test->InvokeMajorGC();
+ }
+
+ // The root SharedFunctionInfo can be retained either by a Global in this
+ // function or by the compilation cache.
+ bool root_sfi_should_still_exist = retain_root_sfi || !flush_root_sfi;
+
+ {
+ v8::HandleScope scope(v8_isolate);
+
+ // The lazy function should still not be compiled.
+ DirectHandle<SharedFunctionInfo> lazy_sfi =
+ GetSharedFunctionInfo(lazy_function.Get(v8_isolate), isolate);
+ EXPECT_FALSE(lazy_sfi->is_compiled());
+
+ // The eager function may have had its bytecode flushed.
+ DirectHandle<SharedFunctionInfo> eager_sfi =
+ GetSharedFunctionInfo(eager_function.Get(v8_isolate), isolate);
+ EXPECT_EQ(!flush_eager_sfi, eager_sfi->is_compiled());
+
+ // Check whether the root SharedFunctionInfo is still reachable from the
+ // Script.
+ DirectHandle<Script> script(Cast<Script>(lazy_sfi->script()), isolate);
+ bool root_sfi_still_exists = false;
+ Tagged<MaybeObject> maybe_root_sfi =
+ script->infos()->get(kFunctionLiteralIdTopLevel);
+ if (Tagged<HeapObject> sfi_or_undefined;
+ maybe_root_sfi.GetHeapObject(&sfi_or_undefined)) {
+ root_sfi_still_exists = !IsUndefined(sfi_or_undefined);
+ }
+ EXPECT_EQ(root_sfi_should_still_exist, root_sfi_still_exists);
+ }
+
+ {
+ // Run the script again and check that no SharedFunctionInfos were
+ // duplicated, and that the expected ones were compiled.
+ v8::HandleScope scope(v8_isolate);
+ v8::Local<v8::Context> context = test->context();
+ v8::Local<v8::String> source_str =
+ v8::String::NewFromUtf8(v8_isolate, source).ToLocalChecked();
+ v8::Local<v8::Script> script =
+ v8::Script::Compile(context, source_str).ToLocalChecked();
+
+ // The script should be compiled by now.
+ DirectHandle<SharedFunctionInfo> script_sfi =
+ GetSharedFunctionInfo(script, isolate);
+ EXPECT_TRUE(script_sfi->is_compiled());
+
+ // This compilation should not have created a new root SharedFunctionInfo if
+ // one already existed.
+ if (retain_root_sfi) {
+ DirectHandle<SharedFunctionInfo> old_script_sfi =
+ GetSharedFunctionInfo(outer_function.Get(v8_isolate), isolate);
+ EXPECT_EQ(*old_script_sfi, *script_sfi);
+ }
+
+ DirectHandle<SharedFunctionInfo> old_lazy_sfi =
+ GetSharedFunctionInfo(lazy_function.Get(v8_isolate), isolate);
+ EXPECT_FALSE(old_lazy_sfi->is_compiled());
+
+ // The only way for the eager function to be uncompiled at this point is if
+ // it was flushed but the root function was not.
+ DirectHandle<SharedFunctionInfo> old_eager_sfi =
+ GetSharedFunctionInfo(eager_function.Get(v8_isolate), isolate);
+ EXPECT_EQ(!(flush_eager_sfi && !flush_root_sfi),
+ old_eager_sfi->is_compiled());
+
+ v8::Local<v8::Value> result = script->Run(context).ToLocalChecked();
+
+ // Check that both functions reused the existing SharedFunctionInfos.
+ v8::Local<v8::Object> result_obj =
+ result->ToObject(context).ToLocalChecked();
+ v8::Local<v8::Value> lazy_function_value =
+ result_obj
+ ->GetRealNamedProperty(
+ context, v8::String::NewFromUtf8(v8_isolate, "lazyFunction")
+ .ToLocalChecked())
+ .ToLocalChecked();
+ EXPECT_TRUE(lazy_function_value->IsFunction());
+ DirectHandle<SharedFunctionInfo> lazy_sfi =
+ GetSharedFunctionInfo(lazy_function_value, isolate);
+ EXPECT_EQ(*old_lazy_sfi, *lazy_sfi);
+ v8::Local<v8::Value> eager_function_value =
+ result_obj
+ ->GetRealNamedProperty(
+ context, v8::String::NewFromUtf8(v8_isolate, "eagerFunction")
+ .ToLocalChecked())
+ .ToLocalChecked();
+ EXPECT_TRUE(eager_function_value->IsFunction());
+ DirectHandle<SharedFunctionInfo> eager_sfi =
+ GetSharedFunctionInfo(eager_function_value, isolate);
+ EXPECT_EQ(*old_eager_sfi, *eager_sfi);
+ }
+}
+
+} // namespace
+
+TEST_F(HeapTest, CompilationCacheRegeneration0) {
+ RunCompilationCacheRegenerationTest(this, false, false, false);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration1) {
+ RunCompilationCacheRegenerationTest(this, false, false, true);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration2) {
+ RunCompilationCacheRegenerationTest(this, false, true, false);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration3) {
+ RunCompilationCacheRegenerationTest(this, false, true, true);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration4) {
+ RunCompilationCacheRegenerationTest(this, true, false, false);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration5) {
+ RunCompilationCacheRegenerationTest(this, true, false, true);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration6) {
+ RunCompilationCacheRegenerationTest(this, true, true, false);
+}
+
+TEST_F(HeapTest, CompilationCacheRegeneration7) {
+ RunCompilationCacheRegenerationTest(this, true, true, true);
+}
+
+void CheckWeakness(HeapTest* test, const char* source) {
+ // ManualGCScope is necessary to finalize any active incremental marking and
+ // disable concurrent/stress marking. Otherwise, under flags like
+ // --stress-incremental-marking, the isolate (initialized before this test
+ // runs) may already have active marking retaining the object, preventing the
+ // weak reference from being cleared.
+ ManualGCScope manual_gc_scope(test->isolate());
+ v8_flags.stress_compaction = false;
+ v8_flags.stress_incremental_marking = false;
+ v8_flags.allow_natives_syntax = true;
+
+ v8::Global<v8::Object> garbage;
+ {
+ v8::HandleScope scope(test->v8_isolate());
+ HandleScope i_scope(test->i_isolate());
+ v8::Local<v8::Object> obj =
+ v8::Utils::ToLocal(test->RunJS<JSObject>(source));
+ garbage.Reset(test->v8_isolate(), obj);
+ }
+ garbage.SetWeak();
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(
+ test->heap());
+ test->InvokeMajorGC();
+ }
+ EXPECT_TRUE(garbage.IsEmpty());
+}
+
+TEST_F(HeapTest, WeakFunctionInConstructor) {
+ // ManualGCScope is necessary to finalize any active incremental marking and
+ // disable concurrent/stress marking so that the weak reference can be
+ // cleared.
+ ManualGCScope manual_gc_scope(isolate());
+ v8_flags.stress_compaction = false;
+ v8_flags.stress_incremental_marking = false;
+ v8_flags.allow_natives_syntax = true;
+
+ RunJS(
+ "function createObj(obj) {"
+ " return new obj();"
+ "}");
+ DirectHandle<JSFunction> createObj = RunJS<JSFunction>("createObj");
+
+ v8::Global<v8::Object> garbage;
+ {
+ v8::HandleScope scope(v8_isolate());
+ HandleScope i_scope(i_isolate());
+ const char* source =
+ " (function() {"
+ " function hat() { this.x = 5; }"
+ " %EnsureFeedbackVectorForFunction(hat);"
+ " %EnsureFeedbackVectorForFunction(createObj);"
+ " createObj(hat);"
+ " createObj(hat);"
+ " return hat;"
+ " })();";
+ v8::Local<v8::Object> obj = v8::Utils::ToLocal(RunJS<JSObject>(source));
+ garbage.Reset(v8_isolate(), obj);
+ }
+ garbage.SetWeak();
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+ EXPECT_TRUE(garbage.IsEmpty());
+
+ // We've determined the constructor in createObj has had its weak cell
+ // cleared. Now, verify that one additional call with a new function
+ // allows monomorphicity.
+ DirectHandle<FeedbackVector> feedback_vector(createObj->feedback_vector(),
+ isolate());
+ for (int i = 0; i < 20; i++) {
+ Tagged<MaybeObject> slot_value = feedback_vector->Get(FeedbackSlot(0));
+ EXPECT_TRUE(slot_value.IsWeakOrCleared());
+ if (slot_value.IsCleared()) break;
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+
+ Tagged<MaybeObject> slot_value = feedback_vector->Get(FeedbackSlot(0));
+ EXPECT_TRUE(slot_value.IsCleared());
+ RunJS(
+ "function coat() { this.x = 6; }"
+ "createObj(coat);");
+ slot_value = feedback_vector->Get(FeedbackSlot(0));
+ EXPECT_TRUE(slot_value.IsWeak());
+}
+
+TEST_F(HeapTest, WeakMapInMonomorphicLoadIC) {
+ CheckWeakness(this,
+ "function loadIC(obj) {"
+ " return obj.name;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(loadIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " loadIC(obj);"
+ " loadIC(obj);"
+ " loadIC(obj);"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInPolymorphicLoadIC) {
+ CheckWeakness(this,
+ "function loadIC(obj) {"
+ " return obj.name;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(loadIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " loadIC(obj);"
+ " loadIC(obj);"
+ " loadIC(obj);"
+ " var poly = Object.create(proto);"
+ " poly.x = true;"
+ " loadIC(poly);"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInMonomorphicKeyedLoadIC) {
+ CheckWeakness(this,
+ "function keyedLoadIC(obj, field) {"
+ " return obj[field];"
+ "}"
+ "%EnsureFeedbackVectorForFunction(keyedLoadIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " keyedLoadIC(obj, 'name');"
+ " keyedLoadIC(obj, 'name');"
+ " keyedLoadIC(obj, 'name');"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInPolymorphicKeyedLoadIC) {
+ CheckWeakness(this,
+ "function keyedLoadIC(obj, field) {"
+ " return obj[field];"
+ "}"
+ "%EnsureFeedbackVectorForFunction(keyedLoadIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " keyedLoadIC(obj, 'name');"
+ " keyedLoadIC(obj, 'name');"
+ " keyedLoadIC(obj, 'name');"
+ " var poly = Object.create(proto);"
+ " poly.x = true;"
+ " keyedLoadIC(poly, 'name');"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInMonomorphicStoreIC) {
+ CheckWeakness(this,
+ "function storeIC(obj, value) {"
+ " obj.name = value;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(storeIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " storeIC(obj, 'x');"
+ " storeIC(obj, 'x');"
+ " storeIC(obj, 'x');"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInPolymorphicStoreIC) {
+ CheckWeakness(this,
+ "function storeIC(obj, value) {"
+ " obj.name = value;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(storeIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " storeIC(obj, 'x');"
+ " storeIC(obj, 'x');"
+ " storeIC(obj, 'x');"
+ " var poly = Object.create(proto);"
+ " poly.x = true;"
+ " storeIC(poly, 'x');"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInMonomorphicKeyedStoreIC) {
+ CheckWeakness(this,
+ "function keyedStoreIC(obj, field, value) {"
+ " obj[field] = value;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(keyedStoreIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " keyedStoreIC(obj, 'x');"
+ " keyedStoreIC(obj, 'x');"
+ " keyedStoreIC(obj, 'x');"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInPolymorphicKeyedStoreIC) {
+ CheckWeakness(this,
+ "function keyedStoreIC(obj, field, value) {"
+ " obj[field] = value;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(keyedStoreIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " keyedStoreIC(obj, 'x');"
+ " keyedStoreIC(obj, 'x');"
+ " keyedStoreIC(obj, 'x');"
+ " var poly = Object.create(proto);"
+ " poly.x = true;"
+ " keyedStoreIC(poly, 'x');"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, WeakMapInMonomorphicCompareNilIC) {
+ v8_flags.allow_natives_syntax = true;
+ CheckWeakness(this,
+ "function compareNilIC(obj) {"
+ " return obj == null;"
+ "}"
+ "%EnsureFeedbackVectorForFunction(compareNilIC);"
+ " (function() {"
+ " var proto = {'name' : 'weak'};"
+ " var obj = Object.create(proto);"
+ " compareNilIC(obj);"
+ " compareNilIC(obj);"
+ " compareNilIC(obj);"
+ " return proto;"
+ " })();");
+}
+
+TEST_F(HeapTest, TestSizeOfRegExpCode) {
+ if (!v8_flags.regexp_optimization) return;
+ v8_flags.stress_concurrent_allocation = false;
+
+ v8::HandleScope scope(v8_isolate());
+
+ EXPECT_EQ(static_cast<int>(RegExp::kMaxOptimizedPatternLength), 20 * KB);
+
+ // Compile a regexp that is much larger if we are using regexp optimizations.
+ RunJS(
+ "var reg_exp_source = '(?:a|bc|def|ghij|klmno|pqrstu)';"
+ "var half_size_reg_exp;"
+ "while (reg_exp_source.length < 20 * 1024) {"
+ " half_size_reg_exp = reg_exp_source;"
+ " reg_exp_source = reg_exp_source + reg_exp_source;"
+ "}"
+ // Flatten string.
+ "reg_exp_source.match(/f/);");
+
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ // Get initial heap size after several full GCs, which will stabilize
+ // the heap size and return with sweeping finished completely.
+ InvokeMemoryReducingMajorGCs();
+ if (heap()->sweeping_in_progress()) {
+ heap()->EnsureSweepingCompleted(
+ Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ }
+ }
+ int initial_size = static_cast<int>(heap()->SizeOfObjects());
+
+ RunJS("'foo'.match(reg_exp_source);");
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMemoryReducingMajorGCs();
+ }
+ int size_with_regexp = static_cast<int>(heap()->SizeOfObjects());
+
+ RunJS("'foo'.match(half_size_reg_exp);");
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMemoryReducingMajorGCs();
+ }
+ int size_with_optimized_regexp = static_cast<int>(heap()->SizeOfObjects());
+
+ int size_of_regexp_code = size_with_regexp - initial_size;
+
+ // On some platforms the debug-code flag causes huge amounts of regexp code
+ // to be emitted, breaking this test.
+ if (!v8_flags.debug_code) {
+ EXPECT_LE(size_of_regexp_code, 1 * MB);
+ }
+
+ // Small regexp is half the size, but compiles to more than twice the code
+ // due to the optimization steps.
+ EXPECT_GE(size_with_optimized_regexp,
+ size_with_regexp + size_of_regexp_code * 2);
+}
+
+TEST_F(HeapTest, TestSizeOfObjects) {
+ v8_flags.stress_concurrent_allocation = false;
+
+ // Disable LAB, such that calculations with SizeOfObjects() and object size
+ // are correct.
+ heap()->DisableInlineAllocation();
+
+ // Get initial heap size after several full GCs, which will stabilize
+ // the heap size and return with sweeping finished completely.
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMemoryReducingMajorGCs();
+ if (heap()->sweeping_in_progress()) {
+ heap()->EnsureSweepingCompleted(
+ Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ }
+ }
+ int initial_size = static_cast<int>(heap()->SizeOfObjects());
+
+ {
+ HandleScope scope(i_isolate());
+ // Allocate objects on several different old-space pages so that
+ // concurrent sweeper threads will be busy sweeping the old space on
+ // subsequent GC runs.
+ AlwaysAllocateScopeForTesting always_allocate(heap());
+ int filler_size = static_cast<int>(FixedArray::SizeFor(8192));
+ for (int i = 1; i <= 100; i++) {
+ i_isolate()->factory()->NewFixedArray(8192, AllocationType::kOld);
+ EXPECT_EQ(initial_size + i * filler_size,
+ static_cast<int>(heap()->SizeOfObjects()));
+ }
+ }
+
+ // The heap size should go back to initial size after a full GC, even
+ // though sweeping didn't finish yet.
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+ // Normally sweeping would not be complete here, but no guarantees.
+ EXPECT_EQ(initial_size, static_cast<int>(heap()->SizeOfObjects()));
+ // Waiting for sweeper threads should not change heap size.
+ if (heap()->sweeping_in_progress()) {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ heap()->EnsureSweepingCompleted(
+ Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ }
+ EXPECT_EQ(initial_size, static_cast<int>(heap()->SizeOfObjects()));
+}
+
+TEST_F(HeapTest, TestAlignmentCalculations) {
+ // Maximum fill amounts are consistent.
+ int maximum_double_misalignment = kDoubleSize - kTaggedSize;
+ int max_word_fill = MainAllocator::GetMaximumFillToAlign(kTaggedAligned);
+ EXPECT_EQ(0, max_word_fill);
+ int max_double_fill = MainAllocator::GetMaximumFillToAlign(kDoubleAligned);
+ EXPECT_EQ(maximum_double_misalignment, max_double_fill);
+ int max_double_unaligned_fill =
+ MainAllocator::GetMaximumFillToAlign(kDoubleUnaligned);
+ EXPECT_EQ(maximum_double_misalignment, max_double_unaligned_fill);
+
+ Address base = kNullAddress;
+ int fill = 0;
+
+ // Word alignment never requires fill.
+ fill = MainAllocator::GetFillToAlign(base, kTaggedAligned);
+ EXPECT_EQ(0, fill);
+ fill = MainAllocator::GetFillToAlign(base + kTaggedSize, kTaggedAligned);
+ EXPECT_EQ(0, fill);
+
+ // No fill is required when address is double aligned.
+ fill = MainAllocator::GetFillToAlign(base, kDoubleAligned);
+ EXPECT_EQ(0, fill);
+ // Fill is required if address is not double aligned.
+ fill = MainAllocator::GetFillToAlign(base + kTaggedSize, kDoubleAligned);
+ EXPECT_EQ(maximum_double_misalignment, fill);
+ // kDoubleUnaligned has the opposite fill amounts.
+ fill = MainAllocator::GetFillToAlign(base, kDoubleUnaligned);
+ EXPECT_EQ(maximum_double_misalignment, fill);
+ fill = MainAllocator::GetFillToAlign(base + kTaggedSize, kDoubleUnaligned);
+ EXPECT_EQ(0, fill);
+}
+
+TEST_F(HeapTest, TestAlignedAllocation) {
+ if (v8_flags.single_generation) return;
+ // Double misalignment is 4 on 32-bit platforms or when pointer compression
+ // is enabled, 0 on 64-bit ones when pointer compression is disabled.
+ const intptr_t double_misalignment = kDoubleSize - kTaggedSize;
+ Address start;
+ Tagged<HeapObject> obj;
+ Tagged<HeapObject> filler;
+ if (double_misalignment) {
+ MainAllocator* allocator = heap()->allocator()->new_space_allocator();
+
+ // Make one allocation to force allocating an allocation area. Using
+ // kDoubleSize to not change space alignment
+ AllocationResult dummy =
+ allocator->AllocateRaw(SafeHeapObjectSize(kDoubleSize), kDoubleAligned,
+ AllocationOrigin::kRuntime, AllocationHint());
+ ASSERT_FALSE(dummy.IsFailure());
+ heap()->CreateFillerObjectAt(dummy.ToObjectChecked().address(),
+ kDoubleSize);
+
+ // Allocate a pointer sized object that must be double aligned at an
+ // aligned address.
+ start = allocator->AlignTopForTesting(kDoubleAligned, 0);
+ obj = AllocateAligned(heap(), allocator, kTaggedSize, kDoubleAligned);
+ EXPECT_TRUE(IsAligned(obj.address(), kDoubleAlignment));
+ // There is no filler.
+ EXPECT_EQ(start, obj.address());
+
+ // Allocate a second pointer sized object that must be double aligned at an
+ // unaligned address.
+ start = allocator->AlignTopForTesting(kDoubleAligned, kTaggedSize);
+ obj = AllocateAligned(heap(), allocator, kTaggedSize, kDoubleAligned);
+ EXPECT_TRUE(IsAligned(obj.address(), kDoubleAlignment));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ EXPECT_NE(obj, filler);
+ EXPECT_TRUE(IsFreeSpaceOrFiller(filler));
+ EXPECT_EQ(filler->Size(), kTaggedSize);
+ EXPECT_EQ(start + double_misalignment, obj.address());
+
+ // Similarly for kDoubleUnaligned.
+ start = allocator->AlignTopForTesting(kDoubleUnaligned, 0);
+ obj = AllocateAligned(heap(), allocator, kTaggedSize, kDoubleUnaligned);
+ EXPECT_TRUE(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
+ EXPECT_EQ(start, obj.address());
+
+ start = allocator->AlignTopForTesting(kDoubleUnaligned, kTaggedSize);
+ obj = AllocateAligned(heap(), allocator, kTaggedSize, kDoubleUnaligned);
+ EXPECT_TRUE(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
+ // There is a filler object before the object.
+ filler = HeapObject::FromAddress(start);
+ EXPECT_NE(obj, filler);
+ EXPECT_TRUE(IsFreeSpaceOrFiller(filler));
+ EXPECT_EQ(filler->Size(), kTaggedSize);
+ EXPECT_EQ(start + kTaggedSize, obj.address());
+ }
+}
+
+// Test the case where allocation must be done from the free list, so filler
+// may precede or follow the object.
+TEST_F(HeapTest, TestAlignedOverAllocation) {
+ if (v8_flags.stress_concurrent_allocation) return;
+ ManualGCScope manual_gc_scope(i_isolate());
+ // Test checks for fillers before and behind objects and requires a fresh
+ // page and empty free list.
+ AbandonCurrentlyFreeMemory(heap()->old_space());
+ // Allocate a dummy object to properly set up the linear allocation info.
+ AllocationResult dummy =
+ heap()->allocator()->old_space_allocator()->AllocateRaw(
+ SafeHeapObjectSize(kTaggedSize), kTaggedAligned,
+ AllocationOrigin::kRuntime, AllocationHint());
+ ASSERT_FALSE(dummy.IsFailure());
+ heap()->CreateFillerObjectAt(dummy.ToObjectChecked().address(), kTaggedSize);
+
+ // Double misalignment is 4 on 32-bit platforms or when pointer compression
+ // is enabled, 0 on 64-bit ones when pointer compression is disabled.
+ const intptr_t double_misalignment = kDoubleSize - kTaggedSize;
+ Address start;
+ Tagged<HeapObject> obj;
+ Tagged<HeapObject> filler;
+ if (double_misalignment) {
+ start = AlignOldSpace(heap(), kDoubleAligned, 0);
+ obj = AllocateAligned(heap(), heap()->allocator()->old_space_allocator(),
+ kTaggedSize, kDoubleAligned);
+ // The object is aligned.
+ EXPECT_TRUE(IsAligned(obj.address(), kDoubleAlignment));
+ // Try the opposite alignment case.
+ start = AlignOldSpace(heap(), kDoubleAligned, kTaggedSize);
+ obj = AllocateAligned(heap(), heap()->allocator()->old_space_allocator(),
+ kTaggedSize, kDoubleAligned);
+ EXPECT_TRUE(IsAligned(obj.address(), kDoubleAlignment));
+ filler = HeapObject::FromAddress(start);
+ EXPECT_NE(obj, filler);
+ EXPECT_TRUE(IsFreeSpaceOrFiller(filler));
+ EXPECT_EQ(kTaggedSize, filler->Size());
+
+ // Similarly for kDoubleUnaligned.
+ start = AlignOldSpace(heap(), kDoubleUnaligned, 0);
+ obj = AllocateAligned(heap(), heap()->allocator()->old_space_allocator(),
+ kTaggedSize, kDoubleUnaligned);
+ // The object is aligned.
+ EXPECT_TRUE(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
+ // Try the opposite alignment case.
+ start = AlignOldSpace(heap(), kDoubleUnaligned, kTaggedSize);
+ obj = AllocateAligned(heap(), heap()->allocator()->old_space_allocator(),
+ kTaggedSize, kDoubleUnaligned);
+ EXPECT_TRUE(IsAligned(obj.address() + kTaggedSize, kDoubleAlignment));
+ filler = HeapObject::FromAddress(start);
+ EXPECT_NE(obj, filler);
+ EXPECT_TRUE(IsFreeSpaceOrFiller(filler));
+ EXPECT_EQ(kTaggedSize, filler->Size());
+ }
+}
+
+#ifdef DEBUG
+TEST_F(HeapTest, TransitionArrayShrinksDuringAllocToZero) {
+ v8_flags.stress_compaction = false;
+ v8_flags.stress_incremental_marking = false;
+ v8_flags.allow_natives_syntax = true;
+
+ static const int transitions_count = 10;
+ RunJS("function F() { }");
+ {
+ AlwaysAllocateScopeForTesting always_allocate(heap());
+ for (int i = 0; i < transitions_count; i++) {
+ base::EmbeddedVector<char, 64> buffer;
+ base::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
+ RunJS(buffer.begin());
+ }
+ }
+ RunJS("var root = new F;");
+ DirectHandle<JSObject> root = RunJS<JSObject>("root");
+
+ // Count number of live transitions before marking.
+ int transitions_before =
+ TransitionsAccessor(i_isolate(), root->map()).NumberOfTransitions();
+ EXPECT_EQ(transitions_count, transitions_before);
+
+ // Get rid of o
+ RunJS(
+ "o = new F;"
+ "root = new F");
+ root = RunJS<JSObject>("root");
+
+ DirectHandle<String> prop_name = factory()->InternalizeUtf8String("funny");
+ DirectHandle<Smi> twenty_three(Smi::FromInt(23), i_isolate());
+ HeapAllocator::SetAllocationGcInterval(2);
+ v8_flags.gc_global = true;
+ v8_flags.retain_maps_for_n_gc = 0;
+ heap()->set_allocation_timeout(2);
+ Object::SetProperty(i_isolate(), root, prop_name, twenty_three).Check();
+ {
+ // We need to invoke GC without stack, otherwise some objects may not be
+ // reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMinorGC();
+ }
+
+ // Count number of live transitions after marking. Note that one transition
+ // is left, because 'o' still holds an instance of one transition target.
+ int transitions_after =
+ TransitionsAccessor(i_isolate(), Cast<Map>(root->map()->GetBackPointer()))
+ .NumberOfTransitions();
+ EXPECT_EQ(1, transitions_after);
+}
+
+TEST_F(HeapTest, TransitionArrayShrinksDuringAllocToOne) {
+ v8_flags.stress_compaction = false;
+ v8_flags.stress_incremental_marking = false;
+ v8_flags.allow_natives_syntax = true;
+
+ static const int transitions_count = 10;
+ RunJS("function F() {}");
+ {
+ AlwaysAllocateScopeForTesting always_allocate(heap());
+ for (int i = 0; i < transitions_count; i++) {
+ base::EmbeddedVector<char, 64> buffer;
+ base::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
+ RunJS(buffer.begin());
+ }
+ }
+ RunJS("var root = new F;");
+ DirectHandle<JSObject> root = RunJS<JSObject>("root");
+
+ // Count number of live transitions before marking.
+ int transitions_before =
+ TransitionsAccessor(i_isolate(), root->map()).NumberOfTransitions();
+ EXPECT_EQ(transitions_count, transitions_before);
+
+ root = RunJS<JSObject>("root");
+ DirectHandle<String> prop_name = factory()->InternalizeUtf8String("funny");
+ DirectHandle<Smi> twenty_three(Smi::FromInt(23), i_isolate());
+ HeapAllocator::SetAllocationGcInterval(2);
+ v8_flags.gc_global = true;
+ v8_flags.retain_maps_for_n_gc = 0;
+ heap()->set_allocation_timeout(2);
+ Object::SetProperty(i_isolate(), root, prop_name, twenty_three).Check();
+ {
+ // We need to invoke GC without stack, otherwise some objects may not be
+ // reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMinorGC();
+ }
+
+ // Count number of live transitions after marking. Note that one transition
+ // is left, because 'o' still holds an instance of one transition target.
+ int transitions_after =
+ TransitionsAccessor(i_isolate(), Cast<Map>(root->map()->GetBackPointer()))
+ .NumberOfTransitions();
+ EXPECT_EQ(2, transitions_after);
+}
+
+TEST_F(HeapTest, TransitionArrayShrinksDuringAllocToOnePropertyFound) {
+ v8_flags.stress_compaction = false;
+ v8_flags.stress_incremental_marking = false;
+ v8_flags.allow_natives_syntax = true;
+
+ static const int transitions_count = 10;
+ RunJS("function F() {}");
+ {
+ AlwaysAllocateScopeForTesting always_allocate(heap());
+ for (int i = 0; i < transitions_count; i++) {
+ base::EmbeddedVector<char, 64> buffer;
+ base::SNPrintF(buffer, "var o = new F; o.prop%d = %d;", i, i);
+ RunJS(buffer.begin());
+ }
+ }
+ RunJS("var root = new F;");
+ DirectHandle<JSObject> root = RunJS<JSObject>("root");
+
+ // Count number of live transitions before marking.
+ int transitions_before =
+ TransitionsAccessor(i_isolate(), root->map()).NumberOfTransitions();
+ EXPECT_EQ(transitions_count, transitions_before);
+
+ root = RunJS<JSObject>("root");
+ DirectHandle<String> prop_name = factory()->InternalizeUtf8String("prop9");
+ DirectHandle<Smi> twenty_three(Smi::FromInt(23), i_isolate());
+ HeapAllocator::SetAllocationGcInterval(0);
+ v8_flags.gc_global = true;
+ v8_flags.retain_maps_for_n_gc = 0;
+ heap()->set_allocation_timeout(0);
+ Object::SetProperty(i_isolate(), root, prop_name, twenty_three).Check();
+ InvokeMajorGC();
+
+ // Count number of live transitions after marking. Note that one transition
+ // is left, because 'o' still holds an instance of one transition target.
+ int transitions_after =
+ TransitionsAccessor(i_isolate(), Cast<Map>(root->map()->GetBackPointer()))
+ .NumberOfTransitions();
+ EXPECT_EQ(1, transitions_after);
+}
+#endif // DEBUG
+
+TEST_F(HeapTest, ReleaseOverReservedPages) {
+ if (!v8_flags.compact) return;
+ v8_flags.trace_gc = true;
+ // The optimizer can allocate stuff, messing up the test.
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ v8_flags.turbofan = false;
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ // - Parallel compaction increases fragmentation, depending on how existing
+ // memory is distributed. Since this is non-deterministic because of
+ // concurrent sweeping, we disable it for this test.
+ // - Concurrent sweeping adds non determinism, depending on when memory is
+ // available for further reuse.
+ // - Fast evacuation of pages may result in a different page count in old
+ // space.
+ ManualGCScope manual_gc_scope(i_isolate());
+ v8_flags.page_promotion = false;
+ v8_flags.parallel_compaction = false;
+ // If there's snapshot available, we don't know whether 20 small arrays will
+ // fit on the initial pages.
+ if (!i_isolate()->snapshot_available()) return;
+ Factory* factory = i_isolate()->factory();
+ Heap* heap = this->heap();
+
+ // Ensure that the young generation is empty.
+ {
+ // In this test, we need to invoke GC without stack, otherwise some objects
+ // may not be reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ EmptyNewSpaceUsingGC();
+ }
+ static const int number_of_test_pages = 20;
+
+ // Prepare many pages with low live-bytes count.
+ PagedSpace* old_space = heap->old_space();
+ const int initial_page_count = old_space->CountTotalPages();
+ const int overall_page_count = number_of_test_pages + initial_page_count;
+
+ Global<v8::FixedArray> fixed_arrays[number_of_test_pages];
+ {
+ v8::HandleScope scope(v8_isolate());
+
+ for (int i = 0; i < number_of_test_pages; i++) {
+ AlwaysAllocateScopeForTesting always_allocate(heap);
+ {
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ SimulateFullSpace(old_space);
+ }
+ Handle<FixedArray> fixed_array =
+ factory->NewFixedArray(1, AllocationType::kOld);
+ fixed_arrays[i].Reset(v8_isolate(),
+ v8::Utils::FixedArrayToLocal(fixed_array));
+ }
+ }
+
+ EXPECT_EQ(overall_page_count, old_space->CountTotalPages());
+
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+
+ // Triggering one GC will cause a lot of garbage to be discovered but
+ // even spread across all allocated pages.
+ InvokeMajorGC();
+ EXPECT_GE(overall_page_count, old_space->CountTotalPages());
+
+ // Triggering subsequent GCs should cause at least half of the pages
+ // to be released to the OS after at most two cycles.
+ InvokeMajorGC();
+ EXPECT_GE(overall_page_count, old_space->CountTotalPages());
+ InvokeMajorGC();
+ EXPECT_GE(number_of_test_pages,
+ (old_space->CountTotalPages() - initial_page_count) * 2);
+
+ // Triggering a last-resort GC should cause all pages to be released to the
+ // OS so that other processes can seize the memory.
+ const int page_count_before_memory_reducing_gcs =
+ old_space->CountTotalPages();
+ InvokeMemoryReducingMajorGCs();
+ // With precise object pinning, some pages may be pinned and thus not
+ // evacuated. It is therefore not guaranteed that the page count can return
+ // to the initial count.
+ EXPECT_GE(v8_flags.precise_object_pinning
+ ? page_count_before_memory_reducing_gcs
+ : initial_page_count,
+ old_space->CountTotalPages());
+}
+
+TEST_F(HeapTest, RememberedSet_InsertOnWriteBarrier) {
+ if (v8_flags.single_generation) return;
+ v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
+ ManualGCScope manual_gc_scope(isolate());
+ SealCurrentObjects();
+ HandleScope scope(isolate());
+
+ // Allocate an object in old space.
+ DirectHandle<FixedArray> arr =
+ factory()->NewFixedArray(3, AllocationType::kOld);
+
+ // Add into 'arr' references to young objects.
+ {
+ HandleScope scope_inner(isolate());
+ DirectHandle<Object> number = factory()->NewHeapNumber(42);
+ arr->set(0, *number);
+ arr->set(1, *number);
+ arr->set(2, *number);
+ DirectHandle<Object> number_other = factory()->NewHeapNumber(24);
+ arr->set(2, *number_other);
+ }
+ // Remembered sets track *slots* pages with cross-generational pointers, so
+ // must have recorded three of them each exactly once.
+ EXPECT_EQ(size_t{3}, GetRememberedSetSize<OLD_TO_NEW>(isolate(), *arr));
+}
+
+TEST_F(HeapTest, RememberedSet_InsertInLargePage) {
+ if (v8_flags.single_generation) return;
+ v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
+ ManualGCScope manual_gc_scope(isolate());
+ Factory* factory = isolate()->factory();
+ Heap* heap = isolate()->heap();
+ SealCurrentObjects();
+ HandleScope scope(isolate());
+
+ // Allocate an object in Large space.
+ const int count = std::max(FixedArray::kMaxRegularLength + 1, 128 * KB);
+ DirectHandle<FixedArray> arr =
+ factory->NewFixedArray(count, AllocationType::kOld);
+ EXPECT_TRUE(heap->lo_space()->Contains(*arr));
+ EXPECT_EQ(size_t{0}, GetRememberedSetSize<OLD_TO_NEW>(isolate(), *arr));
+
+ // Create OLD_TO_NEW references from the large object so that the
+ // corresponding slots end up in different SlotSets.
+ {
+ HandleScope short_lived(isolate());
+ DirectHandle<Object> number = factory->NewHeapNumber(42);
+ arr->set(0, *number);
+ arr->set(count - 1, *number);
+ }
+ EXPECT_EQ(size_t{2}, GetRememberedSetSize<OLD_TO_NEW>(isolate(), *arr));
+}
+
+TEST_F(HeapTest, RememberedSet_RemoveStaleOnScavenge) {
+ if (v8_flags.single_generation || v8_flags.stress_incremental_marking) return;
+ v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
+ ManualGCScope manual_gc_scope(isolate());
+ Factory* factory = isolate()->factory();
+ Heap* heap = isolate()->heap();
+ SealCurrentObjects();
+ HandleScope scope(isolate());
+
+ // Allocate an object in old space and add into it references to young.
+ DirectHandle<FixedArray> arr =
+ factory->NewFixedArray(3, AllocationType::kOld);
+ {
+ HandleScope scope_inner(isolate());
+ DirectHandle<Object> number = factory->NewHeapNumber(42);
+ arr->set(0, *number); // will be trimmed away
+ arr->set(1, *number); // will be replaced with #undefined
+ arr->set(2, *number); // will be promoted into old
+ }
+ EXPECT_EQ(size_t{3}, GetRememberedSetSize<OLD_TO_NEW>(isolate(), *arr));
+
+ arr->set(1, ReadOnlyRoots(heap).undefined_value());
+ DirectHandle<FixedArrayBase> tail(heap->LeftTrimFixedArray(*arr, 1),
+ isolate());
+
+ // The first slot should be removed from the remembered set since the length
+ // is now in that place and represented as a uint32_t.
+ EXPECT_EQ(size_t{2}, GetRememberedSetSize<OLD_TO_NEW>(isolate(), *tail));
+
+ // Run GC to promote the remaining young object and fixup the stale entries in
+ // the remembered set.
+ EmptyNewSpaceUsingGC();
+ EXPECT_EQ(size_t{0}, GetRememberedSetSize<OLD_TO_NEW>(isolate(), *tail));
+}
+
+// The OLD_TO_OLD remembered set is created temporary by GC and is cleared at
+// the end of the pass. There is no way to observe it so the test only checks
+// that compaction has happened and otherwise relies on code's self-validation.
+TEST_F(HeapTest, RememberedSet_OldToOld) {
+ if (v8_flags.stress_incremental_marking) return;
+ v8_flags.stress_concurrent_allocation = false; // For SealCurrentObjects.
+ ManualGCScope manual_gc_scope(isolate());
+ ManualEvacuationCandidatesSelectionScope
+ manual_evacuation_candidate_selection_scope(manual_gc_scope);
+ SealCurrentObjects();
+
+ v8::Global<v8::FixedArray> arr_global;
+ Tagged<FixedArray> prev_location;
+ {
+ HandleScope scope(isolate());
+
+ DirectHandle<FixedArray> arr =
+ factory()->NewFixedArray(10, AllocationType::kOld);
+ {
+ HandleScope short_lived(isolate());
+ factory()->NewFixedArray(100, AllocationType::kOld);
+ }
+ DirectHandle<Object> ref =
+ factory()->NewFixedArray(100, AllocationType::kOld);
+ arr->set(0, *ref);
+
+ // To force compaction of the old space, fill it with garbage and start a
+ // new page (so that the page with 'arr' becomes subject to compaction).
+ {
+ HandleScope short_lived(isolate());
+ SimulateFullSpace(heap()->old_space());
+ factory()->NewFixedArray(100, AllocationType::kOld);
+ }
+
+ ForceEvacuationCandidate(NormalPage::FromHeapObject(*arr));
+ prev_location = *arr;
+ arr_global.Reset(v8_isolate(), v8::Utils::FixedArrayToLocal(arr));
+ }
+ {
+ // This GC pass will evacuate the page with 'arr'/'ref' so it will have to
+ // create OLD_TO_OLD remembered set to track the reference.
+ // We need to invoke GC without stack, otherwise no compaction is performed.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+ {
+ v8::HandleScope scope(v8_isolate());
+ DirectHandle<FixedArray> arr =
+ v8::Utils::OpenDirectHandle(*arr_global.Get(v8_isolate()));
+ EXPECT_NE(prev_location.ptr(), arr->ptr());
+ }
+}
+
+TEST_F(HeapTest, RememberedSetRemoveRange) {
+ if (v8_flags.single_generation) return;
+ HandleScope scope(isolate());
+
+ DirectHandle<FixedArray> array = factory()->NewFixedArray(
+ NormalPage::kPageSize / kTaggedSize, AllocationType::kOld);
+ MutablePage* chunk = MutablePage::FromHeapObject(isolate(), *array);
+ EXPECT_EQ(chunk->owner_identity(), LO_SPACE);
+ Address start = array->address();
+ // Maps slot to boolean indicator of whether the slot should be in the set.
+ std::map<Address, bool> slots;
+ slots[start + 0] = true;
+ slots[start + kTaggedSize] = true;
+ slots[start + NormalPage::kPageSize - kTaggedSize] = true;
+ slots[start + NormalPage::kPageSize] = true;
+ slots[start + NormalPage::kPageSize + kTaggedSize] = true;
+ slots[chunk->area_end() - kTaggedSize] = true;
+
+ for (auto x : slots) {
+ RememberedSet<OLD_TO_NEW>::Insert<AccessMode::ATOMIC>(
+ chunk, chunk->Offset(x.first));
+ }
+
+ RememberedSet<OLD_TO_NEW>::Iterate(
+ chunk,
+ [&slots](MaybeObjectSlot slot) {
+ EXPECT_TRUE(slots[slot.address()]);
+ return KEEP_SLOT;
+ },
+ SlotSet::FREE_EMPTY_BUCKETS);
+
+ RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start, start + kTaggedSize,
+ SlotSet::FREE_EMPTY_BUCKETS);
+ slots[start] = false;
+ RememberedSet<OLD_TO_NEW>::Iterate(
+ chunk,
+ [&slots](MaybeObjectSlot slot) {
+ EXPECT_TRUE(slots[slot.address()]);
+ return KEEP_SLOT;
+ },
+ SlotSet::FREE_EMPTY_BUCKETS);
+
+ RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, start + kTaggedSize,
+ start + NormalPage::kPageSize,
+ SlotSet::FREE_EMPTY_BUCKETS);
+ slots[start + kTaggedSize] = false;
+ slots[start + NormalPage::kPageSize - kTaggedSize] = false;
+ RememberedSet<OLD_TO_NEW>::Iterate(
+ chunk,
+ [&slots](MaybeObjectSlot slot) {
+ EXPECT_TRUE(slots[slot.address()]);
+ return KEEP_SLOT;
+ },
+ SlotSet::FREE_EMPTY_BUCKETS);
+
+ RememberedSet<OLD_TO_NEW>::RemoveRange(
+ chunk, start, start + NormalPage::kPageSize + kTaggedSize,
+ SlotSet::FREE_EMPTY_BUCKETS);
+ slots[start + NormalPage::kPageSize] = false;
+ RememberedSet<OLD_TO_NEW>::Iterate(
+ chunk,
+ [&slots](MaybeObjectSlot slot) {
+ EXPECT_TRUE(slots[slot.address()]);
+ return KEEP_SLOT;
+ },
+ SlotSet::FREE_EMPTY_BUCKETS);
+
+ RememberedSet<OLD_TO_NEW>::RemoveRange(chunk, chunk->area_end() - kTaggedSize,
+ chunk->area_end(),
+ SlotSet::FREE_EMPTY_BUCKETS);
+ slots[chunk->area_end() - kTaggedSize] = false;
+ RememberedSet<OLD_TO_NEW>::Iterate(
+ chunk,
+ [&slots](MaybeObjectSlot slot) {
+ EXPECT_TRUE(slots[slot.address()]);
+ return KEEP_SLOT;
+ },
+ SlotSet::FREE_EMPTY_BUCKETS);
+}
+
+TEST_F(HeapTest, Regress670675) {
+ if (!v8_flags.incremental_marking) return;
+ ManualGCScope manual_gc_scope(isolate());
+ HandleScope scope(isolate());
+ Heap* heap = this->heap();
+ Isolate* isolate = this->isolate();
+ InvokeMajorGC();
+
+ heap->EnsureSweepingCompleted(
+ Heap::SweepingForcedFinalizationMode::kUnifiedHeap,
+ CompleteSweepingReason::kTesting);
+ heap->tracer()->StopFullCycleIfFinished();
+ i::IncrementalMarking* marking = heap->incremental_marking();
+ if (marking->IsStopped()) {
+ SafepointScope safepoint_scope(isolate,
+ kGlobalSafepointForSharedSpaceIsolate);
+ heap->tracer()->StartCycle(
+ GarbageCollector::MARK_COMPACTOR, GarbageCollectionReason::kTesting,
+ "collector unittest", GCTracer::MarkingType::kIncremental);
+ marking->Start(GarbageCollector::MARK_COMPACTOR,
+ i::GarbageCollectionReason::kTesting, "testing");
+ }
+ size_t array_length = 128 * KB;
+ size_t n = OldGenerationSpaceAvailable() / array_length;
+ for (size_t i = 0; i < n + 60; i++) {
+ {
+ HandleScope inner_scope(isolate);
+ isolate->factory()->NewFixedArray(static_cast<int>(array_length),
+ AllocationType::kOld);
+ }
+ if (marking->IsStopped()) break;
+ marking->AdvanceForTesting(v8::base::TimeDelta::FromMillisecondsD(0.1));
+ }
+ EXPECT_TRUE(marking->IsStopped());
+}
+
+TEST_F(HeapTest, RegressMissingWriteBarrierInAllocate) {
+ if (!v8_flags.incremental_marking) return;
+ ManualGCScope manual_gc_scope(isolate());
+ v8::HandleScope scope(v8_isolate());
+ Isolate* iso = isolate();
+ InvokeMajorGC();
+ SimulateIncrementalMarking(false);
+ DirectHandle<Map> map;
+ {
+ AlwaysAllocateScopeForTesting always_allocate(heap());
+ map = factory()->NewContextfulMapForCurrentContext(JS_OBJECT_TYPE,
+ JSObject::kHeaderSize);
+ }
+ EXPECT_TRUE(heap()->incremental_marking()->black_allocation());
+ DirectHandle<JSObject> object;
+ {
+ AlwaysAllocateScopeForTesting always_allocate(heap());
+ object = direct_handle(
+ Cast<JSObject>(factory()->NewForTest(map, AllocationType::kOld)), iso);
+ }
+ // Initialize backing stores to ensure object is valid.
+ ReadOnlyRoots roots(iso);
+ object->set_raw_properties_or_hash(roots.empty_property_array(),
+ SKIP_WRITE_BARRIER);
+ object->set_elements(roots.empty_fixed_array(), SKIP_WRITE_BARRIER);
+
+ // The object is black. If Factory::New sets the map without write-barrier,
+ // then the map is white and will be freed prematurely.
+ SimulateIncrementalMarking(true);
+ InvokeMajorGC();
+ if (heap()->sweeping_in_progress()) {
+ heap()->EnsureSweepingCompleted(
+ Heap::SweepingForcedFinalizationMode::kV8Only,
+ CompleteSweepingReason::kTesting);
+ }
+ EXPECT_TRUE(IsMap(object->map()));
+}
+
+TEST_F(HeapTest, MarkCompactEpochCounter) {
+ if (!v8_flags.incremental_marking) return;
+ ManualGCScope manual_gc_scope(isolate());
+
+ unsigned epoch0 = heap()->mark_compact_collector()->epoch();
+ InvokeMajorGC();
+ unsigned epoch1 = heap()->mark_compact_collector()->epoch();
+ EXPECT_EQ(epoch0 + 1, epoch1);
+ SimulateIncrementalMarking();
+ InvokeMajorGC();
+ unsigned epoch2 = heap()->mark_compact_collector()->epoch();
+ EXPECT_EQ(epoch1 + 1, epoch2);
+ InvokeMinorGC();
+ unsigned epoch3 = heap()->mark_compact_collector()->epoch();
+ EXPECT_EQ(epoch2, epoch3);
+}
+
+TEST_F(TestWithPlatform, ReinitializeStringHashSeed) {
+ // Enable rehashing and create an isolate and context.
+ v8_flags.rehash_snapshot = true;
+ std::unique_ptr<v8::ArrayBuffer::Allocator> allocator(
+ v8::ArrayBuffer::Allocator::NewDefaultAllocator());
+ for (int i = 1; i < 3; i++) {
+ v8_flags.hash_seed = 1337 * i;
+ v8::Isolate::CreateParams create_params;
+ create_params.array_buffer_allocator = allocator.get();
+ v8::Isolate* isolate = v8::Isolate::New(create_params);
+ {
+ v8::Isolate::Scope isolate_scope(isolate);
+ EXPECT_EQ(static_cast<uint64_t>(1337 * i),
+ HashSeed(reinterpret_cast<Isolate*>(isolate)).seed());
+ v8::HandleScope handle_scope(isolate);
+ v8::Local<v8::Context> context = v8::Context::New(isolate);
+ EXPECT_FALSE(context.IsEmpty());
+ v8::Context::Scope context_scope(context);
+ }
+ isolate->Dispose();
+ }
+}
+
+TEST_F(HeapTest, Regress169928) {
+ v8_flags.allow_natives_syntax = true;
+#if !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+ v8_flags.turbofan = false;
+#endif // !defined(V8_LITE_MODE) && defined(V8_ENABLE_TURBOFAN)
+
+ // Some flags turn Scavenge collections into Mark-sweep collections
+ // and hence are incompatible with this test case.
+ if (v8_flags.gc_global || v8_flags.stress_compaction ||
+ v8_flags.stress_incremental_marking || v8_flags.single_generation ||
+ v8_flags.minor_ms) {
+ return;
+ }
+
+ // Prepare the environment
+ RunJS(
+ "function fastliteralcase(literal, value) {"
+ " literal[0] = value;"
+ " return literal;"
+ "}"
+ "function get_standard_literal() {"
+ " var literal = [1, 2, 3];"
+ " return literal;"
+ "}"
+ "obj = fastliteralcase(get_standard_literal(), 1);"
+ "obj = fastliteralcase(get_standard_literal(), 1.5);"
+ "obj = fastliteralcase(get_standard_literal(), 2);");
+
+ // Prepare the heap: pre-allocate strings before page filling to avoid
+ // disturbing heap layout.
+ v8::Local<v8::String> mote_code_string =
+ NewString("fastliteralcase(mote, 2.5);");
+ v8::Local<v8::String> array_name = NewString("mote");
+ EXPECT_TRUE(context()
+ ->Global()
+ ->Set(context(), array_name, v8::Int32::New(v8_isolate(), 0))
+ .FromJust());
+
+ // First make sure we flip spaces
+ InvokeMinorGC();
+
+ // Allocate the object.
+ DirectHandle<FixedArray> array_data =
+ factory()->NewFixedArray(2, AllocationType::kYoung);
+ array_data->set(0, Smi::FromInt(1));
+ array_data->set(1, Smi::FromInt(2));
+
+ FillCurrentPageButNBytes(
+ SemiSpaceNewSpace::From(heap()->new_space()),
+ JSArray::kHeaderSize + sizeof(AllocationMemento) + kTaggedSize);
+
+ DirectHandle<JSArray> array =
+ factory()->NewJSArrayWithElements(array_data, PACKED_SMI_ELEMENTS);
+
+ EXPECT_EQ(Smi::FromInt(2), array->length());
+ EXPECT_TRUE(array->HasSmiOrObjectElements());
+
+ // We need filler the size of AllocationMemento object, plus an extra
+ // fill pointer value.
+ Tagged<HeapObject> obj;
+ AllocationResult allocation =
+ heap()->allocator()->new_space_allocator()->AllocateRaw(
+ SafeHeapObjectSize(sizeof(AllocationMemento) + kTaggedSize),
+ kTaggedAligned, AllocationOrigin::kRuntime, AllocationHint());
+ EXPECT_TRUE(allocation.To(&obj));
+ Address addr_obj = obj.address();
+ heap()->CreateFillerObjectAt(addr_obj,
+ sizeof(AllocationMemento) + kTaggedSize);
+
+ // Give the array a name, making sure not to allocate strings.
+ v8::Local<v8::Object> array_obj = v8::Utils::ToLocal(array);
+ EXPECT_TRUE(
+ context()->Global()->Set(context(), array_name, array_obj).FromJust());
+
+ // This should crash with a protection violation if running a build with the
+ // bug.
+ AlwaysAllocateScopeForTesting aa_scope(heap());
+ v8::Script::Compile(context(), mote_code_string)
+ .ToLocalChecked()
+ ->Run(context())
+ .ToLocalChecked();
+}
+
+TEST_F(HeapTest, LargeObjectSlotRecording) {
+ if (!v8_flags.incremental_marking) return;
+ if (!v8_flags.compact) return;
+ v8_flags.manual_evacuation_candidates_selection = true;
+ ManualGCScope manual_gc_scope(isolate());
+
+ const int size = std::max(1000000, kMaxRegularHeapObjectSize + KB);
+ const int kStep = size / 10;
+
+ v8::Global<v8::FixedArray> lit_global;
+ v8::Global<v8::FixedArray> lo_global;
+ Tagged<FixedArray> old_location;
+ {
+ HandleScope scope(isolate());
+
+ // Create an object on an evacuation candidate.
+ SimulateFullSpace(heap()->old_space());
+ IndirectHandle<FixedArray> lit =
+ factory()->NewFixedArray(4, AllocationType::kOld);
+ MutablePage::FromHeapObject(isolate(), *lit)
+ ->set_forced_evacuation_candidate_for_testing(true);
+ old_location = *lit;
+
+ // Allocate a large object.
+ EXPECT_LT(kMaxRegularHeapObjectSize, size);
+ IndirectHandle<FixedArray> lo =
+ factory()->NewFixedArray(size, AllocationType::kOld);
+ EXPECT_TRUE(heap()->lo_space()->Contains(*lo));
+
+ // Start incremental marking to activate write barrier.
+ SimulateIncrementalMarking(false);
+
+ // Create references from the large object to the object on the evacuation
+ // candidate.
+ for (int i = 0; i < size; i += kStep) {
+ lo->set(i, *lit);
+ EXPECT_EQ(lo->get(i), old_location);
+ }
+
+ SimulateIncrementalMarking(true);
+ lit_global.Reset(v8_isolate(), Utils::FixedArrayToLocal(lit));
+ lo_global.Reset(v8_isolate(), Utils::FixedArrayToLocal(lo));
+ }
+
+ // Move the evacuation candidate object.
+ {
+ // We need to invoke GC without stack, otherwise no compaction is performed.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap());
+ InvokeMajorGC();
+ }
+
+ {
+ v8::HandleScope scope(v8_isolate());
+ IndirectHandle<FixedArray> lit =
+ Utils::OpenHandle(*lit_global.Get(v8_isolate()));
+ IndirectHandle<FixedArray> lo =
+ Utils::OpenHandle(*lo_global.Get(v8_isolate()));
+ // Verify that the pointers in the large object got updated.
+ for (int i = 0; i < size; i += kStep) {
+ EXPECT_EQ(lo->get(i).ptr(), lit->ptr());
+ EXPECT_NE(lo->get(i).ptr(), old_location.ptr());
+ }
+ }
+}
+
+TEST_F(HeapTest, PersistentHandles) {
+ Isolate* isolate = i_isolate();
+ Heap* heap = isolate->heap();
+ v8::HandleScope scope(v8_isolate());
+ HandleScopeData* data = isolate->handle_scope_data();
+ IndirectHandle<Object> init(ReadOnlyRoots(heap).empty_string(), isolate);
+ while (data->next < data->limit) {
+ IndirectHandle<Object> obj(ReadOnlyRoots(heap).empty_string(), isolate);
+ }
+ // An entire block of handles has been filled.
+ // Next handle would require a new block.
+ EXPECT_EQ(data->next, data->limit);
+
+ PersistentHandlesScope persistent(isolate);
+ class DummyVisitor : public RootVisitor {
+ public:
+ void VisitRootPointers(Root root, const char* description,
+ FullObjectSlot start, FullObjectSlot end) override {}
+ } visitor;
+ isolate->handle_scope_implementer()->Iterate(&visitor);
+ persistent.Detach();
+}
+
+void TestFillersFromPersistentHandles(Isolate* isolate, bool promote) {
+ // We assume that the fillers can only arise when left-trimming arrays.
+ ManualGCScope manual_gc_scope(isolate);
+ Heap* heap = isolate->heap();
+ v8::HandleScope scope(reinterpret_cast<v8::Isolate*>(isolate));
+
+ const size_t n = 10;
+ DirectHandle<FixedArray> array = isolate->factory()->NewFixedArray(n);
+
+ if (promote) {
+ // Age the array so it's ready for promotion on next GC.
+ InvokeMinorGC(isolate);
+ }
+ EXPECT_TRUE(HeapLayout::InYoungGeneration(*array));
+
+ PersistentHandlesScope persistent_scope(isolate);
+
+ // Trim the array three times to different sizes so all kinds of fillers are
+ // created and tracked by the persistent handles.
+ DirectHandle<FixedArrayBase> filler_1(*array, isolate);
+ DirectHandle<FixedArrayBase> filler_2(heap->LeftTrimFixedArray(*filler_1, 1),
+ isolate);
+ DirectHandle<FixedArrayBase> filler_3(heap->LeftTrimFixedArray(*filler_2, 2),
+ isolate);
+ DirectHandle<FixedArrayBase> tail(heap->LeftTrimFixedArray(*filler_3, 3),
+ isolate);
+
+ std::unique_ptr<PersistentHandles> persistent_handles(
+ persistent_scope.Detach());
+
+ // GC should retain the trimmed array but drop all of the three fillers.
+ InvokeMinorGC(isolate);
+ if (!v8_flags.single_generation) {
+ if (promote) {
+ EXPECT_TRUE(heap->InOldSpace(*tail));
+ } else {
+ EXPECT_TRUE(HeapLayout::InYoungGeneration(*tail));
+ }
+ }
+ EXPECT_EQ(n - 6, static_cast<size_t>(tail->length().value()));
+ EXPECT_FALSE(IsHeapObject(*filler_1));
+ EXPECT_FALSE(IsHeapObject(*filler_2));
+ EXPECT_FALSE(IsHeapObject(*filler_3));
+}
+
+TEST_F(HeapTest, DoNotEvacuateFillersFromPersistentHandles) {
+ if (v8_flags.single_generation || v8_flags.move_object_start) return;
+ TestFillersFromPersistentHandles(i_isolate(), false /*promote*/);
+}
+
+TEST_F(HeapTest, DoNotPromoteFillersFromPersistentHandles) {
+ if (v8_flags.single_generation || v8_flags.move_object_start) return;
+ TestFillersFromPersistentHandles(i_isolate(), true /*promote*/);
+}
+
+TEST_F(HeapTest, IncrementalMarkingStepMakesBigProgressWithLargeObjects) {
+ if (!v8_flags.incremental_marking) return;
+ ManualGCScope manual_gc_scope(i_isolate());
+ RunJS(
+ "function f(n) {"
+ " var a = new Array(n);"
+ " for (var i = 0; i < n; i += 100) a[i] = i;"
+ "};"
+ "f(10 * 1024 * 1024);");
+ IncrementalMarking* marking = heap()->incremental_marking();
+ if (marking->IsStopped()) {
+ heap()->StartIncrementalMarking(GCFlag::kNoFlags,
+ GarbageCollectionReason::kTesting);
+ }
+ SimulateIncrementalMarking();
+ EXPECT_TRUE(marking->IsMajorMarkingComplete());
+}
+
+TEST_F(HeapTest, DisableInlineAllocation) {
+ v8_flags.allow_natives_syntax = true;
+ RunJS(
+ "function test() {"
+ " var x = [];"
+ " for (var i = 0; i < 10; i++) {"
+ " x[i] = [ {}, [1,2,3], [1,x,3] ];"
+ " }"
+ "}"
+ "function run() {"
+ " %PrepareFunctionForOptimization(test);"
+ " %OptimizeFunctionOnNextCall(test);"
+ " test();"
+ " %DeoptimizeFunction(test);"
+ "}");
+
+ // Warm-up with inline allocation enabled.
+ RunJS("test(); test(); run();");
+
+ // Run test with inline allocation disabled.
+ heap()->DisableInlineAllocation();
+ RunJS("run()");
+
+ // Run test with inline allocation re-enabled.
+ heap()->EnableInlineAllocation();
+ RunJS("run()");
+}
+
+TEST_F(HeapTest, EnsureAllocationSiteDependentCodesProcessed) {
+ if (!V8_ALLOCATION_SITE_TRACKING_BOOL) {
+ return;
+ }
+ v8_flags.allow_natives_syntax = true;
+ Isolate* isolate = i_isolate();
+ Heap* heap = this->heap();
+ GlobalHandles* global_handles = isolate->global_handles();
+
+ if (!isolate->use_optimizer()) return;
+
+ auto allocation_sites_count = [](Heap* heap) {
+ int count = 0;
+ for (Tagged<Object> site = heap->allocation_sites_list();
+ IsAllocationSite(site);) {
+ Tagged<AllocationSiteWithWeakNext> cur =
+ Cast<AllocationSiteWithWeakNext>(site);
+ EXPECT_TRUE(cur->HasWeakNext());
+ site = cur->weak_next();
+ count++;
+ }
+ return count;
+ };
+
+ // The allocation site at the head of the list is ours.
+ IndirectHandle<AllocationSite> site;
+ {
+ v8::HandleScope scope(v8_isolate());
+ v8::Local<v8::Context> context = v8::Context::New(v8_isolate());
+ v8::Context::Scope context_scope(context);
+
+ int count = allocation_sites_count(heap);
+ RunJS(context,
+ "var bar = function() { return (new Array()); };"
+ "%PrepareFunctionForOptimization(bar);"
+ "var a = bar();"
+ "bar();"
+ "bar();");
+
+ // One allocation site should have been created.
+ int new_count = allocation_sites_count(heap);
+ EXPECT_EQ(new_count, count + 1);
+ site = Cast<AllocationSite>(global_handles->Create(
+ Cast<AllocationSite>(heap->allocation_sites_list())));
+
+ RunJS(context, "%OptimizeFunctionOnNextCall(bar); bar();");
+
+ IndirectHandle<JSFunction> bar_handle =
+ Cast<JSFunction>(v8::Utils::OpenIndirectHandle(
+ *v8::Local<v8::Function>::Cast(context->Global()
+ ->Get(context, NewString("bar"))
+ .ToLocalChecked())));
+
+ // Expect a dependent code object for transitioning and pretenuring.
+ Tagged<DependentCode> dependency = site->dependent_code();
+ EXPECT_NE(dependency,
+ DependentCode::empty_dependent_code(ReadOnlyRoots(isolate)));
+ EXPECT_EQ(dependency->length().value(),
+ static_cast<uint32_t>(DependentCode::kSlotsPerEntry));
+ Tagged<MaybeObject> code =
+ dependency->Get(0 + DependentCode::kCodeSlotOffset);
+ EXPECT_TRUE(code.IsWeak());
+ EXPECT_EQ(bar_handle->code(isolate),
+ Cast<CodeWrapper>(code.GetHeapObjectAssumeWeak())->code(isolate));
+ Tagged<Smi> groups =
+ dependency->Get(0 + DependentCode::kGroupsSlotOffset).ToSmi();
+ EXPECT_EQ(static_cast<DependentCode::DependencyGroups>(groups.value()),
+ DependentCode::kAllocationSiteTransitionChangedGroup |
+ DependentCode::kAllocationSiteTenuringChangedGroup);
+ }
+
+ // Now make sure that a gc should get rid of the function, even though we
+ // still have the allocation site alive.
+ for (int i = 0; i < 4; i++) {
+ // We need to invoke GC without stack, otherwise some objects may not be
+ // reclaimed because of conservative stack scanning.
+ DisableConservativeStackScanningScopeForTesting no_stack_scanning(heap);
+ InvokeMajorGC();
+ }
+
+ // The site still exists because of our global handle, but the code is no
+ // longer referred to by dependent_code().
+ EXPECT_TRUE(site->dependent_code()->Get(0).IsCleared());
+}
+
} // 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 6af39bf2d23..4726f1c4139 100644
--- a/deps/v8/test/unittests/heap/heap-utils.cc
+++ b/deps/v8/test/unittests/heap/heap-utils.cc
@@ -10,16 +10,32 @@
#include "src/common/globals.h"
#include "src/flags/flags.h"
#include "src/heap/gc-tracer-inl.h"
+#include "src/heap/heap-layout-inl.h"
#include "src/heap/incremental-marking.h"
+#include "src/heap/main-allocator-inl.h"
#include "src/heap/mark-compact.h"
#include "src/heap/new-spaces.h"
#include "src/heap/normal-page-inl.h"
#include "src/heap/safepoint.h"
+#include "src/heap/spaces-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);
+}
+
void HeapInternalsBase::SimulateIncrementalMarking(Heap* heap,
bool force_completion) {
static constexpr auto kStepSize = v8::base::TimeDelta::FromMilliseconds(100);
@@ -237,8 +253,9 @@ std::vector<Handle<FixedArray>> CreatePadding(Heap* heap, int padding_size,
return handles;
}
-void FillCurrentSemiSpacePage(v8::internal::SemiSpaceNewSpace* space,
- std::vector<Handle<FixedArray>>* out_handles) {
+void FillCurrentSemiSpacePageButNBytes(
+ v8::internal::SemiSpaceNewSpace* space, int extra_bytes,
+ std::vector<Handle<FixedArray>>* out_handles = nullptr) {
// We cannot rely on `space->limit()` to point to the end of the current page
// in the case where inline allocations are disabled, it actually points to
// the current allocation pointer.
@@ -247,14 +264,21 @@ void FillCurrentSemiSpacePage(v8::internal::SemiSpaceNewSpace* space,
space->heap()->NewSpaceTop() == space->heap()->NewSpaceLimit());
int space_remaining = space->GetSpaceRemainingOnCurrentPageForTesting();
- if (space_remaining == 0) return;
+ CHECK_GE(space_remaining, extra_bytes);
+ int new_linear_size = space_remaining - extra_bytes;
+ if (new_linear_size == 0) return;
std::vector<Handle<FixedArray>> handles =
- CreatePadding(space->heap(), space_remaining, i::AllocationType::kYoung);
+ CreatePadding(space->heap(), new_linear_size, i::AllocationType::kYoung);
if (out_handles != nullptr) {
out_handles->insert(out_handles->end(), handles.begin(), handles.end());
}
}
+void FillCurrentSemiSpacePage(v8::internal::SemiSpaceNewSpace* space,
+ std::vector<Handle<FixedArray>>* out_handles) {
+ FillCurrentSemiSpacePageButNBytes(space, 0, out_handles);
+}
+
void FillCurrentPagedSpacePage(v8::internal::NewSpace* space,
std::vector<Handle<FixedArray>>* out_handles) {
const Address top = space->heap()->NewSpaceTop();
@@ -271,15 +295,23 @@ void FillCurrentPagedSpacePage(v8::internal::NewSpace* space,
void HeapInternalsBase::FillCurrentPage(
v8::internal::NewSpace* space,
std::vector<Handle<FixedArray>>* out_handles) {
+ space->heap()->FreeMainThreadLinearAllocationAreas();
PauseAllocationObserversScope pause_observers(space->heap());
- MainAllocator* allocator = space->heap()->allocator()->new_space_allocator();
- allocator->FreeLinearAllocationArea();
if (v8_flags.minor_ms) {
FillCurrentPagedSpacePage(space, out_handles);
} else {
FillCurrentSemiSpacePage(SemiSpaceNewSpace::From(space), out_handles);
}
- allocator->FreeLinearAllocationArea();
+ space->heap()->FreeMainThreadLinearAllocationAreas();
+}
+
+void HeapInternalsBase::FillCurrentPageButNBytes(
+ v8::internal::SemiSpaceNewSpace* space, int extra_bytes,
+ std::vector<Handle<FixedArray>>* out_handles) {
+ space->heap()->FreeMainThreadLinearAllocationAreas();
+ PauseAllocationObserversScope pause_observers(space->heap());
+ FillCurrentSemiSpacePageButNBytes(space, extra_bytes, out_handles);
+ space->heap()->FreeMainThreadLinearAllocationAreas();
}
bool IsNewObjectInCorrectGeneration(Tagged<HeapObject> object) {
@@ -342,5 +374,49 @@ ManualGCScope::~ManualGCScope() {
}
}
+void AbandonCurrentlyFreeMemory(PagedSpace* space) {
+ Heap* heap = space->heap();
+ SafepointScope safepoint_scope(heap->isolate(),
+ kGlobalSafepointForSharedSpaceIsolate);
+ heap->FreeLinearAllocationAreas();
+
+ for (NormalPage* page : *space) {
+ page->MarkNeverAllocateForTesting();
+ }
+}
+
+Tagged<HeapObject> AllocateAligned(Heap* heap, MainAllocator* allocator,
+ int size, AllocationAlignment alignment) {
+ AllocationResult allocation = allocator->AllocateRawForceAlignmentForTesting(
+ size, alignment, AllocationOrigin::kRuntime);
+ Tagged<HeapObject> obj;
+ allocation.To(&obj);
+ heap->CreateFillerObjectAt(obj.address(), size);
+ return obj;
+}
+
+Address AlignOldSpace(Heap* heap, AllocationAlignment alignment, int offset) {
+ LinearAllocationArea* old_space =
+ &heap->isolate()->isolate_data()->old_allocation_info();
+ int fill = MainAllocator::GetFillToAlign(old_space->top(), alignment);
+ int allocation = fill + offset;
+ if (allocation) {
+ AllocateAligned(heap, heap->allocator()->old_space_allocator(), allocation,
+ kTaggedAligned);
+ }
+ Address top = old_space->top();
+ // Now force the remaining allocation onto the free list.
+ heap->FreeMainThreadLinearAllocationAreas();
+ return top;
+}
+
+void ForceEvacuationCandidate(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();
+}
+
} // 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 04dee4e92e3..08f76472f73 100644
--- a/deps/v8/test/unittests/heap/heap-utils.h
+++ b/deps/v8/test/unittests/heap/heap-utils.h
@@ -14,8 +14,13 @@
namespace v8 {
namespace internal {
+class NormalPage;
+void ForceEvacuationCandidate(NormalPage* page);
+class SemiSpaceNewSpace;
+
class HeapInternalsBase {
protected:
+ size_t OldGenerationSpaceAvailable(Heap* heap);
void SimulateIncrementalMarking(Heap* heap, bool force_completion);
void SimulateFullSpace(
v8::internal::NewSpace* space,
@@ -23,6 +28,9 @@ class HeapInternalsBase {
void SimulateFullSpace(v8::internal::PagedSpace* space);
void FillCurrentPage(v8::internal::NewSpace* space,
std::vector<Handle<FixedArray>>* out_handles = nullptr);
+ void FillCurrentPageButNBytes(
+ v8::internal::SemiSpaceNewSpace* space, int extra_bytes,
+ std::vector<Handle<FixedArray>>* out_handles = nullptr);
};
inline void InvokeMajorGC(i::Isolate* isolate) {
@@ -94,6 +102,10 @@ class WithHeapInternals : public TMixin, HeapInternalsBase {
Heap* heap() const { return this->i_isolate()->heap(); }
+ size_t OldGenerationSpaceAvailable() {
+ return HeapInternalsBase::OldGenerationSpaceAvailable(heap());
+ }
+
void SimulateIncrementalMarking(bool force_completion = true) {
return HeapInternalsBase::SimulateIncrementalMarking(heap(),
force_completion);
@@ -108,6 +120,13 @@ class WithHeapInternals : public TMixin, HeapInternalsBase {
return HeapInternalsBase::SimulateFullSpace(space);
}
+ void FillCurrentPageButNBytes(
+ v8::internal::SemiSpaceNewSpace* space, int extra_bytes,
+ std::vector<Handle<FixedArray>>* out_handles = nullptr) {
+ return HeapInternalsBase::FillCurrentPageButNBytes(space, extra_bytes,
+ out_handles);
+ }
+
void GrowNewSpaceToMaximumCapacity() {
IsolateSafepointScope scope(heap());
NewSpace* new_space = heap()->new_space();
@@ -130,7 +149,21 @@ class WithHeapInternals : public TMixin, HeapInternalsBase {
}
}
+ void ForceEvacuationCandidate(NormalPage* page) {
+ i::ForceEvacuationCandidate(page);
+ }
+
void EmptyNewSpaceUsingGC() { InvokeMajorGC(); }
+
+ int NumberOfGlobalObjects() {
+ int count = 0;
+ HeapObjectIterator iterator(heap());
+ for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
+ obj = iterator.Next()) {
+ if (IsJSGlobalObject(obj)) count++;
+ }
+ return count;
+ }
};
template <typename TMixin>
@@ -194,6 +227,18 @@ class V8_NODISCARD ManualGCScope final {
const bool flag_cppheap_concurrent_marking_;
};
+class V8_NODISCARD ManualEvacuationCandidatesSelectionScope final {
+ public:
+ explicit ManualEvacuationCandidatesSelectionScope(ManualGCScope&) {
+ DCHECK(!v8_flags.manual_evacuation_candidates_selection);
+ v8_flags.manual_evacuation_candidates_selection = true;
+ }
+ ~ManualEvacuationCandidatesSelectionScope() {
+ DCHECK(v8_flags.manual_evacuation_candidates_selection);
+ v8_flags.manual_evacuation_candidates_selection = false;
+ }
+};
+
// DisableHandleChecksForMockingScope disables the checks for v8::Local and
// internal::DirectHandle, so that such handles can be allocated off-stack.
// This is required for mocking functions that take such handles as parameters
@@ -215,6 +260,13 @@ class V8_NODISCARD DisableHandleChecksForMockingScope final {
};
#endif
+void AbandonCurrentlyFreeMemory(PagedSpace* space);
+
+Tagged<HeapObject> AllocateAligned(Heap* heap, MainAllocator* allocator,
+ int size, AllocationAlignment alignment);
+
+Address AlignOldSpace(Heap* heap, AllocationAlignment alignment, int offset);
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/heap/iterators-unittest.cc b/deps/v8/test/unittests/heap/iterators-unittest.cc
index b399dde5261..1950593ffec 100644
--- a/deps/v8/test/unittests/heap/iterators-unittest.cc
+++ b/deps/v8/test/unittests/heap/iterators-unittest.cc
@@ -119,4 +119,46 @@ TEST_F(IteratorsTest, SpaceIterator) {
}
}
+TEST_F(IteratorsTest, HeapObjectIteratorMultipleSpaces) {
+ Factory* factory = i_isolate()->factory();
+ Heap* const heap = i_isolate()->heap();
+ HandleScope scope(i_isolate());
+
+ std::vector<Handle<HeapObject>> objs;
+
+ // Allocate a JS array in Young Space and Old Space.
+ objs.push_back(factory->NewJSArray(10));
+ objs.push_back(factory->NewJSArray(10, HOLEY_ELEMENTS, AllocationType::kOld));
+
+ // Allocate a small string in Young Space and Old Space.
+ objs.push_back(factory->NewStringFromStaticChars("abcdefghij"));
+ objs.push_back(
+ factory->NewStringFromStaticChars("abcdefghij", AllocationType::kOld));
+
+ // Allocate a large string in Large Object Space.
+ const int large_size = kMaxRegularHeapObjectSize + 1;
+ std::string large_str(large_size - 1, 'a');
+ objs.push_back(factory->NewStringFromAsciiChecked(large_str.c_str(),
+ AllocationType::kOld));
+
+ // Add a Map object to check.
+ objs.push_back(handle(objs[0]->map(), i_isolate()));
+
+ std::vector<bool> found(objs.size(), false);
+
+ HeapObjectIterator iterator(heap);
+ for (Tagged<HeapObject> obj = iterator.Next(); !obj.is_null();
+ obj = iterator.Next()) {
+ for (size_t i = 0; i < objs.size(); i++) {
+ if (objs[i]->ptr() == obj.ptr()) {
+ found[i] = true;
+ }
+ }
+ }
+
+ for (size_t i = 0; i < found.size(); i++) {
+ EXPECT_TRUE(found[i]);
+ }
+}
+
} // namespace v8::internal::heap
diff --git a/deps/v8/test/unittests/heap/shared-heap-unittest.cc b/deps/v8/test/unittests/heap/shared-heap-unittest.cc
index 2ef41ad122f..8558adfa8cb 100644
--- a/deps/v8/test/unittests/heap/shared-heap-unittest.cc
+++ b/deps/v8/test/unittests/heap/shared-heap-unittest.cc
@@ -16,6 +16,10 @@
#include "test/unittests/test-utils.h"
#include "testing/gtest/include/gtest/gtest.h"
+#if V8_ENABLE_WEBASSEMBLY
+#include "src/wasm/canonical-types.h"
+#endif // V8_ENABLE_WEBASSEMBLY
+
// In multi-cage mode we create one cage per isolate
// and we don't share objects between cages.
#if V8_CAN_CREATE_SHARED_HEAP_BOOL && !COMPRESS_POINTERS_IN_MULTIPLE_CAGES_BOOL
@@ -936,6 +940,107 @@ TEST_F(SharedHeapTest, WriteBarrierForRange_SharedHeapMarking) {
InvokeMajorGC(isolate);
}
+#if V8_ENABLE_WEBASSEMBLY
+namespace {
+
+// The index the shared rtts array is grown to up front, and the larger one the
+// blocking thread asks for so that it has to grow the array again.
+constexpr uint32_t kPreparedTypeIndex = 8;
+constexpr uint32_t kBlockingTypeIndex = 4096;
+
+// Runs into wasm_shared_canonical_types_mutex_ through production code, while
+// the main thread holds it.
+class PrepareSharedCanonicalTypeThread final : public ParkingThread {
+ public:
+ PrepareSharedCanonicalTypeThread(base::Semaphore* sema_mutex_held,
+ base::Semaphore* sema_done)
+ : ParkingThread(Options("PrepareSharedCanonicalTypeThread")),
+ sema_mutex_held_(sema_mutex_held),
+ sema_done_(sema_done) {}
+
+ void Run() override {
+ SetupClientIsolateAndRunCallback(
+ [this](v8::Isolate* client_isolate, Isolate* i_client_isolate) {
+ HandleScope scope(i_client_isolate);
+ // Only start once the main thread holds the mutex, so that this call
+ // is guaranteed to block on it.
+ sema_mutex_held_->Wait();
+ wasm::TypeCanonicalizer::PrepareForCanonicalTypeId(
+ i_client_isolate, wasm::CanonicalTypeIndex{kBlockingTypeIndex},
+ SharedFlag{true});
+ sema_done_->Signal();
+ });
+ }
+
+ private:
+ base::Semaphore* sema_mutex_held_;
+ base::Semaphore* sema_done_;
+};
+
+// Fails the process if the interaction below does not finish. The deadlocked
+// threads cannot report anything themselves, and a hung test would otherwise
+// only be caught by the test runner's global timeout.
+class DeadlockWatchdogThread final : public base::Thread {
+ public:
+ explicit DeadlockWatchdogThread(base::Semaphore* sema_done)
+ : Thread(Options("DeadlockWatchdogThread")), sema_done_(sema_done) {}
+
+ void Run() override {
+ if (!sema_done_->WaitFor(base::TimeDelta::FromSeconds(30))) {
+ FATAL(
+ "deadlock: an isolate blocked on wasm_shared_canonical_types_mutex_ "
+ "never reached a safepoint, so the shared GC could not complete");
+ }
+ }
+
+ private:
+ base::Semaphore* sema_done_;
+};
+
+} // namespace
+
+// Regression test for b/538572369: wasm_shared_canonical_types_mutex_ is held
+// across shared-heap allocations in PrepareForCanonicalTypeId and
+// CreateMapForType, so it has to be acquired in a parked state. A client
+// isolate blocked on it without parking never reaches the safepoint that a
+// concurrent shared GC waits for, and both threads hang.
+TEST_F(SharedHeapTest, SharedCanonicalTypesMutexIsSafepointAware) {
+ Isolate* isolate = i_isolate();
+ CHECK(isolate->is_shared_space_isolate());
+ LocalIsolate* local_isolate = isolate->main_thread_local_isolate();
+
+ // Grow the shared rtts array once, so that the background thread's request
+ // for a larger index gets past the fast path and has to take the mutex.
+ wasm::TypeCanonicalizer::PrepareForCanonicalTypeId(
+ isolate, wasm::CanonicalTypeIndex{kPreparedTypeIndex}, SharedFlag{true});
+
+ base::Semaphore sema_mutex_held(0);
+ base::Semaphore sema_done(0);
+
+ auto blocker = std::make_unique<PrepareSharedCanonicalTypeThread>(
+ &sema_mutex_held, &sema_done);
+ CHECK(blocker->Start());
+
+ DeadlockWatchdogThread watchdog(&sema_done);
+ CHECK(watchdog.Start());
+
+ {
+ base::MutexGuard lock(isolate->wasm_shared_canonical_types_mutex());
+ sema_mutex_held.Signal();
+ // There is no way to observe that the other thread is blocked inside
+ // base::Mutex::Lock, so give it a moment to get there. Losing this race
+ // makes the test pass spuriously, never fail spuriously.
+ base::OS::Sleep(base::TimeDelta::FromMilliseconds(200));
+ // Waits for a global safepoint, which the blocked isolate cannot reach.
+ isolate->heap()->CollectGarbageShared(isolate->main_thread_local_heap(),
+ GarbageCollectionReason::kTesting);
+ }
+
+ blocker->ParkedJoin(local_isolate);
+ watchdog.Join();
+}
+#endif // V8_ENABLE_WEBASSEMBLY
+
template <typename TMixin>
class WithEmptySharedHeapFlagsMixin : public TMixin {
public:
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 fa12e2d27b2..2ce70d9b874 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
@@ -363,11 +363,11 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
kFeedbackIsEmbedded);
// Emit unary and count operator invocations.
- builder.UnaryOperation(Token::kInc, 1)
- .UnaryOperation(Token::kDec, 1)
+ builder.UnaryOperation(Token::kInc, kFeedbackIsEmbedded)
+ .UnaryOperation(Token::kDec, kFeedbackIsEmbedded)
.UnaryOperation(Token::kAdd, 1)
- .UnaryOperation(Token::kSub, 1)
- .UnaryOperation(Token::kBitNot, 1);
+ .UnaryOperation(Token::kSub, kFeedbackIsEmbedded)
+ .UnaryOperation(Token::kBitNot, kFeedbackIsEmbedded);
// Emit unary operator invocations.
builder.LogicalNot(ToBooleanMode::kConvertToBoolean)
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc
index 2084a6f6d9a..307f2c29458 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-iterator-unittest.cc
@@ -7,6 +7,7 @@
#include "src/init/v8.h"
#include "src/interpreter/bytecode-array-builder.h"
#include "src/numbers/hash-seed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "test/unittests/interpreter/bytecode-utils.h"
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc
index ae9c68b1a92..4ee72692431 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-random-iterator-unittest.cc
@@ -7,6 +7,7 @@
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/bytecode-array-random-iterator.h"
#include "src/numbers/hash-seed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/smi.h"
#include "test/unittests/interpreter/bytecode-utils.h"
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc
index e9014a37ade..4df7954e56f 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-writer-unittest.cc
@@ -2,20 +2,21 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "src/init/v8.h"
+#include "src/interpreter/bytecode-array-writer.h"
#include "src/api/api.h"
#include "src/codegen/source-position-table.h"
#include "src/execution/isolate.h"
#include "src/heap/factory.h"
-#include "src/interpreter/bytecode-array-writer.h"
+#include "src/init/v8.h"
#include "src/interpreter/bytecode-label.h"
#include "src/interpreter/bytecode-node.h"
#include "src/interpreter/bytecode-register.h"
#include "src/interpreter/bytecode-source-info.h"
#include "src/interpreter/constant-array-builder.h"
-#include "src/utils/utils.h"
+#include "src/interpreter/handler-table-builder.h"
#include "src/objects/objects-inl.h"
+#include "src/utils/utils.h"
#include "test/unittests/interpreter/bytecode-utils.h"
#include "test/unittests/test-utils.h"
@@ -379,6 +380,25 @@ TEST_F(BytecodeArrayWriterUnittest, DeadcodeElimination) {
CHECK(source_iterator.done());
}
+TEST_F(BytecodeArrayWriterUnittest, HandlerTableBuilderOverflowCheck) {
+ HandlerTableBuilder builder(zone());
+ int handler_id = builder.NewHandlerEntry();
+ builder.SetTryRegionStart(handler_id, 0);
+ builder.SetTryRegionEnd(handler_id, 10);
+ builder.SetHandlerTarget(handler_id,
+ static_cast<size_t>(HandlerTable::kLazyDeopt));
+ DirectHandle<TrustedByteArray> table = builder.ToHandlerTable(isolate());
+ CHECK_GT(table->length().value(), 0u);
+
+ HandlerTableBuilder invalid_builder(zone());
+ int invalid_handler_id = invalid_builder.NewHandlerEntry();
+ invalid_builder.SetTryRegionStart(invalid_handler_id, 0);
+ invalid_builder.SetTryRegionEnd(invalid_handler_id, 10);
+ invalid_builder.SetHandlerTarget(
+ invalid_handler_id, static_cast<size_t>(HandlerTable::kLazyDeopt) + 1);
+ ASSERT_DEATH_IF_SUPPORTED(invalid_builder.ToHandlerTable(isolate()), "");
+}
+
#undef B
#undef R
diff --git a/deps/v8/test/unittests/interpreter/bytecode-decoder-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-decoder-unittest.cc
index 54c3ac61a80..ef603ffaa59 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-decoder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-decoder-unittest.cc
@@ -66,7 +66,11 @@ TEST_F(BytecodeDecoderTest, DecodeBytecodeAndOperands) {
" CallJSRuntime [boolean_function], r0-r0"},
{{B(TestEqualStrict), R8(0), U8(1)},
3,
- " TestEqualStrict r0, EmbeddedFeedback[1]"},
+ " TestEqualStrict r0, EmbeddedFeedback[Boolean]"},
+ {{B(Add), R8(0), U8(1)},
+ 3,
+ " Add r0, EmbeddedFeedback[SignedSmall]"},
+ {{B(Inc), U8(1)}, 2, " Inc EmbeddedFeedback[SignedSmall]"},
};
Handle<TrustedFixedArray> constant_pool =
diff --git a/deps/v8/test/unittests/interpreter/bytecode-expectations-printer.cc b/deps/v8/test/unittests/interpreter/bytecode-expectations-printer.cc
index e03694cda08..940e8520b73 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-expectations-printer.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-expectations-printer.cc
@@ -203,7 +203,9 @@ void BytecodeExpectationsPrinter::PrintBytecodeOperand(
case OperandType::kEmbeddedFeedback: {
// Ignore embedded feedback bytes in bytecode expectation test.
DCHECK(Bytecodes::IsEmbeddedFeedbackBytecode(bytecode));
- DCHECK_EQ(op_index, kEmbeddedFeedbackOperandIndex);
+ DCHECK_EQ(op_index, Bytecodes::IsUnaryOpWithEmbeddedFeedback(bytecode)
+ ? kUnaryEmbeddedFeedbackOperandIndex
+ : kEmbeddedFeedbackOperandIndex);
*stream << "EmbeddedFeedback(";
break;
}
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/ArrayLiterals.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/ArrayLiterals.golden
index 6700035918d..83bc2c76333 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/ArrayLiterals.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/ArrayLiterals.golden
@@ -150,18 +150,18 @@ bytecodes: [
B(Star4),
B(GetNamedProperty), R(4), U8(2:"next"), FBV(6),
B(Star3),
- B(CallProperty0), R(3), R(4), FBV(15),
+ B(CallProperty0), R(3), R(4), FBV(14),
B(Star5),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(5), RegCount8(1),
- B(GetNamedProperty), R(5), U8(3:"done"), FBV(17),
+ B(GetNamedProperty), R(5), U8(3:"done"), FBV(16),
B(JumpIfToBooleanTrue), U8(19),
B(GetNamedProperty), R(5), U8(4:"value"), FBV(8),
- B(StaInArrayLiteral), R(1), R(2), FBV(13),
+ B(StaInArrayLiteral), R(1), R(2), FBV(12),
B(Ldar), R(2),
- B(Inc), FBV(12),
+ B(Inc), EmbeddedFeedback(),
B(Star2),
- B(JumpLoop), U8(31), I8(0), FBV(19),
+ B(JumpLoop), U8(31), I8(0), FBV(18),
B(Ldar), R(1),
/* 71 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
index 3fd80b58466..8e7994eabb3 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/AssignmentsInBinaryExpression.golden
@@ -104,7 +104,7 @@ bytecodes: [
B(Star0),
/* 63 E> */ B(Add), R(1), EmbeddedFeedback(),
B(Star0),
- /* 75 S> */ B(Inc), FBV(0),
+ /* 75 S> */ B(Inc), EmbeddedFeedback(),
B(Star0),
/* 89 S> */ B(Return),
]
@@ -243,13 +243,13 @@ bytecodes: [
B(Ldar), R(0),
B(ToNumeric), FBV(0),
B(Star2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
B(Ldar), R(2),
/* 59 E> */ B(Add), R(1), EmbeddedFeedback(),
B(Star1),
B(Ldar), R(0),
- B(Inc), FBV(1),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
/* 67 E> */ B(Add), R(1), EmbeddedFeedback(),
/* 75 S> */ B(Return),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden
index 79d473f12fd..45ee70bde6a 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/BasicLoops.golden
@@ -574,9 +574,9 @@ bytecodes: [
/* 80 E> */ B(MulSmi), I8(12), EmbeddedFeedback(),
B(Star0),
/* 67 S> */ B(Ldar), R(1),
- B(Dec), FBV(0),
+ B(Dec), EmbeddedFeedback(),
B(Star1),
- /* 45 E> */ B(JumpLoop), U8(15), I8(0), FBV(1),
+ /* 45 E> */ B(JumpLoop), U8(15), I8(0), FBV(0),
/* 88 S> */ B(Ldar), R(0),
/* 97 S> */ B(Return),
]
@@ -634,9 +634,9 @@ bytecodes: [
B(JumpIfFalse), U8(4),
/* 102 S> */ B(Jump), U8(11),
/* 69 S> */ B(Ldar), R(1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 45 E> */ B(JumpLoop), U8(20), I8(0), FBV(1),
+ /* 45 E> */ B(JumpLoop), U8(20), I8(0), FBV(0),
/* 112 S> */ B(Ldar), R(0),
/* 121 S> */ B(Return),
]
@@ -679,10 +679,10 @@ bytecodes: [
/* 113 S> */ B(PopContext), R(3),
B(Jump), U8(10),
/* 126 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 127 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(PopContext), R(3),
- /* 45 E> */ B(JumpLoop), U8(39), I8(0), FBV(1),
+ /* 45 E> */ B(JumpLoop), U8(39), I8(0), FBV(0),
B(LdaUndefined),
/* 137 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden
index 18868fbfac3..c1ab9bc2097 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/BreakableBlocks.golden
@@ -62,7 +62,7 @@ bytecodes: [
/* 111 E> */ B(TestLessThan), R(2), EmbeddedFeedback(),
B(JumpIfFalse), U8(31),
/* 129 S> */ B(Ldar), R(0),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
/* 142 S> */ B(Ldar), R(2),
/* 148 E> */ B(Add), R(1), EmbeddedFeedback(),
@@ -72,13 +72,13 @@ bytecodes: [
B(JumpIfFalse), U8(4),
/* 161 S> */ B(Jump), U8(20),
/* 118 S> */ B(Ldar), R(2),
- B(Inc), FBV(1),
+ B(Inc), EmbeddedFeedback(),
B(Star2),
- /* 93 E> */ B(JumpLoop), U8(32), I8(1), FBV(2),
+ /* 93 E> */ B(JumpLoop), U8(32), I8(1), FBV(0),
/* 84 S> */ B(Ldar), R(1),
- B(Inc), FBV(4),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 58 E> */ B(JumpLoop), U8(50), I8(0), FBV(5),
+ /* 58 E> */ B(JumpLoop), U8(50), I8(0), FBV(2),
/* 188 S> */ B(Ldar), R(0),
/* 199 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/CallAndSpread.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/CallAndSpread.golden
index 326c43c5302..5e85733f684 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/CallAndSpread.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/CallAndSpread.golden
@@ -81,20 +81,20 @@ bytecodes: [
B(Star5),
B(GetNamedProperty), R(5), U8(4:"next"), FBV(10),
B(Star4),
- B(CallProperty0), R(4), R(5), FBV(19),
+ B(CallProperty0), R(4), R(5), FBV(18),
B(Star6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), RegCount8(1),
- B(GetNamedProperty), R(6), U8(5:"done"), FBV(21),
+ B(GetNamedProperty), R(6), U8(5:"done"), FBV(20),
B(JumpIfToBooleanTrue), U8(19),
B(GetNamedProperty), R(6), U8(6:"value"), FBV(12),
- B(StaInArrayLiteral), R(2), R(3), FBV(17),
+ B(StaInArrayLiteral), R(2), R(3), FBV(16),
B(Ldar), R(3),
- B(Inc), FBV(16),
+ B(Inc), EmbeddedFeedback(),
B(Star3),
- B(JumpLoop), U8(31), I8(0), FBV(23),
+ B(JumpLoop), U8(31), I8(0), FBV(22),
B(LdaSmi), I8(4),
- B(StaInArrayLiteral), R(2), R(3), FBV(17),
+ B(StaInArrayLiteral), R(2), R(3), FBV(16),
/* 39 E> */ B(CallJSRuntime), U8(%reflect_apply), R(0), RegCount8(3),
B(LdaUndefined),
/* 64 S> */ B(Return),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareBoolean.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareBoolean.golden
index c462b09cd97..13d88ee1ea6 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareBoolean.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareBoolean.golden
@@ -210,9 +210,9 @@ bytecodes: [
B(TestReferenceEqual), R(0),
B(JumpIfTrue), U8(11),
/* 82 S> */ B(Ldar), R(1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 59 E> */ B(JumpLoop), U8(10), I8(0), FBV(1),
+ /* 59 E> */ B(JumpLoop), U8(10), I8(0), FBV(0),
B(LdaUndefined),
/* 89 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareNil.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareNil.golden
index 20ada13a2ba..fff51e0a646 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareNil.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/CompareNil.golden
@@ -261,9 +261,9 @@ bytecodes: [
/* 73 S> */ B(Ldar), R(0),
B(JumpIfUndefined), U8(11),
/* 92 S> */ B(Ldar), R(1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 64 E> */ B(JumpLoop), U8(9), I8(0), FBV(1),
+ /* 64 E> */ B(JumpLoop), U8(9), I8(0), FBV(0),
B(LdaUndefined),
/* 99 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/CountOperators.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/CountOperators.golden
index 1a6b023e9ba..1425763e59a 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/CountOperators.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/CountOperators.golden
@@ -15,7 +15,7 @@ bytecode array length: 7
bytecodes: [
/* 42 S> */ B(LdaSmi), I8(1),
B(Star0),
- /* 45 S> */ B(Inc), FBV(0),
+ /* 45 S> */ B(Inc), EmbeddedFeedback(),
B(Star0),
/* 56 S> */ B(Return),
]
@@ -36,7 +36,7 @@ bytecodes: [
B(Star0),
/* 45 S> */ B(ToNumeric), FBV(0),
B(Star1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
B(Ldar), R(1),
/* 56 S> */ B(Return),
@@ -56,7 +56,7 @@ bytecode array length: 7
bytecodes: [
/* 42 S> */ B(LdaSmi), I8(1),
B(Star0),
- /* 45 S> */ B(Dec), FBV(0),
+ /* 45 S> */ B(Dec), EmbeddedFeedback(),
B(Star0),
/* 56 S> */ B(Return),
]
@@ -77,7 +77,7 @@ bytecodes: [
B(Star0),
/* 45 S> */ B(ToNumeric), FBV(0),
B(Star1),
- B(Dec), FBV(0),
+ B(Dec), EmbeddedFeedback(),
B(Star0),
B(Ldar), R(1),
/* 56 S> */ B(Return),
@@ -100,7 +100,7 @@ bytecodes: [
/* 54 S> */ B(GetNamedProperty), R(0), U8(1:"val"), FBV(1),
B(ToNumeric), FBV(3),
B(Star2),
- B(Inc), FBV(3),
+ B(Inc), EmbeddedFeedback(),
B(Star3),
/* 66 E> */ B(SetNamedProperty), R(0), U8(1:"val"), FBV(4),
B(Ldar), R(2),
@@ -124,9 +124,9 @@ bytecodes: [
/* 42 S> */ B(CreateObjectLiteral), U8(0:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
B(Star0),
/* 54 S> */ B(GetNamedProperty), R(0), U8(1:"val"), FBV(1),
- B(Dec), FBV(3),
+ B(Dec), EmbeddedFeedback(),
B(Star2),
- /* 65 E> */ B(SetNamedProperty), R(0), U8(1:"val"), FBV(4),
+ /* 65 E> */ B(SetNamedProperty), R(0), U8(1:"val"), FBV(3),
B(Ldar), R(2),
/* 69 S> */ B(Return),
]
@@ -153,7 +153,7 @@ bytecodes: [
/* 81 E> */ B(GetKeyedProperty), R(1), FBV(1),
B(ToNumeric), FBV(3),
B(Star4),
- B(Dec), FBV(3),
+ B(Dec), EmbeddedFeedback(),
B(Star5),
/* 86 E> */ B(SetKeyedProperty), R(1), R(0), FBV(4),
B(Ldar), R(4),
@@ -180,9 +180,9 @@ bytecodes: [
B(Star1),
/* 72 S> */ B(Ldar), R(0),
/* 83 E> */ B(GetKeyedProperty), R(1), FBV(1),
- B(Inc), FBV(3),
+ B(Inc), EmbeddedFeedback(),
B(Star4),
- /* 87 E> */ B(SetKeyedProperty), R(1), R(0), FBV(4),
+ /* 87 E> */ B(SetKeyedProperty), R(1), R(0), FBV(3),
B(Ldar), R(4),
/* 89 S> */ B(Return),
]
@@ -208,7 +208,7 @@ bytecodes: [
/* 53 S> */ B(CreateClosure), U8(1:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
B(Star0),
/* 78 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 87 E> */ B(StaCurrentContextSlotNoCell), C8(2),
/* 89 S> */ B(Return),
]
@@ -236,7 +236,7 @@ bytecodes: [
/* 78 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
B(ToNumeric), FBV(0),
B(Star2),
- B(Dec), FBV(0),
+ B(Dec), EmbeddedFeedback(),
/* 86 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(Ldar), R(2),
/* 89 S> */ B(Return),
@@ -263,7 +263,7 @@ bytecodes: [
/* 63 S> */ B(Ldar), R(0),
B(ToNumeric), FBV(1),
B(Star3),
- B(Inc), FBV(1),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
B(LdaSmi), I8(2),
B(Star4),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/DestructuringAssignment.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/DestructuringAssignment.golden
index 4a90c3bcc7c..2505e3515e5 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/DestructuringAssignment.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/DestructuringAssignment.golden
@@ -87,18 +87,18 @@ bytecodes: [
B(Star13),
B(LdaTrue),
B(Star6),
- B(CallProperty0), R(4), R(5), FBV(19),
+ B(CallProperty0), R(4), R(5), FBV(18),
B(Star11),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), RegCount8(1),
- B(GetNamedProperty), R(11), U8(2:"done"), FBV(21),
+ B(GetNamedProperty), R(11), U8(2:"done"), FBV(20),
B(JumpIfToBooleanTrue), U8(19),
B(GetNamedProperty), R(11), U8(3:"value"), FBV(7),
B(StaInArrayLiteral), R(12), R(13), FBV(16),
B(Ldar), R(13),
- B(Inc), FBV(18),
+ B(Inc), EmbeddedFeedback(),
B(Star13),
- B(JumpLoop), U8(31), I8(0), FBV(23),
+ B(JumpLoop), U8(31), I8(0), FBV(22),
B(Mov), R(12), R(1),
B(LdaSmi), I8(-1),
B(Star8),
@@ -113,10 +113,10 @@ bytecodes: [
B(Ldar), R(6),
B(JumpIfToBooleanTrue), U8(35),
B(Mov), R(context), R(12),
- B(GetNamedProperty), R(5), U8(4:"return"), FBV(25),
+ B(GetNamedProperty), R(5), U8(4:"return"), FBV(24),
B(JumpIfUndefinedOrNull), U8(26),
B(Star13),
- B(CallProperty0), R(13), R(5), FBV(27),
+ B(CallProperty0), R(13), R(5), FBV(26),
B(JumpIfJSReceiver), U8(19),
B(Star14),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(14), RegCount8(1),
@@ -339,3 +339,29 @@ constant pool: [
handlers: [
]
+---
+snippet: "
+ var a = {y:1, w:2, v:3};
+ var { ...y } = a;
+"
+frame size: 3
+parameter count: 1
+bytecode array length: 24
+bytecodes: [
+ /* 42 S> */ B(CreateObjectLiteral), U8(0:OBJECT_BOILERPLATE_DESCRIPTION_TYPE), FBV(0), Flag8(0x29),
+ B(Star0),
+ /* 74 S> */ B(Mov), R(0), R(2),
+ B(JumpIfUndefinedOrNull), U8(4),
+ B(Jump), U8(7),
+ /* 63 E> */ B(CallRuntime), U16(Runtime::kThrowPatternAssignmentNonCoercible), R(2), RegCount8(1),
+ /* 68 E> */ B(CloneObject), R(2), Flag8(0x0), FBV(1),
+ B(Star1),
+ B(LdaUndefined),
+ /* 77 S> */ B(Return),
+]
+constant pool: [
+ OBJECT_BOILERPLATE_DESCRIPTION_TYPE,
+]
+handlers: [
+]
+
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/GlobalCountOperators.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/GlobalCountOperators.golden
index 7e9da39199c..54ffaac0600 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/GlobalCountOperators.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/GlobalCountOperators.golden
@@ -17,9 +17,9 @@ parameter count: 1
bytecode array length: 12
bytecodes: [
/* 31 S> */ B(LdaGlobal), U8(0:"global"), FBV(0),
- B(Inc), FBV(2),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
- /* 40 E> */ B(StaGlobal), U8(0:"global"), FBV(3),
+ /* 40 E> */ B(StaGlobal), U8(0:"global"), FBV(2),
B(Ldar), R(0),
/* 47 S> */ B(Return),
]
@@ -42,7 +42,7 @@ bytecodes: [
/* 31 S> */ B(LdaGlobal), U8(0:"global"), FBV(0),
B(ToNumeric), FBV(2),
B(Star0),
- B(Dec), FBV(2),
+ B(Dec), EmbeddedFeedback(),
B(Star1),
/* 44 E> */ B(StaGlobal), U8(0:"global"), FBV(3),
B(Ldar), R(0),
@@ -65,9 +65,9 @@ parameter count: 1
bytecode array length: 12
bytecodes: [
/* 46 S> */ B(LdaGlobal), U8(0:"unallocated"), FBV(0),
- B(Dec), FBV(2),
+ B(Dec), EmbeddedFeedback(),
B(Star0),
- /* 55 E> */ B(StaGlobal), U8(0:"unallocated"), FBV(3),
+ /* 55 E> */ B(StaGlobal), U8(0:"unallocated"), FBV(2),
B(Ldar), R(0),
/* 67 S> */ B(Return),
]
@@ -90,7 +90,7 @@ bytecodes: [
/* 32 S> */ B(LdaGlobal), U8(0:"unallocated"), FBV(0),
B(ToNumeric), FBV(2),
B(Star0),
- B(Inc), FBV(2),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
/* 50 E> */ B(StaGlobal), U8(0:"unallocated"), FBV(3),
B(Ldar), R(0),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden
index ad0a76f0f57..1cf5bf686fe 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/Modules.golden
@@ -149,12 +149,12 @@ bytecodes: [
/* 17 S> */ B(LdaSmi), I8(42),
/* 17 E> */ B(StaModuleVariable), I8(1), U8(0),
/* 21 S> */ B(LdaModuleVariable), I8(1), U8(0),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 24 E> */ B(StaModuleVariable), I8(1), U8(0),
/* 34 S> */ B(LdaUndefined),
B(Star1),
/* 39 S> */ B(LdaModuleVariable), I8(1), U8(0),
- B(Inc), FBV(1),
+ B(Inc), EmbeddedFeedback(),
/* 42 E> */ B(StaModuleVariable), I8(1), U8(0),
B(LdaUndefined),
/* 50 S> */ B(Return),
@@ -198,12 +198,12 @@ bytecodes: [
/* 17 S> */ B(LdaSmi), I8(42),
/* 17 E> */ B(StaModuleVariable), I8(1), U8(0),
/* 21 S> */ B(LdaModuleVariable), I8(1), U8(0),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 24 E> */ B(StaModuleVariable), I8(1), U8(0),
/* 34 S> */ B(LdaUndefined),
B(Star1),
/* 39 S> */ B(LdaModuleVariable), I8(1), U8(0),
- B(Inc), FBV(1),
+ B(Inc), EmbeddedFeedback(),
/* 42 E> */ B(StaModuleVariable), I8(1), U8(0),
B(LdaUndefined),
/* 50 S> */ B(Return),
@@ -248,12 +248,12 @@ bytecodes: [
/* 19 S> */ B(LdaSmi), I8(42),
/* 19 E> */ B(StaModuleVariable), I8(1), U8(0),
/* 23 S> */ B(LdaModuleVariable), I8(1), U8(0),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 26 E> */ B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), RegCount8(0),
/* 36 S> */ B(LdaUndefined),
B(Star1),
/* 41 S> */ B(LdaModuleVariable), I8(1), U8(0),
- B(Inc), FBV(1),
+ B(Inc), EmbeddedFeedback(),
/* 44 E> */ B(CallRuntime), U16(Runtime::kThrowConstAssignError), R(0), RegCount8(0),
B(LdaUndefined),
/* 52 S> */ B(Return),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/NewAndSpread.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/NewAndSpread.golden
index a12f15fd641..4d4429504e5 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/NewAndSpread.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/NewAndSpread.golden
@@ -113,20 +113,20 @@ bytecodes: [
B(GetNamedProperty), R(5), U8(5:"next"), FBV(6),
B(Star4),
B(Mov), R(0), R(1),
- B(CallProperty0), R(4), R(5), FBV(15),
+ B(CallProperty0), R(4), R(5), FBV(14),
B(Star6),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(6), RegCount8(1),
- B(GetNamedProperty), R(6), U8(6:"done"), FBV(17),
+ B(GetNamedProperty), R(6), U8(6:"done"), FBV(16),
B(JumpIfToBooleanTrue), U8(19),
B(GetNamedProperty), R(6), U8(7:"value"), FBV(8),
- B(StaInArrayLiteral), R(2), R(3), FBV(13),
+ B(StaInArrayLiteral), R(2), R(3), FBV(12),
B(Ldar), R(3),
- B(Inc), FBV(12),
+ B(Inc), EmbeddedFeedback(),
B(Star3),
- B(JumpLoop), U8(31), I8(0), FBV(19),
+ B(JumpLoop), U8(31), I8(0), FBV(18),
B(LdaSmi), I8(4),
- B(StaInArrayLiteral), R(2), R(3), FBV(13),
+ B(StaInArrayLiteral), R(2), R(3), FBV(12),
/* 89 E> */ B(CallJSRuntime), U8(%reflect_construct), R(1), RegCount8(2),
B(LdaUndefined),
/* 116 S> */ B(Return),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorAccess.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorAccess.golden
index 9198265b381..c513769242c 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorAccess.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/PrivateAccessorAccess.golden
@@ -36,27 +36,27 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(2), RegCount8(1),
B(Star3),
B(CallProperty0), R(3), R(this), FBV(4),
- B(Inc), FBV(6),
+ B(Inc), EmbeddedFeedback(),
B(Star3),
/* 83 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), RegCount8(1),
B(Star4),
- B(CallProperty1), R(4), R(this), R(3), FBV(7),
+ B(CallProperty1), R(4), R(this), R(3), FBV(6),
/* 91 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star2),
B(LdaSmi), I8(1),
B(Star3),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 96 E> */ B(GetKeyedProperty), R(this), FBV(9),
+ /* 96 E> */ B(GetKeyedProperty), R(this), FBV(8),
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(2), RegCount8(1),
B(Star4),
- B(CallProperty1), R(4), R(this), R(3), FBV(11),
+ B(CallProperty1), R(4), R(this), R(3), FBV(10),
/* 108 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star2),
B(LdaImmutableCurrentContextSlot), C8(3),
- /* 120 E> */ B(GetKeyedProperty), R(this), FBV(13),
+ /* 120 E> */ B(GetKeyedProperty), R(this), FBV(12),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(2), RegCount8(1),
B(Star3),
- B(CallProperty0), R(3), R(this), FBV(15),
+ B(CallProperty0), R(3), R(this), FBV(14),
/* 123 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden
index 7791efe09c6..b7103eabf9a 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/StandardForLoop.golden
@@ -24,9 +24,9 @@ bytecodes: [
B(JumpIfFalse), U8(14),
/* 56 S> */ B(Mov), R(0), R(1),
/* 43 S> */ B(Ldar), R(1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star0),
- /* 17 E> */ B(JumpLoop), U8(15), I8(0), FBV(1),
+ /* 17 E> */ B(JumpLoop), U8(15), I8(0), FBV(0),
B(LdaUndefined),
/* 61 S> */ B(Return),
]
@@ -77,7 +77,7 @@ bytecodes: [
B(Star1),
B(Jump), U8(8),
/* 43 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 43 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaSmi), I8(1),
B(Star2),
@@ -92,7 +92,7 @@ bytecodes: [
B(LdaSmi), I8(1),
B(TestEqual), R(2), EmbeddedFeedback(),
B(JumpIfFalse), U8(46),
- /* 48 S> */ B(LdaLookupGlobalSlot), U8(3:"eval"), FBV(1), U8(3),
+ /* 48 S> */ B(LdaLookupGlobalSlot), U8(3:"eval"), FBV(0), U8(3),
B(Star7),
B(LdaConstant), U8(4:"1"),
B(Star8),
@@ -107,19 +107,19 @@ bytecodes: [
B(Mov), R(closure), R(11),
B(CallRuntime), U16(Runtime::kResolvePossiblyDirectEval), R(9), RegCount8(6),
B(Star7),
- /* 48 E> */ B(CallUndefinedReceiver1), R(7), R(8), FBV(3),
+ /* 48 E> */ B(CallUndefinedReceiver1), R(7), R(8), FBV(2),
B(LdaZero),
B(Star2),
B(LdaCurrentContextSlotNoCell), C8(2),
B(Star0),
- /* 17 E> */ B(JumpLoop), U8(47), I8(1), FBV(5),
+ /* 17 E> */ B(JumpLoop), U8(47), I8(1), FBV(4),
B(LdaSmi), I8(1),
B(TestEqual), R(2), EmbeddedFeedback(),
B(JumpIfFalse), U8(6),
B(PopContext), R(6),
B(Jump), U8(8),
B(PopContext), R(6),
- B(JumpLoop), U8(111), I8(0), FBV(7),
+ B(JumpLoop), U8(111), I8(0), FBV(6),
B(PopContext), R(5),
B(LdaUndefined),
/* 61 S> */ B(Return),
@@ -163,7 +163,7 @@ bytecodes: [
B(Star1),
B(Jump), U8(8),
/* 43 S> */ B(LdaCurrentContextSlotNoCell), C8(2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
/* 43 E> */ B(StaCurrentContextSlotNoCell), C8(2),
B(LdaSmi), I8(1),
B(Star2),
@@ -180,19 +180,19 @@ bytecodes: [
B(JumpIfFalse), U8(19),
/* 48 S> */ B(CreateClosure), U8(1:SHARED_FUNCTION_INFO_TYPE), FBV(0), Flag8(0x2),
B(Star5),
- /* 74 E> */ B(CallUndefinedReceiver0), R(5), FBV(1),
+ /* 74 E> */ B(CallUndefinedReceiver0), R(5), FBV(0),
B(LdaZero),
B(Star2),
B(LdaCurrentContextSlotNoCell), C8(2),
B(Star0),
- /* 17 E> */ B(JumpLoop), U8(20), I8(1), FBV(3),
+ /* 17 E> */ B(JumpLoop), U8(20), I8(1), FBV(2),
B(LdaSmi), I8(1),
B(TestEqual), R(2), EmbeddedFeedback(),
B(JumpIfFalse), U8(6),
B(PopContext), R(4),
B(Jump), U8(8),
B(PopContext), R(4),
- B(JumpLoop), U8(84), I8(0), FBV(5),
+ B(JumpLoop), U8(84), I8(0), FBV(4),
B(LdaUndefined),
/* 80 S> */ B(Return),
]
@@ -227,9 +227,9 @@ bytecodes: [
/* 77 E> */ B(Add), R(0), EmbeddedFeedback(),
B(Star2),
/* 62 S> */ B(Ldar), R(1),
- B(Dec), FBV(5),
+ B(Dec), EmbeddedFeedback(),
B(Star1),
- /* 17 E> */ B(JumpLoop), U8(17), I8(0), FBV(6),
+ /* 17 E> */ B(JumpLoop), U8(17), I8(0), FBV(5),
B(LdaUndefined),
/* 84 S> */ B(Return),
]
@@ -273,9 +273,9 @@ bytecodes: [
B(JumpIfFalse), U8(14),
/* 57 S> */ B(Mov), R(1), R(2),
/* 44 S> */ B(Ldar), R(2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 18 E> */ B(JumpLoop), U8(15), I8(0), FBV(1),
+ /* 18 E> */ B(JumpLoop), U8(15), I8(0), FBV(0),
B(LdaUndefined),
/* 62 S> */ B(Return),
]
@@ -330,9 +330,9 @@ bytecodes: [
B(Ldar), R(2),
B(Return),
/* 44 S> */ B(Ldar), R(1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 18 E> */ B(JumpLoop), U8(46), I8(0), FBV(1),
+ /* 18 E> */ B(JumpLoop), U8(46), I8(0), FBV(0),
B(LdaUndefined),
/* 56 S> */ B(Return),
]
@@ -370,9 +370,9 @@ bytecodes: [
B(JumpIfFalse), U8(14),
/* 62 S> */ B(Mov), R(1), R(2),
/* 49 S> */ B(Ldar), R(2),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 23 E> */ B(JumpLoop), U8(15), I8(0), FBV(1),
+ /* 23 E> */ B(JumpLoop), U8(15), I8(0), FBV(0),
B(LdaUndefined),
B(Star5),
B(Mov), R(0), R(4),
@@ -427,9 +427,9 @@ bytecodes: [
B(Ldar), R(3),
B(ReThrow),
/* 49 S> */ B(Ldar), R(1),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Star1),
- /* 23 E> */ B(JumpLoop), U8(45), I8(0), FBV(1),
+ /* 23 E> */ B(JumpLoop), U8(45), I8(0), FBV(0),
B(LdaUndefined),
B(Star4),
B(Mov), R(0), R(3),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden
index 41f81c2c61a..5b40068df4e 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/StaticPrivateMethodAccess.golden
@@ -154,11 +154,11 @@ bytecodes: [
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), RegCount8(1),
B(Star2),
B(CallProperty0), R(2), R(0), FBV(0),
- B(Inc), FBV(2),
+ B(Inc), EmbeddedFeedback(),
B(Star2),
/* 97 E> */ B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(1), RegCount8(1),
B(Star3),
- B(CallProperty1), R(3), R(0), R(2), FBV(3),
+ B(CallProperty1), R(3), R(0), R(2), FBV(2),
/* 105 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star1),
B(LdaSmi), I8(1),
@@ -175,7 +175,7 @@ bytecodes: [
B(Throw),
B(CallRuntime), U16(Runtime::kLoadPrivateSetter), R(1), RegCount8(1),
B(Star3),
- B(CallProperty1), R(3), R(0), R(2), FBV(5),
+ B(CallProperty1), R(3), R(0), R(2), FBV(4),
/* 122 S> */ B(LdaImmutableCurrentContextSlot), C8(2),
B(Star1),
B(LdaImmutableCurrentContextSlot), C8(3),
@@ -190,7 +190,7 @@ bytecodes: [
B(Throw),
B(CallRuntime), U16(Runtime::kLoadPrivateGetter), R(1), RegCount8(1),
B(Star2),
- B(CallProperty0), R(2), R(0), FBV(7),
+ B(CallProperty0), R(2), R(0), FBV(6),
/* 137 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden
index 06568bba3ad..6d7b8b99a11 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/SuperCallAndSpread.golden
@@ -116,20 +116,20 @@ bytecodes: [
B(GetNamedProperty), R(10), U8(1:"next"), FBV(5),
B(Star9),
B(Mov), R(1), R(5),
- B(CallProperty0), R(9), R(10), FBV(14),
+ B(CallProperty0), R(9), R(10), FBV(13),
B(Star11),
B(JumpIfJSReceiver), U8(7),
B(CallRuntime), U16(Runtime::kThrowIteratorResultNotAnObject), R(11), RegCount8(1),
- B(GetNamedProperty), R(11), U8(2:"done"), FBV(16),
+ B(GetNamedProperty), R(11), U8(2:"done"), FBV(15),
B(JumpIfToBooleanTrue), U8(19),
B(GetNamedProperty), R(11), U8(3:"value"), FBV(7),
- B(StaInArrayLiteral), R(7), R(8), FBV(12),
+ B(StaInArrayLiteral), R(7), R(8), FBV(11),
B(Ldar), R(8),
- B(Inc), FBV(11),
+ B(Inc), EmbeddedFeedback(),
B(Star8),
- B(JumpLoop), U8(31), I8(0), FBV(18),
+ B(JumpLoop), U8(31), I8(0), FBV(17),
B(LdaSmi), I8(1),
- B(StaInArrayLiteral), R(7), R(8), FBV(12),
+ B(StaInArrayLiteral), R(7), R(8), FBV(11),
/* 140 E> */ B(FindNonDefaultConstructorOrConstruct), R(5), R(0), R(9),
B(Ldar), R(9),
B(Mov), R(0), R(8),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/UnaryOperators.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/UnaryOperators.golden
index 66a24999385..dde27ac38fd 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/UnaryOperators.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/UnaryOperators.golden
@@ -117,7 +117,7 @@ bytecode array length: 6
bytecodes: [
/* 42 S> */ B(LdaSmi), I8(13),
B(Star0),
- /* 53 S> */ B(BitwiseNot), FBV(0),
+ /* 53 S> */ B(BitwiseNot), EmbeddedFeedback(),
/* 56 S> */ B(Return),
]
constant pool: [
@@ -155,7 +155,7 @@ bytecode array length: 6
bytecodes: [
/* 42 S> */ B(LdaSmi), I8(13),
B(Star0),
- /* 53 S> */ B(Negate), FBV(0),
+ /* 53 S> */ B(Negate), EmbeddedFeedback(),
/* 56 S> */ B(Return),
]
constant pool: [
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/VariableWithHint.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/VariableWithHint.golden
index e88f3975423..a37a8116aa5 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/VariableWithHint.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/VariableWithHint.golden
@@ -84,9 +84,9 @@ bytecodes: [
/* 444 E> */ B(TestEqualStrict), R(5), EmbeddedFeedback(),
B(JumpIfFalse), U8(2),
/* 421 S> */ B(Ldar), R(9),
- B(Inc), FBV(4),
+ B(Inc), EmbeddedFeedback(),
B(Star9),
- /* 396 E> */ B(JumpLoop), U8(19), I8(0), FBV(5),
+ /* 396 E> */ B(JumpLoop), U8(19), I8(0), FBV(4),
/* 483 S> */ B(LdaTrue),
B(Star6),
/* 497 S> */ B(LdaConstant), U8(5:"s"),
diff --git a/deps/v8/test/unittests/interpreter/bytecode_expectations/WideRegisters.golden b/deps/v8/test/unittests/interpreter/bytecode_expectations/WideRegisters.golden
index d1a94823145..99dc894a088 100644
--- a/deps/v8/test/unittests/interpreter/bytecode_expectations/WideRegisters.golden
+++ b/deps/v8/test/unittests/interpreter/bytecode_expectations/WideRegisters.golden
@@ -2473,9 +2473,9 @@ bytecodes: [
B(Wide), B(Mov), R16(1), R16(157),
B(Star1),
/* 2176 S> */ B(Wide), B(Ldar), R16(128),
- B(Inc), FBV(0),
+ B(Inc), EmbeddedFeedback(),
B(Wide), B(Star), R16(128),
- /* 2146 E> */ B(JumpLoop), U8(33), I8(0), FBV(1),
+ /* 2146 E> */ B(JumpLoop), U8(33), I8(0), FBV(0),
/* 2195 S> */ B(Wide), B(Ldar), R16(128),
/* 2207 S> */ B(Return),
]
diff --git a/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc
index 224d8b8e5c7..2962ebe4ac8 100644
--- a/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/constant-array-builder-unittest.cc
@@ -10,6 +10,7 @@
#include "src/heap/factory.h"
#include "src/interpreter/constant-array-builder.h"
#include "src/numbers/hash-seed-inl.h"
+#include "src/objects/object-conversions-inl.h"
#include "src/objects/objects-inl.h"
#include "test/unittests/test-utils.h"
diff --git a/deps/v8/test/unittests/interpreter/interpreter-tester.cc b/deps/v8/test/unittests/interpreter/interpreter-tester.cc
index 2413b0e6ffc..ab7292bb687 100644
--- a/deps/v8/test/unittests/interpreter/interpreter-tester.cc
+++ b/deps/v8/test/unittests/interpreter/interpreter-tester.cc
@@ -24,8 +24,7 @@ InterpreterTester::InterpreterTester(
: isolate_(isolate),
source_(source),
bytecode_(bytecode),
- feedback_metadata_(feedback_metadata) {
-}
+ feedback_metadata_(feedback_metadata) {}
InterpreterTester::InterpreterTester(
Isolate* isolate, Handle<BytecodeArray> bytecode,
@@ -82,7 +81,8 @@ EmbeddedFeedbackType::Type InterpreterTester::GetEmbeddedFeedback(
DCHECK(Token::IsCompareOpWithEmbeddedFeedback(token));
} else if constexpr (std::is_same_v<EmbeddedFeedbackType,
BinaryOperationFeedback>) {
- DCHECK(Token::IsBinaryOpWithEmbeddedFeedback(token));
+ DCHECK(Token::IsBinaryOpWithEmbeddedFeedback(token) ||
+ Token::IsUnaryOpWithEmbeddedFeedback(token));
}
auto bytecode_array = bytecode_.ToHandleChecked();
diff --git a/deps/v8/test/unittests/interpreter/interpreter-unittest.cc b/deps/v8/test/unittests/interpreter/interpreter-unittest.cc
index 70d42574421..e39a97bef80 100644
--- a/deps/v8/test/unittests/interpreter/interpreter-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/interpreter-unittest.cc
@@ -812,33 +812,37 @@ TEST_F(InterpreterTest, InterpreterUnaryOpFeedback) {
{Token::kInc, smi_one, smi_max, number, bigint, str},
{Token::kDec, smi_one, smi_min, number, bigint, str}};
for (TestCase const& test_case : kTestCases) {
- i::FeedbackVectorSpec feedback_spec(zone());
- BytecodeArrayBuilder builder(zone(), 6, 0, &feedback_spec);
-
- i::FeedbackSlot slot0 = feedback_spec.AddBinaryOpICSlot();
- i::FeedbackSlot slot1 = feedback_spec.AddBinaryOpICSlot();
- i::FeedbackSlot slot2 = feedback_spec.AddBinaryOpICSlot();
- i::FeedbackSlot slot3 = feedback_spec.AddBinaryOpICSlot();
- i::FeedbackSlot slot4 = feedback_spec.AddBinaryOpICSlot();
-
- Handle<i::FeedbackMetadata> metadata =
- i::FeedbackMetadata::New(i_isolate(), &feedback_spec);
+ BytecodeArrayBuilder builder(zone(), 6, 0);
builder.LoadAccumulatorWithRegister(builder.Parameter(0))
- .UnaryOperation(test_case.op, GetIndex(slot0))
+ .UnaryOperation(test_case.op, kFeedbackIsEmbedded)
.LoadAccumulatorWithRegister(builder.Parameter(1))
- .UnaryOperation(test_case.op, GetIndex(slot1))
+ .UnaryOperation(test_case.op, kFeedbackIsEmbedded)
.LoadAccumulatorWithRegister(builder.Parameter(2))
- .UnaryOperation(test_case.op, GetIndex(slot2))
+ .UnaryOperation(test_case.op, kFeedbackIsEmbedded)
.LoadAccumulatorWithRegister(builder.Parameter(3))
- .UnaryOperation(test_case.op, GetIndex(slot3))
+ .UnaryOperation(test_case.op, kFeedbackIsEmbedded)
.LoadAccumulatorWithRegister(builder.Parameter(4))
- .UnaryOperation(test_case.op, GetIndex(slot4))
+ .UnaryOperation(test_case.op, kFeedbackIsEmbedded)
.Return();
Handle<BytecodeArray> bytecode_array = builder.ToBytecodeArray(i_isolate());
- InterpreterTester tester(i_isolate(), bytecode_array, metadata);
+ // Walk the built bytecode array to recover the exact unary-op offsets;
+ // the register optimizer may defer Ldar emissions so
+ // `current_bytecode_size()` at build time doesn't always match the final
+ // layout.
+ size_t unary_bytecode_offsets[5];
+ int unary_bytecode_count = 0;
+ for (BytecodeArrayIterator it(bytecode_array); !it.done(); it.Advance()) {
+ if (Bytecodes::IsUnaryOpWithEmbeddedFeedback(it.current_bytecode())) {
+ CHECK_LT(unary_bytecode_count, 5);
+ unary_bytecode_offsets[unary_bytecode_count++] = it.current_offset();
+ }
+ }
+ CHECK_EQ(unary_bytecode_count, 5);
+
+ InterpreterTester tester(i_isolate(), bytecode_array);
using H = Handle<Object>;
auto callable = tester.GetCallable<H, H, H, H, H>();
@@ -849,25 +853,25 @@ TEST_F(InterpreterTest, InterpreterUnaryOpFeedback) {
test_case.bigint_feedback_value, test_case.any_feedback_value)
.ToHandleChecked();
USE(return_val);
- Tagged<MaybeObject> feedback0 = callable.vector()->Get(slot0);
- CHECK(IsSmi(feedback0));
- CHECK_EQ(BinaryOperationFeedback::kSignedSmall, feedback0.ToSmi().value());
+ auto feedback0 = tester.GetEmbeddedFeedback<BinaryOperationFeedback>(
+ test_case.op, unary_bytecode_offsets[0], /*feedback_value_offset=*/1);
+ CHECK_EQ(BinaryOperationFeedback::kSignedSmall, feedback0);
- Tagged<MaybeObject> feedback1 = callable.vector()->Get(slot1);
- CHECK(IsSmi(feedback1));
- CHECK_EQ(BinaryOperationFeedback::kNumber, feedback1.ToSmi().value());
+ auto feedback1 = tester.GetEmbeddedFeedback<BinaryOperationFeedback>(
+ test_case.op, unary_bytecode_offsets[1], /*feedback_value_offset=*/1);
+ CHECK_EQ(BinaryOperationFeedback::kNumber, feedback1);
- Tagged<MaybeObject> feedback2 = callable.vector()->Get(slot2);
- CHECK(IsSmi(feedback2));
- CHECK_EQ(BinaryOperationFeedback::kNumber, feedback2.ToSmi().value());
+ auto feedback2 = tester.GetEmbeddedFeedback<BinaryOperationFeedback>(
+ test_case.op, unary_bytecode_offsets[2], /*feedback_value_offset=*/1);
+ CHECK_EQ(BinaryOperationFeedback::kNumber, feedback2);
- Tagged<MaybeObject> feedback3 = callable.vector()->Get(slot3);
- CHECK(IsSmi(feedback3));
- CHECK_EQ(BinaryOperationFeedback::kBigInt, feedback3.ToSmi().value());
+ auto feedback3 = tester.GetEmbeddedFeedback<BinaryOperationFeedback>(
+ test_case.op, unary_bytecode_offsets[3], /*feedback_value_offset=*/1);
+ CHECK_EQ(BinaryOperationFeedback::kBigInt, feedback3);
- Tagged<MaybeObject> feedback4 = callable.vector()->Get(slot4);
- CHECK(IsSmi(feedback4));
- CHECK_EQ(BinaryOperationFeedback::kAny, feedback4.ToSmi().value());
+ auto feedback4 = tester.GetEmbeddedFeedback<BinaryOperationFeedback>(
+ test_case.op, unary_bytecode_offsets[4], /*feedback_value_offset=*/1);
+ CHECK_EQ(BinaryOperationFeedback::kAny, feedback4);
}
}
diff --git a/deps/v8/test/unittests/maglev/maglev-assembler-unittest.cc b/deps/v8/test/unittests/maglev/maglev-assembler-unittest.cc
index a9afccd6e39..7784ff03602 100644
--- a/deps/v8/test/unittests/maglev/maglev-assembler-unittest.cc
+++ b/deps/v8/test/unittests/maglev/maglev-assembler-unittest.cc
@@ -275,6 +275,25 @@ TEST_F(MaglevAssemblerTest, TryTruncateDoubleToInt32InfNegative) {
FinalizeAndRun(&cannot_convert, &can_convert);
}
+#if V8_TARGET_ARCH_LOONG64 || V8_TARGET_ARCH_RISCV64
+TEST_F(MaglevAssemblerTest, SetSlotAddressForFixedArrayElementLargeIndex) {
+ as.CodeEntry();
+ intptr_t base = intptr_t{0x300000000};
+ uint32_t index = static_cast<uint32_t>(std::numeric_limits<int32_t>::min());
+ as.Move(kReturnRegister1, base);
+ as.Move(kReturnRegister2, static_cast<int32_t>(index));
+ as.SetSlotAddressForFixedArrayElement(kReturnRegister0, kReturnRegister1,
+ kReturnRegister2);
+ intptr_t expected = base + OFFSET_OF_DATA_START(FixedArray) - kHeapObjectTag +
+ (intptr_t{index} << kTaggedSizeLog2);
+ as.Move(kReturnRegister1, expected);
+ Label pass, fail;
+ as.CompareIntPtrAndJumpIf(kReturnRegister0, kReturnRegister1, kEqual, &pass);
+ as.jmp(&fail);
+ FinalizeAndRun(&pass, &fail);
+}
+#endif // V8_TARGET_ARCH_LOONG64 || V8_TARGET_ARCH_RISCV64
+
} // namespace maglev
} // namespace internal
} // namespace v8
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 f8bc84c1761..d552380a860 100644
--- a/deps/v8/test/unittests/maglev/maglev-graph-processor-unittest.cc
+++ b/deps/v8/test/unittests/maglev/maglev-graph-processor-unittest.cc
@@ -10,15 +10,54 @@
#include "src/maglev/maglev-compilation-info.h"
#include "src/maglev/maglev-graph-builder.h"
+#include "src/maglev/maglev-graph-optimizer.h"
#include "src/maglev/maglev-ir-inl.h"
#include "src/maglev/maglev-ir.h"
+#include "src/maglev/maglev-reducer-inl.h"
#include "test/unittests/maglev/maglev-test.h"
namespace v8 {
namespace internal {
namespace maglev {
-class MaglevGraphProcessorTest : public TestWithNativeContextAndZone {};
+class MaglevGraphProcessorTest : public TestWithNativeContextAndZone {
+ public:
+ template <typename Function>
+ void RunSubgraphTest(Function&& body) {
+ i::v8_flags.allow_natives_syntax = true;
+ HandleScope scope(isolate());
+ const char* script = R"(
+ function f(a) { return a; }
+ %PrepareFunctionForOptimization(f);
+ f(1);
+ (f)
+ )";
+ Handle<JSFunction> function = RunJS<JSFunction>(script);
+ auto info =
+ MaglevCompilationInfo::New(isolate(), function, BytecodeOffset::None());
+ 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());
+
+ ReachableExceptionHandlerTracker tracker(graph);
+ RecomputeKnownNodeAspectsProcessor kna_processor(graph, tracker);
+ MaglevGraphOptimizer optimizer(graph, kna_processor);
+ MaglevReducer<MaglevGraphOptimizer> reducer(
+ &optimizer, graph, info->toplevel_compilation_unit());
+
+ ASSERT_FALSE(graph->blocks().empty());
+ BasicBlock* block = graph->blocks()[0];
+ reducer.set_current_block(block);
+ reducer.set_known_node_aspects(zone()->New<KnownNodeAspects>(zone()));
+
+ body(reducer, block);
+
+ persistent_scope.Detach();
+ }
+};
namespace {
@@ -117,10 +156,99 @@ TEST_F(MaglevGraphProcessorTest, GraphBackwardMultiProcessorOrder) {
EXPECT_EQ(recorder.log[1], "Second::PreProcessGraph");
// PostProcessGraph should run Second then First (reverse order).
EXPECT_EQ(recorder.log[recorder.log.size() - 2], "Second::PostProcessGraph");
- EXPECT_EQ(recorder.log[recorder.log.size() - 1], "First::PostProcessGraph");
persistent_scope.Detach();
}
+TEST_F(MaglevGraphProcessorTest, SubgraphBufferStashingNodesFromBefore) {
+ RunSubgraphTest(
+ [](MaglevReducer<MaglevGraphOptimizer>& reducer, BasicBlock* block) {
+ reducer.SetNewNodePosition(BasicBlockPosition::End());
+ (void)reducer.AddNewNode<Float64Constant>({}, 1.0);
+
+ size_t original_nodes_size = block->nodes().size();
+
+ {
+ // Top-level Subgraph directly instantiated in C++. Stashes buffered
+ // nodes.
+ Subgraph<MaglevGraphOptimizer> top_sg(&reducer, 0);
+ EXPECT_EQ(original_nodes_size, block->nodes().size());
+
+ {
+ // Nested Subgraph directly instantiated in C++.
+ Subgraph<MaglevGraphOptimizer> nested_sg(&reducer, 0);
+ }
+ }
+
+ // Destruction of empty top-level Subgraph leaves block->nodes()
+ // unmutated.
+ EXPECT_EQ(original_nodes_size, block->nodes().size());
+
+ reducer.FlushNodesToBlock();
+ });
+}
+
+TEST_F(MaglevGraphProcessorTest, SubgraphBufferStashingNestedParentAndChild) {
+ RunSubgraphTest(
+ [](MaglevReducer<MaglevGraphOptimizer>& reducer, BasicBlock* block) {
+ {
+ Subgraph<MaglevGraphOptimizer> parent_sg(&reducer, 0);
+ (void)reducer.AddNewNode<Float64Constant>({}, 2.0);
+
+ {
+ Subgraph<MaglevGraphOptimizer> child_sg(&reducer, 0);
+ (void)reducer.AddNewNode<Float64Constant>({}, 3.0);
+ }
+ }
+
+ // Non-empty subgraphs recorded pending splices cleanly.
+ EXPECT_TRUE(reducer.HasPendingSplice());
+
+ reducer.FlushNodesToBlock();
+ });
+}
+
+TEST_F(MaglevGraphProcessorTest, SubgraphEmptyTopLevelWithNestedNonEmpty) {
+ RunSubgraphTest(
+ [](MaglevReducer<MaglevGraphOptimizer>& reducer, BasicBlock* block) {
+ // Emit node before top_sg.
+ (void)reducer.AddNewNode<Float64Constant>({}, 1.0);
+ size_t original_nodes_size = block->nodes().size();
+
+ {
+ Subgraph<MaglevGraphOptimizer> top_sg(&reducer, 0);
+
+ {
+ Subgraph<MaglevGraphOptimizer> child_sg(&reducer, 0);
+ (void)reducer.AddNewNode<Float64Constant>({}, 4.0);
+ }
+ }
+
+ // Destruction of top_sg restored outer node buffer and flushed it
+ // during splice creation.
+ EXPECT_EQ(original_nodes_size + 1, block->nodes().size());
+ EXPECT_TRUE(reducer.HasPendingSplice());
+
+ reducer.FlushNodesToBlock();
+ });
+}
+
+TEST_F(MaglevGraphProcessorTest, SubgraphAbruptExit) {
+ RunSubgraphTest(
+ [](MaglevReducer<MaglevGraphOptimizer>& reducer, BasicBlock* block) {
+ {
+ Subgraph<MaglevGraphOptimizer> sg(&reducer, 0);
+ (void)reducer.AddNewNode<Float64Constant>({}, 5.0);
+ // Abrupt exit path (e.g. Throw/Deopt) flushes nodes before setting
+ // current_block to null.
+ reducer.FlushNodesToBlock();
+ reducer.set_current_block(nullptr);
+ }
+
+ // Destructor of abrupt exit subgraph completes cleanly.
+ EXPECT_EQ(block, reducer.current_block());
+ });
+}
+
} // namespace maglev
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/maglev/node-type-unittest.cc b/deps/v8/test/unittests/maglev/node-type-unittest.cc
index 2652ce90ed9..1c0c5615e9c 100644
--- a/deps/v8/test/unittests/maglev/node-type-unittest.cc
+++ b/deps/v8/test/unittests/maglev/node-type-unittest.cc
@@ -55,13 +55,19 @@ TEST_F(MaglevTest, NodeTypeMissingEntriesExist) {
}
}
+#if V8_ENABLE_WEBASSEMBLY
+#define SKIP_INACCESSIBLE \
+ if (idx == RootIndex::kWasmNull) continue
+#else
+#define SKIP_INACCESSIBLE (void)0
+#endif
+
// Ensure StaticTypeForConstant is consistent with actual objects.
TEST_F(MaglevTest, ConstantNodeTypeApproximationIsConsistent) {
for (auto idx = RootIndex::kFirstRoot; idx <= RootIndex::kLastRoot; ++idx) {
+ SKIP_INACCESSIBLE;
Tagged<Object> obj = isolate()->roots_table().slot(idx).load(isolate());
- if (obj.ptr() == kNullAddress || !obj.IsHeapObject()) {
- continue;
- }
+ if (obj.ptr() == kNullAddress || !obj.IsHeapObject()) continue;
compiler::HeapObjectRef ref = MakeRef(broker(), Cast<HeapObject>(obj));
NodeType t = StaticTypeForConstant(broker(), ref);
CHECK(!IsEmptyNodeType(t));
@@ -78,6 +84,7 @@ TEST_F(MaglevTest, ConstantNodeTypeApproximationIsConsistent) {
// Ensure StaticTypeForMap is consistent with actual maps.
TEST_F(MaglevTest, NodeTypeApproximationIsConsistent) {
for (auto idx = RootIndex::kFirstRoot; idx <= RootIndex::kLastRoot; ++idx) {
+ SKIP_INACCESSIBLE;
Tagged<Object> obj = isolate()->roots_table().slot(idx).load(isolate());
if (obj.ptr() == kNullAddress || !IsMap(obj)) continue;
Tagged<Map> map = Cast<Map>(obj);
@@ -96,6 +103,7 @@ TEST_F(MaglevTest, NodeTypeApproximationIsConsistent) {
// Ensure IntersectType is consistent with actual maps.
TEST_F(MaglevTest, NodeTypeIntersectIsConsistent) {
for (auto idx = RootIndex::kFirstRoot; idx <= RootIndex::kLastRoot; ++idx) {
+ SKIP_INACCESSIBLE;
Tagged<Object> obj = isolate()->roots_table().slot(idx).load(isolate());
if (obj.ptr() == kNullAddress || !IsMap(obj)) continue;
Tagged<Map> map = Cast<Map>(obj);
@@ -121,6 +129,7 @@ TEST_F(MaglevTest, NodeTypeIntersectIsConsistent) {
// Ensure UnionType is consistent with actual maps.
TEST_F(MaglevTest, NodeTypeUnionIsConsistent) {
for (auto idx = RootIndex::kFirstRoot; idx <= RootIndex::kLastRoot; ++idx) {
+ SKIP_INACCESSIBLE;
Tagged<Object> obj = isolate()->roots_table().slot(idx).load(isolate());
if (obj.ptr() == kNullAddress || !IsMap(obj)) continue;
Tagged<Map> map = Cast<Map>(obj);
diff --git a/deps/v8/test/unittests/objects/elements-kind-unittest.cc b/deps/v8/test/unittests/objects/elements-kind-unittest.cc
index 14ecce928f2..41e212018de 100644
--- a/deps/v8/test/unittests/objects/elements-kind-unittest.cc
+++ b/deps/v8/test/unittests/objects/elements-kind-unittest.cc
@@ -520,5 +520,48 @@ TEST_F(ElementsKindTest, IsFastPackedElementsKind) {
}
}
+TEST_F(ElementsKindTest, JSArraySetLengthDictionaryElements) {
+ v8::HandleScope scope(isolate());
+ DirectHandle<String> name =
+ i_isolate()->factory()->InternalizeUtf8String("Array");
+ DirectHandle<JSArray> array = i_isolate()->factory()->NewJSArray(
+ ElementsKind::PACKED_SMI_ELEMENTS, 0, 0);
+
+ // Set array length to 0.
+ JSArray::SetLength(i_isolate(), array, 0);
+ EXPECT_EQ(Smi::zero(), array->length());
+ EXPECT_TRUE(array->HasSmiOrObjectElements());
+
+ // array[0] = name.
+ Object::SetElement(i_isolate(), array, 0, name, ShouldThrow::kDontThrow)
+ .Check();
+ EXPECT_EQ(Smi::FromInt(1), array->length());
+ DirectHandle<Object> element =
+ Object::GetElement(i_isolate(), array, 0).ToHandleChecked();
+ EXPECT_EQ(*element, *name);
+
+ // Set array length with large value exceeding Smi range.
+ uint32_t large_length = static_cast<uint32_t>(Smi::kMaxValue) + 1;
+ JSArray::SetLength(i_isolate(), array, large_length);
+
+ uint32_t int_length = 0;
+ EXPECT_TRUE(Object::ToArrayIndex(array->length(), &int_length));
+ EXPECT_EQ(large_length, int_length);
+ EXPECT_TRUE(array->HasDictionaryElements());
+
+ // array[length] = name.
+ Object::SetElement(i_isolate(), array, int_length, name,
+ ShouldThrow::kDontThrow)
+ .Check();
+ uint32_t new_int_length = 0;
+ EXPECT_TRUE(Object::ToArrayIndex(array->length(), &new_int_length));
+ EXPECT_EQ(int_length + 1, new_int_length);
+ element =
+ Object::GetElement(i_isolate(), array, int_length).ToHandleChecked();
+ EXPECT_EQ(*element, *name);
+ element = Object::GetElement(i_isolate(), array, 0).ToHandleChecked();
+ EXPECT_EQ(*element, *name);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/objects/feedback-vector-unittest.cc b/deps/v8/test/unittests/objects/feedback-vector-unittest.cc
index 2787c864139..84081da5f1e 100644
--- a/deps/v8/test/unittests/objects/feedback-vector-unittest.cc
+++ b/deps/v8/test/unittests/objects/feedback-vector-unittest.cc
@@ -468,6 +468,19 @@ 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/objects/managed-unittest.cc b/deps/v8/test/unittests/objects/managed-unittest.cc
index 216be2b3704..d10be9101ee 100644
--- a/deps/v8/test/unittests/objects/managed-unittest.cc
+++ b/deps/v8/test/unittests/objects/managed-unittest.cc
@@ -18,7 +18,7 @@ using ManagedTest = TestWithIsolate;
class DeleteCounter {
public:
- static constexpr ExternalPointerTag kManagedTag = kGenericManagedTag;
+ static constexpr ManagedTypeId kTypeID = ManagedTypeId::kTestDeleteCounter;
explicit DeleteCounter(int* deleted) : deleted_(deleted) { *deleted_ = 0; }
~DeleteCounter() { (*deleted_)++; }
@@ -47,7 +47,7 @@ TEST_F(ManagedTest, GCCausesDestruction) {
auto d2 = std::make_unique<DeleteCounter>(&deleted2);
{
HandleScope scope(isolate());
- USE(Managed<DeleteCounter>::From(
+ USE(CppGCManaged<DeleteCounter>::Create(
isolate(), 0, std::make_shared<DeleteCounter>(&deleted1)));
}
@@ -61,6 +61,20 @@ TEST_F(ManagedTest, GCCausesDestruction) {
CHECK_EQ(1, deleted2);
}
+TEST_F(ManagedTest, CppGCManagedGCCausesDestruction) {
+ int deleted = 0;
+ {
+ HandleScope scope(isolate());
+ USE(CppGCManaged<DeleteCounter>::Create(
+ isolate(), 0, std::make_shared<DeleteCounter>(&deleted)));
+ }
+
+ DisableConservativeStackScanningScopeForTesting scope(isolate()->heap());
+ InvokeMemoryReducingMajorGCs(isolate());
+
+ CHECK_EQ(1, deleted);
+}
+
TEST_F(ManagedTest, DisposeCausesDestruction1) {
v8::Isolate::CreateParams create_params;
create_params.array_buffer_allocator = isolate()->array_buffer_allocator();
@@ -71,7 +85,7 @@ TEST_F(ManagedTest, DisposeCausesDestruction1) {
int deleted1 = 0;
{
HandleScope scope(i_isolate);
- USE(Managed<DeleteCounter>::From(
+ USE(CppGCManaged<DeleteCounter>::Create(
i_isolate, 0, std::make_shared<DeleteCounter>(&deleted1)));
}
isolate->Exit();
@@ -90,7 +104,7 @@ TEST_F(ManagedTest, DisposeCausesDestruction2) {
int deleted2 = 0;
{
HandleScope scope(i_isolate);
- USE(Managed<DeleteCounter>::From(
+ USE(CppGCManaged<DeleteCounter>::Create(
i_isolate, 0, std::make_shared<DeleteCounter>(&deleted1)));
}
DeleteCounter* d2 = new DeleteCounter(&deleted2);
@@ -116,7 +130,7 @@ TEST_F(ManagedTest, DisposeWithAnotherSharedPtr) {
auto shared = std::make_shared<DeleteCounter>(&deleted1);
{
HandleScope scope(i_isolate);
- USE(Managed<DeleteCounter>::From(i_isolate, 0, shared));
+ USE(CppGCManaged<DeleteCounter>::Create(i_isolate, 0, shared));
}
isolate->Exit();
isolate->Dispose();
@@ -181,19 +195,19 @@ TEST_F(ManagedTest, DisposeAcrossIsolates) {
{
HandleScope scope1(i_isolate1);
auto shared = std::make_shared<DeleteCounter>(&deleted);
- USE(Managed<DeleteCounter>::From(i_isolate1, 0, shared));
+ USE(CppGCManaged<DeleteCounter>::Create(i_isolate1, 0, shared));
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<i::Isolate*>(isolate2);
isolate2->Enter();
{
HandleScope scope(i_isolate2);
- USE(Managed<DeleteCounter>::From(i_isolate2, 0, shared));
+ USE(CppGCManaged<DeleteCounter>::Create(i_isolate2, 0, shared));
shared.reset();
}
isolate2->Exit();
isolate2->Dispose();
- // The DeleteCounter is kept alive by the Managed in the first isolate.
+ // The DeleteCounter is kept alive by the CppGCManaged in the first isolate.
CHECK_EQ(0, deleted);
}
// Should be deleted after the first isolate is destroyed.
@@ -214,14 +228,14 @@ TEST_F(ManagedTest, CollectAcrossIsolates) {
{
HandleScope scope1(i_isolate1);
auto shared = std::make_shared<DeleteCounter>(&deleted);
- USE(Managed<DeleteCounter>::From(i_isolate1, 0, shared));
+ USE(CppGCManaged<DeleteCounter>::Create(i_isolate1, 0, shared));
v8::Isolate* isolate2 = v8::Isolate::New(create_params);
Isolate* i_isolate2 = reinterpret_cast<i::Isolate*>(isolate2);
isolate2->Enter();
{
HandleScope scope(i_isolate2);
- USE(Managed<DeleteCounter>::From(i_isolate2, 0, shared));
+ USE(CppGCManaged<DeleteCounter>::Create(i_isolate2, 0, shared));
shared.reset();
}
InvokeMemoryReducingMajorGCs(i_isolate2);
diff --git a/deps/v8/test/unittests/objects/modules-unittest.cc b/deps/v8/test/unittests/objects/modules-unittest.cc
index 3814b6635c9..c88c211e5fc 100644
--- a/deps/v8/test/unittests/objects/modules-unittest.cc
+++ b/deps/v8/test/unittests/objects/modules-unittest.cc
@@ -1738,7 +1738,7 @@ TEST_F(ModuleTest, SyntheticModuleGetResourceName) {
Local<String> resource_name = NewString("synthetic-module");
Local<Module> module = Module::CreateSyntheticModule(
isolate(), resource_name, {},
- [](Local<Context> context, Local<Module> module) -> MaybeLocal<Value> {
+ [](Local<Context> context, Local<Module> module) -> MaybeLocal<Promise> {
// Do nothing.
Local<v8::Promise::Resolver> resolver =
v8::Promise::Resolver::New(context).ToLocalChecked();
@@ -1768,12 +1768,12 @@ TEST_F(ModuleTest, SyntheticModuleGetResourceNameInError) {
Local<String> resource_name = NewString("synthetic-module");
Local<Module> module = Module::CreateSyntheticModule(
isolate(), resource_name, {},
- [](Local<Context> context, Local<Module> module) -> MaybeLocal<Value> {
+ [](Local<Context> context, Local<Module> module) -> MaybeLocal<Promise> {
// Throw an error.
Isolate* isolate = Isolate::GetCurrent();
isolate->ThrowException(
v8::String::NewFromUtf8Literal(isolate, "synthetic module error"));
- return MaybeLocal<Value>();
+ return MaybeLocal<Promise>();
});
CHECK_EQ(Module::kUninstantiated, module->GetStatus());
@@ -1792,4 +1792,241 @@ TEST_F(ModuleTest, SyntheticModuleGetResourceNameInError) {
CHECK(module->GetResourceName()->StrictEquals(resource_name));
}
+int* global_use_counts = nullptr;
+
+void MockUseCounterCallback(Isolate* isolate,
+ Isolate::UseCounterFeature feature) {
+ ++global_use_counts[feature];
+}
+
+TEST_F(ModuleTest, ExportStarMissingDefaultUseCounter) {
+ HandleScope scope(isolate());
+ int use_counts[Isolate::kUseCounterFeatureCount] = {};
+ global_use_counts = use_counts;
+ isolate()->SetUseCounterCallback(MockUseCounterCallback);
+
+ const int kCounter = Isolate::kModuleNamespaceMissingDefaultWithStarExport;
+
+ auto Namespace = [&](const char* source_text) {
+ ScriptOrigin origin = ModuleOrigin(NewString("file.js"), isolate());
+ ScriptCompiler::Source source(NewString(source_text), origin);
+ Local<Module> module =
+ ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
+ CHECK(module
+ ->InstantiateModule(context(),
+ CompileSpecifierAsModuleResolveCallback)
+ .FromJust());
+ module->Evaluate(context()).ToLocalChecked();
+ return module->GetModuleNamespace()->ToObject(context()).ToLocalChecked();
+ };
+ auto Get = [&](Local<Object> ns, const char* name) {
+ return ns->Get(context(), NewString(name)).ToLocalChecked();
+ };
+
+ Local<Object> star =
+ Namespace("export * from 'export default 1; export const a = 2;';");
+ CHECK(Get(star, "default")->IsUndefined());
+ CHECK_EQ(1, use_counts[kCounter]);
+
+ // Non-default export
+ use_counts[kCounter] = 0;
+ CHECK(Get(star, "missing")->IsUndefined());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // Explicit default export
+ use_counts[kCounter] = 0;
+ Local<Object> own_default =
+ Namespace("export * from 'export default 1;'; export default 2;");
+ CHECK(!Get(own_default, "default")->IsUndefined());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // No `export * from`
+ use_counts[kCounter] = 0;
+ Local<Object> no_star = Namespace("export const a = 1;");
+ CHECK(Get(no_star, "default")->IsUndefined());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // `export * as ns from` is not `export * from`
+ use_counts[kCounter] = 0;
+ Local<Object> star_as = Namespace("export * as ns from 'export default 1;';");
+ CHECK(Get(star_as, "default")->IsUndefined());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // `export {a} from` is not `export * from`
+ use_counts[kCounter] = 0;
+ Local<Object> indirect = Namespace("export {a} from 'export const a = 1;';");
+ CHECK(Get(indirect, "default")->IsUndefined());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // A synthetic module (e.g. a JSON module) has no `export * from`.
+ use_counts[kCounter] = 0;
+ Local<Module> synthetic = Module::CreateSyntheticModule(
+ isolate(), NewString("synthetic"), {},
+ [](Local<Context> context, Local<Module> module) -> MaybeLocal<Promise> {
+ Local<v8::Promise::Resolver> resolver =
+ v8::Promise::Resolver::New(context).ToLocalChecked();
+ resolver->Resolve(context, v8::Undefined(Isolate::GetCurrent()))
+ .ToChecked();
+ return resolver->GetPromise();
+ });
+ CHECK(synthetic
+ ->InstantiateModule(context(),
+ ResolveModuleByIndexUnreachableCallback)
+ .FromJust());
+ synthetic->Evaluate(context()).ToLocalChecked();
+ Local<Object> synthetic_ns =
+ synthetic->GetModuleNamespace()->ToObject(context()).ToLocalChecked();
+ CHECK(Get(synthetic_ns, "default")->IsUndefined());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // `ns.default` access in the module code itself
+ use_counts[kCounter] = 0;
+ Local<Object> direct = Namespace(
+ "import * as ns from 'export * from \"export default 1;\";';"
+ "export const result = ns.default;");
+ CHECK(Get(direct, "result")->IsUndefined());
+ CHECK_EQ(1, use_counts[kCounter]);
+
+ // Computed property access
+ use_counts[kCounter] = 0;
+ Local<Object> computed = Namespace(
+ "import * as ns from 'export * from \"export default 1;\";';"
+ "export const result = ns['defa' + 'ult'];");
+ CHECK(Get(computed, "result")->IsUndefined());
+ CHECK_LE(1, use_counts[kCounter]);
+
+ // `"default" in`
+ use_counts[kCounter] = 0;
+ Local<Object> has = Namespace(
+ "import * as ns from 'export * from \"export default 1;\";';"
+ "export const result = 'default' in ns;");
+ CHECK(Get(has, "result")->IsFalse());
+ CHECK_LE(1, use_counts[kCounter]);
+
+ // `"other" in`
+ use_counts[kCounter] = 0;
+ Local<Object> has_other = Namespace(
+ "import * as ns from 'export * from \"export default 1;\";';"
+ "export const result = 'missing' in ns;");
+ CHECK(Get(has_other, "result")->IsFalse());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // `"default" in` but with no `export * from`
+ use_counts[kCounter] = 0;
+ Local<Object> has_no_star = Namespace(
+ "import * as ns from 'export const a = 1;';"
+ "export const result = 'default' in ns;");
+ CHECK(Get(has_no_star, "result")->IsFalse());
+ CHECK_EQ(0, use_counts[kCounter]);
+
+ // On the prototype chain
+ use_counts[kCounter] = 0;
+ Local<Object> proto = Namespace(
+ "import * as ns from 'export * from \"export default 1;\";';"
+ "export const result = Object.create(ns).default;");
+ CHECK(Get(proto, "result")->IsUndefined());
+ CHECK_LE(1, use_counts[kCounter]);
+
+ global_use_counts = nullptr;
+}
+
+// Evaluating a deferred module from inside an embedder API callback must not
+// leave the module's exception pending on the isolate while the top-level
+// capability is rejected. V8 calls HostPromiseRejectionTracker from that
+// rejection, and the host is entitled to call back into V8 -- including into
+// paths that assert no exception is pending. See crbug.com/550083806.
+namespace {
+
+v8::Global<Module> deferred_throwing_dependency;
+
+MaybeLocal<Module> ResolveDeferredThrowingDependency(
+ Local<Context> context, Local<String> specifier,
+ Local<FixedArray> import_attributes, Local<Module> referrer) {
+ return deferred_throwing_dependency.Get(Isolate::GetCurrent());
+}
+
+int deferred_rejections_reported = 0;
+
+// Models what an embedder does from its rejection hook: build an Error, which
+// enters a no-exception API scope and captures a stack trace over the frames
+// that are still live -- here, including the API callback below.
+void RecordRejectionAndBuildError(v8::PromiseRejectMessage message) {
+ if (message.GetEvent() != v8::kPromiseRejectWithNoHandler) return;
+ ++deferred_rejections_reported;
+ Isolate* isolate = Isolate::GetCurrent();
+ isolate->SetCaptureStackTraceForUncaughtExceptions(true);
+ v8::Exception::Error(String::NewFromUtf8Literal(isolate, "rejected"));
+}
+
+// An API callback that stringifies its argument. Calling it leaves an
+// API callback exit frame on the stack for the stack walk above to summarize.
+void StringifyCallback(const v8::FunctionCallbackInfo<Value>& info) {
+ Local<v8::String> unused;
+ // Deliberately ignore failure: the point is that ToString evaluates the
+ // deferred module, which throws.
+ (void)info[0]
+ ->ToString(Isolate::GetCurrent()->GetCurrentContext())
+ .ToLocal(&unused);
+}
+
+} // namespace
+
+TEST_F(ModuleTest, DeferredModuleRejectionInsideApiCallback) {
+ i::FlagScope<bool> defer_imports(&i::v8_flags.js_defer_import_eval, true);
+ HandleScope scope(isolate());
+
+ deferred_rejections_reported = 0;
+ isolate()->SetPromiseRejectCallback(RecordRejectionAndBuildError);
+
+ // Install the API callback as a global function.
+ Local<v8::FunctionTemplate> tmpl =
+ v8::FunctionTemplate::New(isolate(), StringifyCallback);
+ CHECK(context()
+ ->Global()
+ ->Set(context(), NewString("stringify"),
+ tmpl->GetFunction(context()).ToLocalChecked())
+ .FromJust());
+
+ // The dependency throws a primitive, so the rejection value is not already a
+ // native Error and the host hook has to fabricate one.
+ ScriptOrigin dependency_origin =
+ ModuleOrigin(NewString("dependency.js"), isolate());
+ ScriptCompiler::Source dependency_source(NewString("throw 123;"),
+ dependency_origin);
+ Local<Module> dependency =
+ ScriptCompiler::CompileModule(isolate(), &dependency_source)
+ .ToLocalChecked();
+ deferred_throwing_dependency.Reset(isolate(), dependency);
+
+ ScriptOrigin origin = ModuleOrigin(NewString("test.js"), isolate());
+ ScriptCompiler::Source source(
+ NewString("import defer * as ns from 'dependency.js';\n"
+ "globalThis.threw = false;\n"
+ "try { stringify(ns); } catch (e) { globalThis.threw = e; }\n"),
+ origin);
+ Local<Module> module =
+ ScriptCompiler::CompileModule(isolate(), &source).ToLocalChecked();
+ CHECK(module->InstantiateModule(context(), ResolveDeferredThrowingDependency)
+ .FromJust());
+
+ {
+ v8::TryCatch try_catch(isolate());
+ CHECK(!module->Evaluate(context()).IsEmpty());
+ CHECK(!try_catch.HasCaught());
+ }
+
+ // The rejection reached the host hook...
+ CHECK_EQ(1, deferred_rejections_reported);
+ // ...the deferred module ran and is errored...
+ CHECK_EQ(Module::kErrored, dependency->GetStatus());
+ // ...and the exception surfaced to JS through the API callback unchanged.
+ Local<Value> threw =
+ context()->Global()->Get(context(), NewString("threw")).ToLocalChecked();
+ CHECK(threw->IsNumber());
+ CHECK_EQ(123, threw.As<v8::Number>()->Value());
+
+ deferred_throwing_dependency.Reset();
+ isolate()->SetPromiseRejectCallback(nullptr);
+}
+
} // anonymous namespace
diff --git a/deps/v8/test/unittests/objects/object-unittest.cc b/deps/v8/test/unittests/objects/object-unittest.cc
index 97db967fd2e..404b56c6138 100644
--- a/deps/v8/test/unittests/objects/object-unittest.cc
+++ b/deps/v8/test/unittests/objects/object-unittest.cc
@@ -8,6 +8,7 @@
#include "src/api/api-inl.h"
#include "src/codegen/compiler.h"
+#include "src/objects/contexts.h"
#include "src/objects/hash-table-inl.h"
#include "src/objects/objects-inl.h"
#include "src/objects/objects.h"
@@ -157,6 +158,51 @@ TEST_F(ObjectWithIsolate, DictionaryGrowth) {
CHECK_EQ(64, dict->Capacity());
}
+TEST_F(TestWithNativeContext, ContextMaps) {
+ auto VerifyFunctionPrototypeMap = [this](int stored_map_context_index,
+ int stored_ctor_context_index) {
+ DirectHandle<Context> context = native_context();
+
+ DirectHandle<Map> this_map(
+ Cast<Map>(context->GetNoCell(stored_map_context_index)), i_isolate());
+
+ DirectHandle<JSFunction> fun(
+ Cast<JSFunction>(context->GetNoCell(stored_ctor_context_index)),
+ i_isolate());
+ DirectHandle<JSObject> proto(
+ Cast<JSObject>(fun->initial_map()->prototype()), i_isolate());
+ DirectHandle<Map> that_map(proto->map(), i_isolate());
+
+ EXPECT_TRUE(proto->HasFastProperties());
+ EXPECT_EQ(*this_map, *that_map);
+ };
+
+ VerifyFunctionPrototypeMap(Context::STRING_FUNCTION_PROTOTYPE_MAP_INDEX,
+ Context::STRING_FUNCTION_INDEX);
+ VerifyFunctionPrototypeMap(Context::REGEXP_PROTOTYPE_MAP_INDEX,
+ Context::REGEXP_FUNCTION_INDEX);
+ VerifyFunctionPrototypeMap(Context::OBJECT_FUNCTION_PROTOTYPE_MAP_INDEX,
+ Context::OBJECT_FUNCTION_INDEX);
+}
+
+TEST_F(TestWithNativeContext, InitialObjects) {
+ // Initial ArrayIterator prototype.
+ EXPECT_EQ(native_context()->initial_array_iterator_prototype(),
+ *RunJS<JSObject>("[][Symbol.iterator]().__proto__"));
+ // Initial Array prototype.
+ EXPECT_EQ(native_context()->initial_array_prototype(),
+ *RunJS<JSObject>("Array.prototype"));
+ // Initial Generator prototype.
+ EXPECT_EQ(native_context()->initial_generator_prototype(),
+ *RunJS<JSObject>("(function*(){}).__proto__.prototype"));
+ // Initial Iterator prototype.
+ EXPECT_EQ(native_context()->initial_iterator_prototype(),
+ *RunJS<JSObject>("[][Symbol.iterator]().__proto__.__proto__"));
+ // Initial Object prototype.
+ EXPECT_EQ(native_context()->initial_object_prototype(),
+ *RunJS<JSObject>("Object.prototype"));
+}
+
TEST_F(TestWithNativeContext, EmptyFunctionScopeInfo) {
// Check that the empty_function has a properly set up ScopeInfo.
DirectHandle<JSFunction> function = RunJS<JSFunction>("(function(){})");
@@ -901,5 +947,68 @@ TEST_F(ObjectTest, LookupIteratorWithStringLookupStartObject) {
}
}
+TEST_F(ObjectTest, JSObjectCopy) {
+ v8::HandleScope scope(isolate());
+ Factory* factory = i_isolate()->factory();
+ DirectHandle<JSFunction> constructor = i_isolate()->object_function();
+ Handle<JSObject> obj = factory->NewJSObject(constructor);
+ DirectHandle<String> first = factory->InternalizeUtf8String("first");
+ DirectHandle<String> second = factory->InternalizeUtf8String("second");
+
+ DirectHandle<Smi> one(Smi::FromInt(1), i_isolate());
+ DirectHandle<Smi> two(Smi::FromInt(2), i_isolate());
+
+ Object::SetProperty(i_isolate(), obj, first, one).Check();
+ Object::SetProperty(i_isolate(), obj, second, two).Check();
+
+ Object::SetElement(i_isolate(), obj, 0, first, ShouldThrow::kDontThrow)
+ .Check();
+ Object::SetElement(i_isolate(), obj, 1, second, ShouldThrow::kDontThrow)
+ .Check();
+
+ // Make the clone.
+ DirectHandle<JSObject> clone = factory->CopyJSObject(obj);
+ EXPECT_FALSE(clone.is_identical_to(obj));
+
+ DirectHandle<Object> value1 =
+ Object::GetElement(i_isolate(), obj, 0).ToHandleChecked();
+ DirectHandle<Object> value2 =
+ Object::GetElement(i_isolate(), clone, 0).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+ value1 = Object::GetElement(i_isolate(), obj, 1).ToHandleChecked();
+ value2 = Object::GetElement(i_isolate(), clone, 1).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+
+ value1 = Object::GetProperty(i_isolate(), obj, first).ToHandleChecked();
+ value2 = Object::GetProperty(i_isolate(), clone, first).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+ value1 = Object::GetProperty(i_isolate(), obj, second).ToHandleChecked();
+ value2 = Object::GetProperty(i_isolate(), clone, second).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+
+ // Flip the values on the clone.
+ Object::SetProperty(i_isolate(), clone, first, two).Check();
+ Object::SetProperty(i_isolate(), clone, second, one).Check();
+
+ Object::SetElement(i_isolate(), clone, 0, second, ShouldThrow::kDontThrow)
+ .Check();
+ Object::SetElement(i_isolate(), clone, 1, first, ShouldThrow::kDontThrow)
+ .Check();
+
+ value1 = Object::GetElement(i_isolate(), obj, 1).ToHandleChecked();
+ value2 = Object::GetElement(i_isolate(), clone, 0).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+ value1 = Object::GetElement(i_isolate(), obj, 0).ToHandleChecked();
+ value2 = Object::GetElement(i_isolate(), clone, 1).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+
+ value1 = Object::GetProperty(i_isolate(), obj, second).ToHandleChecked();
+ value2 = Object::GetProperty(i_isolate(), clone, first).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+ value1 = Object::GetProperty(i_isolate(), obj, first).ToHandleChecked();
+ value2 = Object::GetProperty(i_isolate(), clone, second).ToHandleChecked();
+ EXPECT_EQ(*value1, *value2);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/objects/roots-unittest.cc b/deps/v8/test/unittests/objects/roots-unittest.cc
index 711141d1ad0..e6d0a08f0b2 100644
--- a/deps/v8/test/unittests/objects/roots-unittest.cc
+++ b/deps/v8/test/unittests/objects/roots-unittest.cc
@@ -59,10 +59,12 @@ bool CanBeInReadOnlySpace(Factory* factory, Handle<Object> object) {
V(shared_wasm_memories) \
V(materialized_objects) \
V(public_symbol_table) \
+ V(regexp_split_cache) \
V(serialized_global_proxy_sizes) \
V(serialized_objects) \
IF_WASM(V, js_to_wasm_wrappers) \
IF_WASM(V, wasm_canonical_rtts) \
+ IF_WASM(V, wasm_shared_canonical_rtts) \
V(weak_refs_keep_during_job)
#define TEST_CAN_BE_READ_ONLY(name) \
@@ -112,6 +114,9 @@ TEST_F(RootsTest, TestHeapNumberList) {
ReadOnlyRoots roots(isolate());
for (auto pos = RootIndex::kFirstReadOnlyRoot;
pos <= RootIndex::kLastReadOnlyRoot; ++pos) {
+#if V8_ENABLE_WEBASSEMBLY
+ if (pos == RootIndex::kWasmNull) continue;
+#endif // V8_ENABLE_WEBASSEMBLY
auto obj = roots.object_at(pos);
bool in_nr_range = pos >= RootIndex::kFirstHeapNumberRoot &&
pos <= RootIndex::kLastHeapNumberRoot;
diff --git a/deps/v8/test/unittests/objects/string-table-unittest.cc b/deps/v8/test/unittests/objects/string-table-unittest.cc
index adc5394c1da..903d0093c03 100644
--- a/deps/v8/test/unittests/objects/string-table-unittest.cc
+++ b/deps/v8/test/unittests/objects/string-table-unittest.cc
@@ -47,5 +47,41 @@ TEST_F(StringTableTest, HasString) {
EXPECT_TRUE(string_table->HasString(isolate(), bar));
}
+TEST_F(StringTableTest, InternalizeUtf8String) {
+ static const char* const kTestStrings[] = {
+ "abstract", "boolean", "break", "byte", "case",
+ "catch", "char", "class", "const", "continue",
+ "debugger", "default", "delete", "do", "double",
+ "else", "enum", "export", "extends", "false",
+ "final", "finally", "float", "for", "function",
+ "goto", "if", "implements", "import", "in",
+ "instanceof", "int", "interface", "long", "native",
+ "new", "null", "package", "private", "protected",
+ "public", "return", "short", "static", "super",
+ "switch", "synchronized", "this", "throw", "throws",
+ "transient", "true", "try", "typeof", "var",
+ "void", "volatile", "while", "with", nullptr};
+
+ auto check_internalized_strings = [this](const char* const* strings) {
+ for (const char* const* ptr = strings; *ptr != nullptr; ++ptr) {
+ const char* string = *ptr;
+ HandleScope scope(isolate());
+ DirectHandle<String> a =
+ factory()->InternalizeUtf8String(base::CStrVector(string));
+ EXPECT_TRUE(IsInternalizedString(*a));
+ DirectHandle<String> b = factory()->InternalizeUtf8String(string);
+ EXPECT_EQ(*b, *a);
+ EXPECT_TRUE(b->IsOneByteEqualTo(base::CStrVector(string)));
+ b = factory()->InternalizeUtf8String(base::CStrVector(string));
+ EXPECT_EQ(*b, *a);
+ EXPECT_TRUE(b->IsOneByteEqualTo(base::CStrVector(string)));
+ }
+ };
+
+ check_internalized_strings(kTestStrings);
+ // Re-checking lookups of already internalized strings.
+ check_internalized_strings(kTestStrings);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/objects/value-serializer-unittest.cc b/deps/v8/test/unittests/objects/value-serializer-unittest.cc
index c6df5f2bba1..befa5e60d48 100644
--- a/deps/v8/test/unittests/objects/value-serializer-unittest.cc
+++ b/deps/v8/test/unittests/objects/value-serializer-unittest.cc
@@ -2082,6 +2082,147 @@ TEST_F(ValueSerializerTestWithArrayBufferTransfer,
ExpectScriptTrue("new Uint8Array(result.a).toString() === '0,1,128,255'");
}
+TEST_F(ValueSerializerTest, RoundTripImmutableArrayBufferShared) {
+ v8::Isolate::Scope isolate_scope(isolate());
+ v8::HandleScope handle_scope(isolate());
+ v8::Context::Scope context_scope(serialization_context());
+
+ Local<ArrayBuffer> input_ab = ArrayBuffer::New(isolate(), 4);
+ const uint8_t raw_data[4] = {1, 2, 3, 4};
+ memcpy(input_ab->GetBackingStore()->Data(), raw_data, 4);
+ i::Cast<i::JSArrayBuffer>(v8::Utils::OpenDirectHandle(*input_ab))
+ ->MakeImmutable(reinterpret_cast<i::Isolate*>(isolate()));
+ EXPECT_TRUE(input_ab->IsImmutable());
+
+ ValueSerializer serializer(
+ isolate(), ValueSerializer::SharedImmutableArrayBufferMode::kEnabled);
+ serializer.WriteHeader();
+ ASSERT_TRUE(serializer.WriteValue(serialization_context(), input_ab)
+ .FromMaybe(false));
+ std::pair<uint8_t*, size_t> data = serializer.Release();
+
+ ValueDeserializer deserializer(isolate(), data.first, data.second);
+ deserializer.SetSharedImmutableBackingStores(
+ serializer.ReleaseSharedImmutableBackingStores());
+ ASSERT_TRUE(
+ deserializer.ReadHeader(deserialization_context()).FromMaybe(false));
+ Local<Value> result =
+ deserializer.ReadValue(deserialization_context()).ToLocalChecked();
+
+ ASSERT_TRUE(result->IsArrayBuffer());
+ Local<ArrayBuffer> output_ab = result.As<ArrayBuffer>();
+ EXPECT_TRUE(output_ab->IsImmutable());
+ EXPECT_EQ(input_ab->GetBackingStore()->Data(),
+ output_ab->GetBackingStore()->Data());
+
+ base::Free(data.first);
+}
+
+TEST_F(ValueSerializerTest, RoundTripEmptyImmutableArrayBufferShared) {
+ v8::Isolate::Scope isolate_scope(isolate());
+ v8::HandleScope handle_scope(isolate());
+ v8::Context::Scope context_scope(serialization_context());
+
+ Local<ArrayBuffer> input_ab = ArrayBuffer::New(isolate(), 0);
+ i::Cast<i::JSArrayBuffer>(v8::Utils::OpenDirectHandle(*input_ab))
+ ->MakeImmutable(reinterpret_cast<i::Isolate*>(isolate()));
+ EXPECT_TRUE(input_ab->IsImmutable());
+
+ ValueSerializer serializer(
+ isolate(), ValueSerializer::SharedImmutableArrayBufferMode::kEnabled);
+ serializer.WriteHeader();
+ ASSERT_TRUE(serializer.WriteValue(serialization_context(), input_ab)
+ .FromMaybe(false));
+ std::pair<uint8_t*, size_t> data = serializer.Release();
+
+ ValueDeserializer deserializer(isolate(), data.first, data.second);
+ deserializer.SetSharedImmutableBackingStores(
+ serializer.ReleaseSharedImmutableBackingStores());
+ ASSERT_TRUE(
+ deserializer.ReadHeader(deserialization_context()).FromMaybe(false));
+ Local<Value> result =
+ deserializer.ReadValue(deserialization_context()).ToLocalChecked();
+
+ ASSERT_TRUE(result->IsArrayBuffer());
+ Local<ArrayBuffer> output_ab = result.As<ArrayBuffer>();
+ EXPECT_TRUE(output_ab->IsImmutable());
+ EXPECT_EQ(0u, output_ab->ByteLength());
+
+ base::Free(data.first);
+}
+
+TEST_F(ValueSerializerTest, RoundTripImmutableArrayBufferDefaultCopied) {
+ v8::Isolate::Scope isolate_scope(isolate());
+ v8::HandleScope handle_scope(isolate());
+ v8::Context::Scope context_scope(serialization_context());
+
+ Local<ArrayBuffer> input_ab = ArrayBuffer::New(isolate(), 4);
+ const uint8_t raw_data[4] = {1, 2, 3, 4};
+ memcpy(input_ab->GetBackingStore()->Data(), raw_data, 4);
+ i::Cast<i::JSArrayBuffer>(v8::Utils::OpenDirectHandle(*input_ab))
+ ->MakeImmutable(reinterpret_cast<i::Isolate*>(isolate()));
+ EXPECT_TRUE(input_ab->IsImmutable());
+
+ ValueSerializer serializer(isolate());
+ serializer.WriteHeader();
+ ASSERT_TRUE(serializer.WriteValue(serialization_context(), input_ab)
+ .FromMaybe(false));
+ std::pair<uint8_t*, size_t> data = serializer.Release();
+
+ ValueDeserializer deserializer(isolate(), data.first, data.second);
+ ASSERT_TRUE(
+ deserializer.ReadHeader(deserialization_context()).FromMaybe(false));
+ Local<Value> result =
+ deserializer.ReadValue(deserialization_context()).ToLocalChecked();
+
+ ASSERT_TRUE(result->IsArrayBuffer());
+ Local<ArrayBuffer> output_ab = result.As<ArrayBuffer>();
+ EXPECT_TRUE(output_ab->IsImmutable());
+ EXPECT_NE(input_ab->GetBackingStore()->Data(),
+ output_ab->GetBackingStore()->Data());
+ EXPECT_EQ(0, memcmp(input_ab->GetBackingStore()->Data(),
+ output_ab->GetBackingStore()->Data(), 4));
+
+ base::Free(data.first);
+}
+
+TEST_F(ValueSerializerTest, RoundTripImmutableArrayBufferFlagDisabledCopied) {
+ FLAG_VALUE_SCOPE(js_postmessage_share_immutable_arraybuffer, false);
+ v8::Isolate::Scope isolate_scope(isolate());
+ v8::HandleScope handle_scope(isolate());
+ v8::Context::Scope context_scope(serialization_context());
+
+ Local<ArrayBuffer> input_ab = ArrayBuffer::New(isolate(), 4);
+ const uint8_t raw_data[4] = {1, 2, 3, 4};
+ memcpy(input_ab->GetBackingStore()->Data(), raw_data, 4);
+ i::Cast<i::JSArrayBuffer>(v8::Utils::OpenDirectHandle(*input_ab))
+ ->MakeImmutable(reinterpret_cast<i::Isolate*>(isolate()));
+ EXPECT_TRUE(input_ab->IsImmutable());
+
+ ValueSerializer serializer(
+ isolate(), ValueSerializer::SharedImmutableArrayBufferMode::kEnabled);
+ serializer.WriteHeader();
+ ASSERT_TRUE(serializer.WriteValue(serialization_context(), input_ab)
+ .FromMaybe(false));
+ std::pair<uint8_t*, size_t> data = serializer.Release();
+
+ ValueDeserializer deserializer(isolate(), data.first, data.second);
+ ASSERT_TRUE(
+ deserializer.ReadHeader(deserialization_context()).FromMaybe(false));
+ Local<Value> result =
+ deserializer.ReadValue(deserialization_context()).ToLocalChecked();
+
+ ASSERT_TRUE(result->IsArrayBuffer());
+ Local<ArrayBuffer> output_ab = result.As<ArrayBuffer>();
+ EXPECT_TRUE(output_ab->IsImmutable());
+ EXPECT_NE(input_ab->GetBackingStore()->Data(),
+ output_ab->GetBackingStore()->Data());
+ EXPECT_EQ(0, memcmp(input_ab->GetBackingStore()->Data(),
+ output_ab->GetBackingStore()->Data(), 4));
+
+ base::Free(data.first);
+}
+
TEST_F(ValueSerializerTest, RoundTripTypedArray) {
// Check that the right type comes out the other side for every kind of typed
// array.
diff --git a/deps/v8/test/unittests/parser/decls-unittest.cc b/deps/v8/test/unittests/parser/decls-unittest.cc
index bbee4c9bb86..bd696aa790c 100644
--- a/deps/v8/test/unittests/parser/decls-unittest.cc
+++ b/deps/v8/test/unittests/parser/decls-unittest.cc
@@ -1070,7 +1070,6 @@ TEST_F(DeclsTest, Regress3941_Reads) {
}
TEST_F(DeclsTest, TestUsing) {
- i::v8_flags.js_explicit_resource_management = true;
HandleScope scope(isolate());
{
@@ -1109,7 +1108,6 @@ TEST_F(DeclsTest, TestUsing) {
}
TEST_F(DeclsTest, TestAwaitUsing) {
- i::v8_flags.js_explicit_resource_management = true;
HandleScope scope(isolate());
{
diff --git a/deps/v8/test/unittests/profiler/heap-snapshot-unittest.cc b/deps/v8/test/unittests/profiler/heap-snapshot-unittest.cc
index 8a837b2531b..439db008c0a 100644
--- a/deps/v8/test/unittests/profiler/heap-snapshot-unittest.cc
+++ b/deps/v8/test/unittests/profiler/heap-snapshot-unittest.cc
@@ -202,6 +202,12 @@ TEST_F(HeapSnapshotTest, ScopeInfoProperties) {
ASSERT_NE(nullptr, scope_type_name_edge);
EXPECT_STREQ("FUNCTION_SCOPE", scope_type_name_edge->to()->name());
+ std::optional<int> scope_id = GetIntEdge(scope_info, "scope_id");
+ ASSERT_TRUE(scope_id.has_value());
+ // scope id is the start position of that scope. So needs to be updated when
+ // the script changes.
+ EXPECT_EQ(88, scope_id.value());
+
std::optional<int> parameter_count =
GetIntEdge(scope_info, "parameter_count");
ASSERT_TRUE(parameter_count.has_value());
@@ -253,6 +259,12 @@ TEST_F(HeapSnapshotTest, ScopeInfoProperties) {
ASSERT_NE(nullptr, scope_type_name_edge);
EXPECT_STREQ("FUNCTION_SCOPE", scope_type_name_edge->to()->name());
+ std::optional<int> scope_id = GetIntEdge(scope_info, "scope_id");
+ ASSERT_TRUE(scope_id.has_value());
+ // scope id is the start position of that scope. So needs to be updated when
+ // the script changes.
+ EXPECT_EQ(30, scope_id.value());
+
std::optional<int> parameter_count =
GetIntEdge(scope_info, "parameter_count");
ASSERT_TRUE(parameter_count.has_value());
@@ -699,4 +711,331 @@ TEST_F(HeapSnapshotTest, ScriptMetadata) {
}
}
+TEST_F(HeapSnapshotTest, InstructionStreamReferences) {
+ if (v8_flags.jitless) return;
+ v8_flags.allow_natives_syntax = true;
+ RunJS(
+ "function bar(x) { return x.a + 1; }\n"
+ "function foo(obj) { return bar(obj) + 'constant_string'; }\n"
+ "let obj = {a: 1};\n"
+ "%NeverOptimizeFunction(bar);\n"
+ "%PrepareFunctionForOptimization(foo);\n"
+ "bar(obj);\n"
+ "foo(obj);\n"
+ "%OptimizeFunctionOnNextCall(foo);\n"
+ "foo(obj);\n");
+
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* foo_entry =
+ GetEntryByName(snapshot, "foo", HeapEntry::kClosure);
+ ASSERT_NE(nullptr, foo_entry);
+
+ const HeapGraphEdge* code_edge = GetNamedEdge(*foo_entry, "code");
+ ASSERT_NE(nullptr, code_edge);
+ const HeapEntry* code_entry = code_edge->to();
+ ASSERT_NE(nullptr, code_entry);
+
+ const HeapGraphEdge* istream_edge =
+ GetNamedEdge(*code_entry, "instruction_stream");
+ ASSERT_NE(nullptr, istream_edge);
+ const HeapEntry* istream_entry = istream_edge->to();
+ ASSERT_NE(nullptr, istream_entry);
+
+ const HeapGraphEdge* back_code_edge = GetNamedEdge(*istream_entry, "code");
+ ASSERT_NE(nullptr, back_code_edge);
+ EXPECT_EQ(code_entry, back_code_edge->to());
+
+ const HeapGraphEdge* reloc_info_edge =
+ GetNamedEdge(*istream_entry, "relocation_info");
+ ASSERT_NE(nullptr, reloc_info_edge);
+ EXPECT_EQ(HeapGraphEdge::kInternal, reloc_info_edge->type());
+
+ // foo has a weak edge to bar's InstructionStream.
+ const HeapEntry* bar_entry =
+ GetEntryByName(snapshot, "bar", HeapEntry::kClosure);
+ ASSERT_NE(nullptr, bar_entry);
+
+ const HeapGraphEdge* bar_code_edge = GetNamedEdge(*bar_entry, "code");
+ ASSERT_NE(nullptr, bar_code_edge);
+ const HeapEntry* bar_code_entry = bar_code_edge->to();
+ ASSERT_NE(nullptr, bar_code_entry);
+
+ const HeapGraphEdge* call_edge = FindFirstEdgeTo(*istream_entry, *bar_entry);
+ ASSERT_NE(nullptr, call_edge);
+ EXPECT_EQ(HeapGraphEdge::kWeak, call_edge->type());
+
+ // foo should also reference the string "constant_string".
+ const HeapEntry* string_entry = GetEntryByName(snapshot, "constant_string");
+ ASSERT_NE(nullptr, string_entry);
+
+ const HeapGraphEdge* string_edge =
+ FindFirstEdgeTo(*istream_entry, *string_entry);
+ ASSERT_NE(nullptr, string_edge);
+ EXPECT_EQ(HeapGraphEdge::kHidden, string_edge->type());
+
+ int hidden_edge_count = 0;
+ int weak_edge_count = 0;
+ for (int i = 0; i < istream_entry->children_count(); ++i) {
+ const HeapGraphEdge* edge = istream_entry->child(i);
+ // ExtractInstructionStreamReferences emits RelocInfo edges as either weak
+ // or hidden. The code and relocation_info fields are emitted as internal
+ // edges.
+ EXPECT_TRUE(edge->type() == HeapGraphEdge::kInternal ||
+ edge->type() == HeapGraphEdge::kHidden ||
+ edge->type() == HeapGraphEdge::kWeak);
+ if (edge->type() == HeapGraphEdge::kHidden) {
+ hidden_edge_count++;
+ } else if (edge->type() == HeapGraphEdge::kWeak) {
+ weak_edge_count++;
+ }
+ }
+ EXPECT_GT(hidden_edge_count, 0);
+ EXPECT_GT(weak_edge_count, 0);
+}
+
+const HeapEntry* GetClosureContext(HeapSnapshot* snapshot, const char* name) {
+ const HeapEntry* closure =
+ GetEntryByName(snapshot, name, HeapEntry::kClosure);
+ if (!closure) return nullptr;
+ const HeapGraphEdge* context_edge = GetNamedEdge(*closure, "context");
+ if (!context_edge) return nullptr;
+ return context_edge->to();
+}
+
+void AssertContextType(const HeapEntry* context_entry,
+ InstanceType expected_instance_type,
+ const char* expected_instance_type_name,
+ ScopeType expected_scope_type,
+ const char* expected_scope_type_name) {
+ ASSERT_NE(nullptr, context_entry);
+
+ const HeapGraphEdge* map_edge = GetNamedEdge(*context_entry, "map");
+ ASSERT_NE(nullptr, map_edge);
+ const HeapEntry* map_entry = map_edge->to();
+ EXPECT_EQ(static_cast<int>(expected_instance_type),
+ GetIntEdge(map_entry, "instance_type"));
+ const HeapGraphEdge* instance_type_name_edge =
+ GetNamedEdge(*map_entry, "instance_type_name");
+ ASSERT_NE(nullptr, instance_type_name_edge);
+ EXPECT_STREQ(expected_instance_type_name,
+ instance_type_name_edge->to()->name());
+
+ const HeapGraphEdge* scope_info_edge =
+ GetNamedEdge(*context_entry, "scope_info");
+ ASSERT_NE(nullptr, scope_info_edge);
+ const HeapEntry* scope_info_entry = scope_info_edge->to();
+ EXPECT_EQ(static_cast<int>(expected_scope_type),
+ GetIntEdge(scope_info_entry, "scope_type"));
+ const HeapGraphEdge* scope_type_name_edge =
+ GetNamedEdge(*scope_info_entry, "scope_type_name");
+ ASSERT_NE(nullptr, scope_type_name_edge);
+ EXPECT_STREQ(expected_scope_type_name, scope_type_name_edge->to()->name());
+}
+
+TEST_F(HeapSnapshotTest, FunctionContextVariables) {
+ RunJS(
+ "function factory() {\n"
+ " let func_var = { name: 'function_scope_object' };\n"
+ " return function closure() { return func_var; };\n"
+ "}\n"
+ "globalThis.f = factory();");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* func_context_entry = GetClosureContext(snapshot, "closure");
+ AssertContextType(func_context_entry, FUNCTION_CONTEXT_TYPE,
+ "FUNCTION_CONTEXT_TYPE", FUNCTION_SCOPE, "FUNCTION_SCOPE");
+
+ const HeapGraphEdge* func_var_edge =
+ GetNamedEdge(*func_context_entry, "func_var");
+ ASSERT_NE(nullptr, func_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, func_var_edge->type());
+}
+
+TEST_F(HeapSnapshotTest, BlockContextVariables) {
+ RunJS(
+ "function factory() {\n"
+ " {\n"
+ " let block_var = { name: 'block_scope_object' };\n"
+ " return function closure() { return block_var; };\n"
+ " }\n"
+ "}\n"
+ "globalThis.f = factory();");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* block_context_entry = GetClosureContext(snapshot, "closure");
+ AssertContextType(block_context_entry, BLOCK_CONTEXT_TYPE,
+ "BLOCK_CONTEXT_TYPE", BLOCK_SCOPE, "BLOCK_SCOPE");
+
+ const HeapGraphEdge* block_var_edge =
+ GetNamedEdge(*block_context_entry, "block_var");
+ ASSERT_NE(nullptr, block_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, block_var_edge->type());
+}
+
+TEST_F(HeapSnapshotTest, CatchContextVariables) {
+ RunJS(
+ "function factory() {\n"
+ " try {\n"
+ " throw { name: 'catch_scope_object' };\n"
+ " } catch (catch_var) {\n"
+ " return function closure() { return catch_var; };\n"
+ " }\n"
+ "}\n"
+ "globalThis.f = factory();");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* catch_context_entry = GetClosureContext(snapshot, "closure");
+ AssertContextType(catch_context_entry, CATCH_CONTEXT_TYPE,
+ "CATCH_CONTEXT_TYPE", CATCH_SCOPE, "CATCH_SCOPE");
+
+ const HeapGraphEdge* catch_var_edge =
+ GetNamedEdge(*catch_context_entry, "catch_var");
+ ASSERT_NE(nullptr, catch_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, catch_var_edge->type());
+}
+
+TEST_F(HeapSnapshotTest, SloppyEvalContextVariables) {
+ RunJS(
+ "function factory() {\n"
+ " return eval('let eval_var = { name: \"eval_scope_object\" }; "
+ "function closure() { return eval_var; }; closure;');\n"
+ "}\n"
+ "globalThis.f = factory();");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* eval_context_entry = GetClosureContext(snapshot, "closure");
+ AssertContextType(eval_context_entry, EVAL_CONTEXT_TYPE, "EVAL_CONTEXT_TYPE",
+ EVAL_SCOPE, "EVAL_SCOPE");
+
+ const HeapGraphEdge* eval_var_edge =
+ GetNamedEdge(*eval_context_entry, "eval_var");
+ ASSERT_NE(nullptr, eval_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, eval_var_edge->type());
+}
+
+TEST_F(HeapSnapshotTest, ForOfLoopBlockContextVariables) {
+ RunJS(
+ "function factory() {\n"
+ " const closures = [];\n"
+ " for (let item of [{ name: 'item_1' }, { name: 'item_2' }]) {\n"
+ " closures.push(function closure() { return item; });\n"
+ " }\n"
+ " return closures;\n"
+ "}\n"
+ "globalThis.closures = factory();");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* block_context_entry = GetClosureContext(snapshot, "closure");
+ AssertContextType(block_context_entry, BLOCK_CONTEXT_TYPE,
+ "BLOCK_CONTEXT_TYPE", BLOCK_SCOPE, "BLOCK_SCOPE");
+
+ const HeapGraphEdge* item_var_edge =
+ GetNamedEdge(*block_context_entry, "item");
+ ASSERT_NE(nullptr, item_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, item_var_edge->type());
+}
+
+TEST_F(HeapSnapshotTest, NativeContextGlobalVariable) {
+ RunJS("var global_var = { name: 'global_var_object' };");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* native_context_entry =
+ GetEntryByName(snapshot, "system / NativeContext", HeapEntry::kNative);
+ AssertContextType(native_context_entry, NATIVE_CONTEXT_TYPE,
+ "NATIVE_CONTEXT_TYPE", SCRIPT_SCOPE, "SCRIPT_SCOPE");
+
+ const HeapGraphEdge* global_obj_edge =
+ GetNamedEdge(*native_context_entry, "global_object");
+ ASSERT_NE(nullptr, global_obj_edge);
+ const HeapEntry* global_obj_entry = global_obj_edge->to();
+ ASSERT_NE(nullptr, global_obj_entry);
+
+ const HeapGraphEdge* global_var_edge =
+ GetNamedEdge(*global_obj_entry, "global_var");
+ ASSERT_NE(nullptr, global_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kProperty, global_var_edge->type());
+}
+
+TEST_F(HeapSnapshotTest, ScriptContextVariables) {
+ RunJS(
+ "let script_let_var = { name: 'script_let_object' };\n"
+ "const script_const_var = { name: 'script_const_object' };\n"
+ "globalThis.closure = function closure() {\n"
+ " return [script_let_var, script_const_var];\n"
+ "};");
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* script_context_entry =
+ GetClosureContext(snapshot, "closure");
+ AssertContextType(script_context_entry, SCRIPT_CONTEXT_TYPE,
+ "SCRIPT_CONTEXT_TYPE", SCRIPT_SCOPE, "SCRIPT_SCOPE");
+
+ const HeapGraphEdge* let_var_edge =
+ GetNamedEdge(*script_context_entry, "script_let_var");
+ ASSERT_NE(nullptr, let_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, let_var_edge->type());
+
+ const HeapGraphEdge* const_var_edge =
+ GetNamedEdge(*script_context_entry, "script_const_var");
+ ASSERT_NE(nullptr, const_var_edge);
+ EXPECT_EQ(HeapGraphEdge::kContextVariable, const_var_edge->type());
+
+ const HeapGraphEdge* previous_edge =
+ GetNamedEdge(*script_context_entry, "previous");
+ ASSERT_NE(nullptr, previous_edge);
+ const HeapEntry* native_context_entry = previous_edge->to();
+ AssertContextType(native_context_entry, NATIVE_CONTEXT_TYPE,
+ "NATIVE_CONTEXT_TYPE", SCRIPT_SCOPE, "SCRIPT_SCOPE");
+}
+
+TEST_F(HeapSnapshotTest, ScriptSourceStringsUntruncated) {
+ std::string script_source = "function very_long_function_name() { /* " +
+ std::string(1500, 'x') + " */ return 42; }";
+ RunJS(script_source.c_str());
+
+ // Also test a dynamically constructed ConsString script source via eval.
+ std::string eval_script_source =
+ "function cons_script_func() { /* " + std::string(1500, 'z') + " */ }";
+ RunJS(
+ "eval('function cons_script_func() { /* ' + 'z'.repeat(1500) + ' */ "
+ "}');");
+
+ std::string regular_content(1500, 'y');
+ RunJS(
+ ("globalThis.regular_long_string = '" + regular_content + "';").c_str());
+
+ HeapSnapshot* snapshot = TakeHeapSnapshot();
+
+ const HeapEntry* script_source_entry =
+ GetEntryByName(snapshot, script_source.c_str(), HeapEntry::kString);
+ ASSERT_NE(nullptr, script_source_entry);
+ EXPECT_STREQ(script_source.c_str(), script_source_entry->name());
+
+ // Truncated flag should not be present on script source entry.
+ std::optional<bool> script_truncated =
+ GetBoolEdge(script_source_entry, "truncated");
+ EXPECT_FALSE(script_truncated.has_value());
+
+ // ConsString script source should also not be truncated.
+ const HeapEntry* eval_source_entry =
+ GetEntryByName(snapshot, eval_script_source.c_str(), HeapEntry::kString);
+ ASSERT_NE(nullptr, eval_source_entry);
+ EXPECT_STREQ(eval_script_source.c_str(), eval_source_entry->name());
+ std::optional<bool> eval_script_truncated =
+ GetBoolEdge(eval_source_entry, "truncated");
+ EXPECT_FALSE(eval_script_truncated.has_value());
+
+ // Regular long string should be truncated to 1024 characters.
+ std::string expected_truncated_regular = regular_content.substr(0, 1024);
+ const HeapEntry* regular_string_entry = GetEntryByName(
+ snapshot, expected_truncated_regular.c_str(), HeapEntry::kString);
+ ASSERT_NE(nullptr, regular_string_entry);
+
+ std::optional<bool> regular_truncated =
+ GetBoolEdge(regular_string_entry, "truncated");
+ ASSERT_TRUE(regular_truncated.has_value());
+ EXPECT_TRUE(regular_truncated.value());
+}
+
} // namespace v8::internal
diff --git a/deps/v8/test/unittests/profiler/heap-snapshot-utils.cc b/deps/v8/test/unittests/profiler/heap-snapshot-utils.cc
index 70928868131..3eb5797dbac 100644
--- a/deps/v8/test/unittests/profiler/heap-snapshot-utils.cc
+++ b/deps/v8/test/unittests/profiler/heap-snapshot-utils.cc
@@ -50,9 +50,13 @@ bool IsRetainedByCppStackRoot(HeapSnapshot* snapshot, const HeapEntry& entry) {
FindFirstEdgeTo(*stack_roots_entry, entry) != nullptr;
}
-const HeapEntry* GetEntryByName(HeapSnapshot* snapshot, const char* name) {
+const HeapEntry* GetEntryByName(HeapSnapshot* snapshot, const char* name,
+ std::optional<HeapEntry::Type> type) {
for (const HeapEntry& entry : snapshot->entries()) {
- if (strcmp(entry.name(), name) == 0) return &entry;
+ if (strcmp(entry.name(), name) == 0 &&
+ (!type.has_value() || entry.type() == type.value())) {
+ return &entry;
+ }
}
return nullptr;
}
diff --git a/deps/v8/test/unittests/profiler/heap-snapshot-utils.h b/deps/v8/test/unittests/profiler/heap-snapshot-utils.h
index dcba70caf4e..94d9deee28c 100644
--- a/deps/v8/test/unittests/profiler/heap-snapshot-utils.h
+++ b/deps/v8/test/unittests/profiler/heap-snapshot-utils.h
@@ -23,7 +23,9 @@ const HeapGraphEdge* GetNamedEdge(const HeapEntry& entry, const char* name);
const HeapGraphEdge* FindFirstEdgeTo(const HeapEntry& from,
const HeapEntry& to);
bool IsRetainedByCppStackRoot(HeapSnapshot* snapshot, const HeapEntry& entry);
-const HeapEntry* GetEntryByName(HeapSnapshot* snapshot, const char* name);
+const HeapEntry* GetEntryByName(
+ HeapSnapshot* snapshot, const char* name,
+ std::optional<HeapEntry::Type> type = std::nullopt);
bool HasNamedEdge(const HeapEntry& entry, const char* name);
std::optional<int> GetIntEdge(const HeapEntry* node, const char* name);
std::optional<bool> GetBoolEdge(const HeapEntry* node, const char* name);
diff --git a/deps/v8/test/unittests/profiler/output-stream-writer-unittest.cc b/deps/v8/test/unittests/profiler/output-stream-writer-unittest.cc
new file mode 100644
index 00000000000..b438340382b
--- /dev/null
+++ b/deps/v8/test/unittests/profiler/output-stream-writer-unittest.cc
@@ -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.
+
+#include "src/profiler/output-stream-writer.h"
+
+#include "include/v8-profiler.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8::internal {
+
+namespace {
+
+class AbortingOutputStream : public v8::OutputStream {
+ public:
+ void EndOfStream() override { ++eos_count_; }
+ int GetChunkSize() override { return 8; }
+ WriteResult WriteAsciiChunk(char*, int) override { return kAbort; }
+
+ int eos_count() const { return eos_count_; }
+
+ private:
+ int eos_count_ = 0;
+};
+
+} // namespace
+
+using OutputStreamWriterTest = ::testing::Test;
+
+TEST_F(OutputStreamWriterTest, AbortOnFinalPartialChunkSuppressesEndOfStream) {
+ AbortingOutputStream stream;
+ OutputStreamWriter writer(&stream);
+ writer.AddString("abc");
+ EXPECT_FALSE(writer.aborted());
+
+ writer.Finalize();
+
+ EXPECT_TRUE(writer.aborted());
+ EXPECT_EQ(0, stream.eos_count());
+}
+
+} // namespace v8::internal
diff --git a/deps/v8/test/unittests/profiler/strings-storage-unittest.cc b/deps/v8/test/unittests/profiler/strings-storage-unittest.cc
index 26bdc2e64ba..7d9a46b0b0e 100644
--- a/deps/v8/test/unittests/profiler/strings-storage-unittest.cc
+++ b/deps/v8/test/unittests/profiler/strings-storage-unittest.cc
@@ -198,5 +198,13 @@ TEST_F(StringsStorageWithIsolate, Truncation) {
}
}
+TEST_F(StringsStorageWithIsolate, Untruncated) {
+ StringsStorage storage(2);
+ DirectHandle<String> str =
+ isolate()->factory()->NewStringFromAsciiChecked("foobar");
+ const char* stored_str = storage.GetUntruncated(*str);
+ CHECK(StringEq("foobar", stored_str));
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/regexp/regexp-unittest.cc b/deps/v8/test/unittests/regexp/regexp-unittest.cc
index f794e8f6269..f27ed6e952e 100644
--- a/deps/v8/test/unittests/regexp/regexp-unittest.cc
+++ b/deps/v8/test/unittests/regexp/regexp-unittest.cc
@@ -2632,13 +2632,13 @@ TEST_F(RegExpTest, QuickCheckDeterminesPerfectly) {
Zone zone(i_isolate()->allocator(), ZONE_NAME);
// Create an EndNode to serve as the successor.
- regexp::EndNode* accept =
- zone.New<regexp::EndNode>(regexp::EndNode::ACCEPT, &zone);
+ regexp::EndNode* accept = zone.New<regexp::EndNode>(regexp::EndNode::ACCEPT,
+ regexp::Flags(), &zone);
auto check_determines_perfectly =
[&](ZoneList<regexp::CharacterRange>* ranges, bool is_one_byte) {
regexp::TextNode* node = regexp::TextNode::CreateForCharacterRanges(
- &zone, ranges, false, accept);
+ &zone, ranges, false, accept, regexp::Flags());
regexp::Compiler compiler(i_isolate(), &zone, 0, regexp::Flags(),
is_one_byte);
regexp::QuickCheckDetails details(1);
diff --git a/deps/v8/test/unittests/regress/regress-536271629-unittest.cc b/deps/v8/test/unittests/regress/regress-536271629-unittest.cc
index 57c944dfdb1..a64907fc9f6 100644
--- a/deps/v8/test/unittests/regress/regress-536271629-unittest.cc
+++ b/deps/v8/test/unittests/regress/regress-536271629-unittest.cc
@@ -2,7 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "src/execution/isolate-inl.h"
#include "src/execution/isolate.h"
+#include "src/objects/contexts-inl.h"
#include "src/objects/js-function-inl.h"
#include "src/objects/scope-info.h"
#include "src/objects/shared-function-info-inl.h"
@@ -56,5 +58,18 @@ TEST_F(SloppyArgumentsScopeInfoTest, MappedArgumentsWithNonSimpleScopeInfo) {
EXPECT_DEATH_IF_SUPPORTED(RunJS("duplicate(1, 2)"), "");
}
+// The mapped arguments path allocates with the sloppy arguments map and then
+// installs the fast aliased arguments map, so the two must have the same
+// instance size.
+TEST_F(SloppyArgumentsScopeInfoTest, ArgumentsMapInstanceSizes) {
+ v8::HandleScope scope(isolate());
+ Tagged<NativeContext> context = i_isolate()->raw_native_context();
+
+ const int sloppy_size = context->sloppy_arguments_map()->instance_size();
+ CHECK_EQ(sloppy_size, context->fast_aliased_arguments_map()->instance_size());
+ CHECK_EQ(sloppy_size, context->slow_aliased_arguments_map()->instance_size());
+ CHECK_LT(context->strict_arguments_map()->instance_size(), sloppy_size);
+}
+
} // namespace internal
} // namespace v8
diff --git a/deps/v8/test/unittests/regress/regress-536954139-unittest.cc b/deps/v8/test/unittests/regress/regress-536954139-unittest.cc
new file mode 100644
index 00000000000..8d3943b3180
--- /dev/null
+++ b/deps/v8/test/unittests/regress/regress-536954139-unittest.cc
@@ -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.
+
+#include "src/base/vector.h"
+#include "src/diagnostics/disasm.h"
+#include "src/diagnostics/disassembler.h"
+#include "test/unittests/test-utils.h"
+
+namespace v8 {
+namespace internal {
+
+using DisasmX64RegressTest = TestWithContext;
+
+TEST_F(DisasmX64RegressTest, Regress536954139) {
+ // `62 F2 75 08 39 C2` should disassemble as `vpminsd`, not `vpminsq`.
+ uint8_t code[] = {0x62, 0xF2, 0x75, 0x08, 0x39, 0xC2};
+
+ disasm::NameConverter converter;
+ disasm::Disassembler disassembler(converter);
+
+ v8::base::EmbeddedVector<char, 128> buffer;
+ buffer[0] = '\0';
+ disassembler.InstructionDecode(buffer, code);
+
+ // The disassembled string should contain "vpminsd".
+ EXPECT_NE(nullptr, strstr(buffer.begin(), "vpminsd")) << buffer.begin();
+}
+
+} // namespace internal
+} // namespace v8
diff --git a/deps/v8/test/unittests/run-all-unittests.cc b/deps/v8/test/unittests/run-all-unittests.cc
index 961e7ecd65c..1e2a561b099 100644
--- a/deps/v8/test/unittests/run-all-unittests.cc
+++ b/deps/v8/test/unittests/run-all-unittests.cc
@@ -4,6 +4,10 @@
#include <memory>
+#if defined(_WIN32)
+#include <windows.h>
+#endif
+
#include "include/cppgc/platform.h"
#include "include/libplatform/libplatform.h"
#include "include/v8-initialization.h"
@@ -45,6 +49,11 @@ class CppGCEnvironment final : public ::testing::Environment {
int main(int argc, char** argv) {
+#if defined(_WIN32)
+ // Preload these DLLs before symbolization can reenter ASAN's allocator.
+ ::LoadLibraryW(L"dbghelp.dll");
+ ::LoadLibraryW(L"msdia140.dll");
+#endif
// Don't catch SEH exceptions and continue as the following tests might hang
// in an broken environment on windows.
GTEST_FLAG_SET(catch_exceptions, false);
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 3b7345d49f4..66846793a19 100644
--- a/deps/v8/test/unittests/sandbox/generated-code-validator-unittest.cc
+++ b/deps/v8/test/unittests/sandbox/generated-code-validator-unittest.cc
@@ -6,7 +6,7 @@
#ifdef V8_ENABLE_GENERATED_CODE_VALIDATOR
-#include "src/codegen/macro-assembler.h"
+#include "src/codegen/macro-assembler-inl.h"
#include "src/heap/factory-inl.h"
#include "test/common/assembler-tester.h"
#include "test/unittests/test-utils.h"
@@ -16,9 +16,43 @@ namespace internal {
using GeneratedCodeValidatorTest = TestWithContext;
+namespace {
+
+void CheckValidationSucceeds(Isolate* i_isolate, MacroAssembler& masm) {
+ // Delay validation until we're ready to call it explicitly.
+ v8_flags.validate_generated_code = false;
+ CodeDesc desc;
+ masm.GetCode(i_isolate, &desc);
+ DirectHandle<Code> code =
+ Factory::CodeBuilder(i_isolate, desc, CodeKind::FOR_TESTING).Build();
+
+ // This should not crash.
+ v8_flags.validate_generated_code = true;
+ v8_flags.validate_generated_code_non_fatal = false;
+ GeneratedCodeValidator::Validate(i_isolate, *code);
+}
+
+void CheckValidationFails(Isolate* i_isolate, MacroAssembler& masm,
+ std::string expected_error) {
+ // Delay validation until we're ready to call it explicitly.
+ v8_flags.validate_generated_code = false;
+ CodeDesc desc;
+ masm.GetCode(i_isolate, &desc);
+ DirectHandle<Code> code =
+ Factory::CodeBuilder(i_isolate, desc, CodeKind::FOR_TESTING).Build();
+
+ // This should not crash.
+ v8_flags.validate_generated_code = true;
+ v8_flags.validate_generated_code_non_fatal = false;
+ ASSERT_DEATH_IF_SUPPORTED(GeneratedCodeValidator::Validate(i_isolate, *code),
+ expected_error);
+}
+
+} // namespace
+
#define __ masm.
-TEST_F(GeneratedCodeValidatorTest, ValidateValidCode) {
+TEST_F(GeneratedCodeValidatorTest, DisassembleValidCode) {
// This validation until we're ready to call it explicitly.
v8_flags.validate_generated_code = false;
Isolate* i_isolate = this->i_isolate();
@@ -36,19 +70,10 @@ TEST_F(GeneratedCodeValidatorTest, ValidateValidCode) {
#error "Unsupported architecture for GeneratedCodeValidatorTest"
#endif
- CodeDesc desc;
- masm.GetCode(i_isolate, &desc);
- DirectHandle<Code> code =
- Factory::CodeBuilder(i_isolate, desc, CodeKind::FOR_TESTING).Build();
-
- // This should not crash.
- v8_flags.validate_generated_code = true;
- GeneratedCodeValidator::Validate(i_isolate, *code);
+ CheckValidationSucceeds(i_isolate, masm);
}
-TEST_F(GeneratedCodeValidatorTest, ValidateInvalidCode) {
- // This validation until we're ready to call it explicitly.
- v8_flags.validate_generated_code = false;
+TEST_F(GeneratedCodeValidatorTest, DisassembleInvalidCode) {
Isolate* i_isolate = this->i_isolate();
auto buffer = AllocateAssemblerBuffer();
MacroAssembler masm(i_isolate, CodeObjectRequired{false},
@@ -68,17 +93,197 @@ TEST_F(GeneratedCodeValidatorTest, ValidateInvalidCode) {
#error "Unsupported architecture for GeneratedCodeValidatorTest"
#endif
- CodeDesc desc;
- masm.GetCode(i_isolate, &desc);
- DirectHandle<Code> code =
- Factory::CodeBuilder(i_isolate, desc, CodeKind::FOR_TESTING).Build();
+ CheckValidationFails(i_isolate, masm,
+ "Failed to disassemble invalid instruction");
+}
- // This should crash.
- v8_flags.validate_generated_code = true;
- ASSERT_DEATH_IF_SUPPORTED(GeneratedCodeValidator::Validate(i_isolate, *code),
- "Generated code validator failed");
+TEST_F(GeneratedCodeValidatorTest, ValidateCageBaseModificationFails) {
+ static_assert(kPtrComprCageBaseRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+#if V8_TARGET_ARCH_X64
+ __ movq(kPtrComprCageBaseRegister, Immediate(0));
+ __ ret(0);
+#elif V8_TARGET_ARCH_ARM64
+ __ Mov(kPtrComprCageBaseRegister, 0);
+ __ ret();
+#else
+#error "Unsupported architecture for GeneratedCodeValidatorTest"
+#endif
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction accesses cage bage register at operand 0");
+}
+
+TEST_F(GeneratedCodeValidatorTest, ValidateRootRegisterModificationFails) {
+ static_assert(kRootRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+#if V8_TARGET_ARCH_X64
+ __ movq(kRootRegister, Immediate(0));
+ __ ret(0);
+#elif V8_TARGET_ARCH_ARM64
+ __ Add(kRootRegister, x13, 0);
+ __ ret();
+#else
+#error "Unsupported architecture for GeneratedCodeValidatorTest"
+#endif
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction accesses root register at operand 0");
+}
+
+TEST_F(GeneratedCodeValidatorTest, ValidateCageBaseRegInitWithoutRootRegFails) {
+ static_assert(kRootRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+ __ LoadRootRelative(kPtrComprCageBaseRegister,
+ IsolateData::cage_base_offset());
+
+ CheckValidationFails(
+ i_isolate, masm,
+ "Cage base register initialization uses invalid root register");
+}
+
+TEST_F(GeneratedCodeValidatorTest, ValidateOverwritingCageBaseRegFails) {
+ static_assert(kRootRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+#if V8_TARGET_ARCH_X64
+ __ movq(kRootRegister, kCArgRegs[0]);
+#elif V8_TARGET_ARCH_ARM64
+ __ Mov(kRootRegister, x0);
+#else
+#error "Unsupported architecture for GeneratedCodeValidatorTest"
+#endif
+ __ LoadRootRelative(kPtrComprCageBaseRegister,
+ IsolateData::cage_base_offset());
+ __ LoadRootRelative(kPtrComprCageBaseRegister,
+ IsolateData::cage_base_offset());
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction overwrites a valid cage base register");
+}
+
+TEST_F(GeneratedCodeValidatorTest, ValidateDecompressionPasses) {
+ static_assert(kPtrComprCageBaseRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+#if V8_TARGET_ARCH_X64
+ __ orq(rcx, kPtrComprCageBaseRegister);
+ __ ret(0);
+#elif V8_TARGET_ARCH_ARM64
+ __ Orr(x13, kPtrComprCageBaseRegister, x13);
+ __ DecompressTagged(x13, x13);
+ __ Add(x13, kPtrComprCageBaseRegister, Operand(w13, UXTW, 0));
+ __ ret();
+#else
+#error "Unsupported architecture for GeneratedCodeValidatorTest"
+#endif
+
+ CheckValidationSucceeds(i_isolate, masm);
+}
+
+#if V8_TARGET_ARCH_ARM64
+
+TEST_F(GeneratedCodeValidatorTest, ValidateCageBaseWritebackFails) {
+ static_assert(kPtrComprCageBaseRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+ // Pre-indexed load with writeback updating the cage base register.
+ __ Ldr(x0, MemOperand(kPtrComprCageBaseRegister, 16, PreIndex));
+ __ ret();
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction accesses cage bage register at operand 1");
+}
+
+TEST_F(GeneratedCodeValidatorTest, ValidateRootRegisterPartialInitFails) {
+ static_assert(kRootRegister != no_reg);
+ Isolate* i_isolate = this->i_isolate();
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+ __ Mov(kRootRegister, 0);
+ __ ret();
+
+ CheckValidationFails(i_isolate, masm,
+ "Root register initialization interrupted");
+}
+
+TEST_F(GeneratedCodeValidatorTest, ValidateSystemRegisterWrites) {
+ Isolate* i_isolate = this->i_isolate();
+
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+
+ // Writing to system register should fail validation.
+ __ Msr(NZCV, x0);
+ __ ret();
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction writes to prohibited system registers");
+}
+
+#endif // V8_TARGET_ARCH_ARM64
+
+#if V8_TARGET_ARCH_X64
+
+TEST_F(GeneratedCodeValidatorTest, ValidateSegmentRegisterFails) {
+ Isolate* i_isolate = this->i_isolate();
+
+ // Instruction with segment override prefix.
+ {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+ // mov rax, [fs:rax]
+ __ db(0x64);
+ __ db(0x48);
+ __ db(0x8B);
+ __ db(0x00);
+ __ ret(0);
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction uses a segment register");
+ }
+ // Instruction with segment register operand.
+ {
+ auto buffer = AllocateAssemblerBuffer();
+ MacroAssembler masm(i_isolate, CodeObjectRequired{false},
+ buffer->CreateView());
+ // mov fs, ax
+ __ db(0x8E);
+ __ db(0xE0);
+ __ ret(0);
+
+ CheckValidationFails(i_isolate, masm,
+ "Instruction uses a segment register at operand 0");
+ }
}
+#endif // V8_TARGET_ARCH_X64
+
#undef __
} // namespace internal
diff --git a/deps/v8/test/unittests/sandbox/pointer-table-unittest.cc b/deps/v8/test/unittests/sandbox/pointer-table-unittest.cc
index 5a0be22b76e..86facbef2b2 100644
--- a/deps/v8/test/unittests/sandbox/pointer-table-unittest.cc
+++ b/deps/v8/test/unittests/sandbox/pointer-table-unittest.cc
@@ -85,9 +85,19 @@ class PointerTableTest : public TestWithContext {
return handles;
}
- template <typename Table, typename Handles>
- void MarkAll(Table& table, typename Table::Space* space,
- const Handles& handles) {
+ void MarkAll(
+ ExternalPointerTable& table, ExternalPointerTable::Space* space,
+ const std::vector<std::unique_ptr<ExternalPointerHandle>>& handles,
+ ExternalPointerTagRange tag_range) {
+ for (const auto& handle : handles) {
+ table.Mark(space, *handle, reinterpret_cast<Address>(handle.get()),
+ tag_range);
+ }
+ }
+
+ void MarkAll(
+ CppHeapPointerTable& table, CppHeapPointerTable::Space* space,
+ const std::vector<std::unique_ptr<CppHeapPointerHandle>>& handles) {
for (const auto& handle : handles) {
table.Mark(space, *handle, reinterpret_cast<Address>(handle.get()));
}
@@ -123,9 +133,9 @@ TEST_F(PointerTableTest, ExternalPointerTableCompaction) {
// Simulate a sweep where dead_handle is dead (unmarked) and all other entries
// are marked.
- MarkAll(table, space.get(), handles);
+ MarkAll(table, space.get(), handles, kLastExternalTypeTag);
table.Mark(space.get(), *target_loc,
- reinterpret_cast<Address>(target_loc.get()));
+ reinterpret_cast<Address>(target_loc.get()), kLastExternalTypeTag);
table.SweepAndCompact(space.get(), i_isolate()->counters());
CHECK_EQ(2, space->NumSegmentsForTesting());
CHECK_GE(space->freelist_length(), 1u);
@@ -133,9 +143,9 @@ TEST_F(PointerTableTest, ExternalPointerTableCompaction) {
// Now perform compaction. Start compaction and mark all live entries.
space->StartCompactingIfNeeded();
CHECK(space->IsCompacting());
- MarkAll(table, space.get(), handles);
+ MarkAll(table, space.get(), handles, kLastExternalTypeTag);
table.Mark(space.get(), *target_loc,
- reinterpret_cast<Address>(target_loc.get()));
+ reinterpret_cast<Address>(target_loc.get()), kLastExternalTypeTag);
// Sweeping should now evacuate target_loc into the first segment and
// deallocate the second segment.
@@ -324,9 +334,9 @@ TEST_F(PointerTableTest, ExternalPointerTableFieldInvalidation) {
ExternalPointerHandle handle_before_sweep = *target_loc;
// Free slot 0 on first segment by marking the other handles.
- MarkAll(table, space.get(), handles);
+ MarkAll(table, space.get(), handles, kLastExternalTypeTag);
table.Mark(space.get(), *target_loc,
- reinterpret_cast<Address>(target_loc.get()));
+ reinterpret_cast<Address>(target_loc.get()), kLastExternalTypeTag);
table.SweepAndCompact(space.get(), i_isolate()->counters());
CHECK_EQ(2, space->NumSegmentsForTesting());
CHECK_GE(space->freelist_length(), 1u);
@@ -335,9 +345,9 @@ TEST_F(PointerTableTest, ExternalPointerTableFieldInvalidation) {
// for target_loc.
space->StartCompactingIfNeeded();
CHECK(space->IsCompacting());
- MarkAll(table, space.get(), handles);
+ MarkAll(table, space.get(), handles, kLastExternalTypeTag);
table.Mark(space.get(), *target_loc,
- reinterpret_cast<Address>(target_loc.get()));
+ reinterpret_cast<Address>(target_loc.get()), kLastExternalTypeTag);
// Invalidate the field pointing to target_loc before sweeping.
space->NotifyExternalPointerFieldInvalidated(
@@ -378,11 +388,13 @@ TEST_F(PointerTableTest, ExternalPointerTableHandleOverwriteBailouts) {
CHECK_EQ(2, space->NumSegmentsForTesting());
// Free slots 0 and 1 on first segment by marking the other handles.
- MarkAll(table, space.get(), handles);
+ MarkAll(table, space.get(), handles, kLastExternalTypeTag);
table.Mark(space.get(), *target_loc_null,
- reinterpret_cast<Address>(target_loc_null.get()));
+ reinterpret_cast<Address>(target_loc_null.get()),
+ kLastExternalTypeTag);
table.Mark(space.get(), *target_loc_valid,
- reinterpret_cast<Address>(target_loc_valid.get()));
+ reinterpret_cast<Address>(target_loc_valid.get()),
+ kLastExternalTypeTag);
table.SweepAndCompact(space.get(), i_isolate()->counters());
CHECK_EQ(2, space->NumSegmentsForTesting());
CHECK_GE(space->freelist_length(), 2u);
@@ -390,11 +402,13 @@ TEST_F(PointerTableTest, ExternalPointerTableHandleOverwriteBailouts) {
// Start compaction and mark all live entries, creating evacuation entries.
space->StartCompactingIfNeeded();
CHECK(space->IsCompacting());
- MarkAll(table, space.get(), handles);
+ MarkAll(table, space.get(), handles, kLastExternalTypeTag);
table.Mark(space.get(), *target_loc_null,
- reinterpret_cast<Address>(target_loc_null.get()));
+ reinterpret_cast<Address>(target_loc_null.get()),
+ kLastExternalTypeTag);
table.Mark(space.get(), *target_loc_valid,
- reinterpret_cast<Address>(target_loc_valid.get()));
+ reinterpret_cast<Address>(target_loc_valid.get()),
+ kLastExternalTypeTag);
// Simulate mutator overwriting handles after evacuation entries were created:
// 1. Overwrite with null handle.
diff --git a/deps/v8/test/unittests/sandbox/segmented-table-unittest.cc b/deps/v8/test/unittests/sandbox/segmented-table-unittest.cc
new file mode 100644
index 00000000000..fcf6092ab74
--- /dev/null
+++ b/deps/v8/test/unittests/sandbox/segmented-table-unittest.cc
@@ -0,0 +1,429 @@
+// 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/sandbox/segmented-table.h"
+
+#include <set>
+#include <vector>
+
+#include "src/base/macros.h"
+#include "src/common/globals.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8::internal {
+
+namespace {
+
+class TestSegmentedTable : public SegmentedTableBase {
+ public:
+ using SegmentedTableBase::kAlignment;
+ using SegmentedTableBase::kInternalReadOnlySegmentsOffset;
+ using SegmentedTableBase::kSegmentSize;
+ using SegmentedTableBase::kUseContiguousMemory;
+ using SegmentedTableBase::SegmentBase;
+
+ TestSegmentedTable() = default;
+ ~TestSegmentedTable() {
+ if (is_initialized()) {
+ TearDown();
+ }
+ }
+
+ using SegmentedTableBase::AllocateReadOnlySegment;
+ using SegmentedTableBase::base;
+ using SegmentedTableBase::FreeTableSegment;
+ using SegmentedTableBase::Initialize;
+ using SegmentedTableBase::is_initialized;
+ using SegmentedTableBase::read_only_segments_used;
+ using SegmentedTableBase::ResetReadOnlySegments;
+ using SegmentedTableBase::TearDown;
+ using SegmentedTableBase::TryAllocateSegment;
+};
+
+V8_NOINLINE uint8_t ReadMemory(Address addr) {
+ return *reinterpret_cast<volatile const uint8_t*>(addr);
+}
+
+V8_NOINLINE void WriteMemory(Address addr, uint8_t value) {
+ *reinterpret_cast<volatile uint8_t*>(addr) = value;
+}
+
+} // namespace
+
+TEST(SegmentedTableBaseTest, SegmentBaseProperties) {
+ auto seg0 = TestSegmentedTable::SegmentBase::At(0);
+ EXPECT_EQ(0u, seg0.number());
+ EXPECT_EQ(0u, seg0.offset());
+
+ auto seg1 =
+ TestSegmentedTable::SegmentBase::At(TestSegmentedTable::kSegmentSize);
+ EXPECT_EQ(1u, seg1.number());
+ EXPECT_EQ(TestSegmentedTable::kSegmentSize, seg1.offset());
+
+ auto seg3 =
+ TestSegmentedTable::SegmentBase::At(3 * TestSegmentedTable::kSegmentSize);
+ EXPECT_EQ(3u, seg3.number());
+ EXPECT_EQ(3 * TestSegmentedTable::kSegmentSize, seg3.offset());
+
+ EXPECT_EQ(seg0, seg0);
+ EXPECT_NE(seg0, seg1);
+ EXPECT_LT(seg0, seg1);
+ EXPECT_FALSE(seg1 < seg0);
+ EXPECT_FALSE(seg0 < seg0);
+}
+
+TEST(SegmentedTableBaseTest, InitializationAndTearDown) {
+ TestSegmentedTable table;
+ EXPECT_FALSE(table.is_initialized());
+ EXPECT_EQ(0u, TestSegmentedTable::BaseOffset());
+
+ constexpr size_t kReservationSize = 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ EXPECT_TRUE(table.is_initialized());
+#ifdef V8_TARGET_ARCH_64_BIT
+ EXPECT_NE(kNullAddress, table.base());
+#else
+ EXPECT_EQ(kNullAddress, table.base());
+#endif
+
+ table.TearDown();
+ EXPECT_FALSE(table.is_initialized());
+
+ // Can be re-initialized after TearDown.
+ table.Initialize(kReservationSize, 0, false);
+ EXPECT_TRUE(table.is_initialized());
+#ifdef V8_TARGET_ARCH_64_BIT
+ EXPECT_NE(kNullAddress, table.base());
+#else
+ EXPECT_EQ(kNullAddress, table.base());
+#endif
+ table.TearDown();
+ EXPECT_FALSE(table.is_initialized());
+}
+
+TEST(SegmentedTableBaseTest, AllocateAndFreeSegment) {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize = 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+
+ auto segment_opt = table.TryAllocateSegment();
+ ASSERT_TRUE(segment_opt.has_value());
+ auto segment = *segment_opt;
+ EXPECT_EQ(segment.offset(),
+ segment.number() * TestSegmentedTable::kSegmentSize);
+#ifdef V8_TARGET_ARCH_64_BIT
+ EXPECT_LT(segment.offset(), kReservationSize);
+#endif
+
+ Address base_addr = table.base() + segment.offset();
+ WriteMemory(base_addr, 0xAA);
+ WriteMemory(base_addr + TestSegmentedTable::kSegmentSize / 2, 0xBB);
+ WriteMemory(base_addr + TestSegmentedTable::kSegmentSize - 1, 0xCC);
+
+ EXPECT_EQ(0xAA, ReadMemory(base_addr));
+ EXPECT_EQ(0xBB, ReadMemory(base_addr + TestSegmentedTable::kSegmentSize / 2));
+ EXPECT_EQ(0xCC, ReadMemory(base_addr + TestSegmentedTable::kSegmentSize - 1));
+
+ table.FreeTableSegment(segment);
+}
+
+TEST(SegmentedTableBaseTest, AllocateMultipleSegments) {
+ TestSegmentedTable table;
+ constexpr size_t kNumSegments = 4;
+ constexpr size_t kReservationSize =
+ kNumSegments * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+
+ std::vector<TestSegmentedTable::SegmentBase> segments;
+ for (size_t i = 0; i < kNumSegments; ++i) {
+ auto seg = table.TryAllocateSegment();
+ ASSERT_TRUE(seg.has_value());
+ segments.push_back(*seg);
+ }
+
+ std::set<uint32_t> numbers;
+ for (const auto& s : segments) {
+ EXPECT_TRUE(numbers.insert(s.number()).second);
+ Address addr = table.base() + s.offset();
+ WriteMemory(addr, static_cast<uint8_t>(s.number()));
+ }
+
+ for (const auto& s : segments) {
+ Address addr = table.base() + s.offset();
+ EXPECT_EQ(static_cast<uint8_t>(s.number()), ReadMemory(addr));
+ }
+
+#ifdef V8_TARGET_ARCH_64_BIT
+ // On 64-bit with a fixed contiguous subspace, the reservation is full.
+ EXPECT_FALSE(table.TryAllocateSegment().has_value());
+ // Free one segment and reallocate into the newly available slot.
+ table.FreeTableSegment(segments[0]);
+ auto new_seg = table.TryAllocateSegment();
+ ASSERT_TRUE(new_seg.has_value());
+ EXPECT_EQ(segments[0], *new_seg);
+ for (const auto& s : segments) {
+ table.FreeTableSegment(s);
+ }
+#else
+ for (const auto& s : segments) {
+ table.FreeTableSegment(s);
+ }
+#endif
+}
+
+#ifdef V8_TARGET_ARCH_64_BIT
+
+TEST(SegmentedTableBaseTest, ReadOnlySegments) {
+ TestSegmentedTable table;
+ constexpr size_t kNumReadOnlySegments = 2;
+ constexpr size_t kReadOnlySize =
+ kNumReadOnlySegments * TestSegmentedTable::kSegmentSize;
+ constexpr size_t kReservationSize = 6 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, kReadOnlySize, false);
+
+ EXPECT_EQ(0u, table.read_only_segments_used());
+
+ auto ro_seg0 = table.AllocateReadOnlySegment();
+ EXPECT_EQ(0u, ro_seg0.number());
+ EXPECT_EQ(0u, ro_seg0.offset());
+ EXPECT_EQ(1u, table.read_only_segments_used());
+
+ auto ro_seg1 = table.AllocateReadOnlySegment();
+ EXPECT_EQ(1u, ro_seg1.number());
+ EXPECT_EQ(TestSegmentedTable::kSegmentSize, ro_seg1.offset());
+ EXPECT_EQ(2u, table.read_only_segments_used());
+
+ EXPECT_EQ(2u, table.ResetReadOnlySegments());
+ EXPECT_EQ(0u, table.read_only_segments_used());
+
+ auto ro_seg_again = table.AllocateReadOnlySegment();
+ EXPECT_EQ(0u, ro_seg_again.number());
+ EXPECT_EQ(1u, table.read_only_segments_used());
+
+ // Regular segment allocation must not overlap with read-only segments.
+ auto normal_seg = table.TryAllocateSegment();
+ ASSERT_TRUE(normal_seg.has_value());
+ EXPECT_GE(normal_seg->number(), kNumReadOnlySegments);
+ EXPECT_GE(normal_seg->offset(), kReadOnlySize);
+ table.FreeTableSegment(*normal_seg);
+}
+
+TEST(SegmentedTableBaseTest, UnsealReadOnlySegmentsScope) {
+ TestSegmentedTable table;
+ constexpr size_t kNumReadOnlySegments = 2;
+ constexpr size_t kReadOnlySize =
+ kNumReadOnlySegments * TestSegmentedTable::kSegmentSize;
+ constexpr size_t kReservationSize = 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, kReadOnlySize, false);
+
+ auto ro_seg = table.AllocateReadOnlySegment();
+ Address ro_addr = table.base() + ro_seg.offset();
+
+ {
+ TestSegmentedTable::UnsealReadOnlySegmentScope scope(&table);
+ WriteMemory(ro_addr, 0x42);
+ WriteMemory(ro_addr + 100, 0x43);
+ EXPECT_EQ(0x42, ReadMemory(ro_addr));
+ EXPECT_EQ(0x43, ReadMemory(ro_addr + 100));
+ }
+
+ // After sealing, reads still return the previously written values.
+ EXPECT_EQ(0x42, ReadMemory(ro_addr));
+ EXPECT_EQ(0x43, ReadMemory(ro_addr + 100));
+}
+
+#endif // V8_TARGET_ARCH_64_BIT
+
+// Tests that accessing freed segment memory immediately crashes.
+// This is critical for sandbox security: freed table segments must be rendered
+// inaccessible (e.g. PROT_NONE), preventing use-after-free exploits.
+TEST(SegmentedTableBaseDeathTest, WriteToFreedSegmentCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ auto segment = table.TryAllocateSegment();
+ ASSERT_TRUE(segment.has_value());
+ Address addr = table.base() + segment->offset();
+ WriteMemory(addr, 0x42);
+ EXPECT_EQ(0x42, ReadMemory(addr));
+ table.FreeTableSegment(*segment);
+ WriteMemory(addr, 0x43);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest, ReadFromFreedSegmentCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ auto segment = table.TryAllocateSegment();
+ ASSERT_TRUE(segment.has_value());
+ Address addr = table.base() + segment->offset();
+ WriteMemory(addr, 0x42);
+ EXPECT_EQ(0x42, ReadMemory(addr));
+ table.FreeTableSegment(*segment);
+ ReadMemory(addr);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest, ReadFromFreedSegmentAtEndCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ auto segment = table.TryAllocateSegment();
+ ASSERT_TRUE(segment.has_value());
+ Address addr = table.base() + segment->offset() +
+ TestSegmentedTable::kSegmentSize - 1;
+ WriteMemory(addr, 0x42);
+ EXPECT_EQ(0x42, ReadMemory(addr));
+ table.FreeTableSegment(*segment);
+ ReadMemory(addr);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest, ReadFromFreedSegmentInMiddleCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ auto segment = table.TryAllocateSegment();
+ ASSERT_TRUE(segment.has_value());
+ Address addr = table.base() + segment->offset() +
+ TestSegmentedTable::kSegmentSize / 2;
+ WriteMemory(addr, 0x42);
+ EXPECT_EQ(0x42, ReadMemory(addr));
+ table.FreeTableSegment(*segment);
+ ReadMemory(addr);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest,
+ AccessFreedSegmentWithOtherActiveSegmentsCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ auto seg1 = table.TryAllocateSegment();
+ auto seg2 = table.TryAllocateSegment();
+ ASSERT_TRUE(seg1.has_value());
+ ASSERT_TRUE(seg2.has_value());
+ Address addr1 = table.base() + seg1->offset();
+ Address addr2 = table.base() + seg2->offset();
+ WriteMemory(addr1, 0x11);
+ WriteMemory(addr2, 0x22);
+ EXPECT_EQ(0x11, ReadMemory(addr1));
+ EXPECT_EQ(0x22, ReadMemory(addr2));
+
+ // Free seg1.
+ table.FreeTableSegment(*seg1);
+
+ // Accessing seg2 still works normally.
+ EXPECT_EQ(0x22, ReadMemory(addr2));
+ WriteMemory(addr2, 0x33);
+ EXPECT_EQ(0x33, ReadMemory(addr2));
+
+ // Accessing seg1 must crash.
+ ReadMemory(addr1);
+ },
+ "");
+}
+
+#ifdef V8_TARGET_ARCH_64_BIT
+
+TEST(SegmentedTableBaseDeathTest, AccessAfterTearDownCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ Address addr = kNullAddress;
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, 0, false);
+ auto seg = table.TryAllocateSegment();
+ ASSERT_TRUE(seg.has_value());
+ addr = table.base() + seg->offset();
+ WriteMemory(addr, 0x42);
+ table.TearDown();
+ }
+ ReadMemory(addr);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest, WriteToSealedReadOnlySegmentCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ constexpr size_t kReadOnlySize = 2 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, kReadOnlySize, false);
+ auto ro_seg = table.AllocateReadOnlySegment();
+ Address ro_addr = table.base() + ro_seg.offset();
+ // Read is allowed on sealed segment.
+ ReadMemory(ro_addr);
+ // Write to sealed segment must crash.
+ WriteMemory(ro_addr, 0x42);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest, WriteAfterUnsealScopeExitCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ constexpr size_t kReadOnlySize = 2 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, kReadOnlySize, false);
+ auto ro_seg = table.AllocateReadOnlySegment();
+ Address ro_addr = table.base() + ro_seg.offset();
+ {
+ TestSegmentedTable::UnsealReadOnlySegmentScope unseal_scope(&table);
+ WriteMemory(ro_addr, 0x55);
+ EXPECT_EQ(0x55, ReadMemory(ro_addr));
+ }
+ // After scope exit, reading still works.
+ EXPECT_EQ(0x55, ReadMemory(ro_addr));
+ // But writing now must crash.
+ WriteMemory(ro_addr, 0x66);
+ },
+ "");
+}
+
+TEST(SegmentedTableBaseDeathTest, AllocateReadOnlySegmentBeyondLimitCrashes) {
+ EXPECT_DEATH_IF_SUPPORTED(
+ {
+ TestSegmentedTable table;
+ constexpr size_t kReservationSize =
+ 4 * TestSegmentedTable::kSegmentSize;
+ constexpr size_t kReadOnlySize = 1 * TestSegmentedTable::kSegmentSize;
+ table.Initialize(kReservationSize, kReadOnlySize, false);
+ table.AllocateReadOnlySegment();
+ // Second allocation exceeds kReadOnlySize (1 segment), must crash.
+ table.AllocateReadOnlySegment();
+ },
+ "");
+}
+
+#endif // V8_TARGET_ARCH_64_BIT
+
+} // namespace v8::internal
diff --git a/deps/v8/test/unittests/test-utils.h b/deps/v8/test/unittests/test-utils.h
index 71479cf5eba..57cef05a3cb 100644
--- a/deps/v8/test/unittests/test-utils.h
+++ b/deps/v8/test/unittests/test-utils.h
@@ -440,10 +440,20 @@ class WithInternalIsolateMixin : public TMixin {
return Cast<T>(RunJSInternal(source));
}
+ template <typename T = Object>
+ Handle<T> RunJS(v8::Local<v8::Context> context, const char* source) {
+ return Cast<T>(RunJSInternal(context, source));
+ }
+
Handle<Object> RunJSInternal(const char* source) {
return Utils::OpenHandle(*TMixin::RunJS(source));
}
+ Handle<Object> RunJSInternal(v8::Local<v8::Context> context,
+ const char* source) {
+ return Utils::OpenHandle(*TMixin::RunJS(context, source));
+ }
+
template <typename T = Object>
DirectHandle<T> RunJS(::v8::String::ExternalOneByteStringResource* source) {
return Cast<T>(RunJSInternal(source));
diff --git a/deps/v8/test/unittests/unittests.status b/deps/v8/test/unittests/unittests.status
index bddc81b9b48..f32d348d3fe 100644
--- a/deps/v8/test/unittests/unittests.status
+++ b/deps/v8/test/unittests/unittests.status
@@ -44,6 +44,16 @@
# Those smoke tests fail nondeterministically to test fuzzer infrastructure.
# We cannot run them in unittest mode as they would produce flakes.
'SmokeTest.*': [SKIP],
+
+ ##############################################################################
+ # Behavioural differences between Maglev and Turbofan when the former is used
+ # for OptimizeFunctionOnNextCall.
+ #
+ # Maglev doesn't support compiler::NodeObserver machinery.
+ 'SloppyEqualityTest.SloppyEqualityTest': [SKIP],
+ # RunDeoptTest checks frame->is_turbofan().
+ 'RunDeoptTest.DeoptSimple': [SKIP],
+ 'RunDeoptTest.DeoptSimpleInExpr': [SKIP],
}], # ALWAYS
##############################################################################
@@ -340,14 +350,6 @@
'Torque.Enums': [FAIL],
}], # 'official_build'
-##############################################################################
-# Behavioural differences between Maglev and Turbofan when the former is used
-# for OptimizeFunctionOnNextCall.
-['variant in (stress_maglev, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan)', {
- # Maglev doesn't support compiler::NodeObserver machinery.
- 'SloppyEqualityTest.SloppyEqualityTest': [FAIL],
-}], # variant in (stress_maglev, stress_maglev_non_eager_inlining, stress_maglev_future, stress_maglev_no_turbofan, maglev_no_turbofan)
-
##############################################################################
['system == windows', {
# Bug: crbug.com/v8/14320
diff --git a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc
index 7bf2dc3d126..94ab2eaf96c 100644
--- a/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc
+++ b/deps/v8/test/unittests/wasm/function-body-decoder-unittest.cc
@@ -5432,6 +5432,9 @@ TEST_F(WasmOpcodeLengthTest, Atomics) {
// kExprAtomicNotify: prefix + opcode + align + offset.
ExpectLength(4, kAtomicPrefix, kExprAtomicNotify & 0xFF, 0x02, 0x00);
+
+ // kExprPublish: prefix + opcode.
+ ExpectLength(2, kAtomicPrefix, static_cast<uint8_t>(kExprPublish));
}
class TypeReaderTest : public TestWithZone {
@@ -7206,6 +7209,146 @@ TEST_F(FunctionBodyDecoderTest, Waitqueue) {
kAppendEnd, "Invalid types for ref.test null");
}
+template <typename Subclass,
+ typename ValidationTag = Decoder::FullValidationTag>
+class EmptyInterfaceBase {
+ public:
+ static constexpr DecodingMode decoding_mode = kFunctionBody;
+ static constexpr bool kUsesPoppedArgs = false;
+ using Value = ValueBase<ValidationTag>;
+ using Control = ControlBase<Value, ValidationTag>;
+ using FullDecoder = WasmFullDecoder<ValidationTag, Subclass>;
+
+#define DEFINE_EMPTY_CALLBACK(name, ...) \
+ void name(FullDecoder* decoder, ##__VA_ARGS__) {}
+ INTERFACE_FUNCTIONS(DEFINE_EMPTY_CALLBACK)
+#undef DEFINE_EMPTY_CALLBACK
+};
+
+class PublishTrackingInterface
+ : public EmptyInterfaceBase<PublishTrackingInterface> {
+ public:
+ bool publish_called = false;
+ void Publish(FullDecoder* decoder, const Value& value) {
+ publish_called = true;
+ }
+};
+
+TEST_F(FunctionBodyDecoderTest, Publish) {
+ ValueType any_shared =
+ ValueType::Generic(GenericKind::kAny, kNonNullable, SharedFlag{true});
+ ValueType any_shared_params[] = {any_shared};
+ FunctionSig any_shared_sig(0, 1, any_shared_params);
+
+ // 0. Decoding fails without --wasm-shared.
+ ExpectFailure(&any_shared_sig,
+ {WASM_LOCAL_GET(0), kAtomicPrefix,
+ static_cast<uint8_t>(kExprPublish), WASM_DROP},
+ kAppendEnd, "enable with --wasm-shared");
+
+ WASM_FEATURE_SCOPE(shared);
+
+ // Non-reference types (e.g. i32) fail validation.
+ ExpectFailure(sigs.v_i(),
+ {WASM_LOCAL_GET(0), kAtomicPrefix,
+ static_cast<uint8_t>(kExprPublish), WASM_DROP},
+ kAppendEnd, "expected reference type");
+
+ // Empty stack fails validation.
+ ExpectFailure(sigs.v_v(), {kAtomicPrefix, static_cast<uint8_t>(kExprPublish)},
+ kAppendEnd, "not enough arguments on the stack for publish");
+
+ auto ExpectPublish = [&](const FunctionSig* sig,
+ std::initializer_list<const uint8_t> raw_code) {
+ base::Vector<const uint8_t> code =
+ PrepareBytecode(CodeToVector(raw_code), kAppendEnd);
+ FunctionBody body(sig, 0, code.begin(), code.end());
+ WasmDetectedFeatures detected_features;
+ WasmFullDecoder<Decoder::FullValidationTag, PublishTrackingInterface>
+ decoder(this->zone(), module, enabled_features_, &detected_features,
+ body);
+ decoder.Decode();
+ EXPECT_TRUE(decoder.ok());
+ return decoder.interface().publish_called;
+ };
+
+ auto TestPublish = [&](ValueType type) {
+ ValueType params[] = {type};
+ FunctionSig sig(0, 1, params);
+ return ExpectPublish(&sig, {WASM_LOCAL_GET(0), kAtomicPrefix,
+ static_cast<uint8_t>(kExprPublish), WASM_DROP});
+ };
+
+ // 1. Indexed types: struct, array, func
+ HeapType shared_struct =
+ builder.AddStruct({{kWasmI32, true}}, kNoSuperType, SharedFlag{true});
+ HeapType unshared_struct =
+ builder.AddStruct({{kWasmI32, true}}, kNoSuperType, SharedFlag{false});
+ HeapType shared_array = builder.AddArray(kWasmI32, true, SharedFlag{true});
+ HeapType unshared_array = builder.AddArray(kWasmI32, true, SharedFlag{false});
+ HeapType unshared_func = FuncHeapType(builder.AddSignature(sigs.v_v()));
+
+ // Publish is only emitted for shared references that can possibly be structs
+ // or arrays.
+ EXPECT_TRUE(TestPublish(ValueType::Ref(shared_struct)));
+ EXPECT_FALSE(TestPublish(ValueType::Ref(unshared_struct)));
+
+ EXPECT_TRUE(TestPublish(ValueType::Ref(shared_array)));
+ EXPECT_FALSE(TestPublish(ValueType::Ref(unshared_array)));
+
+ EXPECT_FALSE(TestPublish(ValueType::Ref(unshared_func)));
+
+ // Nullable types accepted.
+ EXPECT_TRUE(TestPublish(ValueType::RefNull(shared_struct)));
+
+ // any
+ EXPECT_TRUE(TestPublish(
+ ValueType::Generic(GenericKind::kAny, kNonNullable, SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(
+ ValueType::Generic(GenericKind::kAny, kNonNullable, SharedFlag{false})));
+
+ // eq
+ EXPECT_TRUE(TestPublish(
+ ValueType::Generic(GenericKind::kEq, kNonNullable, SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(
+ ValueType::Generic(GenericKind::kEq, kNonNullable, SharedFlag{false})));
+
+ // struct
+ EXPECT_TRUE(TestPublish(ValueType::Generic(GenericKind::kStruct, kNonNullable,
+ SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(ValueType::Generic(
+ GenericKind::kStruct, kNonNullable, SharedFlag{false})));
+
+ // array
+ EXPECT_TRUE(TestPublish(
+ ValueType::Generic(GenericKind::kArray, kNonNullable, SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(ValueType::Generic(GenericKind::kArray, kNonNullable,
+ SharedFlag{false})));
+
+ // i31 (publish is a no-op)
+ EXPECT_FALSE(TestPublish(
+ ValueType::Generic(GenericKind::kI31, kNonNullable, SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(
+ ValueType::Generic(GenericKind::kI31, kNonNullable, SharedFlag{false})));
+
+ // none (publish is a no-op)
+ EXPECT_FALSE(TestPublish(
+ ValueType::Generic(GenericKind::kNone, kNonNullable, SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(
+ ValueType::Generic(GenericKind::kNone, kNonNullable, SharedFlag{false})));
+
+ // extern (publish is a no-op)
+ EXPECT_FALSE(TestPublish(ValueType::Generic(GenericKind::kExtern,
+ kNonNullable, SharedFlag{true})));
+ EXPECT_FALSE(TestPublish(ValueType::Generic(
+ GenericKind::kExtern, kNonNullable, SharedFlag{false})));
+
+ // Bottom type from unreachable does not require a publish.
+ EXPECT_FALSE(ExpectPublish(sigs.v_v(),
+ {kExprUnreachable, kAtomicPrefix,
+ static_cast<uint8_t>(kExprPublish), WASM_DROP}));
+}
+
#undef B1
#undef B2
#undef B3
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 d6f7f3b57b8..971819a5132 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
@@ -25,13 +25,14 @@ struct FuzzExtMulPairwiseOp {
};
struct FuzzExtMulPairwiseTree {
- WasmOpcode add_opcode;
FuzzExtMulPairwiseOp left_branch;
FuzzExtMulPairwiseOp right_branch;
WasmOpcode final_binop_opcode;
uint8_t final_rhs_local;
+ // Add a side user of the root add by feeding it into another SIMD binop.
bool use_root_add_again;
WasmOpcode root_add_reuse_binop_opcode;
+ bool suppress_final_binop;
};
#if V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
@@ -41,9 +42,7 @@ struct AVXSupport {
if (!allow) CpuFeatures::SetUnsupported(AVX);
}
~AVXSupport() {
- if (previous_) {
- CpuFeatures::SetSupported(AVX);
- }
+ if (previous_) CpuFeatures::SetSupported(AVX);
}
};
#endif // V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64
@@ -353,16 +352,18 @@ class SimdCrossCompilerDeterminismTest
CommonWasmRunner<void> runner(isolate(), tier);
Simd128* memory = runner.builder().AddMemoryElems<Simd128>(4);
- uint8_t locals_start = runner.AllocateLocals(5, kWasmS128);
+ uint8_t locals_start = runner.AllocateLocals(7, kWasmS128);
auto locals_idx = [locals_start](uint8_t offset) -> uint8_t {
return static_cast<uint8_t>(locals_start + offset);
};
+ uint8_t iteration = runner.AllocateLocal(kWasmI32);
// Build the bytecode.
// Note: `kMaxBytecodeSize` is big enough to hold all bytes we generate
// below across all configuration. If the DCHECK below fails, increase it as
// necessary.
- constexpr size_t kMaxBytecodeSize = 150 + 19 * kMaxPreconsumedLiftoffRegs;
+ constexpr size_t kMaxBytecodeSize = 250 + 19 * kMaxPreconsumedLiftoffRegs;
+ constexpr uint8_t kLoopIterations = 4;
base::SmallVector<uint8_t, kMaxBytecodeSize> bytecode;
// Preconsume some registers.
@@ -386,39 +387,84 @@ class SimdCrossCompilerDeterminismTest
Config::template GetInput<3>(memory, inputs[3]));
bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(3)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_CONSTANT(Simd128{}.bytes())});
+ bytecode.insert(bytecode.end(), {kExprLocalSet, locals_idx(4)});
+ bytecode.insert(bytecode.end(), {WASM_ZERO});
+ bytecode.insert(bytecode.end(), {kExprLocalSet, iteration});
+
// Push the memory index for the final store.
bytecode.insert(bytecode.end(), {WASM_ZERO});
+ bytecode.insert(
+ bytecode.end(),
+ {kExprBlock, static_cast<uint8_t>((kWasmS128).value_type_code()),
+ kExprLoop, kVoidCode});
+
// The extmul opcodes, their inputs, and extadd_pairwise opcode are fuzzed.
- auto emit_extmul_pairwise = [&](FuzzExtMulPairwiseOp op) {
+ auto emit_extmul_pairwise = [&](FuzzExtMulPairwiseOp op,
+ uint8_t local_offset = 0) {
+ auto shifted_local = [local_offset](uint8_t local) {
+ return static_cast<uint8_t>((local + local_offset) % 4);
+ };
bytecode.insert(bytecode.end(),
- {kExprLocalGet, locals_idx(op.local_lhs)});
+ {kExprLocalGet, locals_idx(shifted_local(op.local_lhs))});
bytecode.insert(bytecode.end(),
- {kExprLocalGet, locals_idx(op.local_rhs)});
+ {kExprLocalGet, locals_idx(shifted_local(op.local_rhs))});
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(op.extmul_opcode)});
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(op.pairwise_opcode)});
};
- emit_extmul_pairwise(tree.left_branch);
- emit_extmul_pairwise(tree.right_branch);
-
- // We also fuzz the root add.
- bytecode.insert(bytecode.end(), {WASM_SIMD_OP(tree.add_opcode)});
+ auto emit_extmul_pairwise_tree = [&](bool use_root_add_again,
+ uint8_t local_offset = 0) {
+ emit_extmul_pairwise(tree.left_branch, local_offset);
+ emit_extmul_pairwise(tree.right_branch, local_offset);
+
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4Add)});
+
+ if (!tree.suppress_final_binop) {
+ // Sometimes we insert an extra user of the add, so keep it in a local.
+ if (use_root_add_again) {
+ bytecode.insert(bytecode.end(), {kExprLocalTee, locals_idx(5)});
+ }
+ bytecode.insert(bytecode.end(),
+ {kExprLocalGet, locals_idx(tree.final_rhs_local)});
+ bytecode.insert(bytecode.end(),
+ {WASM_SIMD_OP(tree.final_binop_opcode)});
+
+ // The extra user of the add.
+ if (use_root_add_again) {
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(5)});
+ bytecode.insert(bytecode.end(),
+ {WASM_SIMD_OP(tree.root_add_reuse_binop_opcode)});
+ }
+ }
+ };
- // Sometimes we insert an extra user of the add, so keep it in a local.
- if (tree.use_root_add_again) {
- bytecode.insert(bytecode.end(), {kExprLocalTee, locals_idx(4)});
- }
- bytecode.insert(bytecode.end(),
- {kExprLocalGet, locals_idx(tree.final_rhs_local)});
- bytecode.insert(bytecode.end(), {WASM_SIMD_OP(tree.final_binop_opcode)});
-
- // The extra user of the add.
- if (tree.use_root_add_again) {
- bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(4)});
- bytecode.insert(bytecode.end(),
- {WASM_SIMD_OP(tree.root_add_reuse_binop_opcode)});
- }
+ // For the first pairwise add, never add an extra user so it's always
+ // chained with the second, only with an add, for a multiply-accumulate.
+ emit_extmul_pairwise_tree(false);
+ emit_extmul_pairwise_tree(tree.use_root_add_again, 2);
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4Add)});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(4)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4Add)});
+ bytecode.insert(bytecode.end(), {kExprLocalTee, locals_idx(4)});
+ bytecode.insert(
+ bytecode.end(),
+ {kExprLocalGet, iteration, WASM_ONE, kExprI32Add, kExprLocalTee,
+ iteration, WASM_I32V_1(kLoopIterations), kExprI32Eq, kExprBrIf, 1,
+ kExprDrop, kExprBr, 0, kExprEnd, kExprUnreachable, kExprEnd});
+
+ // Horizontally add the lanes.
+ bytecode.insert(bytecode.end(), {kExprLocalTee, locals_idx(6)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4ExtractLane), 0});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(6)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4ExtractLane), 1});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(6)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4ExtractLane), 2});
+ bytecode.insert(bytecode.end(), {kExprLocalGet, locals_idx(6)});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4ExtractLane), 3});
+ bytecode.insert(bytecode.end(), {kExprI32Add, kExprI32Add, kExprI32Add});
+ bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprI32x4Splat)});
// Store the result in memory.
bytecode.insert(bytecode.end(), {WASM_SIMD_OP(kExprS128StoreMem),
@@ -515,7 +561,9 @@ constexpr std::array kSkippedTernOps = {kExprF16x8Qfma, kExprF16x8Qfms};
// fp16 instructions in `kTernOps`.
#define IS_EXPERIMENTAL_FP16(name, ...) \
+(std::string_view(#name) == "fp16" ? 1 : 0)
-static_assert(FOREACH_WASM_EXPERIMENTAL_FEATURE_FLAG(IS_EXPERIMENTAL_FP16) == 1,
+static_assert(FOREACH_EXPERIMENTAL_FEATURE_FLAG(IGNORE_NON_WASM_FEATURE,
+ IS_EXPERIMENTAL_FP16,
+ IGNORE_NON_WASM_FEATURE) == 1,
"move fp16 instructions to kTernOps before shipping fp16");
#undef IS_EXPERIMENTAL_FP16
@@ -604,32 +652,58 @@ void SimdCrossCompilerDeterminismTest::TestExtMulPairwiseTree(
<< PrintCollection(base::VectorOf(results));
}
+constexpr FuzzExtMulPairwiseTree kDotI8x16AddReduceTree = {
+ {kExprI16x8ExtMulLowI8x16S, kExprI32x4ExtAddPairwiseI16x8S, 0, 1},
+ {kExprI16x8ExtMulHighI8x16S, kExprI32x4ExtAddPairwiseI16x8S, 0, 1},
+ kExprI32x4Add,
+ 2,
+ false,
+ kExprI32x4Add,
+ true};
+
+constexpr FuzzExtMulPairwiseTree kDotI8x16AddReduceTreeWithSideUser = {
+ {kExprI16x8ExtMulLowI8x16S, kExprI32x4ExtAddPairwiseI16x8S, 0, 1},
+ {kExprI16x8ExtMulHighI8x16S, kExprI32x4ExtAddPairwiseI16x8S, 0, 1},
+ kExprI32x4Add,
+ 2,
+ true,
+ kExprI32x4Add,
+ false};
+
inline fuzztest::Domain<FuzzExtMulPairwiseTree> ExtMulPairwiseTree() {
+ // ExtMul opcodes cover both input widths, signedness variants, and low/high
+ // halves. Pairing these independently with the pairwise-add opcodes below
+ // lets the fuzzer exercise a broad set of wasm SIMD shapes.
constexpr std::array kExtMulOps = {
kExprI16x8ExtMulLowI8x16S, kExprI16x8ExtMulHighI8x16S,
kExprI16x8ExtMulLowI8x16U, kExprI16x8ExtMulHighI8x16U,
kExprI32x4ExtMulLowI16x8S, kExprI32x4ExtMulHighI16x8S,
kExprI32x4ExtMulLowI16x8U, kExprI32x4ExtMulHighI16x8U};
+ // Pairwise-add opcodes are generated separately from extmul opcodes because
+ // this test is interested in compiler determinism across many SIMD trees, not
+ // only the hand-written dot-product-shaped trees below.
constexpr std::array kExtAddPairwiseOps = {
kExprI16x8ExtAddPairwiseI8x16S, kExprI16x8ExtAddPairwiseI8x16U,
kExprI32x4ExtAddPairwiseI16x8S, kExprI32x4ExtAddPairwiseI16x8U};
- constexpr std::array kExtMulPairwiseRootAddOps = {
- kExprI16x8Add, kExprI32x4Add, kExprI64x2Add};
-
+ // After the two extmul/pairwise branches are added together, optionally feed
+ // that root through another SIMD binop. All selected opcodes have s128 inputs
+ // and s128 results, so they fit the same generated bytecode shape.
constexpr std::array kExtMulPairwiseFinalBinOps = {
kExprS128And, kExprS128Or, kExprS128Xor, kExprI8x16Add,
kExprI8x16Sub, kExprI16x8Add, kExprI16x8Sub, kExprI32x4Add,
kExprI32x4Sub, kExprI64x2Add, kExprI64x2Sub};
- return fuzztest::Map(
- [](WasmOpcode add_opcode, WasmOpcode left_extmul_opcode,
- WasmOpcode left_pairwise_opcode, uint8_t left_lhs, uint8_t left_rhs,
- WasmOpcode right_extmul_opcode, WasmOpcode right_pairwise_opcode,
- uint8_t right_lhs, uint8_t right_rhs, WasmOpcode final_binop_opcode,
- uint8_t final_rhs_local, bool use_root_add_again,
- WasmOpcode root_add_reuse_binop_opcode) {
+ // Model a tree as simple scalar choices so fuzztest can mutate and shrink
+ // each opcode, input-local index, and optional side user independently.
+ auto random_tree = fuzztest::Map(
+ [](WasmOpcode left_extmul_opcode, WasmOpcode left_pairwise_opcode,
+ uint8_t left_lhs, uint8_t left_rhs, WasmOpcode right_extmul_opcode,
+ WasmOpcode right_pairwise_opcode, uint8_t right_lhs, uint8_t right_rhs,
+ WasmOpcode final_binop_opcode, uint8_t final_rhs_local,
+ bool use_root_add_again, WasmOpcode root_add_reuse_binop_opcode,
+ bool suppress_final_binop) {
auto make_branch = [](WasmOpcode extmul_opcode,
WasmOpcode pairwise_opcode, uint8_t local_lhs,
uint8_t local_rhs) {
@@ -637,7 +711,6 @@ inline fuzztest::Domain<FuzzExtMulPairwiseTree> ExtMulPairwiseTree() {
local_rhs};
};
return FuzzExtMulPairwiseTree{
- add_opcode,
make_branch(left_extmul_opcode, left_pairwise_opcode, left_lhs,
left_rhs),
make_branch(right_extmul_opcode, right_pairwise_opcode, right_lhs,
@@ -645,18 +718,29 @@ inline fuzztest::Domain<FuzzExtMulPairwiseTree> ExtMulPairwiseTree() {
final_binop_opcode,
final_rhs_local,
use_root_add_again,
- root_add_reuse_binop_opcode};
+ root_add_reuse_binop_opcode,
+ suppress_final_binop};
},
- fuzztest::ElementOf<WasmOpcode>(kExtMulPairwiseRootAddOps),
fuzztest::ElementOf<WasmOpcode>(kExtMulOps),
fuzztest::ElementOf<WasmOpcode>(kExtAddPairwiseOps),
+ // Branch inputs refer to the four initial s128 locals loaded from the
+ // fuzzed Simd128 inputs.
fuzztest::InRange<uint8_t>(0, 3), fuzztest::InRange<uint8_t>(0, 3),
fuzztest::ElementOf<WasmOpcode>(kExtMulOps),
fuzztest::ElementOf<WasmOpcode>(kExtAddPairwiseOps),
fuzztest::InRange<uint8_t>(0, 3), fuzztest::InRange<uint8_t>(0, 3),
fuzztest::ElementOf<WasmOpcode>(kExtMulPairwiseFinalBinOps),
+ // When the optional final binop is emitted, its RHS is another one of
+ // the four original s128 input locals.
fuzztest::InRange<uint8_t>(0, 3), fuzztest::Arbitrary<bool>(),
- fuzztest::ElementOf<WasmOpcode>(kExtMulPairwiseFinalBinOps));
+ fuzztest::ElementOf<WasmOpcode>(kExtMulPairwiseFinalBinOps),
+ fuzztest::Arbitrary<bool>());
+
+ // Always include focused dot-product-shaped trees in addition to the fully
+ // random tree so shrinking can land on known interesting patterns.
+ return fuzztest::OneOf(fuzztest::Just(kDotI8x16AddReduceTree),
+ fuzztest::Just(kDotI8x16AddReduceTreeWithSideUser),
+ random_tree);
}
V8_FUZZ_TEST_F(SimdCrossCompilerDeterminismTest, TestExtMulPairwiseTree)
diff --git a/deps/v8/test/unittests/wasm/wasm-interpreter-thread-unittest.cc b/deps/v8/test/unittests/wasm/wasm-interpreter-thread-unittest.cc
new file mode 100644
index 00000000000..ee53f22b74d
--- /dev/null
+++ b/deps/v8/test/unittests/wasm/wasm-interpreter-thread-unittest.cc
@@ -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.
+
+#ifdef V8_ENABLE_DRUMBRAKE
+
+#include "src/wasm/interpreter/wasm-interpreter.h"
+#include "test/unittests/test-utils.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace v8::internal::wasm {
+
+using WasmInterpreterThreadMapTest = TestWithIsolate;
+
+TEST_F(WasmInterpreterThreadMapTest, PerIsolateThread) {
+ Isolate* isolate_a = isolate();
+
+ IsolateWrapper wrapper_b(kNoCounters, false);
+ Isolate* isolate_b = wrapper_b.i_isolate();
+
+ WasmInterpreterThreadMap map;
+
+ WasmInterpreterThread* thread_a = map.GetCurrentInterpreterThread(isolate_a);
+ ASSERT_NE(nullptr, thread_a);
+ EXPECT_EQ(isolate_a, thread_a->GetIsolate());
+
+ WasmInterpreterThread* thread_b;
+ {
+ v8::Isolate::Scope scope_b(wrapper_b.isolate());
+ thread_b = map.GetCurrentInterpreterThread(isolate_b);
+ ASSERT_NE(nullptr, thread_b);
+ EXPECT_EQ(isolate_b, thread_b->GetIsolate());
+ EXPECT_NE(thread_a, thread_b);
+ }
+
+ EXPECT_EQ(thread_a, map.GetCurrentInterpreterThread(isolate_a));
+
+ // Removing entries for one isolate must not affect entries owned by another
+ // isolate on the same OS thread.
+ map.NotifyIsolateDisposal(isolate_a);
+ {
+ v8::Isolate::Scope scope_b(wrapper_b.isolate());
+ EXPECT_EQ(thread_b, map.GetCurrentInterpreterThread(isolate_b));
+ map.NotifyIsolateDisposal(isolate_b);
+ }
+}
+
+} // namespace v8::internal::wasm
+
+#endif // V8_ENABLE_DRUMBRAKE
diff --git a/deps/v8/test/unittests/wasm/wasm-tracing-unittest.cc b/deps/v8/test/unittests/wasm/wasm-tracing-unittest.cc
index 150783b659d..f88e6eab4dc 100644
--- a/deps/v8/test/unittests/wasm/wasm-tracing-unittest.cc
+++ b/deps/v8/test/unittests/wasm/wasm-tracing-unittest.cc
@@ -77,7 +77,7 @@ class WasmTracingTest : public TestWithContextAndZone {
WasmTracesForTesting& traces = GetWasmTracesForTesting();
traces.should_store_trace = true;
- std::optional<Managed<NativeModule>::Ptr> native_module;
+ std::optional<CppGCManaged<NativeModule>::Ptr> native_module;
CompileAndRun(sigs_.v_v(), code_a, &native_module);
MemoryTrace memory_trace_a = std::move(traces.memory_trace);
@@ -113,7 +113,7 @@ class WasmTracingTest : public TestWithContextAndZone {
private:
DirectHandle<WasmInstanceObject> CompileAndRun(
const FunctionSig* sig, base::Vector<const uint8_t> code,
- std::optional<Managed<NativeModule>::Ptr>* native_module) {
+ std::optional<CppGCManaged<NativeModule>::Ptr>* native_module) {
WasmModuleBuilder builder(zone());
builder.AddMemory(1);
diff --git a/deps/v8/test/unittests/wasm/wasm-usecounters.cc b/deps/v8/test/unittests/wasm/wasm-usecounters.cc
index 3e56f36d7f0..afc750ac72b 100644
--- a/deps/v8/test/unittests/wasm/wasm-usecounters.cc
+++ b/deps/v8/test/unittests/wasm/wasm-usecounters.cc
@@ -8,6 +8,7 @@
#include "src/base/logging.h"
#include "src/wasm/wasm-module-builder.h"
#include "test/common/wasm/test-signatures.h"
+#include "test/common/wasm/wasm-macro-gen.h"
#include "test/unittests/test-utils.h"
#include "test/unittests/wasm/wasm-compile-module.h"
#include "testing/gmock/include/gmock/gmock.h"
@@ -32,7 +33,12 @@ class WasmUseCounterTest
}
void AddFunction(std::initializer_list<const uint8_t> body) {
- WasmFunctionBuilder* f = builder_.AddFunction(sigs_.v_i());
+ AddFunction(sigs_.v_i(), body);
+ }
+
+ void AddFunction(const FunctionSig* sig,
+ std::initializer_list<const uint8_t> body) {
+ WasmFunctionBuilder* f = builder_.AddFunction(sig);
f->EmitCode(body);
builder_.WriteTo(&buffer_);
}
@@ -120,4 +126,34 @@ TEST_P(WasmUseCounterTest, Memory64AndRefTypes) {
{UC::kWasmRefTypes, 1}});
}
+TEST_P(WasmUseCounterTest, RefTest) {
+ StructType::Builder<Zone> type_builder(zone(), 1, false, SharedFlag{false});
+ type_builder.AddField(kWasmI32, true);
+ ModuleTypeIndex type_idx =
+ builder().AddStructType(type_builder.Build(), true);
+ ValueType reps[] = {kWasmI32, kWasmAnyRef};
+ FunctionSig sig(1, 1, reps);
+ AddFunction(&sig,
+ {WASM_REF_TEST(WASM_LOCAL_GET(0), type_idx.index), kExprEnd});
+ Compile();
+ CheckUseCounters({{UC::kWasmModuleCompilation, 1}, {UC::kWasmGC, 1}});
+}
+
+TEST_P(WasmUseCounterTest, StructNew) {
+ StructType::Builder<Zone> type_builder(zone(), 1, false, SharedFlag{false});
+ type_builder.AddField(kWasmI32, true);
+ ModuleTypeIndex type_idx =
+ builder().AddStructType(type_builder.Build(), true);
+ HeapType struct_heap_type =
+ HeapType::Index(type_idx, SharedFlag{false}, RefTypeKind::kStruct);
+ ValueType struct_ref = ValueType::Ref(struct_heap_type);
+ ValueType reps[] = {struct_ref};
+ FunctionSig sig(1, 0, reps);
+ AddFunction(&sig, {WASM_STRUCT_NEW(type_idx.index, WASM_I32V(42)), kExprEnd});
+ Compile();
+ CheckUseCounters({{UC::kWasmModuleCompilation, 1},
+ {UC::kWasmGC, 1},
+ {UC::kWasmGCAllocation, 1}});
+}
+
} // namespace v8::internal::wasm
diff --git a/deps/v8/test/wasm-js/tests.tar.gz.sha1 b/deps/v8/test/wasm-js/tests.tar.gz.sha1
index 350fb699b5b..bc8f415216f 100644
--- a/deps/v8/test/wasm-js/tests.tar.gz.sha1
+++ b/deps/v8/test/wasm-js/tests.tar.gz.sha1
@@ -1 +1 @@
-230c4981039b9904e80891e011008b0646b5f308
\ No newline at end of file
+fc011ee3621621398d2b89a962174055bb81038c
\ No newline at end of file
diff --git a/deps/v8/test/wasm-js/wasm-js.status b/deps/v8/test/wasm-js/wasm-js.status
index 25c80e62ef6..82c06ee8bc4 100644
--- a/deps/v8/test/wasm-js/wasm-js.status
+++ b/deps/v8/test/wasm-js/wasm-js.status
@@ -29,11 +29,6 @@
'proposals/threads/memory/wait-notify-unshared': [FAIL],
'limits': [FAIL, HEAVY],
- # TODO(thibaudm): Test failing after the type-reflection change around
- # WebAssembly.Function.type. The tests should be updated anyway since they
- # still use the old API (which works but is deprecated).
- 'proposals/js-promise-integration/js-promise-integration/js-promise-integration': [FAIL],
-
# TODO(402340845): This requires the type reflection proposal to be staged or enabled by default.
'wpt/function/call.tentative': [FAIL],
'wpt/function/table.tentative': [FAIL],
diff --git a/deps/v8/test/wasm-spec-tests/testcfg.py b/deps/v8/test/wasm-spec-tests/testcfg.py
index c905fb8db30..e9e4955c9ae 100644
--- a/deps/v8/test/wasm-spec-tests/testcfg.py
+++ b/deps/v8/test/wasm-spec-tests/testcfg.py
@@ -9,37 +9,52 @@ from testrunner.objects import testcase
# that were merged into that branch.
default_flags = []
-proposal_flags = [{
- 'name': 'tail-call',
- 'flags': []
-}, {
- 'name': 'memory64',
- 'flags': []
-}, {
- 'name': 'extended-const',
- 'flags': []
-}, {
- 'name': 'function-references',
- 'flags': []
-}, {
- 'name': 'gc',
- 'flags': []
-}, {
- 'name': 'multi-memory',
- 'flags': []
-}, {
- 'name': 'exception-handling',
- 'flags': []
-}, {
- 'name': 'js-promise-integration',
- 'flags': []
-}, {
- 'name': 'stack-switching',
- 'flags': ['--wasm-wasmfx']
-}, {
- 'name': 'custom-descriptors',
- 'flags': ['--wasm-custom-descriptors']
-}]
+proposal_flags = [
+ {
+ 'name': 'tail-call',
+ 'flags': []
+ },
+ {
+ 'name': 'memory64',
+ 'flags': []
+ },
+ {
+ 'name': 'extended-const',
+ 'flags': []
+ },
+ {
+ 'name': 'function-references',
+ 'flags': []
+ },
+ {
+ 'name': 'gc',
+ 'flags': []
+ },
+ {
+ 'name': 'multi-memory',
+ 'flags': []
+ },
+ {
+ 'name': 'exception-handling',
+ 'flags': []
+ },
+ {
+ 'name': 'js-promise-integration',
+ 'flags': []
+ },
+ {
+ 'name': 'stack-switching',
+ 'flags': ['--wasm-wasmfx']
+ },
+ {
+ 'name': 'custom-descriptors',
+ 'flags': ['--wasm-custom-descriptors']
+ },
+ {
+ 'name': 'wide-arithmetic',
+ 'flags': ['--wasm-wide-arithmetic']
+ },
+]
class TestLoader(testsuite.JSTestLoader):
diff --git a/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1 b/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1
index ec8cc4c81c7..6cf1524a033 100644
--- a/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1
+++ b/deps/v8/test/wasm-spec-tests/tests.tar.gz.sha1
@@ -1 +1 @@
-82ca8a260af7149a8ab7f1fb24f65302055d64cb
\ No newline at end of file
+e331c94cae0b3b414cc66ce613061e63126795e4
\ No newline at end of file
diff --git a/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status b/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status
index c94cf0b4dae..83bb9ad5e1c 100644
--- a/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status
+++ b/deps/v8/test/wasm-spec-tests/wasm-spec-tests.status
@@ -16,6 +16,13 @@
'memory64/memory64': [FAIL],
'memory64/table64': [FAIL],
'table': [FAIL],
+
+ # Temporarily disable custom descriptors tests while we update the spec to
+ # disallow "L" subtyping.
+ 'proposals/custom-descriptors/custom-descriptors/descriptors': [FAIL],
+ 'proposals/custom-descriptors/custom-descriptors/br_on_cast_desc_eq': [FAIL],
+ 'proposals/custom-descriptors/custom-descriptors/br_on_cast_desc_eq_fail': [FAIL],
+ 'proposals/custom-descriptors/custom-descriptors/ref_cast_desc_eq': [FAIL],
}], # ALWAYS
['lower_limits_mode', {
@@ -150,4 +157,10 @@
'proposals/stack-switching/stack-switching/cont': [SKIP],
}], # system == windows and asan
+##############################################################################
+['clang_coverage and mode == debug', {
+ # Slow tests.
+ 'simd/simd_f*': [PASS, SLOW],
+}], # 'clang_coverage and mode == debug'
+
]
diff --git a/deps/v8/third_party/abseil-cpp/.style.yapf b/deps/v8/third_party/abseil-cpp/.style.yapf
new file mode 100644
index 00000000000..557fa7bf84c
--- /dev/null
+++ b/deps/v8/third_party/abseil-cpp/.style.yapf
@@ -0,0 +1,2 @@
+[style]
+based_on_style = pep8
diff --git a/deps/v8/third_party/abseil-cpp/BUILD.gn b/deps/v8/third_party/abseil-cpp/BUILD.gn
index b5893f37e96..72c1655fee0 100644
--- a/deps/v8/third_party/abseil-cpp/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/BUILD.gn
@@ -65,6 +65,7 @@ group("absl_component_deps") {
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/cleanup",
"//third_party/abseil-cpp/absl/container:btree",
+ "//third_party/abseil-cpp/absl/container:chunked_queue",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/container:flat_hash_map",
"//third_party/abseil-cpp/absl/container:flat_hash_set",
@@ -94,6 +95,8 @@ group("absl_component_deps") {
"//third_party/abseil-cpp/absl/log:log_entry",
"//third_party/abseil-cpp/absl/log:log_sink",
"//third_party/abseil-cpp/absl/log:log_sink_registry",
+ "//third_party/abseil-cpp/absl/log:log_streamer",
+ "//third_party/abseil-cpp/absl/log:structured",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
@@ -102,6 +105,8 @@ group("absl_component_deps") {
"//third_party/abseil-cpp/absl/random:bit_gen_ref",
"//third_party/abseil-cpp/absl/random:distributions",
"//third_party/abseil-cpp/absl/random:mocking_access",
+ "//third_party/abseil-cpp/absl/random:seed_gen_exception",
+ "//third_party/abseil-cpp/absl/random:seed_sequences",
"//third_party/abseil-cpp/absl/status",
"//third_party/abseil-cpp/absl/status:status_builder",
"//third_party/abseil-cpp/absl/status:status_macros",
@@ -110,12 +115,14 @@ group("absl_component_deps") {
"//third_party/abseil-cpp/absl/strings:charset",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:has_ostream_operator",
+ "//third_party/abseil-cpp/absl/strings:resize_and_overwrite",
"//third_party/abseil-cpp/absl/strings:str_format",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/time",
"//third_party/abseil-cpp/absl/time:clock_interface",
"//third_party/abseil-cpp/absl/types:any_span",
+ "//third_party/abseil-cpp/absl/types:compare",
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:optional_ref",
"//third_party/abseil-cpp/absl/types:source_location",
@@ -267,12 +274,20 @@ if (absl_build_tests) {
deps = [
"absl/algorithm:algorithm_test",
"absl/algorithm:container_test",
+ "absl/base:atomic_hook_test",
"absl/base:attributes_test",
+ "absl/base:bit_cast_test",
+ "absl/base:call_once_test",
"absl/base:casts_test",
"absl/base:config_test",
"absl/base:cpu_detect_test",
+ "absl/base:endian_test",
+ "absl/base:errno_saver_test",
+ "absl/base:exception_safety_testing_test",
+ "absl/base:fast_type_id_test",
"absl/base:hardening_test",
"absl/base:iterator_traits_test",
+ "absl/base:log_severity_test",
"absl/base:no_destructor_test",
"absl/base:nullability_default_nonnull_test",
"absl/base:nullability_test",
@@ -281,10 +296,15 @@ if (absl_build_tests) {
"absl/base:poison_test",
"absl/base:prefetch_test",
"absl/base:raw_logging_test",
+ "absl/base:scoped_set_env_test",
+ "absl/base:spinlock_test",
+ "absl/base:strerror_test",
"absl/base:sysinfo_test",
"absl/base:thread_identity_test",
+ "absl/base:throw_delegate_test",
"absl/base:tracing_internal_strong_test",
"absl/base:tracing_internal_weak_test",
+ "absl/base:unique_small_name_test",
"absl/cleanup:cleanup_test",
"absl/container:chunked_queue_test",
"absl/container:common_policy_traits_test",
@@ -293,7 +313,12 @@ if (absl_build_tests) {
"absl/container:flat_hash_map_test",
"absl/container:flat_hash_set_test",
"absl/container:hash_function_defaults_test",
+ "absl/container:hash_policy_testing_test",
+ "absl/container:hash_policy_traits_test",
+ "absl/container:hashtable_control_bytes_test",
+ "absl/container:hashtablez_sampler_test",
"absl/container:inlined_vector_test",
+ "absl/container:layout_test",
"absl/container:linked_hash_map_test",
"absl/container:linked_hash_set_test",
"absl/container:node_hash_map_test",
@@ -302,6 +327,9 @@ if (absl_build_tests) {
"absl/container:raw_hash_set_allocator_test",
"absl/container:raw_hash_set_resize_impl_test",
"absl/container:sample_element_size_test",
+ "absl/container:test_instance_tracker_test",
+ "absl/container:unordered_map_test",
+ "absl/container:unordered_set_test",
"absl/crc:crc32c_test",
"absl/crc:crc_cord_state_test",
"absl/crc:crc_memcpy_test",
@@ -309,13 +337,24 @@ if (absl_build_tests) {
"absl/debugging:bounded_utf8_length_sequence_test",
"absl/debugging:decode_rust_punycode_test",
"absl/debugging:demangle_rust_test",
+ "absl/debugging:leak_check_test",
+ "absl/debugging:stack_consumption_test",
"absl/debugging:stacktrace_test",
"absl/debugging:utf8_for_code_point_test",
+ "absl/flags:config_test",
"absl/flags:flag_test",
+ "absl/flags:marshalling_test",
+ "absl/flags:parse_test",
+ "absl/flags:path_util_test",
+ "absl/flags:program_name_test",
+ "absl/flags:sequence_lock_test",
+ "absl/flags:usage_config_test",
"absl/functional:any_invocable_test",
"absl/functional:bind_back_test",
+ "absl/functional:bind_front_test",
"absl/functional:function_ref_test",
"absl/functional:overload_test",
+ "absl/hash:city_test",
"absl/hash:hash_instantiated_test",
"absl/hash:hash_test",
"absl/hash:low_level_hash_test",
@@ -332,6 +371,7 @@ if (absl_build_tests) {
"absl/log:log_streamer_test",
"absl/log:scoped_mock_log_test",
"absl/log:stripping_test",
+ "absl/log:structured_test",
"absl/log:vlog_is_on_test",
"absl/log/internal:container_test",
"absl/log/internal:fnmatch_test",
@@ -341,20 +381,57 @@ if (absl_build_tests) {
"absl/meta:constexpr_testing_test",
"absl/meta:requires_test",
"absl/meta:type_traits_test",
+ "absl/numeric:bits_test",
"absl/numeric:int128_test",
"absl/profiling:exponential_biased_test",
"absl/profiling:periodic_sampler_test",
+ "absl/random:bernoulli_distribution_test",
+ "absl/random:beta_distribution_test",
+ "absl/random:bit_gen_ref_test",
+ "absl/random:discrete_distribution_test",
"absl/random:distributions_test",
+ "absl/random:examples_test",
+ "absl/random:exponential_distribution_test",
+ "absl/random:gaussian_distribution_test",
+ "absl/random:generators_test",
+ "absl/random:log_uniform_int_distribution_test",
"absl/random:mock_distributions_test",
+ "absl/random:mocking_bit_gen_test",
+ "absl/random:poisson_distribution_test",
+ "absl/random:seed_sequences_test",
+ "absl/random:uniform_int_distribution_test",
+ "absl/random:uniform_real_distribution_test",
+ "absl/random:zipf_distribution_test",
+ "absl/random/internal:chi_square_test",
+ "absl/random/internal:distribution_test_util_test",
+ "absl/random/internal:entropy_pool_test",
+ "absl/random/internal:explicit_seed_seq_test",
+ "absl/random/internal:fast_uniform_bits_test",
+ "absl/random/internal:fastmath_test",
+ "absl/random/internal:generate_real_test",
+ "absl/random/internal:iostream_state_saver_test",
"absl/random/internal:nonsecure_base_test",
+ "absl/random/internal:pcg_engine_test",
+ "absl/random/internal:randen_engine_test",
+ "absl/random/internal:randen_slow_test",
+ "absl/random/internal:randen_test",
+ "absl/random/internal:salted_seed_seq_test",
+ "absl/random/internal:seed_material_test",
+ "absl/random/internal:traits_test",
+ "absl/random/internal:uniform_helper_test",
+ "absl/random/internal:wide_multiply_test",
"absl/status:status_builder_test",
"absl/status:status_macros_test",
"absl/status:status_matchers_test",
+ "absl/status:status_matchers_with_unqualified_macros_test",
"absl/status:status_test",
"absl/status:statusor_test",
"absl/strings:append_and_overwrite_test",
"absl/strings:ascii_test",
"absl/strings:char_formatting_test",
+ "absl/strings:charconv_bigint_test",
+ "absl/strings:charconv_parse_test",
+ "absl/strings:charconv_test",
"absl/strings:charset_test",
"absl/strings:cord_buffer_test",
"absl/strings:cord_data_edge_test",
@@ -372,12 +449,17 @@ if (absl_build_tests) {
"absl/strings:cordz_update_scope_test",
"absl/strings:cordz_update_tracker_test",
"absl/strings:damerau_levenshtein_distance_test",
+ "absl/strings:escaping_test",
"absl/strings:generic_printer_test",
"absl/strings:has_absl_stringify_test",
"absl/strings:has_ostream_operator_test",
"absl/strings:match_test",
+ "absl/strings:memutil_test",
"absl/strings:numbers_test",
+ "absl/strings:ostringstream_test",
+ "absl/strings:pow10_helper_test",
"absl/strings:resize_and_overwrite_test",
+ "absl/strings:resize_uninitialized_test",
"absl/strings:str_cat_test",
"absl/strings:str_format_arg_test",
"absl/strings:str_format_bind_test",
@@ -387,10 +469,15 @@ if (absl_build_tests) {
"absl/strings:str_format_output_test",
"absl/strings:str_format_parser_test",
"absl/strings:str_format_test",
+ "absl/strings:str_join_test",
"absl/strings:str_replace_test",
"absl/strings:str_split_test",
+ "absl/strings:string_constant_test",
"absl/strings:string_view_test",
"absl/strings:stringify_stream_test",
+ "absl/strings:strip_test",
+ "absl/strings:substitute_test",
+ "absl/strings:utf8_test",
"absl/synchronization:barrier_test",
"absl/synchronization:graphcycles_test",
"absl/synchronization:kernel_timeout_internal_test",
@@ -398,8 +485,15 @@ if (absl_build_tests) {
"absl/synchronization:per_thread_sem_test",
"absl/synchronization:waiter_test",
"absl/time:clock_interface_test",
+ "absl/time:flag_test",
"absl/time:simulated_clock_test",
"absl/time:time_test",
+ "absl/time/internal/cctz:civil_time_test",
+ "absl/time/internal/cctz:time_zone_format_test",
+ "absl/time/internal/cctz:time_zone_lookup_test",
+ "absl/time/internal/cctz:time_zone_name_win_test",
+ "absl/time/internal/cctz:time_zone_posix_test",
+ "absl/types:compare_test",
"absl/types:optional_ref_test",
"absl/types:source_location_test",
"absl/types:span_test",
diff --git a/deps/v8/third_party/abseil-cpp/CMake/AbseilDll.cmake b/deps/v8/third_party/abseil-cpp/CMake/AbseilDll.cmake
index 25b2ebf44c9..fa89c82b218 100644
--- a/deps/v8/third_party/abseil-cpp/CMake/AbseilDll.cmake
+++ b/deps/v8/third_party/abseil-cpp/CMake/AbseilDll.cmake
@@ -21,7 +21,6 @@ set(ABSL_INTERNAL_DLL_FILES
"base/internal/direct_mmap.h"
"base/internal/endian.h"
"base/internal/errno_saver.h"
- "base/internal/hardening.cc"
"base/internal/hardening.h"
"base/internal/hide_ptr.h"
"base/internal/iterator_traits.h"
@@ -723,10 +722,18 @@ set(ABSL_INTERNAL_TEST_DLL_TARGETS
"status_matchers"
)
-include(CheckCXXSourceCompiles)
+if(DEFINED CMAKE_CXX_STANDARD AND CMAKE_CXX_STANDARD_REQUIRED)
+ if(CMAKE_CXX_STANDARD GREATER_EQUAL 20)
+ set(ABSL_INTERNAL_AT_LEAST_CXX20 ON)
+ set(ABSL_INTERNAL_AT_LEAST_CXX17 ON)
+ elseif(CMAKE_CXX_STANDARD GREATER_EQUAL 17)
+ set(ABSL_INTERNAL_AT_LEAST_CXX17 ON)
+ endif()
+else()
+ include(CheckCXXSourceCompiles)
-check_cxx_source_compiles(
- [==[
+ check_cxx_source_compiles(
+ [==[
#ifdef _MSC_VER
# if _MSVC_LANG < 201703L
# error "The compiler defaults or is configured for C++ < 17"
@@ -736,10 +743,10 @@ check_cxx_source_compiles(
#endif
int main() { return 0; }
]==]
- ABSL_INTERNAL_AT_LEAST_CXX17)
+ ABSL_INTERNAL_AT_LEAST_CXX17)
-check_cxx_source_compiles(
- [==[
+ check_cxx_source_compiles(
+ [==[
#ifdef _MSC_VER
# if _MSVC_LANG < 202002L
# error "The compiler defaults or is configured for C++ < 20"
@@ -749,7 +756,8 @@ check_cxx_source_compiles(
#endif
int main() { return 0; }
]==]
- ABSL_INTERNAL_AT_LEAST_CXX20)
+ ABSL_INTERNAL_AT_LEAST_CXX20)
+endif()
if(ABSL_INTERNAL_AT_LEAST_CXX20)
set(ABSL_INTERNAL_CXX_STD_FEATURE cxx_std_20)
diff --git a/deps/v8/third_party/abseil-cpp/MODULE.bazel b/deps/v8/third_party/abseil-cpp/MODULE.bazel
index 6dfccce4894..00ab4c35dda 100644
--- a/deps/v8/third_party/abseil-cpp/MODULE.bazel
+++ b/deps/v8/third_party/abseil-cpp/MODULE.bazel
@@ -26,8 +26,8 @@ cc_configure = use_extension(
)
use_repo(cc_configure, "local_config_cc")
-bazel_dep(name = "rules_cc", version = "0.2.18")
-bazel_dep(name = "bazel_skylib", version = "1.9.0")
+bazel_dep(name = "rules_cc", version = "0.2.22")
+bazel_dep(name = "bazel_skylib", version = "1.9.2")
bazel_dep(name = "platforms", version = "1.1.0")
bazel_dep(
@@ -40,7 +40,7 @@ bazel_dep(
# intended to be used by Abseil users depend on GoogleTest.
bazel_dep(
name = "googletest",
- version = "1.17.0.bcr.2",
+ version = "1.18.0",
)
# Note: Gloop is NOT a dev_dependency, but should never be used directly. It is only included here
diff --git a/deps/v8/third_party/abseil-cpp/README.chromium b/deps/v8/third_party/abseil-cpp/README.chromium
index 81402c8ae30..ff16d9c85b3 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: 442cb1b3c9c60ac2982aa97e26658cef7bc4a1bd
+Revision: 1c84143fb79e6041f3e0596df51c3ae7d7e46a8a
Update Mechanism: Manual
Security Critical: yes
Shipped: yes
diff --git a/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.bazel
index 337f0357a02..10b9400bb55 100644
--- a/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.bazel
@@ -88,7 +88,6 @@ cc_test(
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
- "//absl/base:hardening",
"//absl/memory",
"//absl/meta:type_traits",
"//absl/random",
diff --git a/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.gn
index f76bd7735a4..81aba2c573d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/algorithm/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -39,7 +41,6 @@ absl_test("container_test") {
"//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:hardening",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/random",
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 eb201322784..cd7fa221ef7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/algorithm/CMakeLists.txt
@@ -37,7 +37,6 @@ absl_cc_test(
DEPS
absl::algorithm
absl::config
- absl::hardening
GTest::gmock_main
)
diff --git a/deps/v8/third_party/abseil-cpp/absl/algorithm/container.h b/deps/v8/third_party/abseil-cpp/absl/algorithm/container.h
index a6b60cb285c..9d2b48e9f14 100644
--- a/deps/v8/third_party/abseil-cpp/absl/algorithm/container.h
+++ b/deps/v8/third_party/abseil-cpp/absl/algorithm/container.h
@@ -218,7 +218,7 @@ struct IsSpan<std::span<T, Extent>> : std::true_type {};
// types that satisfy std::ranges::borrowed_range.
template <typename C>
using IsPermissibleDestinationRange =
- std::conditional_t<std::is_lvalue_reference<C>::value, std::true_type,
+ std::conditional_t<std::is_lvalue_reference_v<C>, std::true_type,
IsSpan<C>>;
template <typename C, typename OutputRange>
diff --git a/deps/v8/third_party/abseil-cpp/absl/algorithm/container_test.cc b/deps/v8/third_party/abseil-cpp/absl/algorithm/container_test.cc
index 2d2fec18140..e0253827a32 100644
--- a/deps/v8/third_party/abseil-cpp/absl/algorithm/container_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/algorithm/container_test.cc
@@ -36,7 +36,6 @@
#include "gtest/gtest.h"
#include "absl/base/casts.h"
#include "absl/base/config.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/macros.h"
#include "absl/memory/memory.h"
#include "absl/meta/type_traits.h"
@@ -111,8 +110,7 @@ TEST_F(NonMutatingTest, Distance) {
static_cast<size_t>(absl::c_distance(container_)));
EXPECT_EQ(sequence_.size(), static_cast<size_t>(absl::c_distance(sequence_)));
EXPECT_EQ(vector_.size(), static_cast<size_t>(absl::c_distance(vector_)));
- EXPECT_EQ(ABSL_ARRAYSIZE(array_),
- static_cast<size_t>(absl::c_distance(array_)));
+ EXPECT_EQ(std::size(array_), static_cast<size_t>(absl::c_distance(array_)));
// Works with a temporary argument.
EXPECT_EQ(vector_.size(),
@@ -874,7 +872,6 @@ TEST(MutatingTest, CopyToCArrayInvalidSize) {
(void)actual;
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy(input, actual), "");
}
#endif
@@ -886,7 +883,6 @@ TEST(MutatingTest, CopyNToCArrayInvalidSize) {
(void)actual;
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy_n(input, 3, actual), "");
}
#endif
@@ -898,7 +894,6 @@ TEST(MutatingTest, CopyNToCArrayNGreaterThanInput) {
(void)actual;
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy_n(input, 4, actual), "");
}
#endif
@@ -909,7 +904,6 @@ TEST(MutatingTest, CopyToContainerInvalidSize) {
std::list<int> actual = {0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy(input, actual), "");
}
#endif
@@ -920,7 +914,6 @@ TEST(MutatingTest, CopyNToContainerNGreaterThanInput) {
std::vector<int> actual = {0, 0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy_n(input, 4, actual), "");
}
#endif
@@ -931,7 +924,6 @@ TEST(MutatingTest, CopyNToContainerNGreaterThanOutput) {
std::vector<int> actual = {0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy_n(input, 3, actual), "");
}
#endif
@@ -942,7 +934,6 @@ TEST(MutatingTest, CopyToForwardListInvalidSize) {
std::forward_list<int> actual = {0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy(input, actual), "");
}
#endif
@@ -953,7 +944,6 @@ TEST(MutatingTest, CopyNToForwardListNGreaterThanInput) {
std::forward_list<int> actual = {0, 0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy_n(input, 4, actual), "");
}
#endif
@@ -964,7 +954,6 @@ TEST(MutatingTest, CopyNToForwardListNGreaterThanOutput) {
std::forward_list<int> actual = {0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_copy_n(input, 3, actual), "");
}
#endif
@@ -1118,7 +1107,6 @@ TEST(MutatingTest, MoveToCArrayInvalidSize) {
(void)actual;
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_move(input, actual), "");
}
#endif
@@ -1129,7 +1117,6 @@ TEST(MutatingTest, MoveToContainerInvalidSize) {
std::list<int> actual = {0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_move(input, actual), "");
}
#endif
@@ -1140,7 +1127,6 @@ TEST(MutatingTest, MoveToForwardListInvalidSize) {
std::forward_list<int> actual = {0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_move(input, actual), "");
}
#endif
@@ -1244,7 +1230,6 @@ TEST(MutatingTest, TransformToCArrayInvalidSize) {
(void)actual;
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_transform(input, actual, [](int x) { return x * 2; }),
"");
}
@@ -1258,7 +1243,6 @@ TEST(MutatingTest, BinaryTransformToCArrayInvalidSize) {
(void)actual;
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_transform(input1, input2, actual, std::plus<int>()),
"");
}
@@ -1270,7 +1254,6 @@ TEST(MutatingTest, TransformToContainerInvalidSize) {
std::list<int> actual = {0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_transform(input, actual, [](int x) { return x * 2; }),
"");
}
@@ -1283,7 +1266,6 @@ TEST(MutatingTest, BinaryTransformToContainerInvalidSize) {
std::vector<int> actual = {0, 0, 0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_transform(input1, input2, actual, std::plus<int>()),
"");
}
@@ -1296,7 +1278,6 @@ TEST(MutatingTest, BinaryTransformInput2InvalidSize) {
std::vector<int> actual = {0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_transform(input1, input2, actual, std::plus<int>()),
"");
}
@@ -1309,7 +1290,6 @@ TEST(MutatingTest, BinaryTransformInput1InvalidSize) {
std::vector<int> actual = {0};
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH(absl::c_transform(input1, input2, actual, std::plus<int>()),
"");
}
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 db2475e5410..969f746dc05 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/base/BUILD.bazel
@@ -79,7 +79,6 @@ cc_library(
cc_library(
name = "hardening",
- srcs = ["internal/hardening.cc"],
hdrs = [
"internal/hardening.h",
],
@@ -1090,8 +1089,8 @@ cc_library(
"@do_not_use_for_gloop_visibility_only//gloop/perftools/tracing:__subpackages__",
],
deps = [
- "//absl/base:config",
- "//absl/base:core_headers",
+ ":config",
+ ":core_headers",
],
)
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 a74e310f527..3591e5ea904 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/base/BUILD.gn
@@ -1,39 +1,40 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("atomic_hook") {
public = [ "internal/atomic_hook.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":config",
":core_headers",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("errno_saver") {
public = [ "internal/errno_saver.h" ]
- deps = [ ":config" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [ ":config" ]
}
absl_source_set("cpu_detect") {
- public = [ "internal/cpu_detect.h" ]
sources = [ "internal/cpu_detect.cc" ]
- deps = [ ":config" ]
+ public = [ "internal/cpu_detect.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [ ":config" ]
}
absl_source_set("hardening") {
public = [ "internal/hardening.h" ]
- sources = [ "internal/hardening.cc" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":config",
":core_headers",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("log_severity") {
@@ -60,16 +61,20 @@ absl_source_set("nullability") {
absl_source_set("nullability_traits_internal") {
public = [ "internal/nullability_traits.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":config",
":nullability",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("raw_logging_internal") {
sources = [ "internal/raw_logging.cc" ]
public = [ "internal/raw_logging.h" ]
+ visibility = [
+ "//third_party/abseil-cpp:absl_component_deps",
+ "//third_party/abseil-cpp/absl/*",
+ ]
deps = [
":atomic_hook",
":config",
@@ -77,10 +82,6 @@ absl_source_set("raw_logging_internal") {
":errno_saver",
":log_severity",
]
- visibility = [
- "//third_party/abseil-cpp:absl_component_deps",
- "//third_party/abseil-cpp/absl/*",
- ]
}
absl_source_set("spinlock_wait") {
@@ -92,12 +93,12 @@ absl_source_set("spinlock_wait") {
"internal/spinlock_win32.inc",
]
public = [ "internal/spinlock_wait.h" ]
+ visibility = [ ":*" ]
deps = [
":base_internal",
":core_headers",
":errno_saver",
]
- visibility = [ "//third_party/abseil-cpp/absl/base:*" ]
}
absl_source_set("config") {
@@ -122,9 +123,6 @@ absl_source_set("cycleclock_internal") {
absl_source_set("dynamic_annotations") {
public = [ "dynamic_annotations.h" ]
-
- # Abseil's dynamic annotations are only visible inside Abseil because
- # their usage is deprecated in Chromium (see README.chromium for more info).
visibility = [
"//third_party/abseil-cpp:absl_component_deps",
"//third_party/abseil-cpp/absl/*",
@@ -168,11 +166,11 @@ absl_source_set("base_internal") {
"internal/hide_ptr.h",
"internal/scheduling_mode.h",
]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("base") {
@@ -196,10 +194,6 @@ absl_source_set("base") {
"internal/tsan_mutex_interface.h",
"internal/unscaledcycleclock.h",
]
-
- # TODO(mbonadei): The bazel file has:
- # "-DEFAULTLIB:advapi32.lib"
- # understand if this is needed here as well.
deps = [
":atomic_hook",
":base_internal",
@@ -213,6 +207,34 @@ absl_source_set("base") {
]
}
+absl_source_set("atomic_hook_test_helper") {
+ testonly = true
+ sources = [ "internal/atomic_hook_test_helper.cc" ]
+ public = [ "internal/atomic_hook_test_helper.h" ]
+ visibility = [ ":*" ]
+ deps = [
+ ":atomic_hook",
+ ":core_headers",
+ ]
+}
+
+absl_test("atomic_hook_test") {
+ sources = [ "internal/atomic_hook_test.cc" ]
+ deps = [
+ ":atomic_hook",
+ ":atomic_hook_test_helper",
+ ":core_headers",
+ ]
+}
+
+absl_test("bit_cast_test") {
+ sources = [ "bit_cast_test.cc" ]
+ deps = [
+ ":base",
+ ":core_headers",
+ ]
+}
+
absl_test("attributes_test") {
sources = [ "attributes_test.cc" ]
deps = [
@@ -241,154 +263,126 @@ absl_source_set("throw_delegate") {
]
}
-absl_source_set("exception_testing") {
- testonly = true
- public = [ "internal/exception_testing.h" ]
- deps = [ ":config" ]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
+absl_test("throw_delegate_test") {
+ sources = [ "throw_delegate_test.cc" ]
+ deps = [
+ ":config",
+ ":throw_delegate",
+ ]
}
-absl_source_set("pretty_function") {
- public = [ "internal/pretty_function.h" ]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
+absl_test("errno_saver_test") {
+ sources = [ "internal/errno_saver_test.cc" ]
+ deps = [
+ ":errno_saver",
+ ":strerror",
+ ]
}
-absl_source_set("spinlock_test_common") {
+absl_source_set("exception_testing") {
testonly = true
- sources = [ "spinlock_test_common.cc" ]
+ public = [ "internal/exception_testing.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
- ":base",
- ":base_internal",
":config",
- ":core_headers",
- "//third_party/abseil-cpp/absl/synchronization",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
-absl_source_set("endian") {
- public = [
- "internal/endian.h",
- "internal/unaligned_access.h",
- ]
+absl_source_set("pretty_function") {
+ public = [ "internal/pretty_function.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
- deps = [
- ":base",
- ":config",
- ":core_headers",
- ":nullability",
- ]
}
-absl_source_set("scoped_set_env") {
+absl_source_set("exception_safety_testing") {
testonly = true
- public = [ "internal/scoped_set_env.h" ]
- sources = [ "internal/scoped_set_env.cc" ]
+ sources = [ "internal/exception_safety_testing.cc" ]
+ public = [ "internal/exception_safety_testing.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":config",
- ":raw_logging_internal",
+ ":pretty_function",
+ "//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:string_view",
+ "//third_party/abseil-cpp/absl/utility",
+ "//third_party/googletest:gmock",
+ "//third_party/googletest:gtest",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
-absl_source_set("strerror") {
- sources = [ "internal/strerror.cc" ]
- public = [ "internal/strerror.h" ]
+absl_test("exception_safety_testing_test") {
+ sources = [ "exception_safety_testing_test.cc" ]
deps = [
- ":config",
- ":core_headers",
- ":errno_saver",
+ ":exception_safety_testing",
+ "//third_party/abseil-cpp/absl/memory",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
-}
-
-absl_source_set("fast_type_id") {
- public = [ "fast_type_id.h" ]
- deps = [ ":config" ]
}
-absl_source_set("prefetch") {
- public = [ "prefetch.h" ]
+absl_source_set("spinlock_test_common") {
+ testonly = true
+ sources = [ "spinlock_test_common.cc" ]
+ visibility = [ ":*" ]
deps = [
+ ":base",
+ ":base_internal",
":config",
":core_headers",
+ "//third_party/abseil-cpp/absl/synchronization",
+ "//third_party/googletest:gmock",
+ "//third_party/googletest:gtest",
]
}
-absl_test("prefetch_test") {
- sources = [ "prefetch_test.cc" ]
- deps = [ ":prefetch" ]
-}
-
-absl_source_set("poison") {
- public = [ "internal/poison.h" ]
- sources = [ "internal/poison.cc" ]
+absl_test("spinlock_test") {
+ sources = [ "spinlock_test_common.cc" ]
deps = [
+ ":base",
+ ":base_internal",
":config",
":core_headers",
- ":malloc_internal",
+ "//third_party/abseil-cpp/absl/synchronization",
]
}
-absl_test("poison_test") {
- sources = [ "internal/poison_test.cc" ]
- deps = [
- ":config",
- ":poison",
+absl_source_set("endian") {
+ public = [
+ "internal/endian.h",
+ "internal/unaligned_access.h",
]
-}
-
-absl_source_set("iterator_traits_internal") {
- public = [ "internal/iterator_traits.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
+ ":base",
":config",
- "//third_party/abseil-cpp/absl/meta:type_traits",
+ ":core_headers",
+ ":nullability",
]
}
-absl_test("iterator_traits_test") {
- sources = [ "internal/iterator_traits_test.cc" ]
+absl_test("endian_test") {
+ sources = [ "internal/endian_test.cc" ]
deps = [
":config",
- ":iterator_traits_internal",
- ":iterator_traits_test_helper",
+ ":endian",
]
}
-absl_source_set("tracing_internal") {
- public = [ "internal/tracing.h" ]
- sources = [ "internal/tracing.cc" ]
+absl_test("config_test") {
+ sources = [ "config_test.cc" ]
deps = [
":config",
- ":core_headers",
+ "//third_party/abseil-cpp/absl/synchronization:thread_pool",
]
}
-absl_source_set("iterator_traits_test_helper") {
- public = [ "internal/iterator_traits_test_helper.h" ]
- deps = [ ":config" ]
-}
-
-absl_test("tracing_internal_weak_test") {
- sources = [ "internal/tracing_weak_test.cc" ]
- deps = [ ":tracing_internal" ]
-}
-
-absl_test("tracing_internal_strong_test") {
- sources = [ "internal/tracing_strong_test.cc" ]
+absl_test("call_once_test") {
+ sources = [ "call_once_test.cc" ]
deps = [
- ":config",
+ ":base",
":core_headers",
- ":tracing_internal",
- ]
-}
-
-absl_test("config_test") {
- sources = [ "config_test.cc" ]
- deps = [
- ":config",
- "//third_party/abseil-cpp/absl/synchronization:thread_pool",
+ "//third_party/abseil-cpp/absl/synchronization",
]
}
@@ -461,7 +455,7 @@ absl_test("cpu_detect_test") {
]
}
-# low_level_alloc_test is not included because it has own main function.
+# low_level_alloc_test is excluded because defines its own main function
# absl_test("low_level_alloc_test")
absl_test("thread_identity_test") {
@@ -473,7 +467,155 @@ absl_test("thread_identity_test") {
]
}
+absl_source_set("scoped_set_env") {
+ testonly = true
+ sources = [ "internal/scoped_set_env.cc" ]
+ public = [ "internal/scoped_set_env.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [
+ ":config",
+ ":raw_logging_internal",
+ ]
+}
+
+absl_test("scoped_set_env_test") {
+ sources = [ "internal/scoped_set_env_test.cc" ]
+ deps = [ ":scoped_set_env" ]
+}
+
+absl_test("log_severity_test") {
+ sources = [ "log_severity_test.cc" ]
+ deps = [
+ ":log_severity",
+ "//third_party/abseil-cpp/absl/flags:flag_internal",
+ "//third_party/abseil-cpp/absl/flags:marshalling",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
+ ]
+}
+
+absl_source_set("strerror") {
+ sources = [ "internal/strerror.cc" ]
+ public = [ "internal/strerror.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [
+ ":config",
+ ":core_headers",
+ ":errno_saver",
+ ]
+}
+
+absl_test("strerror_test") {
+ sources = [ "internal/strerror_test.cc" ]
+ deps = [
+ ":strerror",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+absl_source_set("fast_type_id") {
+ public = [ "fast_type_id.h" ]
+ deps = [ ":config" ]
+}
+
+absl_test("fast_type_id_test") {
+ sources = [ "fast_type_id_test.cc" ]
+ deps = [
+ ":core_headers",
+ ":fast_type_id",
+ ]
+}
+
+absl_source_set("prefetch") {
+ public = [ "prefetch.h" ]
+ deps = [
+ ":config",
+ ":core_headers",
+ ]
+}
+
+absl_test("prefetch_test") {
+ sources = [ "prefetch_test.cc" ]
+ deps = [ ":prefetch" ]
+}
+
+absl_source_set("poison") {
+ sources = [ "internal/poison.cc" ]
+ public = [ "internal/poison.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [
+ ":config",
+ ":core_headers",
+ ":malloc_internal",
+ ]
+}
+
+absl_test("poison_test") {
+ sources = [ "internal/poison_test.cc" ]
+ deps = [
+ ":config",
+ ":poison",
+ ]
+}
+
+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",
+ ]
+}
+
absl_test("optimization_test") {
sources = [ "optimization_test.cc" ]
deps = [ ":core_headers" ]
}
+
+absl_source_set("iterator_traits_internal") {
+ public = [ "internal/iterator_traits.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [
+ ":config",
+ "//third_party/abseil-cpp/absl/meta:type_traits",
+ ]
+}
+
+absl_test("iterator_traits_test") {
+ sources = [ "internal/iterator_traits_test.cc" ]
+ deps = [
+ ":config",
+ ":iterator_traits_internal",
+ ":iterator_traits_test_helper",
+ ]
+}
+
+absl_source_set("tracing_internal") {
+ sources = [ "internal/tracing.cc" ]
+ public = [ "internal/tracing.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [
+ ":config",
+ ":core_headers",
+ ]
+}
+
+absl_source_set("iterator_traits_test_helper") {
+ public = [ "internal/iterator_traits_test_helper.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [ ":config" ]
+}
+
+absl_test("tracing_internal_weak_test") {
+ sources = [ "internal/tracing_weak_test.cc" ]
+ deps = [ ":tracing_internal" ]
+}
+
+absl_test("tracing_internal_strong_test") {
+ sources = [ "internal/tracing_strong_test.cc" ]
+ deps = [
+ ":config",
+ ":core_headers",
+ ":tracing_internal",
+ ]
+}
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 dacf8e71387..32bcf93951a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/base/CMakeLists.txt
@@ -61,8 +61,6 @@ absl_cc_library(
hardening
HDRS
"internal/hardening.h"
- SRCS
- "internal/hardening.cc"
DEPS
absl::config
absl::core_headers
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 525824a95fe..53e440e68fe 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/attributes.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/attributes.h
@@ -494,8 +494,8 @@
//
// These attributes only take effect when the following conditions are met:
//
-// * The file/target is built in at least C++11 mode, with a Clang compiler
-// that supports XRay attributes.
+// * The file/target is built with a Clang compiler that supports XRay
+// attributes.
// * The file/target is built with the -fxray-instrument flag set for the
// Clang/LLVM compiler.
// * The function is defined in the translation unit (the compiler honors the
@@ -639,47 +639,16 @@
//
// Annotates implicit fall-through between switch labels, allowing a case to
// indicate intentional fallthrough and turn off warnings about any lack of a
-// `break` statement. The ABSL_FALLTHROUGH_INTENDED macro should be followed by
-// a semicolon and can be used in most places where `break` can, provided that
-// no statements exist between it and the next switch label.
+// `break` statement.
//
-// Example:
+// Deprecated: Use the standard C++17 `[[fallthrough]]` instead.
//
-// switch (x) {
-// case 40:
-// case 41:
-// if (truth_is_out_there) {
-// ++x;
-// ABSL_FALLTHROUGH_INTENDED; // Use instead of/along with annotations
-// // in comments
-// } else {
-// return x;
-// }
-// case 42:
-// ...
-//
-// Notes: When supported, GCC and Clang can issue a warning on switch labels
-// with unannotated fallthrough using the warning `-Wimplicit-fallthrough`. See
-// clang documentation on language extensions for details:
-// https://clang.llvm.org/docs/AttributeReference.html#fallthrough-clang-fallthrough
-//
-// When used with unsupported compilers, the ABSL_FALLTHROUGH_INTENDED macro has
-// no effect on diagnostics. In any case this macro has no effect on runtime
-// behavior and performance of code.
+// This macro has no effect on runtime behavior and performance of code.
#ifdef ABSL_FALLTHROUGH_INTENDED
#error "ABSL_FALLTHROUGH_INTENDED should not be defined."
-#elif ABSL_HAVE_CPP_ATTRIBUTE(fallthrough)
-#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
-#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::fallthrough)
-#define ABSL_FALLTHROUGH_INTENDED [[clang::fallthrough]]
-#elif ABSL_HAVE_CPP_ATTRIBUTE(gnu::fallthrough)
-#define ABSL_FALLTHROUGH_INTENDED [[gnu::fallthrough]]
-#else
-#define ABSL_FALLTHROUGH_INTENDED \
- do { \
- } while (0)
#endif
+#define ABSL_FALLTHROUGH_INTENDED [[fallthrough]]
// ABSL_DEPRECATED()
//
@@ -813,22 +782,20 @@ struct AbslInternal_YouForgotToExplicitlyInitializeAField {
// ABSL_CONST_INIT
//
-// A variable declaration annotated with the `ABSL_CONST_INIT` attribute will
-// not compile (on supported platforms) unless the variable has a constant
-// initializer. This is useful for variables with static and thread storage
-// duration, because it guarantees that they will not suffer from the so-called
-// "static init order fiasco".
+// A variable declared with `ABSL_CONST_INIT` will not compile (on supported
+// platforms) unless the variable has a constant initializer. This is useful for
+// variables with static and thread storage duration, because it guarantees that
+// they will not suffer from the so-called "static init order fiasco".
//
-// This attribute must be placed on the initializing declaration of the
-// variable. Some compilers will give a -Wmissing-constinit warning when this
-// attribute is placed on some other declaration but missing from the
-// initializing declaration.
+// `ABSL_CONST_INIT` must be placed on the initializing declaration
+// (i.e. definition) of the variable. Some compilers will give a
+// `-Wmissing-constinit` warning when it is placed on some other
+// declaration but missing from the initializing declaration.
//
-// In some cases (notably with thread_local variables), `ABSL_CONST_INIT` can
-// also be used in a non-initializing declaration to tell the compiler that a
-// variable is already initialized, reducing overhead that would otherwise be
-// incurred by a hidden guard variable. Thus annotating all declarations with
-// this attribute is recommended to potentially enhance optimization.
+// For thread_local variables, placing `ABSL_CONST_INIT` on the non-initializing
+// declaration tells the compiler that the variable is already initialized,
+// reducing overhead that would otherwise be incurred by a hidden guard
+// variable.
//
// Example:
//
@@ -840,9 +807,10 @@ struct AbslInternal_YouForgotToExplicitlyInitializeAField {
// ABSL_CONST_INIT MyType MyClass::my_var = MakeMyType(...);
//
// For code or headers that are assured to only build with C++20 and up, prefer
-// just using the standard `constinit` keyword directly over this macro.
+// using the standard `constinit` keyword directly over this macro.
//
-// Note that this attribute is redundant if the variable is declared constexpr.
+// Note that `ABSL_CONST_INIT` must not be used on a variable declared
+// constexpr.
#if defined(__cpp_constinit) && __cpp_constinit >= 201907L
#define ABSL_CONST_INIT constinit
#elif ABSL_HAVE_CPP_ATTRIBUTE(clang::require_constant_initialization)
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 8a3a41ea023..8bded1dcfa6 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
@@ -16,10 +16,10 @@
#include <cstdint>
#include <cstring>
+#include <iterator>
#include "gtest/gtest.h"
#include "absl/base/casts.h"
-#include "absl/base/macros.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -62,25 +62,25 @@ void TestIntegral(const T values[], int num_values) {
TEST(BitCast, Bool) {
static const bool bool_list[] = { false, true };
- TestMarshall<bool>(bool_list, ABSL_ARRAYSIZE(bool_list));
+ TestMarshall<bool>(bool_list, std::size(bool_list));
}
TEST(BitCast, Int32) {
static const int32_t int_list[] =
{ 0, 1, 100, 2147483647, -1, -100, -2147483647, -2147483647-1 };
- TestMarshall<int32_t>(int_list, ABSL_ARRAYSIZE(int_list));
+ TestMarshall<int32_t>(int_list, std::size(int_list));
}
TEST(BitCast, Int64) {
static const int64_t int64_list[] =
{ 0, 1, 1LL << 40, -1, -(1LL<<40) };
- TestMarshall<int64_t>(int64_list, ABSL_ARRAYSIZE(int64_list));
+ TestMarshall<int64_t>(int64_list, std::size(int64_list));
}
TEST(BitCast, Uint64) {
static const uint64_t uint64_list[] =
{ 0, 1, 1LLU << 40, 1LLU << 63 };
- TestMarshall<uint64_t>(uint64_list, ABSL_ARRAYSIZE(uint64_list));
+ TestMarshall<uint64_t>(uint64_list, std::size(uint64_list));
}
TEST(BitCast, Float) {
@@ -88,9 +88,9 @@ TEST(BitCast, Float) {
{ 0.0f, 1.0f, -1.0f, 10.0f, -10.0f,
1e10f, 1e20f, 1e-10f, 1e-20f,
2.71828f, 3.14159f };
- TestMarshall<float>(float_list, ABSL_ARRAYSIZE(float_list));
- TestIntegral<float, int>(float_list, ABSL_ARRAYSIZE(float_list));
- TestIntegral<float, unsigned>(float_list, ABSL_ARRAYSIZE(float_list));
+ TestMarshall<float>(float_list, std::size(float_list));
+ TestIntegral<float, int>(float_list, std::size(float_list));
+ TestIntegral<float, unsigned>(float_list, std::size(float_list));
}
TEST(BitCast, Double) {
@@ -99,9 +99,9 @@ TEST(BitCast, Double) {
1e10, 1e100, 1e-10, 1e-100,
2.718281828459045,
3.141592653589793238462643383279502884197169399375105820974944 };
- TestMarshall<double>(double_list, ABSL_ARRAYSIZE(double_list));
- TestIntegral<double, int64_t>(double_list, ABSL_ARRAYSIZE(double_list));
- TestIntegral<double, uint64_t>(double_list, ABSL_ARRAYSIZE(double_list));
+ TestMarshall<double>(double_list, std::size(double_list));
+ TestIntegral<double, int64_t>(double_list, std::size(double_list));
+ TestIntegral<double, uint64_t>(double_list, std::size(double_list));
}
} // namespace
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 1abac86798a..77852d124fc 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
@@ -29,6 +29,7 @@
#include <atomic>
#include <cstdint>
#include <functional>
+#include <iterator>
#include <type_traits>
#include <utility>
@@ -38,7 +39,6 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/spinlock_wait.h"
-#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
@@ -180,7 +180,7 @@ 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, ABSL_ARRAYSIZE(trans), trans,
+ base_internal::SpinLockWait(control, std::size(trans), trans,
scheduling_mode) == kOnceInit) {
std::invoke(std::forward<Callable>(fn), std::forward<Args>(args)...);
old_control =
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/casts.h b/deps/v8/third_party/abseil-cpp/absl/base/casts.h
index 1a857983f4c..17cc0b9dede 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/casts.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/casts.h
@@ -30,11 +30,9 @@
#include <typeinfo>
#include <utility>
-#ifdef __has_include
#if __has_include(<version>)
#include <version> // For __cpp_lib_bit_cast.
#endif
-#endif
#if defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L
#include <bit> // For std::bit_cast.
@@ -206,11 +204,11 @@ namespace base_internal {
const char* source_type, const char* target_type);
template <typename To, typename From>
-inline void ValidateDownCast(From* f ABSL_ATTRIBUTE_UNUSED) {
+inline void ValidateDownCast(From* f) {
// Assert only if RTTI is enabled and in debug mode or hardened asserts are
// enabled.
-#ifdef ABSL_INTERNAL_HAS_RTTI
-#if !defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1)
+#if defined(ABSL_INTERNAL_HAS_RTTI) && \
+ (!defined(NDEBUG) || (ABSL_OPTION_HARDENED == 1))
// Suppress erroneous nonnull comparison warning on older GCC.
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic push
@@ -223,7 +221,8 @@ inline void ValidateDownCast(From* f ABSL_ATTRIBUTE_UNUSED) {
absl::base_internal::BadDownCastCrash(
typeid(*f).name(), typeid(std::remove_pointer_t<To>).name());
}
-#endif
+#else
+ (void)f; // Denote this as "used" to avoid warning
#endif
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/config.h b/deps/v8/third_party/abseil-cpp/absl/base/config.h
index 4a35ff12dc7..e3e2c96a39c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/config.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/config.h
@@ -241,41 +241,6 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_TLS 1
#endif
-// ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
-//
-// Checks whether `std::is_trivially_destructible<T>` is supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE cannot be directly set
-#define ABSL_HAVE_STD_IS_TRIVIALLY_DESTRUCTIBLE 1
-#endif
-
-// ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-//
-// Checks whether `std::is_trivially_default_constructible<T>` and
-// `std::is_trivially_copy_constructible<T>` are supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE cannot be directly set
-#else
-#define ABSL_HAVE_STD_IS_TRIVIALLY_CONSTRUCTIBLE 1
-#endif
-
-// ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
-//
-// Checks whether `std::is_trivially_copy_assignable<T>` is supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE cannot be directly set
-#else
-#define ABSL_HAVE_STD_IS_TRIVIALLY_ASSIGNABLE 1
-#endif
-
-// ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
-//
-// Checks whether `std::is_trivially_copyable<T>` is supported.
-#ifdef ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE
-#error ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE cannot be directly set
-#define ABSL_HAVE_STD_IS_TRIVIALLY_COPYABLE 1
-#endif
-
// ABSL_HAVE_THREAD_LOCAL
//
// Checks whether the `thread_local` storage duration specifier is supported.
@@ -512,14 +477,9 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
__cpp_lib_source_location >= 201907L) || \
(defined(ABSL_INTERNAL_CPLUSPLUS_LANG) && \
ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L)
-#ifdef __has_include
#if __has_include(<source_location>)
#define ABSL_HAVE_STD_SOURCE_LOCATION 1
#endif
-#else
-// No __has_include support, so just assume C++ language version is correct.
-#define ABSL_HAVE_STD_SOURCE_LOCATION 1
-#endif
#endif
// ABSL_USES_STD_SOURCE_LOCATION
@@ -709,17 +669,6 @@ static_assert(ABSL_INTERNAL_INLINE_NAMESPACE_STR[0] != 'h' ||
#define ABSL_HAVE_LEAK_SANITIZER 1
#endif
-// ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
-//
-// Deprecated: always defined to 1.
-// Class template argument deduction is a language feature added in C++17,
-// which means all versions of C++ supported by Abseil have it.
-#ifdef ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION
-#error "ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION cannot be directly set."
-#else
-#define ABSL_HAVE_CLASS_TEMPLATE_ARGUMENT_DEDUCTION 1
-#endif
-
// `ABSL_INTERNAL_HAS_RTTI` determines whether abseil is being compiled with
// RTTI support.
#ifdef ABSL_INTERNAL_HAS_RTTI
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/const_init.h b/deps/v8/third_party/abseil-cpp/absl/base/const_init.h
index 16520b61d95..28dee6f3d19 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/const_init.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/const_init.h
@@ -30,8 +30,8 @@
// undefined behavior, unless their constructors and destructors are designed
// with this issue in mind.
//
-// The normal way to deal with this issue in C++11 is to use constant
-// initialization and trivial destructors.
+// The normal way to deal with this issue is to use constant initialization and
+// trivial destructors.
//
// Constant initialization is guaranteed to occur before any other code
// executes. Constructors that are declared 'constexpr' are eligible for
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/fast_type_id_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/fast_type_id_test.cc
index d27d9fa4cb9..a957d70b99b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/fast_type_id_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/fast_type_id_test.cc
@@ -16,6 +16,7 @@
#include <cstddef>
#include <cstdint>
+#include <iterator>
#include <map>
#include <vector>
@@ -61,7 +62,7 @@ TEST(FastTypeIdTest, PrimitiveTypes) {
};
// clang-format on
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kTypeIds); ++i) {
+ for (size_t i = 0; i < std::size(kTypeIds); ++i) {
EXPECT_EQ(kTypeIds[i], kTypeIds[i]);
for (size_t j = 0; j < i; ++j) {
EXPECT_NE(kTypeIds[i], kTypeIds[j]);
@@ -97,7 +98,7 @@ TEST(FastTypeIdTest, FixedWidthTypes) {
};
// clang-format on
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kTypeIds); ++i) {
+ for (size_t i = 0; i < std::size(kTypeIds); ++i) {
EXPECT_EQ(kTypeIds[i], kTypeIds[i]);
for (size_t j = 0; j < i; ++j) {
EXPECT_NE(kTypeIds[i], kTypeIds[j]);
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/cpu_detect.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/cpu_detect.cc
index 52758887317..a939bbfaa78 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/cpu_detect.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/cpu_detect.cc
@@ -26,7 +26,7 @@
#endif
#if defined(__aarch64__) && defined(__APPLE__)
-#if defined(__has_include) && __has_include(<arm/cpu_capabilities_public.h>)
+#if __has_include(<arm/cpu_capabilities_public.h>)
#include <arm/cpu_capabilities_public.h>
#endif
#include <sys/sysctl.h>
@@ -350,31 +350,34 @@ static std::optional<T> ReadSysctlByName(const char* name) {
}
bool SupportsArmCRC32PMULL() {
+ static const bool supported = []() {
// Newer XNU kernels support querying all capabilities in a single
// sysctlbyname.
#if defined(CAP_BIT_CRC32) && defined(CAP_BIT_FEAT_PMULL)
- static const std::optional<uint64_t> caps =
- ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
- if (caps.has_value()) {
- constexpr uint64_t kCrc32AndPmullCaps =
- (uint64_t{1} << CAP_BIT_CRC32) | (uint64_t{1} << CAP_BIT_FEAT_PMULL);
- return (*caps & kCrc32AndPmullCaps) == kCrc32AndPmullCaps;
- }
+ const std::optional<uint64_t> caps =
+ ReadSysctlByName<uint64_t>("hw.optional.arm.caps");
+ if (caps.has_value()) {
+ constexpr uint64_t kCrc32AndPmullCaps =
+ (uint64_t{1} << CAP_BIT_CRC32) | (uint64_t{1} << CAP_BIT_FEAT_PMULL);
+ return (*caps & kCrc32AndPmullCaps) == kCrc32AndPmullCaps;
+ }
#endif
- // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3915619
- static const std::optional<int> armv8_crc32 =
- ReadSysctlByName<int>("hw.optional.armv8_crc32");
- if (armv8_crc32.value_or(0) == 0) {
- return false;
- }
- // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
- static const std::optional<int> feat_pmull =
- ReadSysctlByName<int>("hw.optional.arm.FEAT_PMULL");
- if (feat_pmull.value_or(0) == 0) {
- return false;
- }
- return true;
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3915619
+ const std::optional<int> armv8_crc32 =
+ ReadSysctlByName<int>("hw.optional.armv8_crc32");
+ if (armv8_crc32.value_or(0) == 0) {
+ return false;
+ }
+ // https://developer.apple.com/documentation/kernel/1387446-sysctlbyname/determining_instruction_set_characteristics#3918855
+ const std::optional<int> feat_pmull =
+ ReadSysctlByName<int>("hw.optional.arm.FEAT_PMULL");
+ if (feat_pmull.value_or(0) == 0) {
+ return false;
+ }
+ return true;
+ }();
+ return supported;
}
bool SupportsBmi2() { return false; }
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.cc
index 99466015096..af6babf6a93 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.cc
@@ -28,6 +28,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/unscaledcycleclock.h"
+#include "absl/base/internal/unscaledcycleclock_config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.h
index cbfdf579987..5abffa566aa 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/cycleclock.h
@@ -49,6 +49,7 @@
#include "absl/base/config.h"
#include "absl/base/internal/cycleclock_config.h"
#include "absl/base/internal/unscaledcycleclock.h"
+#include "absl/base/internal/unscaledcycleclock_config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 1beb2ee4e52..f56ba239873 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
@@ -35,8 +35,10 @@
#include <linux/unistd.h>
#include <unistd.h>
+
#include <cerrno>
#include <cstdarg>
+#include <cstddef>
#include <cstdint>
#ifdef __mips__
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/endian_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/endian_test.cc
index a1691b1f82c..0671951f228 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/endian_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/endian_test.cc
@@ -15,13 +15,16 @@
#include "absl/base/internal/endian.h"
#include <algorithm>
+#include <cstddef>
#include <cstdint>
+#include <ios>
#include <limits>
#include <random>
#include <vector>
#include "gtest/gtest.h"
#include "absl/base/config.h"
+#include "absl/base/internal/unaligned_access.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/errno_saver_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/errno_saver_test.cc
index e9b742c588b..06be72036bd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/errno_saver_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/errno_saver_test.cc
@@ -15,6 +15,7 @@
#include "absl/base/internal/errno_saver.h"
#include <cerrno>
+#include <ostream>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
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 330fff90b5f..7082da78a86 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
@@ -646,8 +646,7 @@ class ThrowingAllocator : private exceptions_internal::TrackedObject {
using size_type = size_t;
using difference_type = ptrdiff_t;
- using is_nothrow =
- std::integral_constant<bool, Spec == AllocSpec::kNoThrowAllocate>;
+ using is_nothrow = std::bool_constant<Spec == AllocSpec::kNoThrowAllocate>;
using propagate_on_container_copy_assignment = std::true_type;
using propagate_on_container_move_assignment = std::true_type;
using propagate_on_container_swap = std::true_type;
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.cc
deleted file mode 100644
index 9b11b99d310..00000000000
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening.cc
+++ /dev/null
@@ -1,34 +0,0 @@
-//
-// Copyright 2026 The Abseil Authors.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-
-#include "absl/base/internal/hardening.h"
-
-#include <atomic>
-
-#include "absl/base/config.h"
-#include "absl/base/macros.h"
-
-namespace absl {
-ABSL_NAMESPACE_BEGIN
-
-namespace base_internal {
-
-void SetAbslHardeningEnabled([[maybe_unused]] bool enabled) {
-}
-
-} // namespace base_internal
-
-ABSL_NAMESPACE_END
-} // namespace absl
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 ef6d3277c78..26957a3ada0 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
@@ -34,8 +34,6 @@ ABSL_NAMESPACE_BEGIN
namespace base_internal {
-void SetAbslHardeningEnabled(bool enabled);
-
// `HardeningAssert` performs runtime checks when Abseil Hardening is enabled,
// even if `NDEBUG` is defined.
//
@@ -132,20 +130,6 @@ constexpr void HardeningAssertNonNull(T ptr) {
#endif
}
-class ScopedSetAbslHardeningForTesting {
- private:
- bool prev_state_;
-
- public:
- explicit ScopedSetAbslHardeningForTesting([[maybe_unused]] bool enabled) {
- prev_state_ = false;
- SetAbslHardeningEnabled(enabled);
- }
- ~ScopedSetAbslHardeningForTesting() {
- absl::base_internal::SetAbslHardeningEnabled(prev_state_);
- }
-};
-
} // namespace base_internal
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening_test.cc
index f819331d297..cffa87cabc9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/hardening_test.cc
@@ -42,28 +42,14 @@ bool IsHardenedSlow() {
return hardened;
}
-class HardeningTest : public testing::Test {
- public:
- ~HardeningTest() override {
- absl::base_internal::SetAbslHardeningEnabled(true);
- }
-};
-
-class HardeningDeathTest : public testing::Test {
- public:
- ~HardeningDeathTest() override {
- absl::base_internal::SetAbslHardeningEnabled(true);
- }
-};
-
-TEST_F(HardeningTest, HardeningAssertSlow) {
+TEST(HardeningTest, HardeningAssertSlow) {
absl::base_internal::HardeningAssertSlow(true);
if (!IsHardenedSlow()) {
absl::base_internal::HardeningAssertSlow(false);
}
}
-TEST_F(HardeningDeathTest, HardeningAssertSlow) {
+TEST(HardeningDeathTest, HardeningAssertSlow) {
#if GTEST_HAS_DEATH_TEST
if (IsHardenedSlow()) {
// The underlying mechanism of termination varies, and may include SIGILL
@@ -73,114 +59,107 @@ TEST_F(HardeningDeathTest, HardeningAssertSlow) {
#endif
}
-TEST_F(HardeningTest, HardeningAssertGT) {
+TEST(HardeningTest, HardeningAssertGT) {
absl::base_internal::HardeningAssertGT(1, 0);
}
-TEST_F(HardeningDeathTest, HardeningAssertGT) {
+TEST(HardeningDeathTest, HardeningAssertGT) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertGT(1, 1), "");
EXPECT_DEATH(absl::base_internal::HardeningAssertGT(0, 1), "");
}
#endif
}
-TEST_F(HardeningTest, HardeningAssertGE) {
+TEST(HardeningTest, HardeningAssertGE) {
absl::base_internal::HardeningAssertGE(1, 0);
absl::base_internal::HardeningAssertGE(1, 1);
}
-TEST_F(HardeningDeathTest, HardeningAssertGE) {
+TEST(HardeningDeathTest, HardeningAssertGE) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertGE(0, 1), "");
}
#endif
}
-TEST_F(HardeningTest, HardeningAssertLT) {
+TEST(HardeningTest, HardeningAssertLT) {
absl::base_internal::HardeningAssertLT(0, 1);
}
-TEST_F(HardeningDeathTest, HardeningAssertLT) {
+TEST(HardeningDeathTest, HardeningAssertLT) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertLT(1, 1), "");
EXPECT_DEATH(absl::base_internal::HardeningAssertLT(1, 0), "");
}
#endif
}
-TEST_F(HardeningTest, HardeningAssertLE) {
+TEST(HardeningTest, HardeningAssertLE) {
absl::base_internal::HardeningAssertLE(0, 1);
absl::base_internal::HardeningAssertLE(1, 1);
}
-TEST_F(HardeningDeathTest, HardeningAssertLE) {
+TEST(HardeningDeathTest, HardeningAssertLE) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertLE(1, 0), "");
}
#endif
}
-TEST_F(HardeningTest, HardeningAssertInBounds) {
+TEST(HardeningTest, HardeningAssertInBounds) {
absl::base_internal::HardeningAssertInBounds(0, 10);
}
-TEST_F(HardeningDeathTest, HardeningAssertInBounds) {
+TEST(HardeningDeathTest, HardeningAssertInBounds) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertInBounds(10, 10), "");
}
#endif
}
-TEST_F(HardeningTest, HardeningAssertNonEmpty) {
+TEST(HardeningTest, HardeningAssertNonEmpty) {
std::vector<int> v = {1};
absl::base_internal::HardeningAssertNonEmpty(v);
}
-TEST_F(HardeningDeathTest, HardeningAssertNonEmpty) {
+TEST(HardeningDeathTest, HardeningAssertNonEmpty) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
std::vector<int> v = {};
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertNonEmpty(v), "");
}
#endif
}
-TEST_F(HardeningTest, HardeningAssertNonNull) {
+TEST(HardeningTest, HardeningAssertNonNull) {
int x = 1;
absl::base_internal::HardeningAssertNonNull(&x);
}
-TEST_F(HardeningDeathTest, HardeningAssertNonNull) {
+TEST(HardeningDeathTest, HardeningAssertNonNull) {
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
// The underlying mechanism of termination varies, and may include SIGILL
// or SIGABRT.
int *x = nullptr;
- absl::base_internal::SetAbslHardeningEnabled(true);
EXPECT_DEATH(absl::base_internal::HardeningAssertNonNull(x), "");
}
#endif
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 8fdec09e887..3282076f492 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
@@ -17,16 +17,17 @@
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
+
#include <thread> // NOLINT(build/c++11)
#include <unordered_map>
#include <utility>
+#include "absl/container/node_hash_map.h"
+
#ifdef __EMSCRIPTEN__
#include <emscripten.h>
#endif
-#include "absl/container/node_hash_map.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
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 bba27ef75fb..04e44e94fa2 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
@@ -19,6 +19,7 @@
#define ABSL_BASE_INTERNAL_LOW_LEVEL_SCHEDULING_H_
#include <atomic>
+#include <cstdint>
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/scheduling_mode.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.cc
index 8537f3ec520..7c39f6d3ce7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.cc
@@ -21,16 +21,16 @@
#include <cstring>
#include <string>
-#ifdef __EMSCRIPTEN__
-#include <emscripten/console.h>
-#endif
-
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/atomic_hook.h"
#include "absl/base/internal/errno_saver.h"
#include "absl/base/log_severity.h"
+#ifdef __EMSCRIPTEN__
+#include <emscripten/console.h>
+#endif
+
// We know how to perform low-level writes to stderr in POSIX and Windows. For
// these platforms, we define the token ABSL_LOW_LEVEL_WRITE_SUPPORTED.
// Much of raw_logging.cc becomes a no-op when we can't output messages,
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.h
index d7cfbc576b8..8637030f70f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/raw_logging.h
@@ -19,6 +19,7 @@
#ifndef ABSL_BASE_INTERNAL_RAW_LOGGING_H_
#define ABSL_BASE_INTERNAL_RAW_LOGGING_H_
+#include <cstddef>
#include <string>
#include "absl/base/attributes.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 8a934cb5119..b13e7a2410b 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
@@ -14,14 +14,14 @@
#include "absl/base/internal/scoped_set_env.h"
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
#include <cstdlib>
#include "absl/base/internal/raw_logging.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env_test.cc
index 5cbad246c64..6d6775a8777 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/scoped_set_env_test.cc
@@ -12,13 +12,17 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "absl/base/internal/scoped_set_env.h"
+
+#include <cstdlib>
+#include <string>
+
+#include "gtest/gtest.h"
+
#ifdef _WIN32
#include <windows.h>
#endif
-#include "gtest/gtest.h"
-#include "absl/base/internal/scoped_set_env.h"
-
namespace {
using absl::base_internal::ScopedSetEnv;
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 519b93f4966..e9c4c23b8fa 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
@@ -61,7 +61,7 @@ std::string StrErrorInternal(int errnum) {
}
// kSysNerr is the number of errors from a recent glibc. `StrError()` falls back
-// to `StrErrorAdaptor()` if the value is larger than this.
+// to `StrErrorInternal()` if the value is larger than this.
constexpr int kSysNerr = 135;
std::array<std::string, kSysNerr>* NewStrErrorTable() {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.cc b/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.cc
index b103f49edff..1f380bcc60b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.cc
@@ -14,7 +14,26 @@
#include "absl/base/internal/sysinfo.h"
+#include <string.h>
+
+#include <cassert>
+#include <cerrno>
+#include <cstdint>
+#include <cstdio>
+#include <cstdlib>
+#include <ctime>
+#include <limits>
+#include <thread> // NOLINT(build/c++11)
+#include <utility>
+#include <vector>
+
#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"
+#include "absl/base/internal/unscaledcycleclock.h"
+#include "absl/base/thread_annotations.h"
#ifdef _WIN32
#include <windows.h>
@@ -50,26 +69,6 @@
#include <zircon/process.h>
#endif
-#include <string.h>
-
-#include <cassert>
-#include <cerrno>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-#include <ctime>
-#include <limits>
-#include <thread> // NOLINT(build/c++11)
-#include <utility>
-#include <vector>
-
-#include "absl/base/call_once.h"
-#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/spinlock.h"
-#include "absl/base/internal/unscaledcycleclock.h"
-#include "absl/base/thread_annotations.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.h
index 119cf1f0e85..94df348a45b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/sysinfo.h
@@ -24,15 +24,15 @@
#ifndef ABSL_BASE_INTERNAL_SYSINFO_H_
#define ABSL_BASE_INTERNAL_SYSINFO_H_
-#ifndef _WIN32
-#include <sys/types.h>
-#endif
-
#include <cstdint>
#include "absl/base/config.h"
#include "absl/base/port.h"
+#ifndef _WIN32
+#include <sys/types.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
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 b4c75f50ee9..7248fde9add 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
@@ -14,11 +14,6 @@
#include "absl/base/internal/sysinfo.h"
-#ifndef _WIN32
-#include <sys/types.h>
-#include <unistd.h>
-#endif
-
#include <thread> // NOLINT(build/c++11)
#include <unordered_set>
#include <vector>
@@ -27,6 +22,11 @@
#include "absl/synchronization/barrier.h"
#include "absl/synchronization/mutex.h"
+#ifndef _WIN32
+#include <sys/types.h>
+#include <unistd.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
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 0471a25dcea..27b5816394a 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
@@ -14,15 +14,6 @@
#include "absl/base/internal/thread_identity.h"
-#if !defined(_WIN32) || defined(__MINGW32__)
-#include <pthread.h>
-#ifndef __wasi__
-// WASI does not provide this header, either way we disable use
-// of signals with it below.
-#include <signal.h>
-#endif
-#endif
-
#include <atomic>
#include <cassert>
#include <memory>
@@ -32,6 +23,15 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
+#if !defined(_WIN32) || defined(__MINGW32__)
+#include <pthread.h>
+#ifndef __wasi__
+// WASI does not provide this header, either way we disable use
+// of signals with it below.
+#include <signal.h>
+#endif
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace base_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.h
index 0c2d6195cb7..a9f26d06557 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/thread_identity.h
@@ -20,20 +20,22 @@
#ifndef ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
#define ABSL_BASE_INTERNAL_THREAD_IDENTITY_H_
-#ifndef _WIN32
-#include <pthread.h>
-// Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when
-// supported.
-#include <unistd.h>
-#endif
-
#include <atomic>
+#include <cstddef>
#include <cstdint>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/per_thread_tls.h"
#include "absl/base/optimization.h"
+#ifndef _WIN32
+#include <pthread.h>
+// Defines __GOOGLE_GRTE_VERSION__ (via glibc-specific features.h) when
+// supported.
+#include <unistd.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
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 3ef2ffe540e..94beaa836bf 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
@@ -14,6 +14,7 @@
#include "absl/base/internal/thread_identity.h"
+#include <cstdint>
#include <thread> // NOLINT(build/c++11)
#include <vector>
@@ -22,6 +23,7 @@
#include "absl/base/internal/spinlock.h"
#include "absl/base/macros.h"
#include "absl/base/thread_annotations.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/per_thread_sem.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h
index 39207d8a5c4..e2d3d931913 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/tsan_mutex_interface.h
@@ -16,6 +16,8 @@
// It provides ThreadSanitizer annotations for custom mutexes.
// See <sanitizer/tsan_interface.h> for meaning of these annotations.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
#define ABSL_BASE_INTERNAL_TSAN_MUTEX_INTERFACE_H_
@@ -30,11 +32,10 @@
#error "ABSL_INTERNAL_HAVE_TSAN_INTERFACE cannot be directly set."
#endif
-#if defined(ABSL_HAVE_THREAD_SANITIZER) && defined(__has_include)
-#if __has_include(<sanitizer/tsan_interface.h>)
+#if defined(ABSL_HAVE_THREAD_SANITIZER) && \
+ __has_include(<sanitizer/tsan_interface.h>)
#define ABSL_INTERNAL_HAVE_TSAN_INTERFACE 1
#endif
-#endif
#ifdef ABSL_INTERNAL_HAVE_TSAN_INTERFACE
#include <sanitizer/tsan_interface.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 73e4145e5c1..9e931808412 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,8 @@
#include "absl/base/internal/unscaledcycleclock.h"
+#include "absl/base/internal/unscaledcycleclock_config.h"
+
#if ABSL_USE_UNSCALED_CYCLECLOCK
#if defined(_WIN32)
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h b/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h
index fb5751b5664..c8a4e4b7e0d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/internal/unscaledcycleclock.h
@@ -38,13 +38,13 @@
#include <cstdint>
+#include "absl/base/config.h"
+#include "absl/base/internal/unscaledcycleclock_config.h"
+
#if defined(__APPLE__)
#include <TargetConditionals.h>
#endif
-#include "absl/base/config.h"
-#include "absl/base/internal/unscaledcycleclock_config.h"
-
#if ABSL_USE_UNSCALED_CYCLECLOCK
namespace gloop_do_not_use {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/log_severity_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/log_severity_test.cc
index 3394ecd790f..7b92b4fbfca 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/log_severity_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/log_severity_test.cc
@@ -27,6 +27,7 @@
#include "absl/flags/internal/flag.h"
#include "absl/flags/marshalling.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
namespace {
using ::testing::Eq;
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/macros.h b/deps/v8/third_party/abseil-cpp/absl/base/macros.h
index 263dd04193f..e3a8563b124 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/macros.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/macros.h
@@ -43,6 +43,9 @@
// Returns the number of elements in an array as a compile-time constant, which
// can be used in defining new arrays. If you use this macro on a pointer by
// mistake, you will get a compile-time error.
+//
+// NOTE: Avoid using this macro. Instead, use std::size(a) if possible, or
+// std::extent_v<decltype(a)> otherwise.
#define ABSL_ARRAYSIZE(array) \
(sizeof(::absl::macros_internal::ArraySizeHelper(array)))
@@ -113,10 +116,9 @@ ABSL_NAMESPACE_END
// ABSL_ASSERT()
//
-// In C++11, `assert` can't be used portably within constexpr functions.
-// `assert` also generates spurious unused-symbol warnings.
-// ABSL_ASSERT functions as a runtime assert but works in C++11 constexpr
-// functions, and maintains references to symbols. Example:
+// `assert` generates spurious unused-symbol warnings when NDEBUG is defined.
+// ABSL_ASSERT functions as a runtime assert but maintains references to
+// symbols even under NDEBUG. Example:
//
// constexpr double Divide(double a, double b) {
// return ABSL_ASSERT(b != 0), a / b;
@@ -158,12 +160,12 @@ ABSL_NAMESPACE_END
// See `ABSL_OPTION_HARDENED` in `absl/base/options.h` for more information on
// hardened mode.
#if (ABSL_OPTION_HARDENED == 1 || ABSL_OPTION_HARDENED == 2) && defined(NDEBUG)
- #define ABSL_HARDENING_ASSERT(expr) \
- do { \
- if (!ABSL_PREDICT_TRUE((expr))) { \
- ABSL_INTERNAL_HARDENING_ABORT(); \
- } \
- } while (false)
+#define ABSL_HARDENING_ASSERT(expr) \
+ do { \
+ if (!ABSL_PREDICT_TRUE((expr))) { \
+ ABSL_INTERNAL_HARDENING_ABORT(); \
+ } \
+ } while (false)
#else
#define ABSL_HARDENING_ASSERT(expr) ABSL_ASSERT(expr)
#endif
@@ -243,7 +245,7 @@ ABSL_NAMESPACE_END
// Note: go/cpp-inliner is Google-internal service for automated refactoring.
// While open-source users do not have access to this service, the macro is
// provided for compatibility.
-#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate)
+#if ABSL_HAVE_CPP_ATTRIBUTE(clang::annotate) && !defined(__NVCC__)
#define ABSL_REFACTOR_INLINE \
_Pragma("clang diagnostic push") /* Avoid errors on using-declarations */ \
_Pragma("clang diagnostic ignored \"-Wcxx-attribute-extension\"") \
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/options.h b/deps/v8/third_party/abseil-cpp/absl/base/options.h
index c9f30847309..332ab13c0cf 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/options.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/options.h
@@ -109,8 +109,8 @@
// implemented as aliases to the std:: ordering types, or as an independent
// implementation.
//
-// A value of 0 means to use Abseil's implementation. This requires only C++11
-// support, and is expected to work on every toolchain we support.
+// A value of 0 means to use Abseil's implementation. This is expected to
+// work on every toolchain we support.
//
// A value of 1 means to use aliases. This requires that all code using Abseil
// is built in C++20 mode or later.
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/policy_checks.h b/deps/v8/third_party/abseil-cpp/absl/base/policy_checks.h
index 88b5774399b..45fe3d5b847 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/policy_checks.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/policy_checks.h
@@ -52,7 +52,7 @@
#error "This package requires Visual Studio 2022 (MSVC++ 17.0) or higher."
#endif
-// We support GCC 7 and later.
+// We support GCC 10 and later.
// This minimum will go up.
#if defined(__GNUC__) && !defined(__clang__)
#if __GNUC__ < 10
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/port.h b/deps/v8/third_party/abseil-cpp/absl/base/port.h
index 5bc4d6cd95d..485d2c04d51 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/port.h
+++ b/deps/v8/third_party/abseil-cpp/absl/base/port.h
@@ -15,6 +15,8 @@
// This files is a forwarding header for other headers containing various
// portability macros and functions.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_BASE_PORT_H_
#define ABSL_BASE_PORT_H_
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/prefetch_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/prefetch_test.cc
index ee219897cac..4e50bd17670 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/prefetch_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/prefetch_test.cc
@@ -14,6 +14,7 @@
#include "absl/base/prefetch.h"
+#include <cstring>
#include <memory>
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/raw_logging_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/raw_logging_test.cc
index f4f3445d19e..48158c024e5 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/raw_logging_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/raw_logging_test.cc
@@ -18,6 +18,7 @@
#include "absl/base/internal/raw_logging.h"
+#include <string>
#include <tuple>
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/spinlock_test_common.cc b/deps/v8/third_party/abseil-cpp/absl/base/spinlock_test_common.cc
index 6ac2e36c451..e198fafe682 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/spinlock_test_common.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/spinlock_test_common.cc
@@ -16,6 +16,7 @@
// spinlock. If the spinlock is working properly, all elements of the
// array should be equal at the end of the test.
+#include <cstddef>
#include <cstdint>
#include <limits>
#include <mutex> // NOLINT(build/c++11)
@@ -127,7 +128,7 @@ static void ThreadedTest(SpinLock* spinlock) {
}
#ifndef ABSL_HAVE_THREAD_SANITIZER
-static_assert(std::is_trivially_destructible<SpinLock>(), "");
+static_assert(std::is_trivially_destructible<SpinLock>());
#endif
TEST(SpinLock, StackNonCooperativeDisablesScheduling) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate.cc b/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate.cc
index b960edd100e..3ac399cc6e5 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate.cc
@@ -18,6 +18,7 @@
#include <functional>
#include <new>
#include <stdexcept>
+#include <string>
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate_test.cc b/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate_test.cc
index 3cbc171252e..c8fc1cdd2a8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/base/throw_delegate_test.cc
@@ -17,6 +17,7 @@
#include <functional>
#include <new>
#include <stdexcept>
+#include <string>
#include "gtest/gtest.h"
#include "absl/base/config.h"
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 3ec55593c9c..cf58b066e9a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/cleanup/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
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 0d407b2cf07..a413b7efeb2 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
@@ -97,22 +97,19 @@ TYPED_TEST(CleanupTest, FactoryProducesCorrectType) {
auto cleanup = absl::MakeCleanup(std::move(callback));
static_assert(
- IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(),
- "");
+ IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>());
}
{
auto cleanup = absl::MakeCleanup(&FnPtrFunction);
- static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
- "");
+ static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
}
{
auto cleanup = absl::MakeCleanup(FnPtrFunction);
- static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
- "");
+ static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
}
}
@@ -122,22 +119,19 @@ TYPED_TEST(CleanupTest, CTADProducesCorrectType) {
absl::Cleanup cleanup = std::move(callback);
static_assert(
- IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>(),
- "");
+ IsSame<absl::Cleanup<Tag, decltype(callback)>, decltype(cleanup)>());
}
{
absl::Cleanup cleanup = &FnPtrFunction;
- static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
- "");
+ static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
}
{
absl::Cleanup cleanup = FnPtrFunction;
- static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>(),
- "");
+ static_assert(IsSame<absl::Cleanup<Tag, void (*)()>, decltype(cleanup)>());
}
}
@@ -148,7 +142,7 @@ TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) {
absl::Cleanup deduction_cleanup = callback;
static_assert(
- IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+ IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
}
{
@@ -157,7 +151,7 @@ TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) {
absl::Cleanup deduction_cleanup = FunctorClassFactory::AsCallback([] {});
static_assert(
- IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+ IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
}
{
@@ -166,7 +160,7 @@ TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) {
absl::Cleanup deduction_cleanup = StdFunctionFactory::AsCallback([] {});
static_assert(
- IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+ IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
}
{
@@ -174,7 +168,7 @@ TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) {
absl::Cleanup deduction_cleanup = &FnPtrFunction;
static_assert(
- IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+ IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
}
{
@@ -182,7 +176,7 @@ TYPED_TEST(CleanupTest, FactoryAndCTADProduceSameType) {
absl::Cleanup deduction_cleanup = FnPtrFunction;
static_assert(
- IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>(), "");
+ IsSame<decltype(factory_cleanup), decltype(deduction_cleanup)>());
}
}
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 e535d9e8ecb..f9b0c5cea66 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/container/BUILD.bazel
@@ -91,7 +91,6 @@ cc_test(
":test_allocator",
"//absl/base:config",
"//absl/base:exception_testing",
- "//absl/base:hardening",
"//absl/base:iterator_traits_test_helper",
"//absl/hash:hash_testing",
"//absl/memory",
@@ -184,7 +183,6 @@ cc_test(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:exception_testing",
- "//absl/base:hardening",
"//absl/base:iterator_traits_test_helper",
"//absl/hash:hash_testing",
"//absl/log:check",
@@ -1287,8 +1285,8 @@ cc_library(
"//absl/container:__pkg__",
],
deps = [
+ ":test_instance_tracker",
"//absl/base:config",
- "//absl/container:test_instance_tracker",
"@googletest//:gtest",
],
)
@@ -1301,9 +1299,9 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":common",
+ ":flat_hash_set",
"//absl/base:config",
"//absl/base:core_headers",
- "//absl/container:flat_hash_set",
],
)
@@ -1313,17 +1311,17 @@ cc_test(
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
":heterogeneous_lookup_testing",
":linked_hash_set",
":test_allocator",
+ ":test_instance_tracker",
+ ":unordered_set_constructor_test",
+ ":unordered_set_lookup_test",
+ ":unordered_set_members_test",
+ ":unordered_set_modifiers_test",
"//absl/base:config",
- "//absl/container:hash_generator_testing",
- "//absl/container:hash_policy_testing",
- "//absl/container:test_instance_tracker",
- "//absl/container:unordered_set_constructor_test",
- "//absl/container:unordered_set_lookup_test",
- "//absl/container:unordered_set_members_test",
- "//absl/container:unordered_set_modifiers_test",
"//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1355,10 +1353,10 @@ cc_library(
visibility = ["//visibility:public"],
deps = [
":common",
+ ":flat_hash_set",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:throw_delegate",
- "//absl/container:flat_hash_set",
],
)
@@ -1368,18 +1366,18 @@ cc_test(
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
":heterogeneous_lookup_testing",
":linked_hash_map",
":test_allocator",
+ ":test_instance_tracker",
+ ":unordered_map_constructor_test",
+ ":unordered_map_lookup_test",
+ ":unordered_map_members_test",
+ ":unordered_map_modifiers_test",
"//absl/base:config",
"//absl/base:exception_testing",
- "//absl/container:hash_generator_testing",
- "//absl/container:hash_policy_testing",
- "//absl/container:test_instance_tracker",
- "//absl/container:unordered_map_constructor_test",
- "//absl/container:unordered_map_lookup_test",
- "//absl/container:unordered_map_members_test",
- "//absl/container:unordered_map_modifiers_test",
"//absl/strings:string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1425,7 +1423,6 @@ cc_test(
":chunked_queue",
":test_allocator",
"//absl/base:core_headers",
- "//absl/base:hardening",
"//absl/base:throw_delegate",
"//absl/strings",
"@googletest//:gtest",
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 a49dc289211..1c4de821920 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/container/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -10,7 +12,7 @@ absl_source_set("compressed_tuple") {
}
absl_test("compressed_tuple_test") {
- public = [ "internal/compressed_tuple_test.cc" ]
+ sources = [ "internal/compressed_tuple_test.cc" ]
deps = [
":compressed_tuple",
":test_instance_tracker",
@@ -40,18 +42,20 @@ absl_test("fixed_array_test") {
deps = [
":fixed_array",
":test_allocator",
- ":test_instance_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:exception_testing",
- "//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/base:iterator_traits_test_helper",
"//third_party/abseil-cpp/absl/hash:hash_testing",
"//third_party/abseil-cpp/absl/memory",
]
}
+# skipped because chromium doesn't use c++ exceptions
+# absl_test("fixed_array_exception_safety_test")
+
absl_source_set("inlined_vector_internal") {
public = [ "internal/inlined_vector.h" ]
+ visibility = [ ":*" ]
deps = [
":compressed_tuple",
"//third_party/abseil-cpp/absl/base:base_internal",
@@ -82,11 +86,11 @@ absl_source_set("inlined_vector") {
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",
]
- visibility = [ ":*" ]
}
absl_test("inlined_vector_test") {
@@ -98,7 +102,6 @@ absl_test("inlined_vector_test") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:exception_testing",
- "//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/base:iterator_traits_test_helper",
"//third_party/abseil-cpp/absl/hash:hash_testing",
"//third_party/abseil-cpp/absl/log:check",
@@ -107,12 +110,20 @@ absl_test("inlined_vector_test") {
]
}
+# skipped because chromium doesn't use c++ exceptions
+# absl_test("inlined_vector_exception_safety_test")
+
absl_source_set("test_instance_tracker") {
testonly = true
sources = [ "internal/test_instance_tracker.cc" ]
public = [ "internal/test_instance_tracker.h" ]
- deps = [ "//third_party/abseil-cpp/absl/types:compare" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ deps = [ "//third_party/abseil-cpp/absl/types:compare" ]
+}
+
+absl_test("test_instance_tracker_test") {
+ sources = [ "internal/test_instance_tracker_test.cc" ]
+ deps = [ ":test_instance_tracker" ]
}
absl_source_set("flat_hash_map") {
@@ -174,6 +185,7 @@ absl_test("flat_hash_set_test") {
"//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",
]
}
@@ -236,6 +248,7 @@ absl_test("node_hash_set_test") {
absl_source_set("container_memory") {
public = [ "internal/container_memory.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/hash",
@@ -246,21 +259,11 @@ absl_source_set("container_memory") {
}
# Disabled because container_memory_test requires -frtti
-# absl_test("container_memory_test") {
-# sources = [ "internal/container_memory_test.cc" ]
-# deps = [
-# ":container_memory",
-# ":test_instance_tracker",
-# "//third_party/abseil-cpp/absl/base:config",
-# "//third_party/abseil-cpp/absl/base:no_destructor",
-# "//third_party/abseil-cpp/absl/meta:type_traits",
-# "//third_party/abseil-cpp/absl/strings",
-# ]
-# }
+# absl_test("container_memory_test")
absl_source_set("hash_function_defaults") {
public = [ "internal/hash_function_defaults.h" ]
- visibility = [ "//third_party/abseil-cpp/absl/container:*" ]
+ visibility = [ ":*" ]
deps = [
":common",
"//third_party/abseil-cpp/absl/base:config",
@@ -291,6 +294,7 @@ absl_test("hash_function_defaults_test") {
"//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",
]
}
@@ -298,6 +302,7 @@ absl_source_set("hash_generator_testing") {
testonly = true
sources = [ "internal/hash_generator_testing.cc" ]
public = [ "internal/hash_generator_testing.h" ]
+ visibility = [ ":*" ]
deps = [
":hash_policy_testing",
"//third_party/abseil-cpp/absl/base:config",
@@ -305,6 +310,7 @@ 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",
]
}
@@ -312,14 +318,22 @@ absl_source_set("hash_generator_testing") {
absl_source_set("hash_policy_testing") {
testonly = true
public = [ "internal/hash_policy_testing.h" ]
+ visibility = [ ":*" ]
deps = [
"//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" ]
+}
+
absl_source_set("hash_policy_traits") {
public = [ "internal/hash_policy_traits.h" ]
+ visibility = [ ":*" ]
deps = [
":common_policy_traits",
":container_memory",
@@ -327,9 +341,17 @@ absl_source_set("hash_policy_traits") {
]
}
+absl_test("hash_policy_traits_test") {
+ sources = [ "internal/hash_policy_traits_test.cc" ]
+ deps = [
+ ":container_memory",
+ ":hash_policy_traits",
+ ]
+}
+
absl_source_set("common_policy_traits") {
public = [ "internal/common_policy_traits.h" ]
- visibility = [ "//third_party/abseil-cpp/absl/container:*" ]
+ visibility = [ ":*" ]
deps = [ "//third_party/abseil-cpp/absl/meta:type_traits" ]
}
@@ -343,20 +365,23 @@ absl_test("common_policy_traits_test") {
absl_source_set("hashtable_debug") {
public = [ "internal/hashtable_debug.h" ]
+ visibility = [ ":*" ]
deps = [ ":hashtable_debug_hooks" ]
}
absl_source_set("hashtable_debug_hooks") {
public = [ "internal/hashtable_debug_hooks.h" ]
+ visibility = [ ":*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("hashtablez_sampler") {
- public = [ "internal/hashtablez_sampler.h" ]
sources = [
"internal/hashtablez_sampler.cc",
"internal/hashtablez_sampler_force_weak_definition.cc",
]
+ public = [ "internal/hashtablez_sampler.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
@@ -373,8 +398,26 @@ absl_source_set("hashtablez_sampler") {
]
}
+absl_test("hashtablez_sampler_test") {
+ sources = [ "internal/hashtablez_sampler_test.cc" ]
+ deps = [
+ ":hashtablez_sampler",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/profiling:sample_recorder",
+ "//third_party/abseil-cpp/absl/random",
+ "//third_party/abseil-cpp/absl/synchronization",
+ "//third_party/abseil-cpp/absl/synchronization:thread_pool",
+ "//third_party/abseil-cpp/absl/time",
+ ]
+ if (is_win) {
+ sources = []
+ }
+}
+
absl_source_set("node_slot_policy") {
public = [ "internal/node_slot_policy.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -389,6 +432,7 @@ absl_test("node_slot_policy_test") {
absl_source_set("raw_hash_map") {
public = [ "internal/raw_hash_map.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":common_policy_traits",
":container_memory",
@@ -402,6 +446,7 @@ absl_source_set("raw_hash_map") {
absl_source_set("common") {
public = [ "internal/common.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/types:optional",
@@ -410,6 +455,7 @@ absl_source_set("common") {
absl_source_set("hashtable_control_bytes") {
public = [ "internal/hashtable_control_bytes.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -418,8 +464,17 @@ absl_source_set("hashtable_control_bytes") {
]
}
+absl_test("hashtable_control_bytes_test") {
+ sources = [ "internal/hashtable_control_bytes_test.cc" ]
+ deps = [
+ ":hashtable_control_bytes",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+}
+
absl_source_set("raw_hash_set_resize_impl") {
public = [ "internal/raw_hash_set_resize_impl.h" ]
+ visibility = [ ":*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -464,6 +519,7 @@ absl_source_set("raw_hash_set") {
}
# raw_hash_set_test uses typeid(), i.e., relies on RTTI.
+# absl_test("raw_hash_set_test")
absl_test("raw_hash_set_allocator_test") {
sources = [ "internal/raw_hash_set_allocator_test.cc" ]
@@ -477,6 +533,10 @@ absl_test("raw_hash_set_allocator_test") {
absl_source_set("layout") {
public = [ "internal/layout.h" ]
+ visibility = [
+ "//third_party/abseil-cpp:absl_component_deps",
+ "//third_party/abseil-cpp/absl/*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -502,6 +562,7 @@ absl_test("layout_test") {
absl_source_set("tracked") {
testonly = true
public = [ "internal/tracked.h" ]
+ visibility = [ ":*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -513,6 +574,7 @@ absl_source_set("unordered_map_constructor_test") {
":hash_generator_testing",
":hash_policy_testing",
"//third_party/abseil-cpp/absl/base:config",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -524,6 +586,7 @@ absl_source_set("unordered_map_lookup_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -535,6 +598,7 @@ absl_source_set("unordered_map_modifiers_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -548,6 +612,7 @@ absl_source_set("unordered_set_constructor_test") {
":hash_policy_testing",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -558,6 +623,7 @@ absl_source_set("unordered_set_members_test") {
visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -568,6 +634,7 @@ absl_source_set("unordered_map_members_test") {
visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/meta:type_traits",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -579,6 +646,7 @@ absl_source_set("unordered_set_lookup_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -590,12 +658,33 @@ absl_source_set("unordered_set_modifiers_test") {
deps = [
":hash_generator_testing",
":hash_policy_testing",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
+absl_test("unordered_set_test") {
+ sources = [ "internal/unordered_set_test.cc" ]
+ deps = [
+ ":unordered_set_constructor_test",
+ ":unordered_set_lookup_test",
+ ":unordered_set_members_test",
+ ":unordered_set_modifiers_test",
+ ]
+}
+
+absl_test("unordered_map_test") {
+ sources = [ "internal/unordered_map_test.cc" ]
+ deps = [
+ ":unordered_map_constructor_test",
+ ":unordered_map_lookup_test",
+ ":unordered_map_members_test",
+ ":unordered_map_modifiers_test",
+ ]
+}
+
absl_test("sample_element_size_test") {
- public = [ "sample_element_size_test.cc" ]
+ sources = [ "sample_element_size_test.cc" ]
deps = [
":flat_hash_map",
":flat_hash_set",
@@ -628,6 +717,7 @@ 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",
@@ -637,6 +727,7 @@ absl_source_set("btree") {
absl_source_set("btree_test_common") {
testonly = true
public = [ "btree_test.h" ]
+ visibility = [ ":*" ]
deps = [
":btree",
":flat_hash_set",
@@ -647,32 +738,16 @@ absl_source_set("btree_test_common") {
}
# TODO(mbonadei): Fix issue with EXPECT_DEATH and uncomment.
-# absl_test("btree_test") {
-# sources = [ "btree_test.cc" ]
-# deps = [
-# ":btree",
-# ":btree_test_common",
-# ":test_allocator",
-# ":test_instance_tracker",
-# "//third_party/abseil-cpp/absl/algorithm:container",
-# "//third_party/abseil-cpp/absl/base:core_headers",
-# "//third_party/abseil-cpp/absl/base:raw_logging_internal",
-# "//third_party/abseil-cpp/absl/flags:flag",
-# "//third_party/abseil-cpp/absl/hash:hash_testing",
-# "//third_party/abseil-cpp/absl/memory",
-# "//third_party/abseil-cpp/absl/random",
-# "//third_party/abseil-cpp/absl/strings",
-# "//third_party/abseil-cpp/absl/types:compare",
-# ]
-# }
+# absl_test("btree_test")
absl_source_set("heterogeneous_lookup_testing") {
testonly = true
public = [ "internal/heterogeneous_lookup_testing.h" ]
visibility = [ ":*" ]
deps = [
+ ":test_instance_tracker",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/container:test_instance_tracker",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -681,64 +756,60 @@ absl_source_set("linked_hash_set") {
public = [ "linked_hash_set.h" ]
deps = [
":common",
+ ":flat_hash_set",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
- "//third_party/abseil-cpp/absl/container:flat_hash_set",
]
}
absl_test("linked_hash_set_test") {
sources = [ "linked_hash_set_test.cc" ]
deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
":heterogeneous_lookup_testing",
":linked_hash_set",
":test_allocator",
+ ":test_instance_tracker",
+ ":unordered_set_constructor_test",
+ ":unordered_set_lookup_test",
+ ":unordered_set_members_test",
+ ":unordered_set_modifiers_test",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/container:hash_generator_testing",
- "//third_party/abseil-cpp/absl/container:hash_policy_testing",
- "//third_party/abseil-cpp/absl/container:test_instance_tracker",
- "//third_party/abseil-cpp/absl/container:unordered_set_constructor_test",
- "//third_party/abseil-cpp/absl/container:unordered_set_lookup_test",
- "//third_party/abseil-cpp/absl/container:unordered_set_members_test",
- "//third_party/abseil-cpp/absl/container:unordered_set_modifiers_test",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
-# absl_test("linked_hash_set_benchmark")
-
absl_source_set("linked_hash_map") {
public = [ "linked_hash_map.h" ]
deps = [
":common",
+ ":flat_hash_set",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:throw_delegate",
- "//third_party/abseil-cpp/absl/container:flat_hash_set",
]
}
absl_test("linked_hash_map_test") {
sources = [ "linked_hash_map_test.cc" ]
deps = [
+ ":hash_generator_testing",
+ ":hash_policy_testing",
":heterogeneous_lookup_testing",
":linked_hash_map",
":test_allocator",
+ ":test_instance_tracker",
+ ":unordered_map_constructor_test",
+ ":unordered_map_lookup_test",
+ ":unordered_map_members_test",
+ ":unordered_map_modifiers_test",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:exception_testing",
- "//third_party/abseil-cpp/absl/container:hash_generator_testing",
- "//third_party/abseil-cpp/absl/container:hash_policy_testing",
- "//third_party/abseil-cpp/absl/container:test_instance_tracker",
- "//third_party/abseil-cpp/absl/container:unordered_map_constructor_test",
- "//third_party/abseil-cpp/absl/container:unordered_map_lookup_test",
- "//third_party/abseil-cpp/absl/container:unordered_map_members_test",
- "//third_party/abseil-cpp/absl/container:unordered_map_modifiers_test",
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
-# absl_test("linked_hash_map_benchmark")
-
absl_source_set("chunked_queue") {
sources = [ "internal/chunked_queue.h" ]
public = [ "chunked_queue.h" ]
@@ -757,9 +828,7 @@ absl_test("chunked_queue_test") {
":chunked_queue",
":test_allocator",
"//third_party/abseil-cpp/absl/base:core_headers",
- "//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/base:throw_delegate",
"//third_party/abseil-cpp/absl/strings",
]
}
-# absl_test("chunked_queue_benchmark")
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 2f89efed1d4..effe790f7e3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/container/CMakeLists.txt
@@ -149,7 +149,6 @@ absl_cc_test(
absl::fixed_array
absl::config
absl::exception_testing
- absl::hardening
absl::hash_testing
absl::iterator_traits_test_helper_internal
absl::memory
@@ -236,7 +235,6 @@ absl_cc_test(
absl::config
absl::core_headers
absl::exception_testing
- absl::hardening
absl::hash_testing
absl::inlined_vector
absl::memory
@@ -1238,7 +1236,6 @@ absl_cc_test(
absl::chunked_queue
absl::config
absl::core_headers
- absl::hardening
absl::strings
absl::test_allocator
absl::throw_delegate
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 0746f72bd5b..257a6246de8 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
@@ -94,7 +94,7 @@ using map_params = typename ApplyWithoutDefaultSuffix<
typename btree_map_defaults<Key, Data>::IsMulti>,
TypeList<Key, Data, Compare, Alloc,
std::integral_constant<int, TargetNodeSize>,
- std::integral_constant<bool, IsMulti>>>::type;
+ std::bool_constant<IsMulti>>>::type;
} // namespace container_internal
@@ -371,11 +371,6 @@ class ABSL_ATTRIBUTE_OWNER btree_map
// does not contain an element with a matching key, this function returns an
// empty node handle.
//
- // NOTE: when compiled in an earlier version of C++ than C++17,
- // `node_type::key()` returns a const reference to the key instead of a
- // mutable reference. We cannot safely return a mutable reference without
- // std::launder (which is not available before C++17).
- //
// NOTE: In this context, `node_type` refers to the C++17 concept of a
// move-only type that owns and provides access to the elements in associative
// containers (https://en.cppreference.com/w/cpp/container/node_handle).
@@ -737,11 +732,6 @@ class ABSL_ATTRIBUTE_OWNER btree_multimap
// does not contain an element with a matching key, this function returns an
// empty node handle.
//
- // NOTE: when compiled in an earlier version of C++ than C++17,
- // `node_type::key()` returns a const reference to the key instead of a
- // mutable reference. We cannot safely return a mutable reference without
- // std::launder (which is not available before C++17).
- //
// NOTE: In this context, `node_type` refers to the C++17 concept of a
// move-only type that owns and provides access to the elements in associative
// containers (https://en.cppreference.com/w/cpp/container/node_handle).
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 2dbcc2c54dc..368c6a7b9e6 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
@@ -94,7 +94,7 @@ using set_params = typename ApplyWithoutDefaultSuffix<
typename btree_set_defaults<Key>::TargetNodeSize,
typename btree_set_defaults<Key>::IsMulti>,
TypeList<Key, Compare, Alloc, std::integral_constant<int, TargetNodeSize>,
- std::integral_constant<bool, IsMulti>>>::type;
+ std::bool_constant<IsMulti>>>::type;
} // namespace container_internal
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 86687770f94..5b76c34a0f4 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
@@ -766,15 +766,12 @@ struct NonTransparentCompare {
}
};
-template <typename T>
-bool CanEraseWithEmptyBrace(T t, decltype(t.erase({})) *) {
- return true;
-}
+template <class T, class = void>
+struct CanEraseWithEmptyBrace : std::false_type {};
-template <typename T>
-bool CanEraseWithEmptyBrace(T, ...) {
- return false;
-}
+template <class T>
+struct CanEraseWithEmptyBrace<
+ T, std::void_t<decltype(std::declval<T>().erase({}))*>> : std::true_type {};
template <typename T>
void TestHeterogeneous(T table) {
@@ -819,7 +816,7 @@ void TestHeterogeneous(T table) {
EXPECT_EQ(table.size() - 1, copy.size());
copy.erase({"5"});
EXPECT_EQ(table.size() - 2, copy.size());
- EXPECT_FALSE(CanEraseWithEmptyBrace(table, nullptr));
+ EXPECT_FALSE(CanEraseWithEmptyBrace<T>::value);
// Also run it with const T&.
if (std::is_class<T>()) TestHeterogeneous<const T &>(table);
@@ -1110,7 +1107,7 @@ class BtreeMapTest : public ::testing::Test {
struct Key {};
struct Cmp {
template <typename T>
- bool operator()(T, T) const {
+ [[maybe_unused]] bool operator()(T, T) const {
return false;
}
};
@@ -3533,7 +3530,7 @@ TEST(Btree, FieldTypeEqualsSlotType) {
// This breaks if we try to do layout_type::Pointer<slot_type> because
// slot_type is the same as field_type.
using set_type = absl::btree_set<uint8_t>;
- static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>(), "");
+ static_assert(BtreeNodePeer::FieldTypeEqualsSlotType<set_type>());
TestBasicFunctionality(set_type());
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue.h b/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue.h
index 0e686ca5a5d..8ada20853fa 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue.h
@@ -572,12 +572,6 @@ class chunked_queue {
AllocatorAndSize alloc_and_size_;
};
-template <typename T, size_t BLo, size_t BHi, typename Allocator>
-constexpr size_t chunked_queue<T, BLo, BHi, Allocator>::kBlockSizeMin;
-
-template <typename T, size_t BLo, size_t BHi, typename Allocator>
-constexpr size_t chunked_queue<T, BLo, BHi, Allocator>::kBlockSizeMax;
-
template <typename T, size_t BLo, size_t BHi, typename Allocator>
inline void swap(chunked_queue<T, BLo, BHi, Allocator>& a,
chunked_queue<T, BLo, BHi, Allocator>& b) noexcept {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue_test.cc
index 9540ff9413a..22ce9442786 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/chunked_queue_test.cc
@@ -31,7 +31,6 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/macros.h"
#include "absl/base/throw_delegate.h"
#include "absl/container/internal/test_allocator.h"
@@ -804,7 +803,6 @@ TEST(ChunkedQueue, Hardening) {
GTEST_SKIP() << "Not a hardened build";
}
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
absl::chunked_queue<int> q;
EXPECT_DEATH_IF_SUPPORTED(q.front(), "");
EXPECT_DEATH_IF_SUPPORTED(q.back(), "");
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/fixed_array.h b/deps/v8/third_party/abseil-cpp/absl/container/fixed_array.h
index 48ac57ff2d1..713c68528b2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/fixed_array.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/fixed_array.h
@@ -430,8 +430,8 @@ class ABSL_ATTRIBUTE_WARN_UNUSED FixedArray {
return std::addressof(ptr->array);
}
- static_assert(sizeof(StorageElement) == sizeof(value_type), "");
- static_assert(alignof(StorageElement) == alignof(value_type), "");
+ static_assert(sizeof(StorageElement) == sizeof(value_type));
+ static_assert(alignof(StorageElement) == alignof(value_type));
class NonEmptyInlinedStorage {
public:
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 81fb0e5edbd..71c6819bbdf 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
@@ -18,6 +18,7 @@
#include <cstring>
#include <forward_list>
+#include <iterator>
#include <list>
#include <memory>
#include <numeric>
@@ -31,7 +32,6 @@
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/base/internal/exception_testing.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/internal/iterator_traits_test_helper.h"
#include "absl/base/options.h"
#include "absl/container/internal/test_allocator.h"
@@ -197,7 +197,6 @@ TEST(FixedArrayTest, AtThrows) {
TEST(FixedArrayTest, Hardened) {
#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
absl::FixedArray<int> a = {1, 2, 3};
EXPECT_EQ(a[2], 3);
EXPECT_DEATH_IF_SUPPORTED(a[3], "");
@@ -361,20 +360,20 @@ static void TestArrayOfArrays(int n) {
TEST(IteratorConstructorTest, NonInline) {
int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
- absl::FixedArray<int, ABSL_ARRAYSIZE(kInput) - 1> const fixed(
- kInput, kInput + ABSL_ARRAYSIZE(kInput));
- ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
+ absl::FixedArray<int, std::size(kInput) - 1> const fixed(
+ kInput, kInput + std::size(kInput));
+ ASSERT_EQ(std::size(kInput), fixed.size());
+ for (size_t i = 0; i < std::size(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);
}
}
TEST(IteratorConstructorTest, Inline) {
int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
- absl::FixedArray<int, ABSL_ARRAYSIZE(kInput)> const fixed(
- kInput, kInput + ABSL_ARRAYSIZE(kInput));
- ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
+ absl::FixedArray<int, std::size(kInput)> const fixed(
+ kInput, kInput + std::size(kInput));
+ ASSERT_EQ(std::size(kInput), fixed.size());
+ for (size_t i = 0; i < std::size(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);
}
}
@@ -382,10 +381,9 @@ TEST(IteratorConstructorTest, Inline) {
TEST(IteratorConstructorTest, NonPod) {
char const* kInput[] = {"red", "orange", "yellow", "green",
"blue", "indigo", "violet"};
- absl::FixedArray<std::string> const fixed(kInput,
- kInput + ABSL_ARRAYSIZE(kInput));
- ASSERT_EQ(ABSL_ARRAYSIZE(kInput), fixed.size());
- for (size_t i = 0; i < ABSL_ARRAYSIZE(kInput); ++i) {
+ absl::FixedArray<std::string> const fixed(kInput, kInput + std::size(kInput));
+ ASSERT_EQ(std::size(kInput), fixed.size());
+ for (size_t i = 0; i < std::size(kInput); ++i) {
ASSERT_EQ(kInput[i], fixed[i]);
}
}
@@ -399,7 +397,7 @@ TEST(IteratorConstructorTest, FromEmptyVector) {
TEST(IteratorConstructorTest, FromNonEmptyVector) {
int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
- std::vector<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput));
+ std::vector<int> const items(kInput, kInput + std::size(kInput));
absl::FixedArray<int> const fixed(items.begin(), items.end());
ASSERT_EQ(items.size(), fixed.size());
for (size_t i = 0; i < items.size(); ++i) {
@@ -409,7 +407,7 @@ TEST(IteratorConstructorTest, FromNonEmptyVector) {
TEST(IteratorConstructorTest, FromBidirectionalIteratorRange) {
int const kInput[] = {2, 3, 5, 7, 11, 13, 17};
- std::list<int> const items(kInput, kInput + ABSL_ARRAYSIZE(kInput));
+ std::list<int> const items(kInput, kInput + std::size(kInput));
absl::FixedArray<int> const fixed(items.begin(), items.end());
EXPECT_THAT(fixed, testing::ElementsAreArray(kInput));
}
@@ -695,7 +693,7 @@ TEST(AllocatorSupportTest, CountOutoflineAllocations) {
const int ia[] = {0, 1, 2, 3, 4, 5, 6, 7};
Alloc alloc(&allocated, &active_instances);
- AllocFxdArr arr(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
+ AllocFxdArr arr(ia, ia + std::size(ia), alloc);
EXPECT_EQ(allocated, arr.size() * sizeof(int));
static_cast<void>(arr);
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 f8c3ba74d30..e11d7e2e796 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
@@ -439,11 +439,6 @@ class ABSL_ATTRIBUTE_OWNER flat_hash_map
// key value and returns a node handle owning that extracted data. If the
// `flat_hash_map` does not contain an element with a matching key, this
// function returns an empty node handle.
- //
- // NOTE: when compiled in an earlier version of C++ than C++17,
- // `node_type::key()` returns a const reference to the key instead of a
- // mutable reference. We cannot safely return a mutable reference without
- // std::launder (which is not available before C++17).
using Base::extract;
// flat_hash_map::merge()
@@ -691,10 +686,10 @@ struct FlatHashMapPolicy {
std::forward<Args>(args)...);
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return memory_internal::IsLayoutCompatible<K, V>::value
- ? &TypeErasedApplyToSlotFn<Hash, K, kIsDefault>
+ ? &TypeErasedApplyToSlotFn<Hash, K, kIsDefault, kSeedShift>
: nullptr;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc
index effbae37ac0..213cb70301a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/flat_hash_map_test.cc
@@ -66,7 +66,7 @@ template <class K, class V>
using Map = flat_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual,
Alloc<std::pair<const K, V>>>;
-static_assert(!std::is_standard_layout<NonStandardLayout>(), "");
+static_assert(!std::is_standard_layout<NonStandardLayout>());
using MapTypes =
::testing::Types<Map<int, int>, Map<std::string, int>,
@@ -92,7 +92,7 @@ TEST(FlatHashMap, StandardLayout) {
bool operator==(const Int& other) const { return value == other.value; }
size_t value;
};
- static_assert(std::is_standard_layout<Int>(), "");
+ static_assert(std::is_standard_layout<Int>());
struct Hash {
size_t operator()(const Int& obj) const { return obj.value; }
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 bd24ddeac9d..ed977431cc6 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
@@ -588,9 +588,9 @@ struct FlatHashSetPolicy {
static size_t space_used(const T*) { return 0; }
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
- return &TypeErasedApplyToSlotFn<Hash, T, kIsDefault>;
+ return &TypeErasedApplyToSlotFn<Hash, T, kIsDefault, kSeedShift>;
}
};
} // namespace container_internal
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 2694a5da4fe..8dfbf03c64c 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
@@ -893,8 +893,8 @@ class ABSL_ATTRIBUTE_WARN_UNUSED InlinedVector {
// Assumption check: we shouldn't be told to use memcpy to implement move
// assignment unless we have trivially destructible elements and an
// allocator that does nothing fancy.
- static_assert(std::is_trivially_destructible_v<value_type>, "");
- static_assert(std::is_same_v<A, std::allocator<value_type>>, "");
+ static_assert(std::is_trivially_destructible_v<value_type>);
+ static_assert(std::is_same_v<A, std::allocator<value_type>>);
// Throw away our existing heap allocation, if any. There is no need to
// destroy the existing elements one by one because we know they are
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 c9af35dbac0..73584edde34 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
@@ -32,7 +32,6 @@
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/base/internal/exception_testing.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/internal/iterator_traits_test_helper.h"
#include "absl/base/macros.h"
#include "absl/base/options.h"
@@ -295,7 +294,6 @@ TEST(IntVec, Hardened) {
Fill(&v, 10);
EXPECT_EQ(v[9], 9);
#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH_IF_SUPPORTED(v[10], "");
EXPECT_DEATH_IF_SUPPORTED(v[static_cast<size_t>(-1)], "");
#endif
@@ -1806,7 +1804,9 @@ TEST(AllocatorSupportTest, Constructors) {
MyAlloc alloc(&allocated);
{ AllocVec ABSL_ATTRIBUTE_UNUSED v; }
{ AllocVec ABSL_ATTRIBUTE_UNUSED v(alloc); }
- { AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc); }
+ {
+ AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + std::size(ia), alloc);
+ }
{ AllocVec ABSL_ATTRIBUTE_UNUSED v({1, 2, 3}, alloc); }
AllocVec v2;
@@ -1829,7 +1829,7 @@ TEST(AllocatorSupportTest, CountAllocations) {
EXPECT_THAT(bytes_allocated, Eq(0));
EXPECT_THAT(instance_count, Eq(0));
{
- AllocVec ABSL_ATTRIBUTE_UNUSED v(ia, ia + ABSL_ARRAYSIZE(ia), alloc);
+ AllocVec ABSL_ATTRIBUTE_UNUSED 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())));
@@ -1904,8 +1904,8 @@ TEST(AllocatorSupportTest, SwapBothAllocated) {
const int ia2[] = {0, 1, 2, 3, 4, 5, 6, 7, 8};
MyAlloc a1(&allocated1);
MyAlloc a2(&allocated2);
- AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
- AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
+ AllocVec v1(ia1, ia1 + std::size(ia1), a1);
+ AllocVec v2(ia2, ia2 + std::size(ia2), a2);
EXPECT_LT(v1.capacity(), v2.capacity());
EXPECT_THAT(allocated1,
Eq(static_cast<int64_t>(v1.capacity() * sizeof(int))));
@@ -1933,8 +1933,8 @@ TEST(AllocatorSupportTest, SwapOneAllocated) {
const int ia2[] = {0, 1, 2, 3};
MyAlloc a1(&allocated1);
MyAlloc a2(&allocated2);
- AllocVec v1(ia1, ia1 + ABSL_ARRAYSIZE(ia1), a1);
- AllocVec v2(ia2, ia2 + ABSL_ARRAYSIZE(ia2), a2);
+ AllocVec v1(ia1, ia1 + std::size(ia1), a1);
+ AllocVec v2(ia2, ia2 + std::size(ia2), a2);
EXPECT_THAT(allocated1,
Eq(static_cast<int64_t>(v1.capacity() * sizeof(int))));
EXPECT_THAT(allocated2, Eq(0));
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/btree.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/btree.h
index 5d84bc67706..55ff45731be 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/btree.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/btree.h
@@ -97,7 +97,8 @@ constexpr bool BtreeGenerationsEnabled() { return false; }
#endif
template <typename Compare, typename T, typename U>
-using compare_result_t = absl::result_of_t<const Compare(const T &, const U &)>;
+using compare_result_t =
+ std::invoke_result_t<const Compare, const T &, const U &>;
// A helper class that indicates if the Compare parameter is a key-compare-to
// comparator.
@@ -411,7 +412,7 @@ struct common_params : common_policy_traits<SlotPolicy> {
std::conditional_t<IsMap,
map_value_compare<original_key_compare, value_type>,
original_key_compare>;
- using is_map_container = std::integral_constant<bool, IsMap>;
+ using is_map_container = std::bool_constant<IsMap>;
// For the given lookup key type, returns whether we can have multiple
// equivalent keys in the btree. If this is a multi-container, then we can.
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 429bf31bb37..b2839e6e24d 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
@@ -194,8 +194,6 @@ class node_handle<Policy, PolicyTraits, Alloc,
constexpr node_handle() {}
- // When C++17 is available, we can use std::launder to provide mutable
- // access to the key. Otherwise, we provide const access.
auto key() const
-> decltype(PolicyTraits::mutable_key(std::declval<slot_type*>())) {
return PolicyTraits::mutable_key(this->slot());
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 2e1c7ab6ce9..4d0fb2a08e2 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
@@ -149,8 +149,7 @@ std::true_type Or(std::initializer_list<bool>);
// of CompressedTuple below.
template <typename... Ts>
constexpr bool ShouldAnyUseBase() {
- return decltype(
- Or({std::integral_constant<bool, ShouldUseBase<Ts>()>()...})){};
+ return decltype(Or({std::bool_constant<ShouldUseBase<Ts>()>()...})){};
}
template <typename T, typename V>
@@ -176,10 +175,9 @@ struct compressed_tuple_size<CompressedTuple<Es...>>
template <class T, class... Vs>
struct TupleItemsMoveConstructible
- : std::integral_constant<
- bool, TupleMoveConstructible<compressed_tuple_size<T>::value ==
- sizeof...(Vs),
- T, Vs...>::value> {};
+ : std::bool_constant<TupleMoveConstructible<
+ compressed_tuple_size<T>::value == sizeof...(Vs), T, Vs...>::value> {
+};
} // namespace internal_compressed_tuple
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 a30395bc488..fceb4ebaae1 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
@@ -60,7 +60,7 @@ struct alignas(Alignment) AlignedType {
// returns insufficiently alignment pointer, that's what you are going to get.
template <size_t Alignment, class Alloc>
void* Allocate(Alloc* alloc, size_t n) {
- static_assert(Alignment > 0, "");
+ static_assert(Alignment > 0);
assert(n && "n must be positive");
using M = AlignedType<Alignment>;
using A = typename std::allocator_traits<Alloc>::template rebind_alloc<M>;
@@ -84,14 +84,14 @@ constexpr auto IsDestructionTrivial() {
std::is_same_v<typename std::allocator_traits<
Allocator>::template rebind_alloc<char>,
std::allocator<char>>;
- return std::integral_constant<bool, result>();
+ return std::bool_constant<result>();
}
// The pointer must have been previously obtained by calling
// Allocate<Alignment>(alloc, n).
template <size_t Alignment, class Alloc>
void Deallocate(Alloc* alloc, void* p, size_t n) {
- static_assert(Alignment > 0, "");
+ static_assert(Alignment > 0);
assert(n && "n must be positive");
using M = AlignedType<Alignment>;
using A = typename std::allocator_traits<Alloc>::template rebind_alloc<M>;
@@ -144,10 +144,10 @@ auto TupleRefImpl(T&& t, std::index_sequence<Is...>)
template <class T>
auto TupleRef(T&& t) -> decltype(TupleRefImpl(
std::forward<T>(t),
- std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>())) {
+ std::make_index_sequence<std::tuple_size_v<std::decay_t<T>>>())) {
return TupleRefImpl(
std::forward<T>(t),
- std::make_index_sequence<std::tuple_size<std::decay_t<T>>::value>());
+ std::make_index_sequence<std::tuple_size_v<std::decay_t<T>>>());
}
template <class F, class K, class V>
@@ -167,7 +167,7 @@ template <class Alloc, class T, class Tuple>
void ConstructFromTuple(Alloc* alloc, T* ptr, Tuple&& t) {
memory_internal::ConstructFromTupleImpl(
alloc, ptr, std::forward<Tuple>(t),
- std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>());
+ std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>());
}
// Constructs T using the args specified in the tuple and calls F with the
@@ -177,7 +177,7 @@ decltype(std::declval<F>()(std::declval<T>())) WithConstructed(Tuple&& t,
F&& f) {
return memory_internal::WithConstructedImpl<T>(
std::forward<Tuple>(t),
- std::make_index_sequence<std::tuple_size<std::decay_t<Tuple>>::value>(),
+ std::make_index_sequence<std::tuple_size_v<std::decay_t<Tuple>>>(),
std::forward<F>(f));
}
@@ -486,9 +486,9 @@ 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>
+template <class Hash, bool kIsDefault, size_t kSeedShift>
struct HashElement {
- HashElement(const Hash& h, size_t s) : hash(h), seed(s) {}
+ 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 {
@@ -506,12 +506,12 @@ struct HashElement {
};
// No arguments function hash function for a specific key.
-template <class Hash, class Key, bool kIsDefault>
+template <class Hash, class Key, bool kIsDefault, 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>{hash, seed}(key);
+ return HashElement<Hash, kIsDefault, kSeedShift>{hash, seed}(key);
}
const Hash& hash;
const Key& key;
@@ -534,30 +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>
+template <class Fn, class T, bool kIsDefault, 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>{*f, seed}(*static_cast<const T*>(slot));
+ return HashElement<Fn, kIsDefault, 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>
+template <class Fn, class T, bool kIsDefault, 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>{*f, seed}(*slot);
+ return HashElement<Fn, kIsDefault, 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>
+template <class Fn, class T, bool kIsDefault, 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>{*f, seed}(slot->first);
+ return HashElement<Fn, kIsDefault, 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 9a8ba671ed6..1aa459c2c8a 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
@@ -313,10 +313,10 @@ 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>(
- &fn, &x, seed)),
- (HashElement<decltype(fn), /*kIsDefault=*/false>(fn, seed)(x)));
+ EXPECT_EQ((TypeErasedApplyToSlotFn<decltype(fn), size_t, /*kIsDefault=*/false,
+ /*kSeedShift=*/0>(&fn, &x, seed)),
+ (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/0>(
+ fn, seed)(x)));
}
TEST(ApplyTest, TypeErasedDerefAndApplyToSlotFn) {
@@ -324,10 +324,12 @@ TEST(ApplyTest, TypeErasedDerefAndApplyToSlotFn) {
size_t seed = 100;
auto fn = [](size_t v) { return v * 2; };
size_t* x_ptr = &x;
- EXPECT_EQ((TypeErasedDerefAndApplyToSlotFn<decltype(fn), size_t,
- /*kIsDefault=*/false>(&fn, &x_ptr,
- seed)),
- (HashElement<decltype(fn), /*kIsDefault=*/false>(fn, seed)(x)));
+ EXPECT_EQ(
+ (TypeErasedDerefAndApplyToSlotFn<decltype(fn), size_t,
+ /*kIsDefault=*/false,
+ /*kSeedShift=*/0>(&fn, &x_ptr, seed)),
+ (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/0>(
+ fn, seed)(x)));
}
TEST(HashElement, DefaultHash) {
@@ -339,7 +341,8 @@ TEST(HashElement, DefaultHash) {
return v * 2 + seed * 3;
}
} hash;
- EXPECT_EQ((HashElement<HashWithSeed, /*kIsDefault=*/true>(hash, seed)(x)),
+ EXPECT_EQ((HashElement<HashWithSeed, /*kIsDefault=*/true,
+ /*kSeedShift=*/0>(hash, seed)(x)),
hash.hash_with_seed(x, seed));
}
@@ -348,11 +351,21 @@ TEST(HashElement, NonDefaultHash) {
size_t seed = 100;
auto fn = [](size_t v) { return v * 2; };
EXPECT_EQ(
- (HashElement<decltype(fn), /*kIsDefault=*/false>(
+ (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/0>(
fn, seed)(x)),
fn(x) ^ seed);
}
+TEST(HashElement, NonDefaultHashWithSeedShift) {
+ size_t x = 7;
+ size_t seed = 100;
+ auto fn = [](size_t v) { return v * 2; };
+ EXPECT_EQ(
+ (HashElement<decltype(fn), /*kIsDefault=*/false, /*kSeedShift=*/1>(
+ fn, seed)(x)),
+ fn(x) ^ (seed >> 1));
+}
+
} // namespace
} // namespace container_internal
ABSL_NAMESPACE_END
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 e469d719580..beed150b1d1 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
@@ -146,7 +146,7 @@ template <class Policy, class = void>
return P::value(elem);
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, 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,9 +155,11 @@ 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>() == nullptr
- ? &hash_slot_fn_non_type_erased<Hash, kIsDefault>
- : Policy::template get_hash_slot_fn<Hash, kIsDefault>();
+ return Policy::template get_hash_slot_fn<Hash, kIsDefault, kSeedShift>() ==
+ nullptr
+ ? &hash_slot_fn_non_type_erased<Hash, kIsDefault, kSeedShift>
+ : Policy::template get_hash_slot_fn<Hash, kIsDefault,
+ kSeedShift>();
#if defined(__GNUC__) && !defined(__clang__)
#pragma GCC diagnostic pop
#endif
@@ -167,11 +169,12 @@ template <class Policy, class = void>
static constexpr bool soo_enabled() { return soo_enabled_impl(Rank1{}); }
private:
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, 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>{*static_cast<const Hash*>(hash_fn), seed},
+ HashElement<Hash, kIsDefault, 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 03de1322a1f..8d498e0ff0f 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
@@ -45,7 +45,7 @@ struct PolicyWithoutOptionalOps {
static std::function<int(int)> apply_impl;
static std::function<Slot&(Slot*)> value;
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -99,7 +99,7 @@ struct PolicyNoHashFn {
return fn(v);
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -108,9 +108,9 @@ struct PolicyNoHashFn {
size_t* PolicyNoHashFn::apply_called_count;
struct PolicyCustomHashFn : PolicyNoHashFn {
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
- return &TypeErasedApplyToSlotFn<Hash, int, kIsDefault>;
+ return &TypeErasedApplyToSlotFn<Hash, int, kIsDefault, kSeedShift>;
}
};
@@ -121,10 +121,11 @@ 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>();
+ Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>();
EXPECT_NE(fn, nullptr);
EXPECT_EQ(fn(&hasher, &value, 100),
- (HashElement<Hash, /*kIsDefault=*/false>(hasher, 100)(value)));
+ (HashElement<Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>(
+ hasher, 100)(value)));
EXPECT_EQ(apply_called_count, 1);
}
@@ -135,11 +136,13 @@ 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>();
- EXPECT_EQ(
- fn, (PolicyCustomHashFn::get_hash_slot_fn<Hash, /*kIsDefault=*/false>()));
+ Hash, /*kIsDefault=*/false, /*kSeedShift=*/6>();
+ EXPECT_EQ(fn,
+ (PolicyCustomHashFn::get_hash_slot_fn<Hash, /*kIsDefault=*/false,
+ /*kSeedShift=*/6>()));
EXPECT_EQ(fn(&hasher, &value, 100),
- (HashElement<Hash, /*kIsDefault=*/false>(hasher, 100)(value)));
+ (HashElement<Hash, /*kIsDefault=*/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_control_bytes.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h
index fd4dea4b74e..b70ac8c827d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/hashtable_control_bytes.h
@@ -24,6 +24,9 @@
#include <type_traits>
#include "absl/base/config.h"
+#include "absl/base/internal/endian.h"
+#include "absl/base/optimization.h"
+#include "absl/numeric/bits.h"
#ifdef ABSL_INTERNAL_HAVE_SSE2
#include <emmintrin.h>
@@ -41,10 +44,6 @@
#include <arm_neon.h>
#endif
-#include "absl/base/optimization.h"
-#include "absl/numeric/bits.h"
-#include "absl/base/internal/endian.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace container_internal {
@@ -125,9 +124,9 @@ template <class T, int SignificantBits, int Shift = 0,
bool NullifyBitsOnIteration = false>
class BitMask : public NonIterableBitMask<T, SignificantBits, Shift> {
using Base = NonIterableBitMask<T, SignificantBits, Shift>;
- static_assert(std::is_unsigned_v<T>, "");
- static_assert(Shift == 0 || Shift == 3, "");
- static_assert(!NullifyBitsOnIteration || Shift == 3, "");
+ static_assert(std::is_unsigned_v<T>);
+ static_assert(Shift == 0 || Shift == 3);
+ static_assert(!NullifyBitsOnIteration || Shift == 3);
public:
explicit BitMask(T mask) : Base(mask) {
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 e6491ba38af..5b9763e9738 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
@@ -76,7 +76,7 @@ using MoveIterator = typename std::move_iterator<Iterator<A>>;
template <typename A>
using IsMoveAssignOk = std::is_move_assignable<ValueType<A>>;
template <typename A>
-using IsSwapOk = absl::type_traits_internal::IsSwappable<ValueType<A>>;
+using IsSwapOk = std::is_swappable<ValueType<A>>;
template <typename A, bool IsTriviallyDestructible =
std::is_trivially_destructible_v<ValueType<A>> &&
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/layout.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/layout.h
index fac7d810548..0f9084ceb86 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/layout.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/layout.h
@@ -317,11 +317,10 @@ std::string TypeName() {
// Can `T` be a template argument of `Layout`?
template <class T>
using IsLegalElementType =
- std::integral_constant<bool,
- !std::is_reference_v<T> && !std::is_volatile_v<T> &&
- !std::is_reference_v<typename Type<T>::type> &&
- !std::is_volatile_v<typename Type<T>::type> &&
- adl_barrier::IsPow2(AlignOf<T>::value)>;
+ std::bool_constant<!std::is_reference_v<T> && !std::is_volatile_v<T> &&
+ !std::is_reference_v<typename Type<T>::type> &&
+ !std::is_volatile_v<typename Type<T>::type> &&
+ adl_barrier::IsPow2(AlignOf<T>::value)>;
template <class Elements, class StaticSizeSeq, class RuntimeSizeSeq,
class SizeSeq, class OffsetSeq>
@@ -387,7 +386,7 @@ class LayoutImpl<std::tuple<Elements...>, std::index_sequence<StaticSizeSeq...>,
template <size_t N>
using ElementAlignment =
- AlignOf<typename std::tuple_element<N, std::tuple<Elements...>>::type>;
+ AlignOf<std::tuple_element_t<N, std::tuple<Elements...>>>;
public:
// Element types of all arrays packed in a tuple.
@@ -395,7 +394,7 @@ class LayoutImpl<std::tuple<Elements...>, std::index_sequence<StaticSizeSeq...>,
// Element type of the Nth array.
template <size_t N>
- using ElementType = typename std::tuple_element<N, ElementTypes>::type;
+ using ElementType = std::tuple_element_t<N, ElementTypes>;
constexpr explicit LayoutImpl(IntToSize<RuntimeSizeSeq>... sizes)
: size_{sizes...} {}
@@ -739,8 +738,7 @@ class LayoutWithStaticSizes
// Requires: all arguments are convertible to `size_t`.
template <class... Sizes>
static constexpr PartialType<sizeof...(Sizes)> Partial(Sizes&&... sizes) {
- static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts),
- "");
+ static_assert(sizeof...(Sizes) + StaticSizeSeq::size() <= sizeof...(Ts));
return PartialType<sizeof...(Sizes)>(
static_cast<size_t>(std::forward<Sizes>(sizes))...);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_test.cc
index e99c56ac322..12039e9892a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/layout_test.cc
@@ -50,7 +50,7 @@ size_t Distance(const void* from, const void* to) {
template <class Expected, class Actual>
Expected Type(Actual val) {
- static_assert(std::is_same<Expected, Actual>(), "");
+ static_assert(std::is_same<Expected, Actual>());
return val;
}
@@ -73,20 +73,20 @@ struct alignas(8) Int64 {
};
// Properties of types that this test relies on.
-static_assert(sizeof(int8_t) == 1, "");
-static_assert(alignof(int8_t) == 1, "");
-static_assert(sizeof(int16_t) == 2, "");
-static_assert(alignof(int16_t) == 2, "");
-static_assert(sizeof(int32_t) == 4, "");
-static_assert(alignof(int32_t) == 4, "");
-static_assert(sizeof(Int64) == 8, "");
-static_assert(alignof(Int64) == 8, "");
-static_assert(sizeof(Int128) == 16, "");
-static_assert(alignof(Int128) == 8, "");
+static_assert(sizeof(int8_t) == 1);
+static_assert(alignof(int8_t) == 1);
+static_assert(sizeof(int16_t) == 2);
+static_assert(alignof(int16_t) == 2);
+static_assert(sizeof(int32_t) == 4);
+static_assert(alignof(int32_t) == 4);
+static_assert(sizeof(Int64) == 8);
+static_assert(alignof(Int64) == 8);
+static_assert(sizeof(Int128) == 16);
+static_assert(alignof(Int128) == 8);
template <class Expected, class Actual>
void SameType() {
- static_assert(std::is_same<Expected, Actual>(), "");
+ static_assert(std::is_same<Expected, Actual>());
}
TEST(Layout, ElementType) {
@@ -1435,9 +1435,9 @@ class TupleMatcher {
template <typename Tuple>
bool MatchAndExplain(const Tuple& p,
testing::MatchResultListener* /* listener */) const {
- static_assert(std::tuple_size<Tuple>::value == sizeof...(M), "");
+ static_assert(std::tuple_size_v<Tuple> == sizeof...(M));
return MatchAndExplainImpl(
- p, std::make_index_sequence<std::tuple_size<Tuple>::value>{});
+ p, std::make_index_sequence<std::tuple_size_v<Tuple>>{});
}
// For the matcher concept. Left empty as we don't really need the diagnostics
@@ -1450,8 +1450,7 @@ class TupleMatcher {
bool MatchAndExplainImpl(const Tuple& p, std::index_sequence<Is...>) const {
// Using std::min as a simple variadic "and".
return std::min(
- {true, testing::SafeMatcherCast<
- const typename std::tuple_element<Is, Tuple>::type&>(
+ {true, testing::SafeMatcherCast<const std::tuple_element_t<Is, Tuple>&>(
std::get<Is>(matchers_))
.Matches(std::get<Is>(p))...});
}
@@ -1597,52 +1596,50 @@ TEST(Layout, OverAligned) {
}
TEST(Layout, Alignment) {
- static_assert(Layout<int8_t>::Alignment() == 1, "");
- static_assert(Layout<int32_t>::Alignment() == 4, "");
- static_assert(Layout<Int64>::Alignment() == 8, "");
- static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64, "");
- static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8, "");
- static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8, "");
- static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8, "");
- static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8, "");
- static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8, "");
- static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
- static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8, "");
- static_assert(
- Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, "");
- static_assert(
- Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, "");
+ static_assert(Layout<int8_t>::Alignment() == 1);
+ static_assert(Layout<int32_t>::Alignment() == 4);
+ static_assert(Layout<Int64>::Alignment() == 8);
+ static_assert(Layout<Aligned<int8_t, 64>>::Alignment() == 64);
+ static_assert(Layout<int8_t, int32_t, Int64>::Alignment() == 8);
+ static_assert(Layout<int8_t, Int64, int32_t>::Alignment() == 8);
+ static_assert(Layout<int32_t, int8_t, Int64>::Alignment() == 8);
+ static_assert(Layout<int32_t, Int64, int8_t>::Alignment() == 8);
+ static_assert(Layout<Int64, int8_t, int32_t>::Alignment() == 8);
+ static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8);
+ static_assert(Layout<Int64, int32_t, int8_t>::Alignment() == 8);
+ static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() ==
+ 64);
+ static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() ==
+ 64);
}
TEST(Layout, StaticAlignment) {
- static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1, "");
- static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1, "");
- static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1, "");
- static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4, "");
- static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4, "");
- static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4, "");
- static_assert(
- Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() == 64, "");
- static_assert(
- Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() == 64, "");
- static_assert(
- Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() == 64, "");
+ static_assert(Layout<int8_t>::WithStaticSizes<>::Alignment() == 1);
+ static_assert(Layout<int8_t>::WithStaticSizes<0>::Alignment() == 1);
+ static_assert(Layout<int8_t>::WithStaticSizes<7>::Alignment() == 1);
+ static_assert(Layout<int32_t>::WithStaticSizes<>::Alignment() == 4);
+ static_assert(Layout<int32_t>::WithStaticSizes<0>::Alignment() == 4);
+ static_assert(Layout<int32_t>::WithStaticSizes<3>::Alignment() == 4);
+ static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<>::Alignment() ==
+ 64);
+ static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<0>::Alignment() ==
+ 64);
+ static_assert(Layout<Aligned<int8_t, 64>>::WithStaticSizes<2>::Alignment() ==
+ 64);
static_assert(
- Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8, "");
+ Layout<int32_t, Int64, int8_t>::WithStaticSizes<>::Alignment() == 8);
static_assert(
Layout<int32_t, Int64, int8_t>::WithStaticSizes<0, 0, 0>::Alignment() ==
- 8,
- "");
+ 8);
static_assert(
Layout<int32_t, Int64, int8_t>::WithStaticSizes<1, 1, 1>::Alignment() ==
- 8,
- "");
+ 8);
}
TEST(Layout, ConstexprPartial) {
constexpr size_t M = alignof(max_align_t);
constexpr Layout<unsigned char, Aligned<unsigned char, 2 * M>> x(1, 3);
- static_assert(x.Partial(1).template Offset<1>() == 2 * M, "");
+ static_assert(x.Partial(1).template Offset<1>() == 2 * M);
}
TEST(Layout, StaticConstexpr) {
@@ -1650,7 +1647,7 @@ TEST(Layout, StaticConstexpr) {
using L = Layout<unsigned char, Aligned<unsigned char, 2 * M>>;
using SL = L::WithStaticSizes<1, 3>;
constexpr SL x;
- static_assert(x.Offset<1>() == 2 * M, "");
+ static_assert(x.Offset<1>() == 2 * M);
}
// [from, to)
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/node_slot_policy.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/node_slot_policy.h
index 7213dda51b3..4a7dca27c4b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/node_slot_policy.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/node_slot_policy.h
@@ -47,7 +47,7 @@ namespace container_internal {
template <class Reference, class Policy>
struct node_slot_policy {
- static_assert(std::is_lvalue_reference_v<Reference>, "");
+ static_assert(std::is_lvalue_reference_v<Reference>);
using slot_type = std::remove_cv_t<std::remove_reference_t<Reference>>*;
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h
index 04e9e616e2b..8301b50d084 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_map.h
@@ -95,11 +95,11 @@ class raw_hash_map : public raw_hash_set<Policy, Params...> {
using key_type = typename Policy::key_type;
using mapped_type = typename Policy::mapped_type;
- static_assert(!std::is_reference_v<key_type>, "");
+ static_assert(!std::is_reference_v<key_type>);
// TODO(b/187807849): Evaluate whether to support reference mapped_type and
// remove this assertion if/when it is supported.
- static_assert(!std::is_reference_v<mapped_type>, "");
+ static_assert(!std::is_reference_v<mapped_type>);
using iterator = typename raw_hash_map::raw_hash_set::iterator;
using const_iterator = typename raw_hash_map::raw_hash_set::const_iterator;
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 d37c781f903..3f9263c4d3d 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
@@ -141,9 +141,8 @@ inline void* PrevSlot(void* slot, size_t slot_size) {
// Must be defined out-of-line to avoid MSVC error C2482 on some platforms,
// which is caused by non-constexpr initialization.
-uint16_t NextHashTableSeed() {
- static_assert(PerTableSeed::kBitCount <= 16);
- return static_cast<uint16_t>(RandomSeed());
+uint8_t NextHashTableSeed() {
+ return static_cast<uint8_t>(RandomSeed());
}
GenerationType* EmptyGeneration() {
@@ -943,6 +942,7 @@ void Clear(CommonFields& c, const PolicyFunctions& __restrict policy,
destroy_slot(&c, SingleSlotAddress<kSooEnabled>(c));
}
DecrementSmallSize<kSooEnabled>(c);
+ c.infoz().RecordStorageChanged(0, cap);
}
} else {
if (destroy_slot != nullptr) {
@@ -2289,7 +2289,10 @@ void Copy(CommonFields& common, const PolicyFunctions& __restrict policy,
const size_t slot_size = policy.slot_size;
const bool soo_enabled = policy.soo_enabled;
if (size == 1) {
- if (!soo_enabled) ReserveTableToFitNewSize(common, policy, 1);
+ if (!soo_enabled) {
+ ReserveEmptyNonAllocatedTableToFitNewSize(common, policy, 1);
+ common.infoz().RecordStorageChanged(1, 1);
+ }
IncrementSmallSize(common, policy);
const size_t other_capacity = other.capacity();
const void* other_slot =
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 e158cfc1533..ad416cd79b5 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
@@ -431,19 +431,22 @@ constexpr size_t PreviousCapacity(size_t n) {
// General notes on capacity/growth methods below:
// - We use 7/8th as maximum load factor. For 16-wide groups, that gives an
// average of two empty slots per group.
-// - For (capacity+1) >= Group::kWidth, growth is 7/8*capacity.
// - For (capacity+1) < Group::kWidth, growth == capacity. In this case, we
// never need to probe (the whole table fits in one group) so we don't need a
// load factor less than 1.
+// - For tables with capacity <= kMaxCapacityForLoadFactorOne, we leave one
+// empty slot.
+// - For capacity > kMaxCapacityForLoadFactorOne, growth is 7/8*capacity.
+constexpr inline size_t kMaxCapacityForLoadFactorOne = Group::kWidth * 4 - 1;
// Given `capacity`, applies the load factor; i.e., it returns the maximum
// number of values we should put into the table before a resizing rehash.
constexpr size_t CapacityToGrowth(size_t capacity) {
ABSL_SWISSTABLE_ASSERT(IsValidCapacity(capacity));
// `capacity*7/8`
- if (Group::kWidth == 8 && capacity == 7) {
- // x-x/8 does not work when x==7.
- return 6;
+ if (capacity <= kMaxCapacityForLoadFactorOne) {
+ // For small capacities we leave at most one empty slot.
+ return capacity - (capacity >= Group::kWidth - 1);
}
return capacity - capacity / 8;
}
@@ -460,7 +463,13 @@ constexpr size_t SizeToCapacity(size_t size) {
// The minimum possible capacity is NormalizeCapacity(size).
// Shifting right `~size_t{}` by `leading_zeros` yields
// NormalizeCapacity(size).
- int leading_zeros = absl::countl_zero(size);
+ int leading_zeros = absl::countl_zero(
+ size +
+ // Tables larger than half a group require at least one empty slot.
+ (size >= Group::kWidth / 2));
+ if (size < kMaxCapacityForLoadFactorOne) {
+ return (~size_t{}) >> leading_zeros;
+ }
constexpr size_t kLast3Bits = size_t{7} << (sizeof(size_t) * 8 - 3);
// max_size_for_next_capacity = max_load_factor * next_capacity
// = (7/8) * (~size_t{} >> leading_zeros)
@@ -469,10 +478,6 @@ constexpr size_t SizeToCapacity(size_t size) {
size_t max_size_for_next_capacity = kLast3Bits >> leading_zeros;
// Decrease shift if size is too big for the minimum capacity.
leading_zeros -= static_cast<int>(size > max_size_for_next_capacity);
- if constexpr (Group::kWidth == 8) {
- // Formula doesn't work when size==7 for 8-wide groups.
- leading_zeros -= (size == 7);
- }
return (~size_t{}) >> leading_zeros;
}
@@ -563,7 +568,9 @@ class HashtableCapacityImpl {
// We use these sentinel capacity values in debug mode to indicate different
// classes of bugs.
enum InvalidCapacity : IntType {
- kAboveMaxValidCapacity = (std::numeric_limits<IntType>::max)() - 100,
+ kAboveMaxValidCapacity = StorageMode == kCapacityByValue
+ ? (std::numeric_limits<IntType>::max)() - 100
+ : 64 - 10,
kReentrance,
kDestroyed,
@@ -585,61 +592,92 @@ template <HashtableCapacityStorageMode StorageMode>
class HashtableInlineDataImpl;
// Returns next per-table seed.
-uint16_t NextHashTableSeed();
+uint8_t NextHashTableSeed();
// Per table hash salt. This gets mixed into H1 to randomize iteration order
// per-table.
// The seed is needed to ensure non-determinism of iteration order.
-template <typename StorageType>
-class PerTableSeedImpl {
+class PerTableSeed {
public:
- using IntType = StorageType;
-
- // The number of bits in the seed.
- // It is big enough to ensure non-determinism of iteration order.
- // We store the seed inside a uint64_t together with size and other metadata.
- // Using 8 or 16 bits allows us to save one `and` instruction in H1 (we use
- // zero-extended move instead of mov+and). When absl::Hash is inlined, it can
- // also have lower latency knowing that the high bits of the seed are zero.
- static constexpr size_t kBitCount = sizeof(IntType) * 8;
-
- // We need to use a constant seed when the table is sampled so that sampled
- // hashes use the same seed and can e.g. identify stuck bits accurately.
- static constexpr IntType kSampledSeed = static_cast<IntType>(~IntType{0});
-
// Returns the seed for the table.
size_t seed() const { return seed_; }
private:
- template <HashtableCapacityStorageMode StorageMode>
+ template <HashtableCapacityStorageMode StorageModeOfData>
friend class HashtableInlineDataImpl;
- explicit PerTableSeedImpl(uint64_t seed)
- : seed_(static_cast<IntType>(seed)) {}
+ explicit PerTableSeed(uint64_t seed)
+ : seed_(static_cast<uint16_t>(seed)) {}
- const IntType seed_;
+ const uint16_t seed_;
+};
+
+// Represents blocked elements info: log2_period and tail_blocked.
+// Every `2**log2_period` is a blocked slot. The first blocked slot is at
+// index `2**log2_period-1`. E.g. if log2_period is 2, then every 4th slot
+// is blocked: 0, 1, 2, X, 4, 5, 6, X, ...
+//
+// tail_blocked is the number of blocked slots at the end in addition.
+// E.g., log2_period = 2 and tail_blocked = 3, then there are 6 blocked for
+// capacity = 15.
+// slots: 0, 1, 2, X, 4, 5, 6, X, 8, 9, 10, X, X, X, X, S. (S = sentinel)
+class BlockedInfo {
+ public:
+ constexpr BlockedInfo(uint8_t log2_period, uint8_t tail_blocked)
+ : log2_period_(log2_period), tail_blocked_(tail_blocked) {
+ ABSL_ASSUME(log2_period < 64);
+ }
+
+ // Returns the log2 of the period for blocked elements.
+ // Every `2**K` element is blocked starting from index `2**K - 1`.
+ constexpr uint8_t log2_period() const { return log2_period_; }
+ // Returns the number of blocked elements at the end of the table.
+ constexpr uint8_t tail_blocked() const { return tail_blocked_; }
+
+ // Returns the number of blocked elements before the given index.
+ // Doesn't account for tail_blocked because there are no useful indices in
+ // the blocked tail.
+ constexpr size_t blocked_before(size_t index) const {
+ return index >> log2_period();
+ }
+
+ // Returns the number of blocked elements in the table.
+ constexpr size_t total_blocked_count(size_t capacity) const {
+ return blocked_before(capacity) + tail_blocked();
+ }
+
+ private:
+ uint8_t log2_period_;
+ uint8_t tail_blocked_;
};
// 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
// the table.
-// 3) PerTableSeed::kBitCount bits for the seed. (For SOO tables, the lowest
-// bit of the seed is repurposed to track if sampling has been tried).
+// 3) kSeedBitCount bits for the seed. (For SOO tables, the lowest bit of the
+// seed is repurposed to track if sampling has been tried).
template <HashtableCapacityStorageMode StorageMode>
class HashtableInlineDataImpl {
+ // The number of bits in the seed. It is big enough to ensure
+ // non-determinism of iteration order. We store the seed inside a uint64_t
+ // together with size and other metadata. When absl::Hash is inlined, it can
+ // have lower latency knowing that the high bits of the seed are zero.
+ static constexpr size_t kSeedBitCount = 5;
+
public:
static constexpr HashtableCapacityStorageMode kStorageMode = StorageMode;
- using PerTableSeed = PerTableSeedImpl<
- std::conditional_t<StorageMode == kCapacityByValue, uint16_t, uint8_t>>;
using HashtableCapacity = HashtableCapacityImpl<StorageMode>;
static constexpr size_t kBlockedElementBitCount = 3;
static constexpr size_t kMaxBlockedElementCount =
(uint64_t{1} << kBlockedElementBitCount) - 1;
+ static constexpr size_t kCapacityBitCount =
+ StorageMode == kCapacityByValue ? sizeof(HashtableCapacity) * 8 : 6;
+ static constexpr size_t kCapacityBitStoredInDataCount =
+ StorageMode == kCapacityByValue ? 0 : kCapacityBitCount;
static constexpr size_t kSizeBitCount =
- 64 -
- (kBlockedElementBitCount + PerTableSeed::kBitCount + /*has_infoz*/ 1 +
- (StorageMode == kCapacityByValue ? 0 : sizeof(HashtableCapacity) * 8));
+ 64 - (kBlockedElementBitCount + kSeedBitCount +
+ /*has_infoz*/ 1 + kCapacityBitStoredInDataCount);
explicit HashtableInlineDataImpl(uninitialized_tag_t) {}
explicit HashtableInlineDataImpl(HashtableCapacity capacity,
@@ -683,18 +721,18 @@ class HashtableInlineDataImpl {
(data_ & kMetadataMask) | (static_cast<uint64_t>(size) << kSizeShift);
}
- PerTableSeed seed() const { return PerTableSeed(data_ & kSeedMask); }
-
- void generate_new_seed() {
- set_seed(static_cast<typename PerTableSeed::IntType>(NextHashTableSeed()));
+ PerTableSeed seed() const {
+ return PerTableSeed(ToPublicSeed(data_ & kSeedMask));
}
+ void generate_new_seed() { set_seed(NextHashTableSeed()); }
+
// We need to use a constant seed when the table is sampled so that sampled
// hashes use the same seed and can e.g. identify stuck bits accurately.
- void set_sampled_seed() { set_seed(PerTableSeed::kSampledSeed); }
+ void set_sampled_seed() { set_seed(kSampledSeed); }
bool is_sampled_seed() const {
- return seed().seed() == PerTableSeed::kSampledSeed;
+ return seed().seed() == ToPublicSeed(kSampledSeed);
}
// Returns true if the table has infoz.
@@ -723,34 +761,46 @@ class HashtableInlineDataImpl {
void set_no_seed_for_testing() { data_ &= ~kSeedMask; }
private:
- // Bit layout of `data_` from MSB to LSB:
- // (44 bits) : size
+ // Bit layout of `data_` and `capacity_internal_` from MSB to LSB:
+ // (55/49 bits) : size
// (3 bits) : blocked_element_count
// (1 bit) : has_infoz
- // (16 or 8 bits) : seed
+ // (5 bits) : seed
+ // (6 bits) : capacity (only for kCapacityByLog)
// 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 =
- PerTableSeed::kBitCount + 1 + kSizeBitCount + kBlockedElementBitCount;
+ kSeedBitCount + 1 + kSizeBitCount + kBlockedElementBitCount;
static constexpr size_t kSizeShift = kDataBitCount - kSizeBitCount;
static constexpr uint64_t kSizeOneNoMetadata = uint64_t{1} << kSizeShift;
static constexpr uint64_t kMetadataMask = kSizeOneNoMetadata - 1;
- static constexpr uint64_t kSeedMask =
- (uint64_t{1} << PerTableSeed::kBitCount) - 1;
+ static constexpr uint64_t kSeedMask = (uint64_t{1} << kSeedBitCount) - 1;
// The next bit after the seed.
static constexpr uint64_t kHasInfozMask = kSeedMask + 1;
- static constexpr uint64_t kBlockedElementsShift = PerTableSeed::kBitCount + 1;
+ static constexpr uint64_t kBlockedElementsShift = kSeedBitCount + 1;
static constexpr uint64_t kBlockedElementMask = kMaxBlockedElementCount
<< kBlockedElementsShift;
// 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;
- void set_seed(typename PerTableSeed::IntType seed) {
- data_ = (data_ & ~kSeedMask) | seed;
+ // We need to use a constant seed when the table is sampled so that sampled
+ // hashes use the same seed and can e.g. identify stuck bits accurately.
+ static constexpr uint8_t kSampledSeed = (1 << kSeedBitCount) - 1;
+
+ static constexpr uint64_t ToPublicSeed(uint64_t seed) {
+ // In kCapacityByLog mode, we shift public seed to the left to keep bits of
+ // the seed in the original place. It allows us to use single instruction to
+ // access the seed (e.g., `andl $0x7c0, %r8d`).
+ return seed << kCapacityBitStoredInDataCount;
+ }
+
+ void set_seed(uint8_t seed) {
+ data_ = (data_ & ~kSeedMask) | (seed & kSeedMask);
}
- uint64_t capacity_internal_ : sizeof(HashtableCapacity) * 8;
+ uint64_t capacity_internal_ : kCapacityBitCount;
uint64_t data_ : kDataBitCount;
};
@@ -770,7 +820,6 @@ using HashtableInlineData = HashtableInlineDataImpl<kCapacityByLog>;
#else
using HashtableInlineData = HashtableInlineDataImpl<kCapacityByValue>;
#endif // ABSL_SWISSTABLE_INTERNAL_ENABLE_CAPACITY_BY_VALUE
-using PerTableSeed = HashtableInlineData::PerTableSeed;
using HashtableCapacity = HashtableInlineData::HashtableCapacity;
// For large tables, we limit the number of blocked elements to maintain O(1)
@@ -2225,6 +2274,15 @@ class raw_hash_set {
constexpr static bool kIsDefaultHash =
std::is_same_v<hasher, absl::Hash<key_type>> ||
std::is_same_v<hasher, absl::container_internal::StringHash>;
+ // 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
+ // all 0s, and (c) we require random iteration order for small tables.
+ // In ToPublicSeed we shift the seed by kCapacityBitStoredInDataCount as
+ // 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),
@@ -3456,12 +3514,13 @@ class raw_hash_set {
}
template <class K>
ABSL_ATTRIBUTE_ALWAYS_INLINE size_t hash_of(const K& key) const {
- return HashElement<hasher, kIsDefaultHash>{hash_ref(),
- common().seed().seed()}(key);
+ return HashElement<hasher, kIsDefaultHash, 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>{hash_ref(), common().seed().seed()},
+ HashElement<hasher, kIsDefaultHash, kSeedShift>{hash_ref(),
+ common().seed().seed()},
PolicyTraits::element(slot));
}
@@ -3536,7 +3595,7 @@ class raw_hash_set {
hash_ref() = that.hash_ref();
eq_ref() = that.eq_ref();
CopyAlloc(char_alloc_ref(), that.char_alloc_ref(),
- std::integral_constant<bool, propagate_alloc>());
+ std::bool_constant<propagate_alloc>());
that.common() = CommonFields::CreateDefault<SooEnabled()>();
annotate_for_bug_detection_on_move(that);
return *this;
@@ -3600,9 +3659,10 @@ class raw_hash_set {
GrowSooTableToNextCapacityAndPrepareInsert<
kUseMemcpy ? OptimalMemcpySizeForSooSlotTransfer(sizeof(slot_type))
: 0,
- kUseMemcpy>(common(), GetPolicyFunctions(),
- HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key},
- force_sampling));
+ kUseMemcpy>(
+ common(), GetPolicyFunctions(),
+ HashKey<hasher, K, kIsDefaultHash, kSeedShift>{hash_ref(), key},
+ force_sampling));
return {slot, true};
}
@@ -3618,10 +3678,11 @@ class raw_hash_set {
return {single_slot(), false};
}
}
- return {to_slot(PrepareInsertSmallNonSoo(
- common(), GetPolicyFunctions(),
- HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})),
- true};
+ return {
+ to_slot(PrepareInsertSmallNonSoo(
+ common(), GetPolicyFunctions(),
+ HashKey<hasher, K, kIsDefaultHash, kSeedShift>{hash_ref(), key})),
+ true};
}
template <class K>
@@ -3649,15 +3710,15 @@ class raw_hash_set {
auto mask_empty = g.MaskEmpty();
if (ABSL_PREDICT_TRUE(mask_empty)) {
size_t target_group_offset = seq.offset();
- void* slot =
- SwisstableGenerationsEnabled()
- ? PrepareInsertLargeGenerationsEnabled(
- common(), GetPolicyFunctions(), hash, mask_empty,
- FindInfo{target_group_offset, seq.index()},
- HashKey<hasher, K, kIsDefaultHash>{hash_ref(), key})
- : PrepareInsertLarge(
- common(), GetPolicyFunctions(), hash, mask_empty,
- FindInfo{target_group_offset, seq.index()});
+ void* slot = SwisstableGenerationsEnabled()
+ ? PrepareInsertLargeGenerationsEnabled(
+ common(), GetPolicyFunctions(), hash, mask_empty,
+ FindInfo{target_group_offset, seq.index()},
+ HashKey<hasher, K, kIsDefaultHash, kSeedShift>{
+ hash_ref(), key})
+ : PrepareInsertLarge(
+ common(), GetPolicyFunctions(), hash, mask_empty,
+ FindInfo{target_group_offset, seq.index()});
return {to_slot(slot), true};
}
seq.next();
@@ -3958,7 +4019,8 @@ 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, kIsDefaultHash,
+ kSeedShift>(),
PolicyTraits::transfer_uses_memcpy()
? TransferNRelocatable<sizeof(slot_type)>
: &raw_hash_set::transfer_n_slots_fn,
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc
index c4bff60452a..eaee003409b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/raw_hash_set_allocator_test.cc
@@ -70,13 +70,13 @@ class CheckedAlloc {
};
using propagate_on_container_copy_assignment =
- std::integral_constant<bool, (Spec & kPropagateOnCopy) != 0>;
+ std::bool_constant<(Spec & kPropagateOnCopy) != 0>;
using propagate_on_container_move_assignment =
- std::integral_constant<bool, (Spec & kPropagateOnMove) != 0>;
+ std::bool_constant<(Spec & kPropagateOnMove) != 0>;
using propagate_on_container_swap =
- std::integral_constant<bool, (Spec & kPropagateOnSwap) != 0>;
+ std::bool_constant<(Spec & kPropagateOnSwap) != 0>;
CheckedAlloc select_on_container_copy_construction() const {
if (Spec & kPropagateOnCopy) return *this;
@@ -184,7 +184,7 @@ struct Policy {
static slot_type& element(slot_type* slot) { return *slot; }
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
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 5cbaf5ca6b2..4c0a78a2b67 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
@@ -69,7 +69,7 @@ struct IntPolicy {
return std::forward<F>(f)(x, x);
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -136,7 +136,7 @@ class StringPolicy {
PairArgs(std::forward<Args>(args)...));
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
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 dcd1596c3c9..fee9531aca3 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>
+ template <class Hash, bool kIsDefault, 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 e97648d6749..ec5ec30495f 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
@@ -252,6 +252,60 @@ TEST(RawHashSetLayout, Large) {
#endif // defined(ABSL_INTERNAL_HASHTABLEZ_SAMPLE)
}
+TEST(BlockedInfoTest, ConstructFromComponents) {
+ constexpr BlockedInfo info(10, 2);
+ EXPECT_EQ(info.log2_period(), 10);
+ EXPECT_EQ(info.tail_blocked(), 2);
+
+ constexpr BlockedInfo info_zero(0, 0);
+ EXPECT_EQ(info_zero.log2_period(), 0);
+ EXPECT_EQ(info_zero.tail_blocked(), 0);
+
+ constexpr BlockedInfo info_max(63, 3);
+ EXPECT_EQ(info_max.log2_period(), 63);
+ EXPECT_EQ(info_max.tail_blocked(), 3);
+}
+
+TEST(BlockedInfoTest, BlockedBefore) {
+ constexpr BlockedInfo info3(3, 0);
+ EXPECT_EQ(info3.blocked_before(0), 0);
+ EXPECT_EQ(info3.blocked_before(7), 0);
+ EXPECT_EQ(info3.blocked_before(8), 1);
+ EXPECT_EQ(info3.blocked_before(15), 1);
+ EXPECT_EQ(info3.blocked_before(16), 2);
+ EXPECT_EQ(info3.blocked_before(24), 3);
+ EXPECT_EQ(info3.blocked_before(100), 12);
+
+ constexpr BlockedInfo info0(0, 0);
+ EXPECT_EQ(info0.blocked_before(0), 0);
+ EXPECT_EQ(info0.blocked_before(5), 5);
+ EXPECT_EQ(info0.blocked_before(10), 10);
+
+ constexpr BlockedInfo info4(4, 1);
+ EXPECT_EQ(info4.blocked_before(0), 0);
+ EXPECT_EQ(info4.blocked_before(15), 0);
+ EXPECT_EQ(info4.blocked_before(16), 1);
+ EXPECT_EQ(info4.blocked_before(31), 1);
+ EXPECT_EQ(info4.blocked_before(32), 2);
+}
+
+TEST(BlockedInfoTest, TotalBlockedCount) {
+ constexpr BlockedInfo info(3, 2);
+ EXPECT_EQ(info.total_blocked_count(0), 2);
+ EXPECT_EQ(info.total_blocked_count(7), 2);
+ EXPECT_EQ(info.total_blocked_count(8), 3);
+ EXPECT_EQ(info.total_blocked_count(15), 3);
+ EXPECT_EQ(info.total_blocked_count(31), 5);
+
+ constexpr BlockedInfo info_zero(0, 0);
+ EXPECT_EQ(info_zero.total_blocked_count(0), 0);
+ EXPECT_EQ(info_zero.total_blocked_count(15), 15);
+
+ constexpr BlockedInfo info_tail(5, 3);
+ EXPECT_EQ(info_tail.total_blocked_count(31), 3);
+ EXPECT_EQ(info_tail.total_blocked_count(63), 4);
+}
+
class GrowthInfoAllocator {
public:
explicit GrowthInfoAllocator(size_t capacity) {
@@ -582,25 +636,49 @@ TEST(Util, SizeToCapacitySmallValues) {
EXPECT_EQ(SizeToCapacity(4), 7);
EXPECT_EQ(SizeToCapacity(5), 7);
EXPECT_EQ(SizeToCapacity(6), 7);
+ EXPECT_EQ(SizeToCapacity(14), 15);
+ EXPECT_EQ(SizeToCapacity(15), 31);
+ EXPECT_EQ(SizeToCapacity(28), 31);
+ EXPECT_EQ(SizeToCapacity(29), 31);
+ EXPECT_EQ(SizeToCapacity(30), 31);
+ EXPECT_EQ(SizeToCapacity(31), 63);
+ EXPECT_EQ(SizeToCapacity(56), 63);
if (Group::kWidth == 16) {
EXPECT_EQ(SizeToCapacity(7), 7);
- EXPECT_EQ(SizeToCapacity(14), 15);
+ EXPECT_EQ(SizeToCapacity(57), 63);
+ EXPECT_EQ(SizeToCapacity(60), 63);
+ EXPECT_EQ(SizeToCapacity(61), 63);
+ EXPECT_EQ(SizeToCapacity(62), 63);
} else {
EXPECT_EQ(SizeToCapacity(7), 15);
+ EXPECT_EQ(SizeToCapacity(57), 127);
}
}
TEST(Util, CapacityToGrowthSmallValues) {
EXPECT_EQ(CapacityToGrowth(1), 1);
EXPECT_EQ(CapacityToGrowth(3), 3);
+ EXPECT_EQ(CapacityToGrowth(15), 14);
+ EXPECT_EQ(CapacityToGrowth(31), 30);
if (Group::kWidth == 16) {
EXPECT_EQ(CapacityToGrowth(7), 7);
+ EXPECT_EQ(CapacityToGrowth(31), 30);
+ EXPECT_EQ(CapacityToGrowth(63), 62);
} else {
EXPECT_EQ(CapacityToGrowth(7), 6);
+ EXPECT_EQ(CapacityToGrowth(63), 56);
}
- EXPECT_EQ(CapacityToGrowth(15), 14);
- EXPECT_EQ(CapacityToGrowth(31), 28);
- EXPECT_EQ(CapacityToGrowth(63), 56);
+ EXPECT_EQ(CapacityToGrowth(127), 112);
+}
+
+TEST(Table, ReserveGroupWidthCapacity) {
+ absl::flat_hash_set<int> set;
+ set.reserve(Group::kWidth * 2 - 2);
+ EXPECT_EQ(set.capacity(), Group::kWidth * 2 - 1);
+ set.reserve(Group::kWidth * 2 - 1);
+ EXPECT_EQ(set.capacity(), Group::kWidth * 4 - 1);
+ set.reserve(Group::kWidth * 4 - 2);
+ EXPECT_EQ(set.capacity(), Group::kWidth * 4 - 1);
}
TEST(Util, GrowthAndCapacity) {
@@ -919,8 +997,9 @@ struct ValuePolicy {
}
template <class Allocator>
- static std::integral_constant<bool, kTransferable> transfer(
- Allocator* alloc, slot_type* new_slot, slot_type* old_slot) {
+ static std::bool_constant<kTransferable> transfer(Allocator* alloc,
+ slot_type* new_slot,
+ slot_type* old_slot) {
construct(alloc, new_slot, std::move(*old_slot));
destroy(alloc, old_slot);
return {};
@@ -936,7 +1015,7 @@ struct ValuePolicy {
std::forward<F>(f), std::forward<Args>(args)...);
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -1090,7 +1169,7 @@ class StringPolicy {
PairArgs(std::forward<Args>(args)...));
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -1273,8 +1352,8 @@ using NonMemcpyableSooIntCustomAllocTable =
ChangingSizeAndTrackingTypeAlloc<int64_t>>;
TEST(Table, EmptyFunctorOptimization) {
- static_assert(std::is_empty_v<std::equal_to<absl::string_view>>, "");
- static_assert(std::is_empty_v<std::allocator<int>>, "");
+ static_assert(std::is_empty_v<std::equal_to<absl::string_view>>);
+ static_assert(std::is_empty_v<std::allocator<int>>);
struct MockTableByValue {
size_t capacity;
@@ -1466,13 +1545,12 @@ TEST(Table, ReservedTableRehashWithoutGrowthWorksWell) {
for (size_t capacity = 31; capacity < 256;
capacity = NextCapacity(capacity)) {
SCOPED_TRACE(absl::StrCat("capacity: ", capacity));
- // Number of elements we keep empty in order to force a rehash without
+ // Number of elements we reserve in order to force a rehash without
// growth. RehashOrGrowToNextCapacityAndPrepareInsert grow if number of full
- // slots is greater than 25/32 of capacity, so we leave 7/32 + 5 empty to
- // have extra margin.
- size_t empty_till_full = (capacity + 1) / 32 * 7 + 5;
+ // slots is greater than 25/32 of capacity. We reserve slightly less than
+ // 25/32 of capacity to have extra space for tombstones.
int64_t reserve_size =
- static_cast<int64_t>(CapacityToGrowth(capacity) - empty_till_full);
+ static_cast<int64_t>((capacity - 5) * 25 / 32 - 2);
BadTwoValuesHashTable t(
0,
@@ -1481,9 +1559,8 @@ TEST(Table, ReservedTableRehashWithoutGrowthWorksWell) {
// will be placed at the beginning of the table.
BadTwoValuesHash(static_cast<size_t>(reserve_size)));
// Remove seed to make table layout deterministic.
- RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing();
-
t.reserve(static_cast<size_t>(reserve_size));
+ RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing();
for (int64_t i = 1; i <= reserve_size; ++i) {
ASSERT_TRUE(t.insert(i * kCoef).second);
}
@@ -1553,10 +1630,9 @@ TEST(Table,
BadTwoValuesHashTable t(0,
// Negative number goes to the end of the table.
BadTwoValuesHash(kReserveSize + 2));
+ t.reserve(kReserveSize);
// Remove seed to make table layout deterministic.
RawHashSetTestOnlyAccess::GetCommon(t).set_no_seed_for_testing();
-
- t.reserve(kReserveSize);
for (int64_t i = 0; i < static_cast<int64_t>(Group::kWidth); ++i) {
ASSERT_TRUE(t.insert(i * kCoef).second);
}
@@ -2266,11 +2342,24 @@ void GenerateIrrelevantSeeds(int cnt) {
}
}
+template <class TableType>
+class IterationOrderTest : public testing::Test {};
+
+struct CustomHashIntTable
+ : raw_hash_set<IntPolicy, std::hash<int64_t>> {
+ using Base = typename CustomHashIntTable::raw_hash_set;
+ using Base::Base;
+};
+
+using IterationOrderTypes =
+ ::testing::Types<SooIntTable, NonSooIntTable, CustomHashIntTable>;
+TYPED_TEST_SUITE(IterationOrderTest, IterationOrderTypes);
+
// These IterationOrderChanges tests depend on non-deterministic behavior.
// We are injecting non-determinism to the table.
// We have to retry enough times to make sure that the seed changes in bits that
// matter for the iteration order.
-TYPED_TEST(SooTest, IterationOrderChangesByInstance) {
+TYPED_TEST(IterationOrderTest, IterationOrderChangesByInstance) {
DisableSampling(); // We do not want test to pass only because of sampling.
for (bool do_reserve : {false, true}) {
for (size_t size : {2u, 6u, 12u, 20u}) {
@@ -2291,7 +2380,7 @@ TYPED_TEST(SooTest, IterationOrderChangesByInstance) {
}
}
-TYPED_TEST(SooTest, IterationOrderChangesOnRehash) {
+TYPED_TEST(IterationOrderTest, IterationOrderChangesOnRehash) {
DisableSampling(); // We do not want test to pass only because of sampling.
// We test different sizes with many small numbers, because small table
@@ -2755,7 +2844,7 @@ struct DecomposePolicy {
return std::forward<F>(f)(x, x);
}
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return nullptr;
}
@@ -4030,6 +4119,22 @@ TEST(RawHashSamplerTest, NonSooTableRepeatedInsertEraseCountSizeRight) {
}
}
+TEST(RawHashSamplerTest, NonSooTableRepeatedInsertClearCountSizeRight) {
+ ASSERT_EQ(NonSooIntTable().capacity(), 0);
+ std::vector<const HashtablezInfo*> infos =
+ SampleNonSooMutation([](NonSooIntTable& t) {
+ for (int i = 0; i < 10; ++i) {
+ t.insert(1);
+ t.clear();
+ }
+ });
+ for (const HashtablezInfo* info : infos) {
+ EXPECT_EQ(info->soo_capacity, 0);
+ ASSERT_EQ(info->capacity, 1);
+ ASSERT_EQ(info->size, 0);
+ }
+}
+
// Verifies that copy-constructing or copy-assigning an SOO table does not
// incorrectly trigger new sampling evaluations.
TEST(RawHashSamplerTest, SooTableCopyDoesNotOversample) {
@@ -4138,6 +4243,22 @@ TEST(RawHashSamplerTest, SooTableSampleOnCopy) {
}
}
+TEST(RawHashSamplerTest, NonSooTableSampleOnCopy) {
+ NonSooIntTable t_orig;
+ t_orig.insert(1);
+
+ std::vector<const HashtablezInfo*> infos =
+ SampleNonSooMutation([&t_orig](NonSooIntTable& t) { t = t_orig; });
+
+ for (const HashtablezInfo* info : infos) {
+ ASSERT_EQ(info->inline_element_size,
+ sizeof(typename NonSooIntTable::value_type));
+ ASSERT_EQ(info->soo_capacity, 0);
+ ASSERT_EQ(info->capacity, 1);
+ ASSERT_EQ(info->size, 1);
+ }
+}
+
// This tests that rehash(0) on a sampled table with size that fits in SOO
// doesn't incorrectly result in losing sampling.
TEST(RawHashSamplerTest, SooTableRehashShrinkWhenSizeFitsInSoo) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/internal/tracked.h b/deps/v8/third_party/abseil-cpp/absl/container/internal/tracked.h
index 29f5829f719..6962eb86e9c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/internal/tracked.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/internal/tracked.h
@@ -50,12 +50,14 @@ class Tracked {
num_moves_ = that.num_moves_;
num_copies_ = that.num_copies_;
++(*num_copies_);
+ return *this;
}
Tracked& operator=(Tracked&& that) {
val_ = std::move(that.val_);
num_moves_ = std::move(that.num_moves_);
num_copies_ = std::move(that.num_copies_);
++(*num_moves_);
+ return *this;
}
const T& val() const { return val_; }
@@ -67,8 +69,8 @@ class Tracked {
return !(a == b);
}
- size_t num_copies() { return *num_copies_; }
- size_t num_moves() { return *num_moves_; }
+ size_t num_copies() const { return *num_copies_; }
+ size_t num_moves() const { return *num_moves_; }
private:
T val_;
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 2c9f57f8b03..932c320daf8 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
@@ -52,11 +52,9 @@ TYPED_TEST_P(LookupTest, Find) {
for (const auto& v : values) {
typename TypeParam::iterator it = m.find(v);
static_assert(
- std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>,
- "");
+ std::is_same_v<const typename TypeParam::value_type&, decltype(*it)>);
static_assert(std::is_same<const typename TypeParam::value_type*,
- decltype(it.operator->())>::value,
- "");
+ decltype(it.operator->())>::value);
EXPECT_TRUE(m.end() != it) << ::testing::PrintToString(v);
EXPECT_EQ(v, *it) << ::testing::PrintToString(v);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map.h b/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map.h
index 7ebeaf7d478..6d0e320cafc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_map.h
@@ -21,6 +21,7 @@
// order.
//
// This class is thread-compatible.
+// This class is NOT exception-safe.
//
// Iterators point into the list and should be stable in the face of
// mutations, except for an iterator pointing to an element that was just
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 e8df8073303..8b95c123eee 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
@@ -53,7 +53,7 @@ template <class K, class V>
using Map = linked_hash_map<K, V, StatefulTestingHash, StatefulTestingEqual,
Alloc<std::pair<const K, V>>>;
-static_assert(!std::is_standard_layout<NonStandardLayout>(), "");
+static_assert(!std::is_standard_layout<NonStandardLayout>());
using MapTypes =
::testing::Types<Map<int, int>, Map<std::string, int>,
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_set.h b/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_set.h
index cda21d640a2..7fe0adc09d6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_set.h
+++ b/deps/v8/third_party/abseil-cpp/absl/container/linked_hash_set.h
@@ -21,6 +21,7 @@
// order.
//
// This class is thread-compatible.
+// This class is NOT exception-safe.
//
// Iterators point into the list and should be stable in the face of
// mutations, except for an iterator pointing to an element that was just
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 d58feed7495..75fc0ccab6c 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
@@ -428,10 +428,6 @@ class ABSL_ATTRIBUTE_OWNER node_hash_map
// `node_hash_map` does not contain an element with a matching key, this
// function returns an empty node handle.
//
- // NOTE: when compiled in an earlier version of C++ than C++17,
- // `node_type::key()` returns a const reference to the key instead of a
- // mutable reference. We cannot safely return a mutable reference without
- // std::launder (which is not available before C++17).
using Base::extract;
// node_hash_map::merge()
@@ -685,11 +681,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>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
return memory_internal::IsLayoutCompatible<Key, Value>::value
? &TypeErasedDerefAndApplyToSlotFirstFn<Hash, value_type,
- kIsDefault>
+ kIsDefault, kSeedShift>
: nullptr;
}
};
diff --git a/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map_test.cc b/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map_test.cc
index 107b329a025..476b12f072d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/container/node_hash_map_test.cc
@@ -196,7 +196,7 @@ TEST(NodeHashMap, MergeExtractInsert) {
// NonMovableKey is neither copyable nor movable. We should still be able to
// move nodes around.
- static_assert(!std::is_move_constructible_v<NonMovableKey>, "");
+ static_assert(!std::is_move_constructible_v<NonMovableKey>);
set1.merge(set2);
EXPECT_THAT(set1,
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 55568b79eaa..9da52e7c64c 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
@@ -582,9 +582,9 @@ struct NodeHashSetPolicy
static size_t element_space_used(const T*) { return sizeof(T); }
- template <class Hash, bool kIsDefault>
+ template <class Hash, bool kIsDefault, size_t kSeedShift>
static constexpr HashSlotFn get_hash_slot_fn() {
- return &TypeErasedDerefAndApplyToSlotFn<Hash, T, kIsDefault>;
+ return &TypeErasedDerefAndApplyToSlotFn<Hash, T, kIsDefault, kSeedShift>;
}
};
} // namespace container_internal
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 98ae3af04a6..fdc709273a0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/BUILD.gn
@@ -1,19 +1,22 @@
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("crc_internal") {
- public = [
- "internal/crc.h",
- "internal/crc32_x86_arm_combined_simd.h",
- ]
sources = [
"internal/crc.cc",
"internal/crc_internal.h",
"internal/crc_x86_arm_combined.cc",
]
+ public = [
+ "internal/crc.h",
+ "internal/crc32_x86_arm_combined_simd.h",
+ ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -24,15 +27,9 @@ absl_source_set("crc_internal") {
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/numeric:bits",
]
- visibility = [ ":*" ]
}
absl_source_set("crc32c") {
- public = [
- "crc32c.h",
- "internal/crc32c.h",
- "internal/crc_memcpy.h",
- ]
sources = [
"crc32c.cc",
"internal/crc32c_inline.h",
@@ -40,6 +37,11 @@ absl_source_set("crc32c") {
"internal/crc_memcpy_x86_arm_combined.cc",
"internal/crc_non_temporal_memcpy.cc",
]
+ public = [
+ "crc32c.h",
+ "internal/crc32c.h",
+ "internal/crc_memcpy.h",
+ ]
deps = [
":crc_internal",
":non_temporal_memcpy",
@@ -48,6 +50,7 @@ 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",
]
@@ -65,18 +68,18 @@ absl_test("crc32c_test") {
absl_source_set("non_temporal_arm_intrinsics") {
public = [ "internal/non_temporal_arm_intrinsics.h" ]
- deps = [ "//third_party/abseil-cpp/absl/base:config" ]
visibility = [ ":*" ]
+ deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("non_temporal_memcpy") {
public = [ "internal/non_temporal_memcpy.h" ]
+ visibility = [ ":*" ]
deps = [
":non_temporal_arm_intrinsics",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
- visibility = [ ":*" ]
}
absl_test("crc_memcpy_test") {
@@ -97,18 +100,18 @@ absl_test("non_temporal_memcpy_test") {
}
absl_source_set("crc_cord_state") {
- public = [ "internal/crc_cord_state.h" ]
sources = [ "internal/crc_cord_state.cc" ]
+ public = [ "internal/crc_cord_state.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/strings:*",
+ ]
deps = [
":crc32c",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:no_destructor",
"//third_party/abseil-cpp/absl/numeric:bits",
]
- visibility = [
- "//third_party/abseil-cpp/absl/crc/*",
- "//third_party/abseil-cpp/absl/strings:*",
- ]
}
absl_test("crc_cord_state_test") {
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 9b1ef7e2efc..902056373c4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.cc
@@ -14,6 +14,7 @@
#include "absl/crc/crc32c.h"
+#include <cstddef>
#include <cstdint>
#include "absl/crc/internal/crc.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 5ecc6b35464..4ce941dc440 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c.h
@@ -25,6 +25,7 @@
#ifndef ABSL_CRC_CRC32C_H_
#define ABSL_CRC_CRC32C_H_
+#include <cstddef>
#include <cstdint>
#include <ostream>
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c_benchmark.cc
index 0ac922527ab..fb226a20cbb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/crc32c_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/crc32c_benchmark.cc
@@ -12,6 +12,8 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstddef>
+#include <cstdint>
#include <memory>
#include <string>
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 6262dd2f779..ec6a031c512 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
@@ -41,7 +41,9 @@
#include "absl/crc/internal/crc.h"
+#include <cstddef>
#include <cstdint>
+#include <iterator>
#include "absl/base/internal/endian.h"
#include "absl/base/internal/raw_logging.h"
@@ -206,7 +208,7 @@ void CRC32::InitTables() {
}
int j = FillZeroesTable(kCrc32cPoly, t);
- ABSL_RAW_CHECK(j <= static_cast<int>(ABSL_ARRAYSIZE(this->zeroes_)), "");
+ ABSL_RAW_CHECK(j <= static_cast<int>(std::size(this->zeroes_)), "");
for (int i = 0; i < j; i++) {
this->zeroes_[i] = t[0][i];
}
@@ -250,8 +252,7 @@ void CRC32::InitTables() {
FillWordTable(kCrc32cUnextendPoly, kCrc32cUnextendPoly, 1, &reverse_table0_);
j = FillZeroesTable(kCrc32cUnextendPoly, &reverse_zeroes_);
- ABSL_RAW_CHECK(j <= static_cast<int>(ABSL_ARRAYSIZE(this->reverse_zeroes_)),
- "");
+ ABSL_RAW_CHECK(j <= static_cast<int>(std::size(this->reverse_zeroes_)), "");
}
void CRC32::Extend(uint32_t* crc, const void* bytes, size_t length) const {
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.h
index 4efdd0325ab..90e05f1a89b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc.h
@@ -15,6 +15,7 @@
#ifndef ABSL_CRC_INTERNAL_CRC_H_
#define ABSL_CRC_INTERNAL_CRC_H_
+#include <cstddef>
#include <cstdint>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h
index 07f5a69f256..c50a3013c74 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32_x86_arm_combined_simd.h
@@ -20,6 +20,10 @@
#include "absl/base/config.h"
+#ifdef __SSE4_2__
+#include <immintrin.h>
+#endif
+
// -------------------------------------------------------------------------
// Many x86 and ARM machines have CRC acceleration hardware.
// We can do a faster version of Extend() on such machines.
@@ -107,6 +111,12 @@ V128 V128_PMul10(const V128 l, const V128 r);
// Produces a XOR operation of |l| and |r|.
V128 V128_Xor(const V128 l, const V128 r);
+// Produces a 3-way XOR operation of |a|, |b|, and |c|.
+// When `kUseEor3` is true, uses the ARMv8.2-A `EOR3` (3-way Exclusive-OR)
+// instruction.
+template <bool kUseEor3 = false>
+V128 V128_Xor3(const V128 a, const V128 b, const V128 c);
+
// Sets the lower half of a 128 bit register to the given 64-bit value and
// zeroes the upper half.
// dst[63:0] := |r|
@@ -182,6 +192,11 @@ inline V128 V128_PMul10(const V128 l, const V128 r) {
inline V128 V128_Xor(const V128 l, const V128 r) { return _mm_xor_si128(l, r); }
+template <bool kUseEor3>
+inline V128 V128_Xor3(const V128 a, const V128 b, const V128 c) {
+ return V128_Xor(V128_Xor(a, b), c);
+}
+
inline V128 V128_From64WithZeroFill(const uint64_t r) {
return _mm_set_epi64x(static_cast<int64_t>(0), static_cast<int64_t>(r));
}
@@ -266,6 +281,28 @@ inline V128 V128_PMul10(const V128 l, const V128 r) {
inline V128 V128_Xor(const V128 l, const V128 r) { return veorq_u64(l, r); }
+template <bool kUseEor3>
+inline V128 V128_Xor3(const V128 a, const V128 b, const V128 c) {
+#ifndef __ARM_FEATURE_SHA3
+ if constexpr (kUseEor3) {
+ // If the binary is compiled without SHA3 support, we need inline assembly
+ // to use the EOR3 instruction. We want to only use the below inline
+ // assembly block when both the CPU supports EOR3 and the binary is built
+ // without it, since we remove the sha3 extension support after the eor3
+ // instruction.
+ uint64x2_t res;
+ __asm__ __volatile__(
+ ".arch_extension sha3 \n\t"
+ "eor3 %0.16b, %1.16b, %2.16b, %3.16b \n\t"
+ ".arch_extension nosha3 \n\t"
+ : "=w"(res)
+ : "w"(a), "w"(b), "w"(c));
+ return res;
+ }
+#endif
+ return V128_Xor(V128_Xor(a, b), c);
+}
+
inline V128 V128_From64WithZeroFill(const uint64_t r){
constexpr uint64x2_t kZero = {0, 0};
return vsetq_lane_u64(r, kZero, 0);
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c.h
index 34027c55e42..20e9b73e8a1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c.h
@@ -15,6 +15,8 @@
#ifndef ABSL_CRC_INTERNAL_CRC32C_H_
#define ABSL_CRC_INTERNAL_CRC32C_H_
+#include <cstddef>
+
#include "absl/base/config.h"
#include "absl/crc/crc32c.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c_inline.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c_inline.h
index 6236c10b3b5..e117c8697ce 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c_inline.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc32c_inline.h
@@ -15,6 +15,7 @@
#ifndef ABSL_CRC_INTERNAL_CRC32C_INLINE_H_
#define ABSL_CRC_INTERNAL_CRC32C_INLINE_H_
+#include <cstddef>
#include <cstdint>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.cc b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.cc
index 303a55593a2..cccd0b06c11 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.cc
@@ -14,10 +14,14 @@
#include "absl/crc/internal/crc_cord_state.h"
+#include <atomic>
#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include "absl/base/config.h"
#include "absl/base/no_destructor.h"
+#include "absl/crc/crc32c.h"
#include "absl/numeric/bits.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.h
index fbbb8c004c8..a68e0b327b8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_cord_state.h
@@ -16,7 +16,9 @@
#define ABSL_CRC_INTERNAL_CRC_CORD_STATE_H_
#include <atomic>
+#include <cassert>
#include <cstddef>
+#include <cstdint>
#include <deque>
#include "absl/base/config.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 0447858ab50..ac9c38d68d8 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
@@ -15,11 +15,13 @@
#ifndef ABSL_CRC_INTERNAL_CRC_INTERNAL_H_
#define ABSL_CRC_INTERNAL_CRC_INTERNAL_H_
+#include <cstddef>
#include <cstdint>
#include <memory>
#include <vector>
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/optimization.h"
#include "absl/crc/internal/crc.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc
index fd3ce60d88b..dac0446349c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_memcpy_x86_arm_combined.cc
@@ -38,14 +38,6 @@
// using 3 CRCs over fixed-size blocks where the zero-extensions required for
// CRC32C::Concat can be precomputed.
-#ifdef __SSE4_2__
-#include <immintrin.h>
-#endif
-
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
#include <array>
#include <cstddef>
#include <cstdint>
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc
index e44a009aa7f..edffd36717d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/crc_x86_arm_combined.cc
@@ -40,7 +40,9 @@ namespace crc_internal {
using ::absl::base_internal::CpuType;
using ::absl::base_internal::GetCpuType;
+#if defined(__aarch64__)
using ::absl::base_internal::SupportsArmCRC32PMULL;
+#endif
#if defined(ABSL_INTERNAL_CAN_USE_SIMD_CRC32C)
@@ -214,11 +216,11 @@ constexpr uint64_t kClmulConstants[] = {
0x19fb2a8b0, 0x02178513a, 0x1a0f717c4, 0x0170076fa,
};
-enum class CutoffStrategy {
- // Use 3 CRC streams to fold into 1.
- Fold3,
- // Unroll CRC instructions for 64 bytes.
- Unroll64CRC,
+enum class PclmulStreamType {
+ PCLMUL,
+ VPCLMUL,
+ NEON_PCLMUL,
+ NEON_PCLMUL_EOR3,
};
// Base class for CRC32AcceleratedX86ARMCombinedMultipleStreams containing the
@@ -234,6 +236,85 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreamsBase
// Computation for Generic Polynomials Using PCLMULQDQ Instruction"
// https://www.intel.com/content/dam/www/public/us/en/documents/white-papers/fast-crc-computation-generic-polynomials-pclmulqdq-paper.pdf
// We are applying it to CRC32C polynomial.
+#if defined(ABSL_CRC_INTERNAL_HAVE_ARM_SIMD)
+ template <bool kUseEor3 = false>
+ ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesNeonPclmul(
+ const uint8_t* p, V128* partialCRC) const {
+ V128 loopMultiplicands =
+ V128_Load(reinterpret_cast<const V128*>(kFoldAcross512Bits));
+
+ V128 partialCRC1 = partialCRC[0];
+ V128 partialCRC2 = partialCRC[1];
+ V128 partialCRC3 = partialCRC[2];
+ V128 partialCRC4 = partialCRC[3];
+
+ V128 tmp1 = V128_PMulHi(partialCRC1, loopMultiplicands);
+ V128 tmp2 = V128_PMulHi(partialCRC2, loopMultiplicands);
+ V128 tmp3 = V128_PMulHi(partialCRC3, loopMultiplicands);
+ V128 tmp4 = V128_PMulHi(partialCRC4, loopMultiplicands);
+ V128 data1 = V128_LoadU(reinterpret_cast<const V128*>(p + 16 * 0));
+ V128 data2 = V128_LoadU(reinterpret_cast<const V128*>(p + 16 * 1));
+ V128 data3 = V128_LoadU(reinterpret_cast<const V128*>(p + 16 * 2));
+ V128 data4 = V128_LoadU(reinterpret_cast<const V128*>(p + 16 * 3));
+ partialCRC1 = V128_PMulLow(partialCRC1, loopMultiplicands);
+ partialCRC2 = V128_PMulLow(partialCRC2, loopMultiplicands);
+ partialCRC3 = V128_PMulLow(partialCRC3, loopMultiplicands);
+ partialCRC4 = V128_PMulLow(partialCRC4, loopMultiplicands);
+ partialCRC1 = V128_Xor3<kUseEor3>(tmp1, partialCRC1, data1);
+ partialCRC2 = V128_Xor3<kUseEor3>(tmp2, partialCRC2, data2);
+ partialCRC3 = V128_Xor3<kUseEor3>(tmp3, partialCRC3, data3);
+ partialCRC4 = V128_Xor3<kUseEor3>(tmp4, partialCRC4, data4);
+ partialCRC[0] = partialCRC1;
+ partialCRC[1] = partialCRC2;
+ partialCRC[2] = partialCRC3;
+ partialCRC[3] = partialCRC4;
+ }
+
+ // Reduce partialCRC produced by Process64BytesNeonPclmul into a single value,
+ // that represents crc checksum of all the processed bytes.
+ template <bool kUseEor3 = false>
+ ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t
+ FinalizeNeonPclmulStream(V128* partialCRC) const {
+ V128 partialCRC1 = partialCRC[0];
+ V128 partialCRC2 = partialCRC[1];
+ V128 partialCRC3 = partialCRC[2];
+ V128 partialCRC4 = partialCRC[3];
+
+ // Combine 4 vectors of partial crc into a single vector.
+ V128 reductionMultiplicands =
+ V128_Load(reinterpret_cast<const V128*>(kFoldAcross256Bits));
+
+ V128 low = V128_PMulLow(reductionMultiplicands, partialCRC1);
+ V128 high = V128_PMulHi(reductionMultiplicands, partialCRC1);
+
+ partialCRC1 = V128_Xor3<kUseEor3>(low, high, partialCRC3);
+
+ low = V128_PMulLow(reductionMultiplicands, partialCRC2);
+ high = V128_PMulHi(reductionMultiplicands, partialCRC2);
+
+ partialCRC2 = V128_Xor3<kUseEor3>(low, high, partialCRC4);
+
+ reductionMultiplicands =
+ V128_Load(reinterpret_cast<const V128*>(kFoldAcross128Bits));
+
+ low = V128_PMulLow(reductionMultiplicands, partialCRC1);
+ high = V128_PMulHi(reductionMultiplicands, partialCRC1);
+ V128 fullCRC = V128_Xor3<kUseEor3>(low, high, partialCRC2);
+
+ // Reduce fullCRC into scalar value.
+ uint32_t crc = 0;
+ crc = CRC32_u64(crc, V128_Extract64<0>(fullCRC));
+ crc = CRC32_u64(crc, V128_Extract64<1>(fullCRC));
+ return crc;
+ }
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesPclmul(const uint8_t*,
+ V128*) const {}
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t FinalizePclmulStream(V128*) const {
+ return 0;
+ }
+#else
ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesPclmul(
const uint8_t* p, V128* partialCRC) const {
V128 loopMultiplicands =
@@ -310,6 +391,16 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreamsBase
return crc;
}
+ template <bool kUseEor3 = false>
+ ABSL_ATTRIBUTE_ALWAYS_INLINE void Process64BytesNeonPclmul(const uint8_t*,
+ V128*) const {}
+
+ template <bool kUseEor3 = false>
+ ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t FinalizeNeonPclmulStream(V128*) const {
+ return 0;
+ }
+#endif
+
// Update crc with 64 bytes of data from p.
ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t Process64BytesCRC(const uint8_t* p,
uint64_t crc) const {
@@ -361,7 +452,8 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreamsBase
crc[2] = crc2;
}
-#if defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD) && defined(__AVX__)
+#if defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD) && defined(__AVX__) && \
+ (!defined(_MSC_VER) || defined(__clang__))
// This is only used if we have vector version of PCLMULQDQ.
// We don't have it on arm, and it isn't supported by default
// compiler targets on x86. If we want to use it, we need to either use
@@ -424,7 +516,8 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreamsBase
ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t FinalizeVpclmulStream(V256*) const {
return 0;
}
-#endif // defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD) && defined(__AVX__)
+#endif // defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD) && defined(__AVX__) &&
+ // (!defined(_MSC_VER) || defined(__clang__))
// Constants generated by './scripts/gen-crc-consts.py x86_pclmul
// crc32_lsb_0x82f63b78' from the Linux kernel.
@@ -455,7 +548,7 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreamsBase
};
template <size_t num_crc_streams, size_t num_pclmul_streams,
- size_t num_vpclmul_streams, CutoffStrategy strategy>
+ PclmulStreamType pclmul_stream_type>
class CRC32AcceleratedX86ARMCombinedMultipleStreams
: public CRC32AcceleratedX86ARMCombinedMultipleStreamsBase {
ABSL_ATTRIBUTE_HOT
@@ -465,9 +558,6 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
"Invalid number of crc streams");
static_assert(num_pclmul_streams >= 0 && num_pclmul_streams <= kMaxStreams,
"Invalid number of pclmul streams");
- static_assert(
- num_vpclmul_streams >= 0 && num_vpclmul_streams <= kMaxStreams,
- "Invalid number of vpclmul streams");
const uint8_t* p = static_cast<const uint8_t*>(bytes);
const uint8_t* e = p + length;
uint32_t l = *crc;
@@ -475,15 +565,15 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
// For small blocks just run simple loop, because cost of combining multiple
// streams is significant.
- if (strategy != CutoffStrategy::Unroll64CRC && (length < kSmallCutoff)) {
+ if (num_crc_streams > 1 && (length < kSmallCutoff)) {
// fallthrough; Use the same strategy as we do for processing the
// remaining bytes after any other strategy.
- } else if (length < kMediumCutoff) {
+ } else if (length < kMediumCutoff) {
// For medium blocks we run 3 crc streams and combine them as described in
// Intel paper above. Running 4th stream doesn't help, because crc
// instruction has latency 3 and throughput 1.
l64 = l;
- if (strategy == CutoffStrategy::Fold3) {
+ if (num_crc_streams > 1) {
uint64_t l641 = 0;
uint64_t l642 = 0;
const size_t blockSize = 32;
@@ -524,7 +614,7 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
l64 = CRC32_u64(static_cast<uint32_t>(l642), l64);
p = p2 + 8;
- } else if (strategy == CutoffStrategy::Unroll64CRC) {
+ } else {
while ((e - p) >= 64) {
l64 = Process64BytesCRC(p, l64);
p += 64;
@@ -546,8 +636,7 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
}
size_t bs = static_cast<size_t>(e - p) /
- (num_crc_streams + num_pclmul_streams + num_vpclmul_streams) /
- 64;
+ (num_crc_streams + num_pclmul_streams) / 64;
const uint8_t* stream_start = p;
const uint8_t* crc_streams[kMaxStreams];
for (size_t i = 0; i < num_crc_streams; i++) {
@@ -559,11 +648,6 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
pclmul_streams[i] = stream_start;
stream_start += bs * 64;
}
- const uint8_t* vpclmul_streams[kMaxStreams];
- for (size_t i = 0; i < num_vpclmul_streams; i++) {
- vpclmul_streams[i] = stream_start;
- stream_start += bs * 64;
- }
// Per stream crc sums.
uint64_t l64_crc[kMaxStreams] = {l};
@@ -585,29 +669,10 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
crc_streams[2] += 16 * 4;
}
- V128 partialCRC[kMaxStreams][4];
+ // Align to 32 bytes for vpclmul implementation.
+ alignas(32) V128 partialCRC[kMaxStreams][4];
for (size_t i = 0; i < num_pclmul_streams; i++) {
- partialCRC[i][0] = V128_LoadU(
- reinterpret_cast<const V128*>(pclmul_streams[i] + 16 * 0));
- partialCRC[i][1] = V128_LoadU(
- reinterpret_cast<const V128*>(pclmul_streams[i] + 16 * 1));
- partialCRC[i][2] = V128_LoadU(
- reinterpret_cast<const V128*>(pclmul_streams[i] + 16 * 2));
- partialCRC[i][3] = V128_LoadU(
- reinterpret_cast<const V128*>(pclmul_streams[i] + 16 * 3));
- pclmul_streams[i] += 16 * 4;
- }
-
- V256 vpartialCRC[kMaxStreams][2];
- V256 loopMultiplicands{};
- loopMultiplicands =
- V256_Broadcast128(reinterpret_cast<const V128*>(kFoldAcross512Bits));
- for (size_t i = 0; i < num_vpclmul_streams; i++) {
- vpartialCRC[i][0] = V256_LoadU(
- reinterpret_cast<const V256*>(vpclmul_streams[i] + 32 * 0));
- vpartialCRC[i][1] = V256_LoadU(
- reinterpret_cast<const V256*>(vpclmul_streams[i] + 32 * 1));
- vpclmul_streams[i] += 16 * 4;
+ InitPclmulStream(&pclmul_streams[i], partialCRC[i]);
}
for (size_t i = 1; i < bs; i++) {
@@ -620,10 +685,6 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
PrefetchToLocalCache(reinterpret_cast<const char*>(pclmul_streams[j] +
kPrefetchHorizon));
}
- for (size_t j = 0; j < num_vpclmul_streams; j++) {
- PrefetchToLocalCache(reinterpret_cast<const char*>(
- vpclmul_streams[j] + kPrefetchHorizon));
- }
// We process each stream in 64 byte blocks. This can be written as
// for (int i = 0; i < num_pclmul_streams; i++) {
@@ -650,23 +711,8 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
crc_streams[1] += 16 * 4;
crc_streams[2] += 16 * 4;
}
- if (num_pclmul_streams > 0) {
- Process64BytesPclmul(pclmul_streams[0], partialCRC[0]);
- pclmul_streams[0] += 16 * 4;
- }
- if (num_pclmul_streams > 1) {
- Process64BytesPclmul(pclmul_streams[1], partialCRC[1]);
- pclmul_streams[1] += 16 * 4;
- }
- if (num_pclmul_streams > 2) {
- Process64BytesPclmul(pclmul_streams[2], partialCRC[2]);
- pclmul_streams[2] += 16 * 4;
- }
-
- if constexpr (num_vpclmul_streams > 0) {
- Process64BytesVpclmul(vpclmul_streams[0], vpartialCRC[0],
- loopMultiplicands);
- vpclmul_streams[0] += 16 * 4;
+ for (size_t j = 0; j < num_pclmul_streams; j++) {
+ ProcessPclmulStream(&pclmul_streams[j], partialCRC[j]);
}
}
@@ -676,13 +722,6 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
l64_pclmul[i] = FinalizePclmulStream(partialCRC[i]);
}
- uint64_t l64_vpclmul[kMaxStreams] = {0};
- if constexpr (num_vpclmul_streams > 0) {
- for (size_t i = 0; i < num_vpclmul_streams; i++) {
- l64_vpclmul[i] = FinalizeVpclmulStream(vpartialCRC[i]);
- }
- }
-
// Combine all streams into single result.
static_assert(64 % (1 << kNumDroppedBits) == 0);
uint32_t magic = ComputeZeroConstant(bs * 64);
@@ -695,15 +734,9 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
l64 = MultiplyWithExtraX33(static_cast<uint32_t>(l64), magic);
l64 ^= l64_pclmul[i];
}
- for (size_t i = 0; i < num_vpclmul_streams; i++) {
- l64 = MultiplyWithExtraX33(static_cast<uint32_t>(l64), magic);
- l64 ^= l64_vpclmul[i];
- }
// Update p.
- if constexpr (num_vpclmul_streams > 0) {
- p = vpclmul_streams[num_vpclmul_streams - 1];
- } else if constexpr (num_pclmul_streams > 0) {
+ if constexpr (num_pclmul_streams > 0) {
p = pclmul_streams[num_pclmul_streams - 1];
} else {
p = crc_streams[num_crc_streams - 1];
@@ -733,6 +766,63 @@ class CRC32AcceleratedX86ARMCombinedMultipleStreams
*crc = l;
}
+
+ private:
+ ABSL_ATTRIBUTE_ALWAYS_INLINE void InitPclmulStream(
+ const uint8_t** pclmul_stream, V128* partialCRC) const {
+ if constexpr (pclmul_stream_type == PclmulStreamType::VPCLMUL) {
+ V256* vpartialCRC = reinterpret_cast<V256*>(partialCRC);
+ vpartialCRC[0] =
+ V256_LoadU(reinterpret_cast<const V256*>(*pclmul_stream + 32 * 0));
+ vpartialCRC[1] =
+ V256_LoadU(reinterpret_cast<const V256*>(*pclmul_stream + 32 * 1));
+ } else {
+ partialCRC[0] =
+ V128_LoadU(reinterpret_cast<const V128*>(*pclmul_stream + 16 * 0));
+ partialCRC[1] =
+ V128_LoadU(reinterpret_cast<const V128*>(*pclmul_stream + 16 * 1));
+ partialCRC[2] =
+ V128_LoadU(reinterpret_cast<const V128*>(*pclmul_stream + 16 * 2));
+ partialCRC[3] =
+ V128_LoadU(reinterpret_cast<const V128*>(*pclmul_stream + 16 * 3));
+ }
+ *pclmul_stream += 16 * 4;
+ }
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE void ProcessPclmulStream(
+ const uint8_t** pclmul_stream, V128* partialCRC) const {
+ if constexpr (pclmul_stream_type == PclmulStreamType::VPCLMUL) {
+ V256 loopMultiplicands =
+ V256_Broadcast128(reinterpret_cast<const V128*>(kFoldAcross512Bits));
+ Process64BytesVpclmul(*pclmul_stream, reinterpret_cast<V256*>(partialCRC),
+ loopMultiplicands);
+ } else if constexpr (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL ||
+ pclmul_stream_type ==
+ PclmulStreamType::NEON_PCLMUL_EOR3) {
+ constexpr bool kUseEor3 =
+ (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL_EOR3);
+ Process64BytesNeonPclmul<kUseEor3>(*pclmul_stream, partialCRC);
+ } else {
+ Process64BytesPclmul(*pclmul_stream, partialCRC);
+ }
+ *pclmul_stream += 16 * 4;
+ }
+
+ ABSL_ATTRIBUTE_ALWAYS_INLINE uint64_t
+ FinalizePclmulStream(V128* partialCRC) const {
+ if constexpr (pclmul_stream_type == PclmulStreamType::VPCLMUL) {
+ return FinalizeVpclmulStream(reinterpret_cast<V256*>(partialCRC));
+ } else if constexpr (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL ||
+ pclmul_stream_type ==
+ PclmulStreamType::NEON_PCLMUL_EOR3) {
+ constexpr bool kUseEor3 =
+ (pclmul_stream_type == PclmulStreamType::NEON_PCLMUL_EOR3);
+ return FinalizeNeonPclmulStream<kUseEor3>(partialCRC);
+ } else {
+ return CRC32AcceleratedX86ARMCombinedMultipleStreamsBase::
+ FinalizePclmulStream(partialCRC);
+ }
+ }
};
#undef ABSL_INTERNAL_STEP8BY3
@@ -751,22 +841,23 @@ CRCImpl* TryNewCRC32AcceleratedX86ARMCombined() {
switch (type) {
case CpuType::kAmdRome:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 0, 0, CutoffStrategy::Fold3>();
+ 3, 0, PclmulStreamType::PCLMUL>();
case CpuType::kIntelHaswell:
case CpuType::kAmdNaples:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 1, 0, CutoffStrategy::Fold3>();
+ 3, 1, PclmulStreamType::PCLMUL>();
case CpuType::kAmdMilan:
case CpuType::kAmdGenoa:
case CpuType::kAmdTurin:
-#if defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD) && defined(__AVX__)
+#if defined(ABSL_CRC_INTERNAL_HAVE_X86_SIMD) && defined(__AVX__) && \
+ (!defined(_MSC_VER) || defined(__clang__))
// We don't have vector pclmul on arm, but this still needs to
// compile.
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 0, 1, CutoffStrategy::Fold3>();
+ 3, 1, PclmulStreamType::VPCLMUL>();
#else
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 1, 0, CutoffStrategy::Fold3>();
+ 3, 1, PclmulStreamType::PCLMUL>();
#endif
// PCLMULQDQ is fast, use combined PCLMULQDQ + CRC implementation.
case CpuType::kIntelCascadelakeXeon:
@@ -778,33 +869,35 @@ CRCImpl* TryNewCRC32AcceleratedX86ARMCombined() {
case CpuType::kIntelEmeraldrapids:
case CpuType::kIntelGraniterapids:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 2, 0, CutoffStrategy::Fold3>();
+ 3, 2, PclmulStreamType::PCLMUL>();
// PCLMULQDQ is slow, don't use it.
case CpuType::kIntelIvybridge:
case CpuType::kIntelSandybridge:
case CpuType::kIntelWestmere:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 0, 0, CutoffStrategy::Fold3>();
+ 3, 0, PclmulStreamType::PCLMUL>();
case CpuType::kArmNeoverseN1:
- case CpuType::kArmNeoverseN2:
case CpuType::kArmNeoverseV1:
+ return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
+ 1, 1, PclmulStreamType::NEON_PCLMUL>();
+ case CpuType::kArmNeoverseN2:
case CpuType::kArmNeoverseN3:
case CpuType::kNvidiaGrace:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 1, 1, 0, CutoffStrategy::Unroll64CRC>();
+ 1, 1, PclmulStreamType::NEON_PCLMUL_EOR3>();
case CpuType::kAmpereSiryn:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 2, 0, CutoffStrategy::Fold3>();
+ 3, 2, PclmulStreamType::NEON_PCLMUL_EOR3>();
case CpuType::kArmNeoverseV2:
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 1, 2, 0, CutoffStrategy::Unroll64CRC>();
+ 1, 2, PclmulStreamType::NEON_PCLMUL_EOR3>();
#if defined(__aarch64__)
default:
// Not all ARM processors support the needed instructions, so check here
// before trying to use an accelerated implementation.
if (SupportsArmCRC32PMULL()) {
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 1, 1, 0, CutoffStrategy::Unroll64CRC>();
+ 1, 1, PclmulStreamType::NEON_PCLMUL>();
} else {
return nullptr;
}
@@ -812,7 +905,7 @@ CRCImpl* TryNewCRC32AcceleratedX86ARMCombined() {
default:
// Something else, play it safe and assume slow PCLMULQDQ.
return new CRC32AcceleratedX86ARMCombinedMultipleStreams<
- 3, 0, 0, CutoffStrategy::Fold3>();
+ 3, 0, PclmulStreamType::PCLMUL>();
#endif
}
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h b/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h
index 5d3e4e3ff15..96eb17834ce 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy.h
@@ -15,6 +15,15 @@
#ifndef ABSL_CRC_INTERNAL_NON_TEMPORAL_MEMCPY_H_
#define ABSL_CRC_INTERNAL_NON_TEMPORAL_MEMCPY_H_
+#include <algorithm>
+#include <cassert>
+#include <cstdint>
+#include <cstring>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+
#ifdef _MSC_VER
#include <intrin.h>
#endif
@@ -28,15 +37,6 @@
#include "absl/crc/internal/non_temporal_arm_intrinsics.h"
#endif
-#include <algorithm>
-#include <cassert>
-#include <cstdint>
-#include <cstring>
-
-#include "absl/base/attributes.h"
-#include "absl/base/config.h"
-#include "absl/base/optimization.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace crc_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy_test.cc b/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy_test.cc
index b2b19d351b2..179998ebfbe 100644
--- a/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/crc/internal/non_temporal_memcpy_test.cc
@@ -15,6 +15,7 @@
#include "absl/crc/internal/non_temporal_memcpy.h"
#include <algorithm>
+#include <cstddef>
#include <cstdint>
#include <iostream>
#include <vector>
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 556ab9c6044..d3eb74da5ae 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.bazel
@@ -202,6 +202,7 @@ cc_test(
":failure_signal_handler",
":stacktrace",
":symbolize",
+ "//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/log:check",
"//absl/strings",
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 251e02eb5af..8d621a847ac 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/BUILD.gn
@@ -1,8 +1,9 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
-import("//build/config/sanitizers/sanitizers.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("stacktrace") {
@@ -66,13 +67,10 @@ absl_source_set("symbolize") {
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
-
- # TODO(mbonadei): The bazel file has:
- # -DEFAULTLIB:dbghelp.lib
- # evaluate if this needs to be added here as well.
}
# symbolize_test is excluded because defines its own main function
+# absl_test("symbolize_test")
absl_source_set("examine_stack") {
sources = [ "internal/examine_stack.cc" ]
@@ -103,6 +101,9 @@ absl_source_set("failure_signal_handler") {
]
}
+# failure_signal_handler_test is excluded because defines its own main function
+# absl_test("failure_signal_handler_test")
+
absl_source_set("debugging_internal") {
sources = [
"internal/address_is_readable.cc",
@@ -129,8 +130,8 @@ absl_source_set("demangle_internal") {
sources = [ "internal/demangle.cc" ]
public = [ "internal/demangle.h" ]
visibility = [
+ ":*",
"//third_party/abseil-cpp/absl/container:*",
- "//third_party/abseil-cpp/absl/debugging:*",
]
deps = [
":demangle_rust",
@@ -143,20 +144,11 @@ absl_source_set("demangle_internal") {
}
# Disabled because this test relies on RTTI
-# absl_test("demangle_test") {
-# sources = [ "internal/demangle_test.cc" ]
-# deps = [
-# ":demangle_internal",
-# ":stack_consumption",
-# "//third_party/abseil-cpp/absl/base:config",
-# "//third_party/abseil-cpp/absl/base:core_headers",
-# "//third_party/abseil-cpp/absl/log",
-# "//third_party/abseil-cpp/absl/memory",
-# ]
-# }
+# absl_test("demangle_test")
absl_source_set("bounded_utf8_length_sequence") {
public = [ "internal/bounded_utf8_length_sequence.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/numeric:bits",
@@ -174,6 +166,7 @@ absl_test("bounded_utf8_length_sequence_test") {
absl_source_set("decode_rust_punycode") {
sources = [ "internal/decode_rust_punycode.cc" ]
public = [ "internal/decode_rust_punycode.h" ]
+ visibility = [ ":*" ]
deps = [
":bounded_utf8_length_sequence",
":utf8_for_code_point",
@@ -193,6 +186,7 @@ absl_test("decode_rust_punycode_test") {
absl_source_set("demangle_rust") {
sources = [ "internal/demangle_rust.cc" ]
public = [ "internal/demangle_rust.h" ]
+ visibility = [ ":*" ]
deps = [
":decode_rust_punycode",
"//third_party/abseil-cpp/absl/base:config",
@@ -212,6 +206,7 @@ absl_test("demangle_rust_test") {
absl_source_set("utf8_for_code_point") {
sources = [ "internal/utf8_for_code_point.cc" ]
public = [ "internal/utf8_for_code_point.h" ]
+ visibility = [ ":*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -232,14 +227,32 @@ absl_source_set("leak_check") {
]
}
+absl_test("leak_check_test") {
+ sources = [ "leak_check_test.cc" ]
+ deps = [
+ ":leak_check",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/log",
+ ]
+}
+
absl_source_set("stack_consumption") {
testonly = true
sources = [ "internal/stack_consumption.cc" ]
public = [ "internal/stack_consumption.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
- visibility = [ ":*" ]
+}
+
+absl_test("stack_consumption_test") {
+ sources = [ "internal/stack_consumption_test.cc" ]
+ deps = [
+ ":stack_consumption",
+ "//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/failure_signal_handler.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler.cc
index 46cb97f2c1c..e15d49de599 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
@@ -16,7 +16,20 @@
#include "absl/debugging/failure_signal_handler.h"
+#include <algorithm>
+#include <atomic>
+#include <cerrno>
+#include <csignal>
+#include <cstdio>
+#include <cstring>
+#include <ctime>
+
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/sysinfo.h"
+#include "absl/debugging/internal/examine_stack.h"
+#include "absl/debugging/stacktrace.h"
#ifdef _WIN32
#include <windows.h>
@@ -41,20 +54,6 @@
#include <sys/prctl.h>
#endif
-#include <algorithm>
-#include <atomic>
-#include <cerrno>
-#include <csignal>
-#include <cstdio>
-#include <cstring>
-#include <ctime>
-
-#include "absl/base/attributes.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/sysinfo.h"
-#include "absl/debugging/internal/examine_stack.h"
-#include "absl/debugging/stacktrace.h"
-
#if !defined(_WIN32) && !defined(__wasi__)
#define ABSL_HAVE_SIGACTION
// Apple WatchOS and TVOS don't allow sigaltstack
@@ -71,7 +70,7 @@
// Checks whether pthread_cpu_number_np is available.
#ifdef ABSL_HAVE_PTHREAD_CPU_NUMBER_NP
#error ABSL_HAVE_PTHREAD_CPU_NUMBER_NP cannot be directly set
-#elif defined(__APPLE__) && defined(__has_include) && \
+#elif defined(__APPLE__) && \
((defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \
__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ >= 110000) || \
(defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) && \
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc
index 72816a3e727..7a84e388b6a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/failure_signal_handler_test.cc
@@ -21,9 +21,11 @@
#include <cstdlib>
#include <cstring>
#include <fstream>
+#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
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 be17a105912..e9be2caf5a7 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
@@ -17,6 +17,8 @@
#include "absl/debugging/internal/address_is_readable.h"
+#include <cerrno>
+
#if !defined(__linux__) || defined(__ANDROID__)
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.cc
index 5b2d62398bb..e97a8ffbbed 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.cc
@@ -973,6 +973,7 @@ static bool ParseUnnamedTypeName(State *state) {
// Unnamed type local to function or class.
if (ParseTwoCharToken(state, "Ut") && Optional(ParseNumber(state, &which)) &&
+ which >= -1 && // Don't print garbage.
which <= std::numeric_limits<int>::max() - 2 && // Don't overflow.
ParseOneCharToken(state, '_')) {
MaybeAppend(state, "{unnamed type#");
@@ -988,6 +989,7 @@ static bool ParseUnnamedTypeName(State *state) {
ZeroOrMore(ParseTemplateParamDecl, state) &&
OneOrMore(ParseType, state) && RestoreAppend(state, copy.append) &&
ParseOneCharToken(state, 'E') && Optional(ParseNumber(state, &which)) &&
+ which >= -1 && // Don't print garbage.
which <= std::numeric_limits<int>::max() - 2 && // Don't overflow.
ParseOneCharToken(state, '_')) {
MaybeAppend(state, "{lambda()#");
@@ -1643,7 +1645,11 @@ static bool ParseBuiltinType(State *state) {
return false;
}
MaybeAppend(state, "_Float");
- MaybeAppendDecimal(state, number);
+ if (number >= 0) {
+ MaybeAppendDecimal(state, number);
+ } else {
+ MaybeAppend(state, "?"); // the best we can do for an invalid width
+ }
if (ParseOneCharToken(state, 'x')) {
MaybeAppend(state, "x");
return true;
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.h b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.h
index cb0aba13e55..93193a97f57 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.h
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle.h
@@ -15,7 +15,9 @@
#ifndef ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
#define ABSL_DEBUGGING_INTERNAL_DEMANGLE_H_
+#include <cstddef>
#include <string>
+
#include "absl/base/config.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc
index 75c46ec2068..6ca481bdc3c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust.cc
@@ -720,14 +720,30 @@ class RustSymbolParser {
if (!ParseDecimalNumber(num_bytes)) return false;
(void)Eat('_'); // optional separator, needed if a digit follows
if (is_punycoded) {
- DecodeRustPunycodeOptions options;
- options.punycode_begin = &encoding_[pos_];
- options.punycode_end = &encoding_[pos_] + num_bytes;
- options.out_begin = out_;
- options.out_end = out_end_;
- out_ = DecodeRustPunycode(options);
- if (out_ == nullptr) return false;
- pos_ += static_cast<size_t>(num_bytes);
+ // A length exceeding the remaining input would make punycode_end point
+ // past the end of the buffer, forming an out-of-bounds pointer.
+ if (static_cast<size_t>(num_bytes) > std::strlen(&encoding_[pos_])) {
+ return false;
+ }
+ if (silence_depth_ == 0) {
+ DecodeRustPunycodeOptions options;
+ options.punycode_begin = &encoding_[pos_];
+ options.punycode_end = &encoding_[pos_] + num_bytes;
+ options.out_begin = out_;
+ options.out_end = out_end_;
+ out_ = DecodeRustPunycode(options);
+ if (out_ == nullptr) return false;
+ pos_ += static_cast<size_t>(num_bytes);
+ } else {
+ // Output is silenced, so like EmitChar and Emit we produce nothing and
+ // use no output space. Still consume the identifier's encoded bytes,
+ // stopping at a premature NUL exactly as the raw-bytes branch below
+ // does, so a suppressed punycoded identifier (e.g. a punycoded
+ // fn-signature abi) cannot leak into the demangling.
+ for (int i = 0; i < num_bytes; ++i) {
+ if (Take() == '\0') return false;
+ }
+ }
}
// Emit the beginnings of braced forms like {shim:vtable#0}.
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust_test.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust_test.cc
index 110700e51e0..3f0a904731f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_rust_test.cc
@@ -118,6 +118,11 @@ TEST(DemangleRust, UnicodeIdentifiers) {
"ice_cap::Eyjafjallajökull");
EXPECT_DEMANGLING("_RNvC7ice_caps_u19Eyjafjallajkull_jtb",
"ice_cap::Eyjafjallajökull");
+
+ // A punycode byte count larger than the remaining input is rejected instead
+ // of running the decoder past the end of the buffer.
+ EXPECT_DEMANGLING_FAILS("_RNvC7ice_caps_u2000000000Eyjafjallajkull_jtb");
+ EXPECT_DEMANGLING_FAILS("_RNvC7ice_caps_u99Eyj_a");
}
TEST(DemangleRust, FunctionInModule) {
@@ -524,6 +529,15 @@ TEST(DemangleRust, ExternOther) {
"<fn... as c::t>::f");
}
+TEST(DemangleRust, ExternPunycodedAbiIsSuppressed) {
+ // The abi is part of the silenced function signature, so a punycoded abi must
+ // be suppressed like any other identifier; its decoded form must not leak
+ // into the output.
+ EXPECT_DEMANGLING(
+ // <extern "Eyjafjallajökull" fn() as c::t>::f
+ "_RNvYFKu19Eyjafjallajkull_jtbEuNtC1c1t1f", "<fn... as c::t>::f");
+}
+
TEST(DemangleRust, Unsafe) {
EXPECT_DEMANGLING("_RNvYFUEuNtC1c1t1f", // <unsafe fn() as c::t>::f
"<fn... as c::t>::f");
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc
index 7238fd023a2..3023c5c834d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/demangle_test.cc
@@ -471,6 +471,31 @@ TEST(Demangle, AvoidSignedOverflowForUnfortunateParameterNumbers) {
EXPECT_STREQ(tmp, "S::f()::{default arg#1}::{lambda()#1}::operator()()");
}
+TEST(Demangle, NegativeUnnamedTypeNumbers) {
+ char tmp[100];
+
+ // An omitted <number> denotes index 1 and is left as the -1 sentinel.
+ ASSERT_TRUE(Demangle("_ZUt_", tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "{unnamed type#1}");
+ ASSERT_TRUE(Demangle("_ZUlvE_", tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "{lambda()#1}");
+
+ // Reject an explicitly negative <number>. Left unstrained, <number> + 2 is
+ // negative, and MaybeAppendDecimal emits (val % 10) + '0' per digit, which
+ // for a negative val yields characters below '0'.
+ ASSERT_FALSE(Demangle("_ZUtn3_", tmp, sizeof(tmp)));
+ ASSERT_FALSE(Demangle("_ZUlvEn3_", tmp, sizeof(tmp)));
+
+ // ParseNumber truncates to int, so an in-range-looking <number> can also
+ // arrive negative.
+ ASSERT_FALSE(Demangle("_ZUt2147483648_", tmp, sizeof(tmp)));
+ ASSERT_FALSE(Demangle("_ZUlvE2147483648_", tmp, sizeof(tmp)));
+
+ // The largest <number> whose index still fits in an int is unaffected.
+ ASSERT_TRUE(Demangle("_ZUt2147483645_", tmp, sizeof(tmp)));
+ EXPECT_STREQ(tmp, "{unnamed type#2147483647}");
+}
+
TEST(Demangle, SubstpackNotationForTroublesomeTemplatePack) {
char tmp[100];
@@ -680,6 +705,18 @@ TEST(Demangle, Float128x) {
EXPECT_STREQ("S::operator _Float128x()", tmp);
}
+TEST(Demangle, InvalidFloatNWidth) {
+ char tmp[80];
+
+ // A negative or overflowed _FloatN width is not printable, so render it as
+ // "?" like the sibling _BitInt path instead of emitting garbage bytes.
+ EXPECT_TRUE(Demangle("_ZNK1ScvDFn3_Ev", tmp, sizeof(tmp)));
+ EXPECT_STREQ("S::operator _Float?()", tmp);
+
+ EXPECT_TRUE(Demangle("_ZNK1ScvDF2147483648_Ev", tmp, sizeof(tmp)));
+ EXPECT_STREQ("S::operator _Float?()", tmp);
+}
+
TEST(Demangle, Bfloat16) {
char tmp[80];
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
index c8a103669ca..4d31a474cfd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/elf_mem_image.h
@@ -22,6 +22,7 @@
// Including this will define the __GLIBC__ macro if glibc is being
// used.
#include <climits>
+#include <cstddef>
#include <cstdint>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc
index a871b049999..9869c18a732 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/examine_stack.cc
@@ -16,12 +16,22 @@
#include "absl/debugging/internal/examine_stack.h"
+#include <csignal>
+#include <cstdint>
+#include <cstdio>
+#include <iterator>
+
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/raw_logging.h"
+#include "absl/base/macros.h"
+#include "absl/debugging/stacktrace.h"
+#include "absl/debugging/symbolize.h"
+
#ifndef _WIN32
#include <unistd.h>
#endif
-#include "absl/base/config.h"
-
#ifdef ABSL_HAVE_MMAP
#include <sys/mman.h>
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
@@ -33,15 +43,6 @@
#include <sys/ucontext.h>
#endif
-#include <csignal>
-#include <cstdio>
-
-#include "absl/base/attributes.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/macros.h"
-#include "absl/debugging/stacktrace.h"
-#include "absl/debugging/symbolize.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
@@ -167,7 +168,7 @@ void* GetProgramCounter(void* const vuc) {
#elif defined(__hppa__)
return reinterpret_cast<void*>(context->uc_mcontext.sc_iaoq[0]);
#elif defined(__i386__)
- if (14 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs))
+ if (14 < std::size(context->uc_mcontext.gregs))
return reinterpret_cast<void*>(context->uc_mcontext.gregs[14]);
#elif defined(__ia64__)
return reinterpret_cast<void*>(context->uc_mcontext.sc_ip);
@@ -192,7 +193,7 @@ void* GetProgramCounter(void* const vuc) {
#elif defined(__sparc__) && defined(__arch64__)
return reinterpret_cast<void*>(context->uc_mcontext.mc_gregs[19]);
#elif defined(__x86_64__)
- if (16 < ABSL_ARRAYSIZE(context->uc_mcontext.gregs))
+ if (16 < std::size(context->uc_mcontext.gregs))
return reinterpret_cast<void*>(context->uc_mcontext.gregs[16]);
#elif defined(__e2k__)
return reinterpret_cast<void*>(context->uc_mcontext.cr0_hi);
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc
index 0010644f44b..79d685810e7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_aarch64-inl.inc
@@ -3,13 +3,6 @@
// Generate stack tracer for aarch64
-#if defined(__linux__)
-#include <signal.h>
-#include <sys/mman.h>
-#include <ucontext.h>
-#include <unistd.h>
-#endif
-
#include <atomic>
#include <cassert>
#include <cstddef>
@@ -23,6 +16,13 @@
#include "absl/debugging/internal/vdso_support.h" // a no-op on non-elf or non-glibc systems
#include "absl/debugging/stacktrace.h"
+#if defined(__linux__)
+#include <signal.h>
+#include <sys/mman.h>
+#include <ucontext.h>
+#include <unistd.h>
+#endif
+
static const size_t kUnknownFrameSize = 0;
// Stack end to use when we don't know the actual stack end
// (effectively just the end of address space).
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h
index c82d4a3694d..1ce2ad6b337 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_config.h
@@ -18,6 +18,9 @@
* This header is "private" to stacktrace.cc.
* DO NOT include it into any other files.
*/
+
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_CONFIG_H_
@@ -59,7 +62,7 @@
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_libunwind-inl.inc"
#define STACKTRACE_USES_LIBUNWIND 1
-#elif defined(NO_FRAME_POINTER) && defined(__has_include)
+#elif defined(NO_FRAME_POINTER)
#if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)
// Note: When using glibc this may require -funwind-tables to function properly.
#define ABSL_STACKTRACE_INL_HEADER \
@@ -77,13 +80,13 @@
#elif defined(__riscv)
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_riscv-inl.inc"
-#elif defined(__has_include)
+#else
#if __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)
// Note: When using glibc this may require -funwind-tables to function properly.
#define ABSL_STACKTRACE_INL_HEADER \
"absl/debugging/internal/stacktrace_generic-inl.inc"
#endif // __has_include(<execinfo.h>) && defined(ABSL_HAVE_THREAD_LOCAL)
-#endif // defined(__has_include)
+#endif
#endif // defined(__linux__) && !defined(__ANDROID__)
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 f446655b922..f23c29cb0a0 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
@@ -21,13 +21,8 @@
#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_POWERPC_INL_H_
-#include "absl/debugging/internal/addresses.h"
-#if defined(__linux__)
-#include <asm/ptrace.h> // for PT_NIP.
-#include <ucontext.h> // for ucontext_t
-#endif
-
#include <unistd.h>
+
#include <cassert>
#include <cstdint>
#include <cstdio>
@@ -35,9 +30,15 @@
#include "absl/base/attributes.h"
#include "absl/base/optimization.h"
#include "absl/base/port.h"
-#include "absl/debugging/stacktrace.h"
#include "absl/debugging/internal/address_is_readable.h"
+#include "absl/debugging/internal/addresses.h"
#include "absl/debugging/internal/vdso_support.h" // a no-op on non-elf or non-glibc systems
+#include "absl/debugging/stacktrace.h"
+
+#if defined(__linux__)
+#include <asm/ptrace.h> // for PT_NIP.
+#include <ucontext.h> // for ucontext_t
+#endif
// Given a stack pointer, return the saved link register value.
// Note that this is the link register for a callee.
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc
index a4fb3834dcf..e950e76c0f3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_riscv-inl.inc
@@ -19,14 +19,6 @@
#include <sys/ucontext.h>
-#include "absl/base/config.h"
-#include "absl/debugging/internal/addresses.h"
-#if defined(__linux__)
-#include <sys/mman.h>
-#include <ucontext.h>
-#include <unistd.h>
-#endif
-
#include <atomic>
#include <cassert>
#include <cstdint>
@@ -35,8 +27,16 @@
#include <utility>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/debugging/internal/addresses.h"
#include "absl/debugging/stacktrace.h"
+#if defined(__linux__)
+#include <sys/mman.h>
+#include <ucontext.h>
+#include <unistd.h>
+#endif
+
static constexpr ptrdiff_t kUnknownFrameSize = 0;
// Compute the size of a stack frame in [low..high). We assume that low < high.
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc
index 27ee32ac395..55cf29a8cf2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/stacktrace_x86-inl.inc
@@ -17,15 +17,8 @@
#ifndef ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_
#define ABSL_DEBUGGING_INTERNAL_STACKTRACE_X86_INL_INC_
-#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
-#include <ucontext.h> // for ucontext_t
-#endif
-
-#if !defined(_WIN32)
-#include <unistd.h>
-#endif
-
#include <cassert>
+#include <cstddef>
#include <cstdint>
#include <limits>
@@ -37,6 +30,14 @@
#include "absl/debugging/internal/vdso_support.h" // a no-op on non-elf or non-glibc systems
#include "absl/debugging/stacktrace.h"
+#if defined(__linux__) && (defined(__i386__) || defined(__x86_64__))
+#include <ucontext.h> // for ucontext_t
+#endif
+
+#if !defined(_WIN32)
+#include <unistd.h>
+#endif
+
using absl::debugging_internal::AddressIsReadable;
#if defined(__linux__) && defined(__i386__)
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/symbolize.h b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/symbolize.h
index 3360af56631..fd655449c3e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/internal/symbolize.h
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/internal/symbolize.h
@@ -22,6 +22,7 @@
#include <cstddef>
#include <cstdint>
+#include <functional>
#include <memory>
#include "absl/base/config.h"
@@ -35,7 +36,6 @@
#include <elf.h>
#include <link.h> // For ElfW() macro.
-#include <functional>
namespace absl {
ABSL_NAMESPACE_BEGIN
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 f7e2a443500..9d96f3bc87e 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
@@ -17,14 +17,14 @@
// VDSOSupport -- a class representing kernel VDSO (if present).
#include "absl/debugging/internal/vdso_support.h"
+
+#include <atomic>
+
#include "absl/base/attributes.h"
+#include "absl/debugging/internal/elf_mem_image.h"
#ifdef ABSL_HAVE_VDSO_SUPPORT // defined in vdso_support.h
-#if !defined(__has_include)
-#define __has_include(header) 0
-#endif
-
#include <errno.h>
#include <fcntl.h>
#if __has_include(<syscall.h>)
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 17552b4b2b3..0bf94f70d57 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
@@ -312,7 +312,8 @@ TEST(StackTrace, CustomUnwinderPerformsFixup) {
const void* g_return_address = nullptr;
bool g_sigusr2_raised = false;
-void SigUsr2Handler(int, siginfo_t*, void* uc) {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS void SigUsr2Handler(int, siginfo_t*,
+ void* uc) {
absl::base_internal::ErrnoSaver errno_saver;
// Many platforms don't support this by default.
bool support_is_expected = false;
@@ -333,18 +334,19 @@ void SigUsr2Handler(int, siginfo_t*, void* uc) {
g_sigusr2_raised = true;
}
-void SigUsr1Handler(int, siginfo_t*, void*) {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS void SigUsr1Handler(int, siginfo_t*, void*) {
raise(SIGUSR2);
ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
}
-ABSL_ATTRIBUTE_NOINLINE void RaiseSignal() {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE void RaiseSignal() {
g_return_address = __builtin_return_address(0);
raise(SIGUSR1);
ABSL_BLOCK_TAIL_CALL_OPTIMIZATION();
}
-ABSL_ATTRIBUTE_NOINLINE void TestNestedSignal() {
+ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE void
+TestNestedSignal() {
constexpr size_t kAltstackSize = 1 << 14;
// Allocate altstack on regular stack to make sure it'll have a higher
// address than some of the regular stack frames.
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 56f31afbafc..06c56344543 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
@@ -67,6 +67,7 @@
#include <cstdio>
#include <cstdlib>
#include <cstring>
+#include <iterator>
#include <memory>
#include "absl/base/casts.h"
@@ -712,7 +713,7 @@ static bool ShouldPickFirstSymbol(const ElfW(Sym) & symbol1,
// If one of the symbols is weak and the other is not, pick the one
// this is not a weak symbol.
char bind1 = ELF_ST_BIND(symbol1.st_info);
- char bind2 = ELF_ST_BIND(symbol1.st_info);
+ char bind2 = ELF_ST_BIND(symbol2.st_info);
if (bind1 == STB_WEAK && bind2 != STB_WEAK) return false;
if (bind2 == STB_WEAK && bind1 != STB_WEAK) return true;
@@ -728,7 +729,7 @@ static bool ShouldPickFirstSymbol(const ElfW(Sym) & symbol1,
// If one of the symbols has no type and the other is not, pick the
// one that has a type.
char type1 = ELF_ST_TYPE(symbol1.st_info);
- char type2 = ELF_ST_TYPE(symbol1.st_info);
+ char type2 = ELF_ST_TYPE(symbol2.st_info);
if (type1 != STT_NOTYPE && type2 == STT_NOTYPE) {
return true;
}
@@ -1320,7 +1321,7 @@ const char *Symbolizer::FindSymbolInCache(const void *const pc) {
if (pc == nullptr) return nullptr;
SymbolCacheLine *line = GetCacheLine(pc);
- for (size_t i = 0; i < ABSL_ARRAYSIZE(line->pc); ++i) {
+ for (size_t i = 0; i < std::size(line->pc); ++i) {
if (line->pc[i] == pc) {
AgeSymbols(line);
line->age[i] = 0;
@@ -1338,7 +1339,7 @@ const char *Symbolizer::InsertSymbolInCache(const void *const pc,
uint32_t max_age = 0;
size_t oldest_index = 0;
bool found_oldest_index = false;
- for (size_t i = 0; i < ABSL_ARRAYSIZE(line->pc); ++i) {
+ for (size_t i = 0; i < std::size(line->pc); ++i) {
if (line->pc[i] == nullptr) {
AgeSymbols(line);
line->pc[i] = pc;
diff --git a/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_test.cc b/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_test.cc
index 2862394418c..2cb16381b6f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/debugging/symbolize_test.cc
@@ -13,23 +13,14 @@
// limitations under the License.
#include "absl/debugging/symbolize.h"
-#include <cstddef>
-
-#include "absl/debugging/internal/symbolize.h"
-#include "absl/strings/str_format.h"
-
-#ifdef __EMSCRIPTEN__
-#include <emscripten.h>
-#endif
-
-#ifndef _WIN32
-#include <fcntl.h>
-#include <sys/mman.h>
-#endif
+#include <cstddef>
+#include <cstdint>
#include <cstring>
#include <iostream>
#include <memory>
+#include <string>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
@@ -41,11 +32,22 @@
#include "absl/base/optimization.h"
#include "absl/cleanup/cleanup.h"
#include "absl/debugging/internal/stack_consumption.h"
+#include "absl/debugging/internal/symbolize.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/memory/memory.h"
+#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
+#ifdef __EMSCRIPTEN__
+#include <emscripten.h>
+#endif
+
+#ifndef _WIN32
+#include <fcntl.h>
+#include <sys/mman.h>
+#endif
+
#if defined(MAP_ANON) && !defined(MAP_ANONYMOUS)
#define MAP_ANONYMOUS MAP_ANON
#endif
@@ -244,8 +246,8 @@ static const char *SymbolizeStackConsumption(void *pc, int *stack_consumed) {
}
static int GetStackConsumptionUpperLimit() {
- // Symbolize stack consumption should be within 2kB.
- int stack_consumption_upper_limit = 2048;
+ // Symbolize stack consumption should be within 4kB.
+ int stack_consumption_upper_limit = 4096;
#if defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
defined(ABSL_HAVE_MEMORY_SANITIZER) || defined(ABSL_HAVE_THREAD_SANITIZER)
// Account for sanitizer instrumentation requiring additional stack space.
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 29632d978f6..ffba58ed66a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/BUILD.gn
@@ -1,33 +1,37 @@
# Copyright 2019 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("path_util") {
public = [ "internal/path_util.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
- visibility = [ ":*" ]
}
absl_source_set("program_name") {
sources = [ "internal/program_name.cc" ]
public = [ "internal/program_name.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":path_util",
"//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",
]
- visibility = [
- ":*",
- "../log:*",
- ]
}
# Since absl/flags are only used by some test binaries (e.g. in WebRTC),
@@ -39,7 +43,6 @@ config("absl_flags_config") {
absl_source_set("config") {
sources = [ "usage_config.cc" ]
- public_configs = [ ":absl_flags_config" ]
public = [
"config.h",
"usage_config.h",
@@ -54,6 +57,7 @@ absl_source_set("config") {
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
]
+ public_configs = [ ":absl_flags_config" ]
}
absl_source_set("marshalling") {
@@ -72,9 +76,9 @@ absl_source_set("marshalling") {
}
absl_source_set("commandlineflag_internal") {
- visibility = [ ":*" ]
- public = [ "internal/commandlineflag.h" ]
sources = [ "internal/commandlineflag.cc" ]
+ public = [ "internal/commandlineflag.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
@@ -89,6 +93,7 @@ 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",
]
@@ -97,13 +102,17 @@ absl_source_set("commandlineflag") {
absl_source_set("private_handle_accessor") {
sources = [ "internal/private_handle_accessor.cc" ]
public = [ "internal/private_handle_accessor.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/flags/rust:*",
+ ]
deps = [
":commandlineflag",
":commandlineflag_internal",
"//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:string_view",
]
- visibility = [ ":*" ]
}
absl_source_set("reflection") {
@@ -134,6 +143,10 @@ absl_source_set("flag_internal") {
"internal/flag.h",
"internal/sequence_lock.h",
]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/base/*",
+ ]
deps = [
":commandlineflag",
":commandlineflag_internal",
@@ -153,10 +166,6 @@ absl_source_set("flag_internal") {
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/utility",
]
- visibility = [
- ":*",
- "//third_party/abseil-cpp/absl/base/*",
- ]
}
absl_source_set("flag") {
@@ -172,6 +181,7 @@ 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",
]
}
@@ -179,6 +189,7 @@ absl_source_set("flag") {
absl_source_set("usage_internal") {
sources = [ "internal/usage.cc" ]
public = [ "internal/usage.h" ]
+ visibility = [ ":*" ]
deps = [
":commandlineflag",
":config",
@@ -195,7 +206,6 @@ absl_source_set("usage_internal") {
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
]
- visibility = [ ":*" ]
}
absl_source_set("usage") {
@@ -206,6 +216,7 @@ 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",
]
@@ -238,6 +249,14 @@ absl_source_set("parse") {
]
}
+# Conflicts at link_time with "parse_test" because defines the same flags.
+# absl_test("commandlineflag_test")
+
+absl_test("config_test") {
+ sources = [ "config_test.cc" ]
+ deps = [ ":config" ]
+}
+
absl_test("flag_test") {
sources = [
"flag_test.cc",
@@ -259,3 +278,67 @@ absl_test("flag_test") {
"//third_party/abseil-cpp/absl/time",
]
}
+
+absl_test("marshalling_test") {
+ sources = [ "marshalling_test.cc" ]
+ deps = [ ":marshalling" ]
+}
+
+absl_test("parse_test") {
+ sources = [ "parse_test.cc" ]
+ deps = [
+ ":config",
+ ":flag",
+ ":parse",
+ ":reflection",
+ ":usage_internal",
+ "//third_party/abseil-cpp/absl/base:scoped_set_env",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
+ "//third_party/abseil-cpp/absl/types:span",
+ ]
+ if (is_ios) {
+ sources = []
+ }
+}
+
+absl_test("path_util_test") {
+ sources = [ "internal/path_util_test.cc" ]
+ deps = [ ":path_util" ]
+}
+
+absl_test("program_name_test") {
+ sources = [ "internal/program_name_test.cc" ]
+ deps = [
+ ":program_name",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
+ ]
+}
+
+# Conflicts at link time with "flag_test" because defines the same flags.
+# absl_test("reflection_test")
+
+absl_test("sequence_lock_test") {
+ sources = [ "internal/sequence_lock_test.cc" ]
+ deps = [
+ ":flag_internal",
+ "//third_party/abseil-cpp/absl/base",
+ "//third_party/abseil-cpp/absl/container:fixed_array",
+ "//third_party/abseil-cpp/absl/time",
+ ]
+}
+
+absl_test("usage_config_test") {
+ sources = [ "usage_config_test.cc" ]
+ deps = [
+ ":config",
+ ":path_util",
+ ":program_name",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
+ ]
+}
+# usage_test is excluded because defines its own main function
+# absl_test("usage_test")
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 638998667e7..5c74d765f24 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,13 +13,12 @@
// limitations under the License.
#include "absl/flags/config.h"
+#include "gtest/gtest.h"
#ifdef __APPLE__
#include <TargetConditionals.h>
#endif
-#include "gtest/gtest.h"
-
#ifndef ABSL_FLAGS_STRIP_NAMES
#error ABSL_FLAGS_STRIP_NAMES is not defined
#endif
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 d303c8d2293..1dd2f5c97be 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
@@ -19,6 +19,7 @@
#include <stdint.h>
#include <atomic>
+#include <iterator>
#include <optional>
#include <string>
#include <thread> // NOLINT
@@ -690,10 +691,10 @@ TEST_F(FlagTest, ConcurrentSetAndGet) {
});
}
absl::Time end_time = absl::Now() + absl::Seconds(1);
- int i = 0;
+ size_t i = 0;
while (absl::Now() < end_time) {
absl::SetFlag(&FLAGS_test_flag_12,
- kValidDurations[i++ % ABSL_ARRAYSIZE(kValidDurations)]);
+ kValidDurations[i++ % std::size(kValidDurations)]);
}
stop.store(true, std::memory_order_relaxed);
for (auto& t : threads) t.join();
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 fd41040783a..7855a104b45 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
@@ -299,19 +299,16 @@ constexpr FlagDefaultArg DefaultArg(char) {
template <typename T>
using FlagUseValueAndInitBitStorage =
- std::integral_constant<bool, std::is_trivially_copyable_v<T> &&
- std::is_default_constructible_v<T> &&
- (sizeof(T) < 8)>;
+ std::bool_constant<std::is_trivially_copyable_v<T> &&
+ std::is_default_constructible_v<T> && (sizeof(T) < 8)>;
template <typename T>
using FlagUseOneWordStorage =
- std::integral_constant<bool,
- std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>;
+ std::bool_constant<std::is_trivially_copyable_v<T> && (sizeof(T) <= 8)>;
template <class T>
using FlagUseSequenceLockStorage =
- std::integral_constant<bool,
- std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>;
+ std::bool_constant<std::is_trivially_copyable_v<T> && (sizeof(T) > 8)>;
enum class FlagValueStorageKind : uint8_t {
kValueAndInitBit = 0,
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/internal/parse.h b/deps/v8/third_party/abseil-cpp/absl/flags/internal/parse.h
index 10c531b82ba..aa29dea00d5 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/internal/parse.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/internal/parse.h
@@ -63,6 +63,12 @@ bool WasPresentOnCommandLine(absl::string_view flag_name);
// misspellings.
std::vector<std::string> GetMisspellingHints(absl::string_view flag);
+// IsIndirectFlagExpansionEnabled()
+//
+// If DisableFlagfileAndEnvParsing() has been called, returns false. Otherwise,
+// returns true.
+[[nodiscard]] bool IsIndirectFlagExpansionEnabled();
+
} // namespace flags_internal
ABSL_NAMESPACE_END
} // 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 c3ec372ed8c..a244d67d18b 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
@@ -113,12 +113,12 @@ std::vector<int> MultiplicativeRange(int low, int high, int scale) {
return result;
}
-#ifndef ABSL_HAVE_THREAD_SANITIZER
-const int kMaxThreads = absl::base_internal::NumCPUs();
-#else
+#if defined(ABSL_HAVE_THREAD_SANITIZER)
// With TSAN, a lot of threads contending for atomic access on the sequence
// lock make this test run too slowly.
const int kMaxThreads = std::min(absl::base_internal::NumCPUs(), 4);
+#else
+const int kMaxThreads = absl::base_internal::NumCPUs();
#endif
// Return all of the interesting buffer sizes worth testing:
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/parse.cc b/deps/v8/third_party/abseil-cpp/absl/flags/parse.cc
index 4961930451d..940bf565c45 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/parse.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/parse.cc
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <algorithm>
+#include <atomic>
#include <cstdint>
#include <cstdlib>
#include <fstream>
@@ -28,10 +29,6 @@
#include <utility>
#include <vector>
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
#include "absl/base/config.h"
@@ -57,6 +54,10 @@
#include "absl/strings/strip.h"
#include "absl/synchronization/mutex.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
// --------------------------------------------------------------------
namespace absl {
@@ -64,6 +65,8 @@ ABSL_NAMESPACE_BEGIN
namespace flags_internal {
namespace {
+ABSL_CONST_INIT std::atomic<bool> g_disable_indirect_flag_expansion(false);
+
absl::Mutex& ProcessingChecksMutex() {
static absl::NoDestructor<absl::Mutex> mutex;
return *mutex;
@@ -354,6 +357,12 @@ void CheckDefaultValuesParsingRoundtrip() {
// etc.
bool ReadFlagfiles(const std::vector<std::string>& flagfiles,
std::vector<ArgsList>& input_args) {
+ if (!flags_internal::IsIndirectFlagExpansionEnabled()) {
+ flags_internal::ReportUsageError(
+ "Skipping expansion of --flagfile as it is disabled.", false);
+ return true;
+ }
+
bool success = true;
for (auto it = flagfiles.rbegin(); it != flagfiles.rend(); ++it) {
ArgsList al;
@@ -376,6 +385,13 @@ bool ReadFlagfiles(const std::vector<std::string>& flagfiles,
bool ReadFlagsFromEnv(const std::vector<std::string>& flag_names,
std::vector<ArgsList>& input_args,
bool fail_on_absent_in_env) {
+ if (!flags_internal::IsIndirectFlagExpansionEnabled()) {
+ flags_internal::ReportUsageError(
+ "Skipping expansion of --fromenv/--tryfromenv as it is disabled.",
+ false);
+ return true;
+ }
+
bool success = true;
std::vector<std::string> args;
@@ -921,8 +937,16 @@ HelpMode ParseAbseilFlagsOnlyImpl(
: HelpMode::kNone;
}
+bool IsIndirectFlagExpansionEnabled() {
+ return !g_disable_indirect_flag_expansion;
+}
+
} // namespace flags_internal
+void DisableFlagfileAndEnvParsing() {
+ flags_internal::g_disable_indirect_flag_expansion = true;
+}
+
void ParseAbseilFlagsOnly(int argc, char* argv[],
std::vector<char*>& positional_args,
std::vector<UnrecognizedFlag>& unrecognized_flags) {
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 f2a5cb10f46..fdb3d1eb89d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/parse.h
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/parse.h
@@ -124,6 +124,21 @@ void ReportUnrecognizedFlags(
// `ParseAbseilFlagsOnly`.
std::vector<char*> ParseCommandLine(int argc, char* argv[]);
+// DisableFlagfileAndEnvParsing()
+//
+// Disables the processing of flags that load values from secondary sources,
+// specifically `--flagfile`, `--fromenv`, and `--tryfromenv`. When disabled,
+// occurrences of these flags on the command line are skipped without opening
+// files or inspecting environment variables, and a warning is printed to
+// stderr. Direct command-line flags passed via argv are still parsed normally.
+//
+// This is primarily intended as a security precaution for privileged or setuid
+// processes parsing untrusted command lines prior to dropping privileges.
+//
+// Should only be called in `main()` before calling `absl::ParseCommandLine()`
+// or `absl::ParseAbseilFlagsOnly()`.
+void DisableFlagfileAndEnvParsing();
+
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/deps/v8/third_party/abseil-cpp/absl/flags/parse_test.cc b/deps/v8/third_party/abseil-cpp/absl/flags/parse_test.cc
index 08eb81ae816..138cf6e09d1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/parse_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/parse_test.cc
@@ -1091,4 +1091,65 @@ TEST_F(ParseDeathTest, ExitOnUnrecognizedFlagPrintsHelp) {
// --------------------------------------------------------------------
+TEST_F(ParseDeathTest, DisableFlagfileAndEnvParsing) {
+ EXPECT_EXIT(
+ ([]() {
+ absl::DisableFlagfileAndEnvParsing();
+ std::string flagfile_flag;
+ const char* args[] = {
+ "testbin",
+ "--string_flag=abc",
+ GetFlagfileFlag({{"parse_test.ff_disabled", {"--int_flag=123"}}},
+ flagfile_flag),
+ };
+ InvokeParse(args);
+ exit(absl::GetFlag(FLAGS_int_flag) == 123 ||
+ absl::GetFlag(FLAGS_string_flag) != "abc"
+ ? 1
+ : 0);
+ })(),
+ testing::ExitedWithCode(0),
+ "Skipping expansion of --flagfile as it is disabled");
+
+ EXPECT_EXIT(([]() {
+ absl::DisableFlagfileAndEnvParsing();
+ ScopedSetEnv set_int_flag("FLAGS_int_flag", "123");
+ const char* args[] = {"testbin", "--string_flag=abc",
+ "--fromenv=int_flag"};
+ InvokeParse(args);
+ exit(absl::GetFlag(FLAGS_int_flag) == 123 ||
+ absl::GetFlag(FLAGS_string_flag) != "abc"
+ ? 1
+ : 0);
+ })(),
+ testing::ExitedWithCode(0),
+ "Skipping expansion of --fromenv/--tryfromenv as it is disabled");
+
+ EXPECT_EXIT(([]() {
+ absl::DisableFlagfileAndEnvParsing();
+ ScopedSetEnv set_int_flag("FLAGS_int_flag", "123");
+ const char* args[] = {"testbin", "--string_flag=abc",
+ "--tryfromenv=int_flag"};
+ InvokeParse(args);
+ exit(absl::GetFlag(FLAGS_int_flag) == 123 ||
+ absl::GetFlag(FLAGS_string_flag) != "abc"
+ ? 1
+ : 0);
+ })(),
+ testing::ExitedWithCode(0),
+ "Skipping expansion of --fromenv/--tryfromenv as it is disabled");
+}
+
+TEST_F(ParseDeathTest, IsIndirectFlagExpansionEnabledWorks) {
+ EXPECT_EXIT(
+ ([]() {
+ if (!absl::flags_internal::IsIndirectFlagExpansionEnabled()) {
+ exit(1);
+ }
+ absl::DisableFlagfileAndEnvParsing();
+ exit(absl::flags_internal::IsIndirectFlagExpansionEnabled() ? 2 : 0);
+ })(),
+ testing::ExitedWithCode(0), "");
+}
+
} // namespace
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 fb64a65394a..e92ff961b45 100644
--- a/deps/v8/third_party/abseil-cpp/absl/flags/reflection.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/flags/reflection.cc
@@ -294,8 +294,8 @@ class RetiredFlagObj final : public CommandLineFlag {
} // namespace
void Retire(const char* name, FlagFastTypeId type_id, unsigned char* buf) {
- static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize, "");
- static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment, "");
+ static_assert(sizeof(RetiredFlagObj) == kRetiredFlagObjSize);
+ static_assert(alignof(RetiredFlagObj) == kRetiredFlagObjAlignment);
auto* flag = ::new (buf) flags_internal::RetiredFlagObj(name, type_id);
FlagRegistry::GlobalRegistry().RegisterFlag(*flag, nullptr);
}
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 6bf6307812e..585574a0cf7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -63,6 +65,14 @@ absl_source_set("bind_front") {
]
}
+absl_test("bind_front_test") {
+ sources = [ "bind_front_test.cc" ]
+ deps = [
+ ":bind_front",
+ "//third_party/abseil-cpp/absl/memory",
+ ]
+}
+
absl_source_set("function_ref") {
sources = [ "internal/function_ref.h" ]
public = [ "function_ref.h" ]
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 689c51008da..d667fa427ec 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
@@ -59,15 +59,14 @@ struct Wrapper {
// This will cause a recursive trait instantiation if the SFINAE checks are
// not ordered correctly for constructibility.
static_assert(std::is_constructible_v<Wrapper<absl::AnyInvocable<void()>>,
- Wrapper<absl::AnyInvocable<void()>>>,
- "");
+ Wrapper<absl::AnyInvocable<void()>>>);
// A metafunction that takes the cv and l-value reference qualifiers that were
// associated with a function type (here passed via qualifiers of an object
// type), and .
template <class Qualifiers, class This>
struct QualifiersForThisImpl {
- static_assert(std::is_object_v<This>, "");
+ static_assert(std::is_object_v<This>);
using type =
std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&;
};
@@ -78,7 +77,7 @@ struct QualifiersForThisImpl<Qualifiers&, This>
template <class Qualifiers, class This>
struct QualifiersForThisImpl<Qualifiers&&, This> {
- static_assert(std::is_object_v<This>, "");
+ static_assert(std::is_object_v<This>);
using type =
std::conditional_t<std::is_const_v<Qualifiers>, const This, This>&&;
};
@@ -421,7 +420,7 @@ using IsMemberSwappable = IsMemberSwappableImpl<T>;
template <class T>
using IsNothrowMemberSwappable =
- std::integral_constant<bool, IsMemberSwappableImpl<T>::kIsNothrow>;
+ std::bool_constant<IsMemberSwappableImpl<T>::kIsNothrow>;
template <class T>
class AnyInvTestBasic : public ::testing::Test {};
@@ -1011,7 +1010,7 @@ TYPED_TEST_P(AnyInvTestCombinatoric, SwapEmptyLhsEmptyRhs) {
EXPECT_FALSE(static_cast<bool>(other));
EXPECT_TRUE(
- absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+ std::is_nothrow_swappable_v<AnyInvType>);
}
// Member swap
@@ -1046,7 +1045,7 @@ TYPED_TEST_P(AnyInvTestCombinatoric, SwapEmptyLhsNonemptyRhs) {
EXPECT_EQ(29, TypeParam::ToThisParam(fun)(7, 8, 9).value);
EXPECT_TRUE(
- absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+ std::is_nothrow_swappable_v<AnyInvType>);
}
// Member swap
@@ -1083,7 +1082,7 @@ TYPED_TEST_P(AnyInvTestCombinatoric, SwapNonemptyLhsEmptyRhs) {
EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
EXPECT_TRUE(
- absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+ std::is_nothrow_swappable_v<AnyInvType>);
}
// Member swap
@@ -1121,7 +1120,7 @@ TYPED_TEST_P(AnyInvTestCombinatoric, SwapNonemptyLhsNonemptyRhs) {
EXPECT_EQ(29, TypeParam::ToThisParam(other)(7, 8, 9).value);
EXPECT_TRUE(
- absl::type_traits_internal::IsNothrowSwappable<AnyInvType>::value);
+ std::is_nothrow_swappable_v<AnyInvType>);
}
// Member swap
@@ -1280,8 +1279,8 @@ TYPED_TEST_P(AnyInvTestNonRvalue, NonMoveableResultType) {
Result(Result&&) = delete;
};
- static_assert(!std::is_move_constructible_v<Result>, "");
- static_assert(!std::is_copy_constructible_v<Result>, "");
+ static_assert(!std::is_move_constructible_v<Result>);
+ static_assert(!std::is_copy_constructible_v<Result>);
// Assumption check: it should nevertheless be possible to use functors that
// return a Result struct according to the language rules.
@@ -1358,8 +1357,8 @@ TYPED_TEST_P(AnyInvTestRvalue, NonMoveableResultType) {
Result(Result&&) = delete;
};
- static_assert(!std::is_move_constructible_v<Result>, "");
- static_assert(!std::is_copy_constructible_v<Result>, "");
+ static_assert(!std::is_move_constructible_v<Result>);
+ static_assert(!std::is_copy_constructible_v<Result>);
// Assumption check: it should nevertheless be possible to use functors that
// return a Result struct according to the language rules.
@@ -1590,9 +1589,8 @@ REGISTER_TYPED_TEST_SUITE_P(AnyInvTestRvalue,
// Minimal SFINAE testing for platforms where we can't run the tests, but we can
// build binaries for.
-static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>,
- "");
-static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>, "");
+static_assert(std::is_convertible_v<void (*)(), absl::AnyInvocable<void() &&>>);
+static_assert(!std::is_convertible_v<void*, absl::AnyInvocable<void() &&>>);
} // namespace absl_any_invocable_test
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/bind_back.h b/deps/v8/third_party/abseil-cpp/absl/functional/bind_back.h
index ba31fb43ec4..8d9ff7cd3c8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/bind_back.h
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/bind_back.h
@@ -30,11 +30,9 @@
#ifndef ABSL_FUNCTIONAL_BIND_BACK_H_
#define ABSL_FUNCTIONAL_BIND_BACK_H_
-#ifdef __has_include
#if __has_include(<version>)
#include <version>
#endif
-#endif
#if defined(__cpp_lib_bind_back) && __cpp_lib_bind_back >= 202202L
#include <functional> // For std::bind_back.
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 09adc093932..4dcee393f02 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,11 +30,9 @@
#ifndef ABSL_FUNCTIONAL_BIND_FRONT_H_
#define ABSL_FUNCTIONAL_BIND_FRONT_H_
-#ifdef __has_include
#if __has_include(<version>)
#include <version>
#endif
-#endif
#if defined(__cpp_lib_bind_front) && __cpp_lib_bind_front >= 201907L
#include <functional> // For std::bind_front.
diff --git a/deps/v8/third_party/abseil-cpp/absl/functional/internal/any_invocable.h b/deps/v8/third_party/abseil-cpp/absl/functional/internal/any_invocable.h
index ecf03196ba1..1ff8bb6fa58 100644
--- a/deps/v8/third_party/abseil-cpp/absl/functional/internal/any_invocable.h
+++ b/deps/v8/third_party/abseil-cpp/absl/functional/internal/any_invocable.h
@@ -63,7 +63,6 @@
#include <type_traits>
#include <utility>
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/nullability.h"
@@ -145,8 +144,8 @@ T&& ForwardImpl(std::false_type);
// as a workaround for b/206991861 on MSVC versions < 1924.
template <class T>
struct ForwardedParameter {
- using type = decltype((
- ForwardImpl<T>)(std::integral_constant<bool, std::is_scalar_v<T>>()));
+ using type =
+ decltype((ForwardImpl<T>)(std::bool_constant<std::is_scalar_v<T>>()));
};
template <class T>
@@ -252,7 +251,7 @@ void LocalManagerNontrivial(FunctionToCall operation,
case FunctionToCall::relocate_from_to_and_query_rust:
// NOTE: Requires that the left-hand operand is already empty.
::new (static_cast<void*>(&to->storage)) T(std::move(from_object));
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case FunctionToCall::dispose:
from_object.~T(); // Must not throw. // NOLINT
return;
@@ -607,8 +606,7 @@ using UnwrapStdReferenceWrapper =
// NOTE: We avoid std::void_t here to avoid a bug in GCC < 11:
// https://godbolt.org/z/sxbfGMdcb
template <class... T>
-using TrueAlias =
- std::integral_constant<bool, sizeof(std::common_type<T...>*) != 0>;
+using TrueAlias = std::bool_constant<sizeof(std::common_type<T...>*) != 0>;
/*SFINAE constraints for the conversion-constructor.*/
template <class Sig, class F,
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 3170ff97616..1e905fa2571 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
@@ -45,11 +45,11 @@ struct PassByValue : std::false_type {};
template <typename T>
struct PassByValue<T, /*IsLValueReference=*/false>
- : std::integral_constant<
- bool, std::is_trivially_copy_constructible_v<T> &&
- std::is_trivially_copy_assignable_v<std::remove_cv_t<T>> &&
- std::is_trivially_destructible_v<T> &&
- sizeof(T) <= 2 * sizeof(void*)> {};
+ : std::bool_constant<
+ std::is_trivially_copy_constructible_v<T> &&
+ std::is_trivially_copy_assignable_v<std::remove_cv_t<T>> &&
+ std::is_trivially_destructible_v<T> &&
+ sizeof(T) <= 2 * sizeof(void*)> {};
template <typename T>
struct ForwardT : std::conditional<PassByValue<T>::value, T, T&&> {};
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 9f12e9a7bfa..41d7d686b0c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.bazel
@@ -98,6 +98,7 @@ cc_test(
"//absl/memory",
"//absl/meta:type_traits",
"//absl/numeric:bits",
+ "//absl/strings:cord",
"//absl/strings:cord_test_helpers",
"//absl/strings:string_view",
"@googletest//:gtest",
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 1d37a9c05c5..f4aba2abdba 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/BUILD.gn
@@ -1,8 +1,9 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
-import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("hash") {
@@ -23,6 +24,7 @@ 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",
@@ -38,6 +40,7 @@ absl_source_set("hash_testing") {
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/types:variant",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -57,6 +60,7 @@ absl_test("hash_test") {
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
+ "//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:cord_test_helpers",
"//third_party/abseil-cpp/absl/strings:string_view",
]
@@ -82,18 +86,19 @@ absl_test("hash_instantiated_test") {
absl_source_set("spy_hash_state") {
testonly = true
public = [ "internal/spy_hash_state.h" ]
+ visibility = [ ":*" ]
deps = [
":hash",
":weakly_mixed_integer",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_source_set("city") {
- public = [ "internal/city.h" ]
sources = [ "internal/city.cc" ]
+ public = [ "internal/city.h" ]
+ visibility = [ ":*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -102,9 +107,19 @@ absl_source_set("city") {
]
}
+absl_test("city_test") {
+ sources = [ "internal/city_test.cc" ]
+ deps = [ ":city" ]
+}
+
absl_source_set("weakly_mixed_integer") {
public = [ "internal/weakly_mixed_integer.h" ]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/container:*",
+ "//third_party/abseil-cpp/absl/strings:*",
+ "//third_party/abseil-cpp/absl/types:*",
+ ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -113,5 +128,6 @@ absl_test("low_level_hash_test") {
deps = [
":hash",
"//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
]
}
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 86650b3bb8b..978b5bcfb63 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
@@ -196,7 +196,7 @@ auto MakeLongTuple() {
auto t6 = std::tuple_cat(t5, t5);
// Ideally this would be much larger, but some configurations can't handle
// making tuples with that many elements. They break inside std::tuple itself.
- static_assert(std::tuple_size<decltype(t6)>::value == 32, "");
+ static_assert(std::tuple_size_v<decltype(t6)> == 32);
return t6;
}
@@ -344,7 +344,7 @@ static constexpr size_t kEntropySize = 16 << 10;
static char entropy[kEntropySize + 1024];
ABSL_ATTRIBUTE_UNUSED static const bool kInitialized = [] {
absl::BitGen gen;
- static_assert(sizeof(entropy) % sizeof(uint64_t) == 0, "");
+ static_assert(sizeof(entropy) % sizeof(uint64_t) == 0);
for (int i = 0; i != sizeof(entropy); i += sizeof(uint64_t)) {
auto rand = absl::Uniform<uint64_t>(gen);
memcpy(&entropy[i], &rand, sizeof(uint64_t));
@@ -365,8 +365,8 @@ struct PodPairInt64 {
template <class T>
struct PodRand {
- static_assert(std::is_pod_v<T>, "");
- static_assert(kEntropySize + sizeof(T) < sizeof(entropy), "");
+ static_assert(std::is_pod_v<T>);
+ static_assert(kEntropySize + sizeof(T) < sizeof(entropy));
T Get(size_t i) const {
T v;
@@ -377,7 +377,7 @@ struct PodRand {
template <size_t N>
struct StringRand {
- static_assert(kEntropySize + N < sizeof(entropy), "");
+ static_assert(kEntropySize + N < sizeof(entropy));
absl::string_view Get(size_t i) const {
// This has a small bias towards small numbers. Because max N is ~200 this
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 63ac785a036..4198102effc 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
@@ -49,6 +49,7 @@
#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"
#include "absl/strings/string_view.h"
@@ -916,14 +917,14 @@ struct CustomHashType {
template <InvokeTag allowed, InvokeTag... tags>
struct EnableIfContained
- : std::enable_if<std::disjunction_v<
- std::integral_constant<bool, allowed == tags>...>> {};
+ : std::enable_if<
+ std::disjunction_v<std::bool_constant<allowed == tags>...>> {};
template <
typename H, InvokeTag... Tags,
typename = typename EnableIfContained<InvokeTag::kHashValue, Tags...>::type>
H AbslHashValue(H state, CustomHashType<Tags...> t) {
- static_assert(MinTag<Tags...>::value == InvokeTag::kHashValue, "");
+ static_assert(MinTag<Tags...>::value == InvokeTag::kHashValue);
return H::combine(std::move(state),
t.value + static_cast<int>(InvokeTag::kHashValue));
}
@@ -949,7 +950,7 @@ struct hash<CustomHashType<Tags...>> {
template <InvokeTag... TagsIn, typename = typename EnableIfContained<
InvokeTag::kLegacyHash, TagsIn...>::type>
size_t operator()(CustomHashType<TagsIn...> t) const {
- static_assert(MinTag<Tags...>::value == InvokeTag::kLegacyHash, "");
+ static_assert(MinTag<Tags...>::value == InvokeTag::kLegacyHash);
return t.value + static_cast<int>(InvokeTag::kLegacyHash);
}
};
@@ -962,7 +963,7 @@ struct hash<CustomHashType<Tags...>> {
template <InvokeTag... TagsIn, typename = typename EnableIfContained<
InvokeTag::kStdHash, TagsIn...>::type>
size_t operator()(CustomHashType<TagsIn...> t) const {
- static_assert(MinTag<Tags...>::value == InvokeTag::kStdHash, "");
+ static_assert(MinTag<Tags...>::value == InvokeTag::kStdHash);
return t.value + static_cast<int>(InvokeTag::kStdHash);
}
};
@@ -1041,10 +1042,10 @@ struct StructWithPadding {
static_assert(sizeof(StructWithPadding) > sizeof(char) + sizeof(int),
"StructWithPadding doesn't have padding");
-static_assert(std::is_standard_layout_v<StructWithPadding>, "");
+static_assert(std::is_standard_layout_v<StructWithPadding>);
// This check has to be disabled because libstdc++ doesn't support it.
-// static_assert(std::is_trivially_constructible_v<StructWithPadding>, "");
+// static_assert(std::is_trivially_constructible_v<StructWithPadding>);
template <typename T>
struct ArraySlice {
@@ -1263,6 +1264,9 @@ TEST(HashOf, DoubleSignCollision) {
TEST(PrecombineLengthMix, ShortStringCollision) {
#if defined(__wasm__)
GTEST_SKIP() << "Fails flakily on wasm due to no ASLR and 32-bit size_t.";
+#endif
+#if defined(__ANDROID__) && defined(__arm__)
+ GTEST_SKIP() << "Fails on 32-bit Android due to layout changes.";
#endif
std::string s1 = "00";
std::string s2 = "000";
@@ -1305,7 +1309,11 @@ TEST(SwisstableCollisions, LowEntropyStrings) {
// 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) {
- absl::flat_hash_set<std::string> set;
+ // Pre-reserve table capacity so the test measures hash distribution
+ // quality under standard load factors, avoiding probe length spikes
+ // caused by near-maximum load factors right before incremental resizing.
+ absl::flat_hash_set<std::string> set(
+ size_t{kMaxChar - kMinChar} * size_t{kMaxChar - kMinChar});
std::string s(size, '\0');
for (char c1 = kMinChar; c1 < kMaxChar; ++c1) {
for (char c2 = kMinChar; c2 < kMaxChar; ++c2) {
@@ -1326,8 +1334,12 @@ TEST(SwisstableCollisions, LowEntropyStrings) {
TEST(SwisstableCollisions, LowEntropyInts) {
constexpr int kSizeTBits = sizeof(size_t) * 8;
for (int bit = 0; bit < kSizeTBits; ++bit) {
- absl::flat_hash_set<size_t> set;
- for (size_t i = 0; i < 128 * 1024; ++i) {
+ // Pre-reserve table capacity so the test measures hash distribution
+ // quality under standard load factors, avoiding probe length spikes
+ // caused by near-maximum load factors right before incremental resizing.
+ const size_t kNumElements = 128 * 1024;
+ absl::flat_hash_set<size_t> set(kNumElements);
+ for (size_t i = 0; i < kNumElements; ++i) {
size_t v = absl::rotl(i, bit);
set.insert(v);
ASSERT_LT(HashtableDebugAccess<decltype(set)>::GetNumProbes(set, v), 48)
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/internal/city.cc b/deps/v8/third_party/abseil-cpp/absl/hash/internal/city.cc
index 416beed453d..bc2999ae295 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/internal/city.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/internal/city.cc
@@ -22,6 +22,9 @@
#include "absl/hash/internal/city.h"
#include <algorithm>
+#include <cstddef>
+#include <cstdint>
+#include <utility>
#include "absl/base/config.h"
#include "absl/base/internal/endian.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 1bbf02e0d1e..822b39974d6 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
@@ -15,8 +15,11 @@
#include "absl/hash/internal/city.h"
#include <string.h>
+
+#include <cstdint>
#include <cstdio>
#include <iostream>
+
#include "gtest/gtest.h"
namespace absl {
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 f68872fc488..a7dc74c60ff 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
@@ -19,11 +19,6 @@
#ifndef ABSL_HASH_INTERNAL_HASH_H_
#define ABSL_HASH_INTERNAL_HASH_H_
-#ifdef __APPLE__
-#include <Availability.h>
-#include <TargetConditionals.h>
-#endif
-
// We include config.h here to make sure that ABSL_INTERNAL_CPLUSPLUS_LANG is
// defined.
#include "absl/base/config.h"
@@ -31,11 +26,9 @@
// GCC15 warns that <ciso646> is deprecated in C++17 and suggests using
// <version> instead, even though <version> is not available in C++17 mode prior
// to GCC9.
-#if defined(__has_include)
#if __has_include(<version>)
#define ABSL_INTERNAL_VERSION_HEADER_AVAILABLE 1
#endif
-#endif
// For feature testing and determining which headers can be included.
#if ABSL_INTERNAL_CPLUSPLUS_LANG >= 202002L || \
@@ -92,6 +85,11 @@
#include "absl/types/variant.h"
#include "absl/utility/utility.h"
+#ifdef __APPLE__
+#include <Availability.h>
+#include <TargetConditionals.h>
+#endif
+
#if defined(__cpp_lib_filesystem) && __cpp_lib_filesystem >= 201703L && \
!defined(__XTENSA__)
#include <filesystem> // NOLINT
@@ -397,7 +395,7 @@ struct is_uniquely_represented<unsigned __int128> : std::true_type {};
#endif // ABSL_HAVE_INTRINSIC_INT128
template <typename T>
-struct FitsIn64Bits : std::integral_constant<bool, sizeof(T) <= 8> {};
+struct FitsIn64Bits : std::bool_constant<sizeof(T) <= 8> {};
struct CombineRaw {
template <typename H>
@@ -575,9 +573,7 @@ H AbslHashValue(H hash_state, T C::*ptr) {
#else
// On other platforms, we assume that pointers-to-members do not have
// padding.
-#ifdef __cpp_lib_has_unique_object_representations
static_assert(std::has_unique_object_representations_v<T C::*>);
-#endif // __cpp_lib_has_unique_object_representations
return n;
#endif
};
@@ -809,6 +805,9 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
for (size_t j = 0; j < 64; ++j) {
word |= static_cast<uint64_t>(vector[i + j]) << j;
}
+ if constexpr (absl::endian::native == absl::endian::big) {
+ word = absl::byteswap(word);
+ }
hash_state = combiner.add_buffer(
std::move(hash_state), reinterpret_cast<const unsigned char*>(&word),
sizeof(word));
@@ -821,6 +820,9 @@ AbslHashValue(H hash_state, const std::vector<T, Allocator>& vector) {
for (size_t j = 0; j < rem; ++j) {
word |= static_cast<uint64_t>(vector[i + j]) << j;
}
+ if constexpr (absl::endian::native == absl::endian::big) {
+ word = absl::byteswap(word);
+ }
hash_state = combiner.add_buffer(
std::move(hash_state), reinterpret_cast<const unsigned char*>(&word),
(rem + 7) / 8);
@@ -988,6 +990,9 @@ H AbslHashValue(H hash_state, const std::bitset<N>& set) {
for (size_t j = 0; j < 64; ++j) {
word |= static_cast<uint64_t>(set[i + j]) << j;
}
+ if constexpr (absl::endian::native == absl::endian::big) {
+ word = absl::byteswap(word);
+ }
hash_state = combiner.add_buffer(
std::move(hash_state), reinterpret_cast<const unsigned char*>(&word),
sizeof(word));
@@ -1000,6 +1005,9 @@ H AbslHashValue(H hash_state, const std::bitset<N>& set) {
for (size_t j = 0; j < rem; ++j) {
word |= static_cast<uint64_t>(set[i + j]) << j;
}
+ if constexpr (absl::endian::native == absl::endian::big) {
+ word = absl::byteswap(word);
+ }
hash_state = combiner.add_buffer(
std::move(hash_state), reinterpret_cast<const unsigned char*>(&word),
(rem + 7) / 8);
@@ -1416,8 +1424,8 @@ struct HashSelect {
};
template <typename T>
-struct is_hashable
- : std::integral_constant<bool, HashSelect::template Apply<T>::value> {};
+struct is_hashable : std::bool_constant<HashSelect::template Apply<T>::value> {
+};
class ABSL_DLL MixingHashState : public HashStateBase<MixingHashState> {
template <typename T>
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash_test.h b/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash_test.h
index 9963dc0b8d9..962a9967e6d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash_test.h
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/internal/hash_test.h
@@ -18,6 +18,7 @@
#ifndef ABSL_HASH_INTERNAL_HASH_TEST_H_
#define ABSL_HASH_INTERNAL_HASH_TEST_H_
+#include <initializer_list>
#include <type_traits>
#include <utility>
diff --git a/deps/v8/third_party/abseil-cpp/absl/hash/internal/print_hash_of.cc b/deps/v8/third_party/abseil-cpp/absl/hash/internal/print_hash_of.cc
index c392125a69f..883cf9935ee 100644
--- a/deps/v8/third_party/abseil-cpp/absl/hash/internal/print_hash_of.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/hash/internal/print_hash_of.cc
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
+
+#include <cstdio>
#include <cstdlib>
#include "absl/hash/hash.h"
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 51caaf18dc1..543e7197284 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
@@ -23,6 +23,7 @@
#include <ostream>
#include <string>
#include <type_traits>
+#include <utility>
#include <vector>
#include "absl/hash/hash.h"
@@ -48,7 +49,7 @@ template <typename T>
class SpyHashStateImpl : public HashStateBase<SpyHashStateImpl<T>> {
public:
SpyHashStateImpl() : error_(std::make_shared<std::optional<std::string>>()) {
- static_assert(std::is_void_v<T>, "");
+ static_assert(std::is_void_v<T>);
}
// Move-only
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 f44b1c0c32b..188186622ad 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/log/BUILD.bazel
@@ -466,11 +466,11 @@ cc_library(
textual_hdrs = ["log_basic_test_impl.inc"],
visibility = ["//visibility:private"],
deps = [
+ ":globals",
+ ":log_entry",
+ ":scoped_mock_log",
"//absl/base",
"//absl/base:log_severity",
- "//absl/log:globals",
- "//absl/log:log_entry",
- "//absl/log:scoped_mock_log",
"//absl/log/internal:globals",
"//absl/log/internal:test_actions",
"//absl/log/internal:test_helpers",
@@ -510,8 +510,10 @@ cc_test(
deps = [
":check",
":log",
+ ":log_entry",
":scoped_mock_log",
"//absl/base:config",
+ "//absl/base:core_headers",
"//absl/log/internal:test_matchers",
"//absl/strings",
"//absl/strings:str_format",
@@ -550,10 +552,12 @@ cc_test(
],
deps = [
":log",
+ ":log_entry",
":log_sink",
":log_sink_registry",
":scoped_mock_log",
"//absl/base:core_headers",
+ "//absl/base:log_severity",
"//absl/log/internal:test_actions",
"//absl/log/internal:test_helpers",
"//absl/log/internal:test_matchers",
@@ -594,8 +598,10 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":log",
+ ":log_entry",
":log_sink",
":scoped_mock_log",
+ "//absl/base:log_severity",
"//absl/log/internal:test_actions",
"//absl/log/internal:test_helpers",
"//absl/log/internal:test_matchers",
@@ -622,6 +628,7 @@ cc_test(
deps = [
":globals",
":log",
+ ":log_entry",
":scoped_mock_log",
"//absl/base:core_headers",
"//absl/base:log_severity",
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 715f34831e5..d9d6f7a997b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/log/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -71,6 +73,7 @@ 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",
]
}
@@ -139,6 +142,7 @@ 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",
@@ -158,6 +162,7 @@ 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",
@@ -165,12 +170,12 @@ absl_source_set("scoped_mock_log") {
}
absl_source_set("structured") {
- testonly = true
public = [ "structured.h" ]
deps = [
"//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",
]
}
@@ -182,6 +187,7 @@ absl_source_set("absl_vlog_is_on") {
"//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",
]
}
@@ -207,13 +213,13 @@ absl_test("vlog_is_on_test") {
absl_test("absl_check_test") {
sources = [ "absl_check_test.cc" ]
- if (is_ios) {
- sources = []
- }
deps = [
":absl_check",
":check_test_impl",
]
+ if (is_ios) {
+ sources = []
+ }
}
absl_test("absl_log_basic_test") {
@@ -224,16 +230,8 @@ absl_test("absl_log_basic_test") {
]
}
-absl_test("check_test") {
- sources = [ "check_test.cc" ]
- if (is_ios) {
- sources = []
- }
- deps = [
- ":check",
- ":check_test_impl",
- ]
-}
+# Overlaps with absl_check_test
+# absl_test("check_test")
absl_source_set("check_test_impl") {
testonly = true
@@ -292,17 +290,12 @@ absl_test("globals_test") {
]
}
-absl_test("log_basic_test") {
- sources = [ "log_basic_test.cc" ]
- deps = [
- ":log",
- ":log_basic_test_impl",
- ]
-}
+# Overlaps with absl_log_basic_test
+# absl_test("log_basic_test")
absl_source_set("log_basic_test_impl") {
- public = [ "log_basic_test_impl.inc" ]
testonly = true
+ public = [ "log_basic_test_impl.inc" ]
visibility = [ ":*" ]
deps = [
":globals",
@@ -341,8 +334,10 @@ absl_test("log_format_test") {
deps = [
":check",
":log",
+ ":log_entry",
":scoped_mock_log",
"//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/log/internal:test_matchers",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
@@ -363,20 +358,23 @@ absl_test("log_macro_hygiene_test") {
absl_test("log_sink_test") {
sources = [ "log_sink_test.cc" ]
- if (is_ios) {
- sources = []
- }
deps = [
":log",
+ ":log_entry",
":log_sink",
":log_sink_registry",
":scoped_mock_log",
"//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/base:log_severity",
"//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) {
+ sources = []
+ }
}
absl_test("log_streamer_test") {
@@ -391,6 +389,7 @@ 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",
]
@@ -400,8 +399,10 @@ absl_test("log_modifier_methods_test") {
sources = [ "log_modifier_methods_test.cc" ]
deps = [
":log",
+ ":log_entry",
":log_sink",
":scoped_mock_log",
+ "//third_party/abseil-cpp/absl/base:log_severity",
"//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",
@@ -414,12 +415,10 @@ absl_test("log_modifier_methods_test") {
absl_test("scoped_mock_log_test") {
sources = [ "scoped_mock_log_test.cc" ]
- if (is_ios) {
- sources = []
- }
deps = [
":globals",
":log",
+ ":log_entry",
":scoped_mock_log",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:log_severity",
@@ -430,6 +429,9 @@ absl_test("scoped_mock_log_test") {
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/synchronization",
]
+ if (is_ios) {
+ sources = []
+ }
}
absl_test("stripping_test") {
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 3c1f8efed59..9b9645ce387 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
@@ -1,11 +1,17 @@
# Copyright 2022 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("check_impl") {
public = [ "check_impl.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":check_op",
":conditions",
@@ -17,6 +23,10 @@ absl_source_set("check_impl") {
absl_source_set("check_op") {
sources = [ "check_op.cc" ]
public = [ "check_op.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":nullguard",
":nullstream",
@@ -28,12 +38,17 @@ absl_source_set("check_op") {
"//third_party/abseil-cpp/absl/debugging:leak_check",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:has_ostream_operator",
+ "//third_party/abseil-cpp/absl/strings:string_view",
]
}
absl_source_set("conditions") {
sources = [ "conditions.cc" ]
public = [ "conditions.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":voidify",
"//third_party/abseil-cpp/absl/base",
@@ -44,21 +59,30 @@ absl_source_set("conditions") {
absl_source_set("config") {
public = [ "config.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("flags") {
public = [ "flags.h" ]
- deps = [ "//third_party/abseil-cpp/absl/flags:flag" ]
visibility = [
- "//third_party/abseil-cpp/absl/log/*",
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
"//third_party/abseil-cpp/absl/status:*",
]
+ deps = [ "//third_party/abseil-cpp/absl/flags:flag" ]
}
absl_source_set("format") {
sources = [ "log_format.cc" ]
public = [ "log_format.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":append_truncated",
":config",
@@ -77,6 +101,10 @@ absl_source_set("format") {
absl_source_set("globals") {
sources = [ "globals.cc" ]
public = [ "globals.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -90,6 +118,10 @@ absl_source_set("globals") {
absl_source_set("log_impl") {
public = [ "log_impl.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":conditions",
":log_message",
@@ -101,6 +133,10 @@ absl_source_set("log_impl") {
absl_source_set("log_message") {
sources = [ "log_message.cc" ]
public = [ "log_message.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":append_truncated",
":format",
@@ -123,7 +159,6 @@ absl_source_set("log_message") {
"//third_party/abseil-cpp/absl/log:log_entry",
"//third_party/abseil-cpp/absl/log:log_sink",
"//third_party/abseil-cpp/absl/log:log_sink_registry",
- "//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:internal",
"//third_party/abseil-cpp/absl/strings:string_view",
@@ -135,8 +170,13 @@ absl_source_set("log_message") {
absl_source_set("append_truncated") {
public = [ "append_truncated.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
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",
@@ -146,6 +186,10 @@ absl_source_set("append_truncated") {
absl_source_set("log_sink_set") {
sources = [ "log_sink_set.cc" ]
public = [ "log_sink_set.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":config",
":globals",
@@ -159,6 +203,7 @@ 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",
@@ -171,6 +216,10 @@ absl_source_set("log_sink_set") {
absl_source_set("nullguard") {
sources = [ "nullguard.cc" ]
public = [ "nullguard.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -179,16 +228,25 @@ absl_source_set("nullguard") {
absl_source_set("nullstream") {
public = [ "nullstream.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//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",
]
}
absl_source_set("strip") {
public = [ "strip.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
":log_message",
":nullstream",
@@ -199,6 +257,11 @@ absl_source_set("strip") {
absl_source_set("structured") {
public = [ "structured.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ "//third_party/abseil-cpp/absl/log/*",
+ ]
deps = [
":log_message",
":structured_proto",
@@ -213,7 +276,10 @@ absl_source_set("structured") {
absl_source_set("structured_proto") {
sources = [ "structured_proto.cc" ]
public = [ "structured_proto.h" ]
- visibility = [ "//third_party/abseil-cpp/absl/log/*" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log/*",
+ ]
deps = [
":proto",
"//third_party/abseil-cpp/absl/base:config",
@@ -230,7 +296,6 @@ absl_test("structured_proto_test") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:span",
- "//third_party/abseil-cpp/absl/utility",
]
}
@@ -238,6 +303,10 @@ absl_source_set("test_actions") {
testonly = true
sources = [ "test_actions.cc" ]
public = [ "test_actions.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -253,12 +322,18 @@ absl_source_set("test_helpers") {
testonly = true
sources = [ "test_helpers.cc" ]
public = [ "test_helpers.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ "//third_party/abseil-cpp/absl/log/*",
+ ]
deps = [
":globals",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:log_severity",
"//third_party/abseil-cpp/absl/log:globals",
"//third_party/abseil-cpp/absl/log:initialize",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -267,12 +342,18 @@ absl_source_set("test_matchers") {
testonly = true
sources = [ "test_matchers.cc" ]
public = [ "test_matchers.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ "//third_party/abseil-cpp/absl/log/*",
+ ]
deps = [
":test_helpers",
"//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/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",
@@ -282,6 +363,10 @@ absl_source_set("test_matchers") {
absl_source_set("voidify") {
public = [ "voidify.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -291,10 +376,15 @@ absl_source_set("voidify") {
absl_source_set("proto") {
sources = [ "proto.cc" ]
public = [ "proto.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//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",
]
@@ -303,9 +393,14 @@ absl_source_set("proto") {
absl_source_set("fnmatch") {
sources = [ "fnmatch.cc" ]
public = [ "fnmatch.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/log:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
]
}
@@ -313,6 +408,7 @@ absl_source_set("vlog_config") {
sources = [ "vlog_config.cc" ]
public = [ "vlog_config.h" ]
visibility = [
+ ":*",
"//third_party/abseil-cpp/absl/log/*",
"//third_party/abseil-cpp/absl/status:*",
]
@@ -325,15 +421,13 @@ absl_source_set("vlog_config") {
"//third_party/abseil-cpp/absl/base:no_destructor",
"//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/synchronization",
]
}
absl_test("stderr_log_sink_test") {
sources = [ "stderr_log_sink_test.cc" ]
- if (is_apple || is_android) {
- sources = []
- }
deps = [
":test_helpers",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -341,6 +435,9 @@ absl_test("stderr_log_sink_test") {
"//third_party/abseil-cpp/absl/log",
"//third_party/abseil-cpp/absl/log:globals",
]
+ if (is_apple || is_android) {
+ sources = []
+ }
}
absl_test("fnmatch_test") {
@@ -349,7 +446,7 @@ absl_test("fnmatch_test") {
}
absl_source_set("container") {
- sources = [ "container.h" ]
+ public = [ "container.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
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 3325a318b17..8be029d58db 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
@@ -23,11 +23,6 @@
#ifndef ABSL_LOG_INTERNAL_CONDITIONS_H_
#define ABSL_LOG_INTERNAL_CONDITIONS_H_
-#if defined(_WIN32) || defined(__hexagon__)
-#include <cstdlib>
-#else
-#include <unistd.h>
-#endif
#include <stdlib.h>
#include <atomic>
@@ -37,6 +32,12 @@
#include "absl/base/config.h"
#include "absl/log/internal/voidify.h"
+#if defined(_WIN32) || defined(__hexagon__)
+#include <cstdlib>
+#else
+#include <unistd.h>
+#endif
+
// `ABSL_LOG_INTERNAL_CONDITION` prefixes another macro that expands to a
// temporary `LogMessage` instantiation followed by zero or more streamed
// expressions. This definition is tricky to read correctly. It evaluates to
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/globals.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/globals.cc
index 51b72453ec5..658ebfd2bff 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/globals.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/globals.cc
@@ -17,10 +17,6 @@
#include <atomic>
#include <cstdio>
-#if defined(__EMSCRIPTEN__)
-#include <emscripten/console.h>
-#endif
-
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
@@ -29,6 +25,10 @@
#include "absl/strings/strip.h" // IWYU pragma: keep
#include "absl/time/time.h"
+#if defined(__EMSCRIPTEN__)
+#include <emscripten/console.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/log_format.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/log_format.cc
index d54cf19bdf4..ac33021edf9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/log_format.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/log_format.cc
@@ -17,12 +17,6 @@
#include <string.h>
-#ifdef _MSC_VER
-#include <winsock2.h> // For timeval
-#else
-#include <sys/time.h>
-#endif
-
#include <cstddef>
#include <cstdint>
#include <limits>
@@ -42,34 +36,36 @@
#include "absl/time/time.h"
#include "absl/types/span.h"
+#ifdef _MSC_VER
+#include <winsock2.h> // For timeval
+#else
+#include <sys/time.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
namespace {
-// This templated function avoids compiler warnings about tautological
-// comparisons when log_internal::Tid is unsigned. It can be replaced with a
-// constexpr if once the minimum C++ version Abseil supports is C++17.
+// The `if constexpr` avoids compiler warnings about tautological comparisons
+// when log_internal::Tid is unsigned.
template <typename T>
-inline std::enable_if_t<!std::is_signed_v<T>> PutLeadingWhitespace(T tid,
- char*& p) {
- if (tid < 10) *p++ = ' ';
- if (tid < 100) *p++ = ' ';
- if (tid < 1000) *p++ = ' ';
- if (tid < 10000) *p++ = ' ';
- if (tid < 100000) *p++ = ' ';
- if (tid < 1000000) *p++ = ' ';
-}
-
-template <typename T>
-inline std::enable_if_t<std::is_signed_v<T>> PutLeadingWhitespace(T tid,
- char*& p) {
- if (tid >= 0 && tid < 10) *p++ = ' ';
- if (tid > -10 && tid < 100) *p++ = ' ';
- if (tid > -100 && tid < 1000) *p++ = ' ';
- if (tid > -1000 && tid < 10000) *p++ = ' ';
- if (tid > -10000 && tid < 100000) *p++ = ' ';
- if (tid > -100000 && tid < 1000000) *p++ = ' ';
+inline void PutLeadingWhitespace(T tid, char*& p) {
+ if constexpr (std::is_signed_v<T>) {
+ if (tid >= 0 && tid < 10) *p++ = ' ';
+ if (tid > -10 && tid < 100) *p++ = ' ';
+ if (tid > -100 && tid < 1000) *p++ = ' ';
+ if (tid > -1000 && tid < 10000) *p++ = ' ';
+ if (tid > -10000 && tid < 100000) *p++ = ' ';
+ if (tid > -100000 && tid < 1000000) *p++ = ' ';
+ } else {
+ if (tid < 10) *p++ = ' ';
+ if (tid < 100) *p++ = ' ';
+ if (tid < 1000) *p++ = ' ';
+ if (tid < 10000) *p++ = ' ';
+ if (tid < 100000) *p++ = ' ';
+ if (tid < 1000000) *p++ = ' ';
+ }
}
// The fields before the filename are all fixed-width except for the thread ID,
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 673bd8d431a..8ac81dfed0d 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
@@ -20,10 +20,6 @@
#include <stdlib.h>
#include <string.h>
-#ifndef _WIN32
-#include <unistd.h>
-#endif
-
#include <algorithm>
#include <array>
#include <atomic>
@@ -59,6 +55,10 @@
#include "absl/time/time.h"
#include "absl/types/span.h"
+#ifndef _WIN32
+#include <unistd.h>
+#endif
+
extern "C" ABSL_ATTRIBUTE_WEAK void ABSL_INTERNAL_C_SYMBOL(
AbslInternalOnFatalLogMessage)(const absl::LogEntry&) {
// Default - Do nothing
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc
index c4c7e5ff8d0..8f0eb2279ad 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/log_sink_set.cc
@@ -15,18 +15,6 @@
#include "absl/log/internal/log_sink_set.h"
-#ifndef ABSL_HAVE_THREAD_LOCAL
-#include <pthread.h>
-#endif
-
-#ifdef __ANDROID__
-#include <android/log.h>
-#endif
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
#include <algorithm>
#include <vector>
@@ -47,6 +35,18 @@
#include "absl/synchronization/mutex.h"
#include "absl/types/span.h"
+#ifndef ABSL_HAVE_THREAD_LOCAL
+#include <pthread.h>
+#endif
+
+#ifdef __ANDROID__
+#include <android/log.h>
+#endif
+
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/nullstream.h b/deps/v8/third_party/abseil-cpp/absl/log/internal/nullstream.h
index 4eae52e51ee..f582a05185a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/nullstream.h
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/nullstream.h
@@ -23,11 +23,6 @@
#ifndef ABSL_LOG_INTERNAL_NULLSTREAM_H_
#define ABSL_LOG_INTERNAL_NULLSTREAM_H_
-#ifdef _WIN32
-#include <cstdlib>
-#else
-#include <unistd.h>
-#endif
#include <ios>
#include <ostream>
@@ -36,6 +31,12 @@
#include "absl/base/log_severity.h"
#include "absl/strings/string_view.h"
+#ifdef _WIN32
+#include <cstdlib>
+#else
+#include <unistd.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/test_helpers.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/test_helpers.cc
index 9abcd87e591..4a79664b277 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/test_helpers.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/test_helpers.cc
@@ -16,6 +16,13 @@
#include <csignal>
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+#include "absl/base/log_severity.h"
+#include "absl/log/globals.h"
+#include "absl/log/initialize.h"
+#include "absl/log/internal/globals.h"
+
#ifdef __Fuchsia__
#include <zircon/syscalls.h>
#endif
@@ -24,13 +31,6 @@
#include <signal.h>
#endif
-#include "gtest/gtest.h"
-#include "absl/base/config.h"
-#include "absl/base/log_severity.h"
-#include "absl/log/globals.h"
-#include "absl/log/initialize.h"
-#include "absl/log/internal/globals.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace log_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc
index 2634ca3929c..1916e2c11d8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/internal/vlog_config_benchmark.cc
@@ -115,7 +115,7 @@ class SyntheticBinary {
sites[num_tus - 1]->next_.store(nullptr, std::memory_order_seq_cst);
}
~SyntheticBinary() {
- static_assert(std::is_trivially_destructible_v<VLogSite>, "");
+ static_assert(std::is_trivially_destructible_v<VLogSite>);
absl::log_internal::SetVModuleListHeadForTestOnly(nullptr);
}
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 aa520e463ff..eb7585c158a 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
@@ -26,16 +26,14 @@
#include <string_view>
#include <type_traits>
-#ifdef __ANDROID__
-#include <android/api-level.h>
-#endif
-
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/log/check.h"
#include "absl/log/internal/test_matchers.h"
#include "absl/log/log.h"
+#include "absl/log/log_entry.h"
#include "absl/log/scoped_mock_log.h"
#include "absl/strings/match.h"
#include "absl/strings/str_cat.h"
@@ -43,6 +41,10 @@
#include "absl/strings/string_view.h"
#include "absl/types/source_location.h"
+#ifdef __ANDROID__
+#include <android/api-level.h>
+#endif
+
namespace {
using ::absl::log_internal::AsString;
using ::absl::log_internal::MatchesOstream;
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/log_modifier_methods_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/log_modifier_methods_test.cc
index 1c7c35dd0b4..42a5147fc9c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/log_modifier_methods_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/log_modifier_methods_test.cc
@@ -19,10 +19,12 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/log_severity.h"
#include "absl/log/internal/test_actions.h"
#include "absl/log/internal/test_helpers.h"
#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"
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 fa7430606e6..cbb5a531b60 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
@@ -18,10 +18,12 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
+#include "absl/base/log_severity.h"
#include "absl/log/internal/test_actions.h"
#include "absl/log/internal/test_helpers.h"
#include "absl/log/internal/test_matchers.h"
#include "absl/log/log.h"
+#include "absl/log/log_entry.h"
#include "absl/log/log_sink_registry.h"
#include "absl/log/scoped_mock_log.h"
#include "absl/strings/string_view.h"
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 fd7c10bcde8..6f1d8fb7fc4 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
@@ -27,6 +27,7 @@
#include "absl/log/internal/test_helpers.h"
#include "absl/log/internal/test_matchers.h"
#include "absl/log/log.h"
+#include "absl/log/log_entry.h"
#include "absl/memory/memory.h"
#include "absl/strings/match.h"
#include "absl/strings/string_view.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/log/stripping_test.cc b/deps/v8/third_party/abseil-cpp/absl/log/stripping_test.cc
index 20231b9fa6c..b0f718cdd0e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/log/stripping_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/log/stripping_test.cc
@@ -33,14 +33,9 @@
#include <stdio.h>
-#if defined(__APPLE__)
-#include <mach-o/dyld.h>
-#elif defined(_WIN32)
-#include <Windows.h>
-#include <tchar.h>
-#endif
-
#include <algorithm>
+#include <cerrno>
+#include <cstring>
#include <functional>
#include <memory>
#include <ostream>
@@ -56,9 +51,17 @@
#include "absl/log/log.h"
#include "absl/status/status.h"
#include "absl/strings/escaping.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
+#if defined(__APPLE__)
+#include <mach-o/dyld.h>
+#elif defined(_WIN32)
+#include <Windows.h>
+#include <tchar.h>
+#endif
+
// Set a flag that controls whether we actually execute fatal statements, but
// prevent the compiler from optimizing it out.
static volatile bool kReallyDie = false;
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 1c1f6f89092..7d9b7c67171 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
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 d364df8f989..cbc98125099 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/memory.h
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/memory.h
@@ -29,6 +29,7 @@
#include <new>
#include <type_traits>
#include <utility>
+#include <version>
#include "absl/base/macros.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/memory/memory_test.cc b/deps/v8/third_party/abseil-cpp/absl/memory/memory_test.cc
index 8ed14c6f06c..3ef6830046d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/memory/memory_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/memory/memory_test.cc
@@ -19,6 +19,7 @@
#include <sys/types.h>
#include <cstddef>
+#include <cstring>
#include <memory>
#include <string>
#include <type_traits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/meta/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/meta/BUILD.gn
index 5c3baad9b88..783a5795d68 100644
--- a/deps/v8/third_party/abseil-cpp/absl/meta/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/meta/BUILD.gn
@@ -1,12 +1,14 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("constexpr_testing") {
testonly = true
- sources = [ "internal/constexpr_testing.h" ]
+ public = [ "internal/constexpr_testing.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -17,7 +19,7 @@ absl_test("constexpr_testing_test") {
}
absl_source_set("requires") {
- sources = [ "internal/requires.h" ]
+ public = [ "internal/requires.h" ]
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing.h b/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing.h
index eddf64b9bbd..bb10b379688 100644
--- a/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing.h
+++ b/deps/v8/third_party/abseil-cpp/absl/meta/internal/constexpr_testing.h
@@ -49,8 +49,7 @@ constexpr F default_instance = default_instance<F>;
#endif
template <typename F>
-constexpr std::integral_constant<bool, (default_instance<F>(), true)> Tester(
- int) {
+constexpr std::bool_constant<(default_instance<F>(), true)> Tester(int) {
return {};
}
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 f7c22dcfd9d..3739919857c 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
@@ -17,7 +17,7 @@
// type_traits.h
// -----------------------------------------------------------------------------
//
-// This file contains C++11-compatible versions of standard <type_traits> API
+// This file contains C++17-compatible versions of standard <type_traits> API
// functions for determining the characteristics of types. Such traits can
// support type inference, classification, and transformation, as well as
// make it easier to write templates based on generic type behavior.
@@ -35,12 +35,15 @@
#ifndef ABSL_META_TYPE_TRAITS_H_
#define ABSL_META_TYPE_TRAITS_H_
+#include <array>
#include <cstddef>
#include <functional>
#include <string>
#include <string_view>
+#include <tuple>
#include <type_traits>
#include <utility>
+#include <variant>
#include <vector>
#include "absl/base/attributes.h"
@@ -52,7 +55,7 @@
#endif
// Defines the default alignment. `__STDCPP_DEFAULT_NEW_ALIGNMENT__` is a C++17
-// feature.
+// feature, but GCC leaves it undefined under -fno-aligned-new.
#if defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
#define ABSL_INTERNAL_DEFAULT_NEW_ALIGNMENT __STDCPP_DEFAULT_NEW_ALIGNMENT__
#else // defined(__STDCPP_DEFAULT_NEW_ALIGNMENT__)
@@ -236,7 +239,7 @@ using remove_cvref_t = std::remove_cvref_t<T>;
#else
// remove_cvref()
//
-// C++11 compatible implementation of std::remove_cvref which was added in
+// C++17 compatible implementation of std::remove_cvref which was added in
// C++20.
template <typename T>
struct remove_cvref {
@@ -271,22 +274,16 @@ using type_identity_t = typename type_identity<T>::type;
namespace type_traits_internal {
-#if (defined(__cpp_lib_is_invocable) && __cpp_lib_is_invocable >= 201703L) || \
- (defined(_MSVC_LANG) && _MSVC_LANG >= 201703L)
-// std::result_of is deprecated (C++17) or removed (C++20)
template <typename>
struct result_of;
template <typename F, typename... Args>
struct result_of<F(Args...)> : std::invoke_result<F, Args...> {};
-#else
-template <typename F>
-using result_of = std::result_of<F>;
-#endif
} // namespace type_traits_internal
template <typename F>
-using result_of_t = typename type_traits_internal::result_of<F>::type;
+using result_of_t [[deprecated("Use std::invoke_result_t instead.")]] =
+ typename type_traits_internal::result_of<F>::type;
namespace type_traits_internal {
@@ -342,69 +339,12 @@ inline void AssertHashEnabled() {
Helper::Sink(Helper::DoIt<Ts>()...);
}
-} // namespace type_traits_internal
-
-// An internal namespace that is required to implement the C++17 swap traits.
-// It is not further nested in type_traits_internal to avoid long symbol names.
-namespace swap_internal {
-
-// Necessary for the traits.
-using std::swap;
-
-// This declaration prevents global `swap` and `absl::swap` overloads from being
-// considered unless ADL picks them up.
-void swap();
-
template <class T>
-using IsSwappableImpl = decltype(swap(std::declval<T&>(), std::declval<T&>()));
-
-// NOTE: This dance with the default template parameter is for MSVC.
-template <class T,
- class IsNoexcept = std::integral_constant<
- bool, noexcept(swap(std::declval<T&>(), std::declval<T&>()))>>
-using IsNothrowSwappableImpl = std::enable_if_t<IsNoexcept::value>;
+using IsSwappable ABSL_DEPRECATE_AND_INLINE() = std::is_swappable<T>;
-// IsSwappable
-//
-// Determines whether the standard swap idiom is a valid expression for
-// arguments of type `T`.
template <class T>
-struct IsSwappable
- : absl::type_traits_internal::is_detected<IsSwappableImpl, T> {};
-
-// IsNothrowSwappable
-//
-// Determines whether the standard swap idiom is a valid expression for
-// arguments of type `T` and is noexcept.
-template <class T>
-struct IsNothrowSwappable
- : absl::type_traits_internal::is_detected<IsNothrowSwappableImpl, T> {};
-
-// Swap()
-//
-// Performs the swap idiom from a namespace where valid candidates may only be
-// found in `std` or via ADL.
-template <class T, std::enable_if_t<IsSwappable<T>::value, int> = 0>
-void Swap(T& lhs, T& rhs) noexcept(IsNothrowSwappable<T>::value) {
- swap(lhs, rhs);
-}
-
-// StdSwapIsUnconstrained
-//
-// Some standard library implementations are broken in that they do not
-// constrain `std::swap`. This will effectively tell us if we are dealing with
-// one of those implementations.
-using StdSwapIsUnconstrained = IsSwappable<void()>;
-
-} // namespace swap_internal
-
-namespace type_traits_internal {
-
-// Make the swap-related traits/function accessible from this namespace.
-using swap_internal::IsNothrowSwappable;
-using swap_internal::IsSwappable;
-using swap_internal::StdSwapIsUnconstrained;
-using swap_internal::Swap;
+using IsNothrowSwappable ABSL_DEPRECATE_AND_INLINE() =
+ std::is_nothrow_swappable<T>;
} // namespace type_traits_internal
@@ -471,8 +411,7 @@ using swap_internal::Swap;
// ABSL_HAVE_ATTRIBUTE_TRIVIAL_ABI will have no effect on this trait.
template <class T>
struct is_trivially_relocatable
- : std::integral_constant<bool, __builtin_is_cpp_trivially_relocatable(T)> {
-};
+ : std::bool_constant<__builtin_is_cpp_trivially_relocatable(T)> {};
#elif ABSL_HAVE_BUILTIN(__is_trivially_relocatable) && defined(__clang__) && \
!(defined(_WIN32) || defined(_WIN64)) && !defined(__APPLE__) && \
!defined(__NVCC__)
@@ -481,10 +420,9 @@ struct is_trivially_relocatable
// TODO(b/325479096): Remove this case.
template <class T>
struct is_trivially_relocatable
- : std::integral_constant<bool,
- std::is_trivially_copyable_v<T> ||
- (__is_trivially_relocatable(T) &&
- std::is_trivially_move_assignable_v<T>)> {};
+ : std::bool_constant<std::is_trivially_copyable_v<T> ||
+ (__is_trivially_relocatable(T) &&
+ std::is_trivially_move_assignable_v<T>)> {};
#else
// Otherwise we use a fallback that detects only those types we can feasibly
// detect. Any type that is trivially copyable is by definition trivially
@@ -564,16 +502,32 @@ struct IsOwnerImpl<
template <typename T>
struct IsOwner : IsOwnerImpl<T> {};
+template <typename T>
+struct IsOwner<T&> : std::false_type {};
+
+template <typename T>
+struct IsOwner<T&&> : std::false_type {};
+
+template <typename T>
+struct IsOwner<const T> : IsOwner<T> {};
+
+template <typename T>
+struct IsOwner<volatile T> : IsOwner<T> {};
+
+template <typename T>
+struct IsOwner<const volatile T> : IsOwner<T> {};
+
+template <typename T>
+struct IsOwner<std::reference_wrapper<T>> : std::false_type {};
+
+template <typename T, std::size_t N>
+struct IsOwner<std::array<T, N>>
+ : std::conditional_t<N != 0, IsOwner<T>, std::false_type> {};
+
// This allows incomplete types to be used for associative containers, and also
// expands the set of types we can handle to include std::pair.
template <typename T1, typename T2>
-struct IsOwner<std::pair<T1, T2>>
- : std::integral_constant<
- bool, std::conditional_t<std::is_reference_v<T1>, std::false_type,
- IsOwner<std::remove_cv_t<T1>>>::value &&
- std::conditional_t<std::is_reference_v<T2>, std::false_type,
- IsOwner<std::remove_cv_t<T2>>>::value> {
-};
+struct IsOwner<std::pair<T1, T2>> : IsOwner<std::tuple<T1, T2>> {};
template <typename T, typename Traits, typename Alloc>
struct IsOwner<std::basic_string<T, Traits, Alloc>> : std::true_type {};
@@ -581,6 +535,17 @@ struct IsOwner<std::basic_string<T, Traits, Alloc>> : std::true_type {};
template <typename T, typename Alloc>
struct IsOwner<std::vector<T, Alloc>> : std::true_type {};
+template <typename... T>
+struct IsOwner<std::tuple<T...>>
+ : std::bool_constant<(sizeof...(T) > 0) &&
+ // Uses a C++17 fold expression where '...' unpacks the
+ // parameter pack T, and 'true &&' provides the base
+ // case for the logical AND operation across all types.
+ (true && ... && IsOwner<T>::value)> {};
+
+template <typename... T>
+struct IsOwner<std::variant<T...>> : IsOwner<std::tuple<T...>> {};
+
// Detects if a class's definition has declared itself to be a view by declaring
// using absl_internal_is_view = std::true_type;
// as a member.
@@ -605,19 +570,50 @@ struct IsViewImpl<
// If it ever becomes possible to detect [[gsl::Pointer]], we should leverage
// it: https://wg21.link/p1179
template <typename T>
-struct IsView : std::integral_constant<bool, std::is_pointer_v<T> ||
- IsViewImpl<T>::value> {};
+struct IsView
+ : std::bool_constant<std::is_pointer_v<T> || IsViewImpl<T>::value> {};
+
+template <typename T>
+struct IsView<T&> : std::true_type {};
+
+template <typename T>
+struct IsView<T&&> : std::true_type {};
+
+template <typename T>
+struct IsView<const T> : IsView<T> {};
+
+template <typename T>
+struct IsView<volatile T> : IsView<T> {};
+
+template <typename T>
+struct IsView<const volatile T> : IsView<T> {};
+
+template <typename T>
+struct IsView<std::reference_wrapper<T>> : std::true_type {};
+
+template <typename T, std::size_t N>
+struct IsView<std::array<T, N>>
+ : std::conditional_t<N != 0, IsView<T>, std::false_type> {};
// This allows incomplete types to be used for associative containers, and also
// expands the set of types we can handle to include std::pair.
template <typename T1, typename T2>
-struct IsView<std::pair<T1, T2>>
- : std::integral_constant<bool, IsView<std::remove_cv_t<T1>>::value &&
- IsView<std::remove_cv_t<T2>>::value> {};
+struct IsView<std::pair<T1, T2>> : IsView<std::tuple<T1, T2>> {};
template <typename Char, typename Traits>
struct IsView<std::basic_string_view<Char, Traits>> : std::true_type {};
+template <typename... T>
+struct IsView<std::tuple<T...>>
+ : std::bool_constant<(sizeof...(T) > 0) &&
+ // Uses a C++17 fold expression where '...' unpacks the
+ // parameter pack T, and 'true &&' provides the base
+ // case for the logical AND operation across all types.
+ (true && ... && IsView<T>::value)> {};
+
+template <typename... T>
+struct IsView<std::variant<T...>> : IsView<std::tuple<T...>> {};
+
#ifdef __cpp_lib_span
template <typename T>
struct IsView<std::span<T>> : std::true_type {};
@@ -631,9 +627,10 @@ struct IsView<std::span<T>> : std::true_type {};
// Until then, we consider an assignment from an "owner" (such as std::string)
// to a "view" (such as std::string_view) to be a lifetime-bound assignment.
template <typename T, typename U>
-using IsLifetimeBoundAssignment = std::conjunction<
- std::integral_constant<bool, !std::is_lvalue_reference_v<U>>,
- IsOwner<absl::remove_cvref_t<U>>, IsView<absl::remove_cvref_t<T>>>;
+using IsLifetimeBoundAssignment =
+ std::conjunction<std::bool_constant<!std::is_lvalue_reference_v<U>>,
+ IsOwner<absl::remove_cvref_t<U>>,
+ IsView<absl::remove_cvref_t<T>>>;
} // namespace type_traits_internal
diff --git a/deps/v8/third_party/abseil-cpp/absl/meta/type_traits_test.cc b/deps/v8/third_party/abseil-cpp/absl/meta/type_traits_test.cc
index 9734fc18068..a11049c6ba7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/meta/type_traits_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/meta/type_traits_test.cc
@@ -14,11 +14,15 @@
#include "absl/meta/type_traits.h"
+#include <array>
#include <cstdint>
+#include <functional>
#include <string>
#include <string_view>
+#include <tuple>
#include <type_traits>
#include <utility>
+#include <variant>
#include <vector>
#include "gtest/gtest.h"
@@ -31,6 +35,11 @@ namespace {
using ::testing::StaticAssertTypeEq;
+template <typename T>
+using IsViewAndNotOwner =
+ std::conjunction<absl::type_traits_internal::IsView<T>,
+ std::negation<absl::type_traits_internal::IsOwner<T>>>;
+
template <typename T>
using IsOwnerAndNotView =
std::conjunction<absl::type_traits_internal::IsOwner<T>,
@@ -45,9 +54,9 @@ static_assert(IsOwnerAndNotView<std::string>::value,
"string is an owner, not a view");
static_assert(IsOwnerAndNotView<std::wstring>::value,
"wstring is an owner, not a view");
-static_assert(!IsOwnerAndNotView<std::string_view>::value,
+static_assert(IsViewAndNotOwner<std::string_view>::value,
"string_view is a view, not an owner");
-static_assert(!IsOwnerAndNotView<std::wstring_view>::value,
+static_assert(IsViewAndNotOwner<std::wstring_view>::value,
"wstring_view is a view, not an owner");
template <class T, class U>
@@ -175,7 +184,7 @@ struct GetTypeT {
struct GetTypeExtT {
template <typename T>
- absl::result_of_t<const GetTypeT&(T)> operator()(T&& arg) const {
+ std::invoke_result_t<const GetTypeT&, T> operator()(T&& arg) const {
return GetType(std::forward<T>(arg));
}
@@ -207,7 +216,6 @@ void swap(SpecialNoexceptSwap&, SpecialNoexceptSwap&) noexcept {}
TEST(TypeTraitsTest, IsSwappable) {
using absl::type_traits_internal::IsSwappable;
- using absl::type_traits_internal::StdSwapIsUnconstrained;
EXPECT_TRUE(IsSwappable<int>::value);
@@ -220,14 +228,14 @@ TEST(TypeTraitsTest, IsSwappable) {
~NoConstruct() = default;
};
- EXPECT_EQ(IsSwappable<NoConstruct>::value, StdSwapIsUnconstrained::value);
+ EXPECT_FALSE(IsSwappable<NoConstruct>::value);
struct NoAssign {
NoAssign(NoAssign&&) {}
NoAssign& operator=(NoAssign&&) = delete;
~NoAssign() = default;
};
- EXPECT_EQ(IsSwappable<NoAssign>::value, StdSwapIsUnconstrained::value);
+ EXPECT_FALSE(IsSwappable<NoAssign>::value);
EXPECT_FALSE(IsSwappable<adl_namespace::DeletedSwap>::value);
@@ -236,7 +244,6 @@ TEST(TypeTraitsTest, IsSwappable) {
TEST(TypeTraitsTest, IsNothrowSwappable) {
using absl::type_traits_internal::IsNothrowSwappable;
- using absl::type_traits_internal::StdSwapIsUnconstrained;
EXPECT_TRUE(IsNothrowSwappable<int>::value);
@@ -270,9 +277,9 @@ TEST(TypeTraitsTest, IsNothrowSwappable) {
}
TEST(TriviallyRelocatable, PrimitiveTypes) {
- static_assert(absl::is_trivially_relocatable<int>::value, "");
- static_assert(absl::is_trivially_relocatable<char>::value, "");
- static_assert(absl::is_trivially_relocatable<void*>::value, "");
+ static_assert(absl::is_trivially_relocatable<int>::value);
+ static_assert(absl::is_trivially_relocatable<char>::value);
+ static_assert(absl::is_trivially_relocatable<void*>::value);
}
// User-defined types can be trivially relocatable as long as they don't have a
@@ -283,7 +290,7 @@ TEST(TriviallyRelocatable, UserDefinedTriviallyRelocatable) {
int y;
};
- static_assert(absl::is_trivially_relocatable<S>::value, "");
+ static_assert(absl::is_trivially_relocatable<S>::value);
}
// A user-provided move constructor disqualifies a type from being trivially
@@ -293,7 +300,7 @@ TEST(TriviallyRelocatable, UserProvidedMoveConstructor) {
S(S&&) {} // NOLINT(modernize-use-equals-default)
};
- static_assert(!absl::is_trivially_relocatable<S>::value, "");
+ static_assert(!absl::is_trivially_relocatable<S>::value);
}
// A user-provided copy constructor disqualifies a type from being trivially
@@ -303,7 +310,7 @@ TEST(TriviallyRelocatable, UserProvidedCopyConstructor) {
S(const S&) {} // NOLINT(modernize-use-equals-default)
};
- static_assert(!absl::is_trivially_relocatable<S>::value, "");
+ static_assert(!absl::is_trivially_relocatable<S>::value);
}
// A user-provided copy assignment operator disqualifies a type from
@@ -316,7 +323,7 @@ TEST(TriviallyRelocatable, UserProvidedCopyAssignment) {
}
};
- static_assert(!absl::is_trivially_relocatable<S>::value, "");
+ static_assert(!absl::is_trivially_relocatable<S>::value);
}
// A user-provided move assignment operator disqualifies a type from
@@ -327,7 +334,7 @@ TEST(TriviallyRelocatable, UserProvidedMoveAssignment) {
S& operator=(S&&) { return *this; } // NOLINT(modernize-use-equals-default)
};
- static_assert(!absl::is_trivially_relocatable<S>::value, "");
+ static_assert(!absl::is_trivially_relocatable<S>::value);
}
// A user-provided destructor disqualifies a type from being trivially
@@ -337,7 +344,105 @@ TEST(TriviallyRelocatable, UserProvidedDestructor) {
~S() {} // NOLINT(modernize-use-equals-default)
};
- static_assert(!absl::is_trivially_relocatable<S>::value, "");
+ static_assert(!absl::is_trivially_relocatable<S>::value);
+}
+
+TEST(Ownership, References) {
+ static_assert(IsViewAndNotOwner<std::string&>::value,
+ "std::string& is a view, not an owner");
+ static_assert(IsViewAndNotOwner<int&>::value, "int& is a view, not an owner");
+
+ static_assert(IsViewAndNotOwner<std::string&&>::value,
+ "std::string&& is a view, not an owner");
+ static_assert(IsViewAndNotOwner<int&&>::value,
+ "int&& is a view, not an owner");
+
+ static_assert(IsViewAndNotOwner<std::reference_wrapper<std::string>>::value,
+ "std::reference_wrapper<std::string> is a view, not an owner");
+ static_assert(IsViewAndNotOwner<std::reference_wrapper<int>>::value,
+ "std::reference_wrapper<int> is a view, not an owner");
+}
+
+TEST(Ownership, CVQualifiers) {
+ static_assert(IsOwnerAndNotView<const std::string>::value,
+ "const std::string is an owner, not a view");
+ static_assert(IsViewAndNotOwner<const std::string_view>::value,
+ "const std::string_view is a view, not an owner");
+
+ static_assert(IsOwnerAndNotView<volatile std::string>::value,
+ "volatile std::string is an owner, not a view");
+ static_assert(IsViewAndNotOwner<volatile std::string_view>::value,
+ "volatile std::string_view is a view, not an owner");
+
+ static_assert(IsOwnerAndNotView<const volatile std::string>::value,
+ "const volatile std::string is an owner, not a view");
+ static_assert(IsViewAndNotOwner<const volatile std::string_view>::value,
+ "const volatile std::string_view is a view, not an owner");
+}
+
+TEST(Ownership, Array) {
+ static_assert(!IsOwnerAndNotView<std::array<std::string, 0>>::value,
+ "empty array is not an owner");
+ static_assert(!IsViewAndNotOwner<std::array<std::string, 0>>::value,
+ "empty array is not a view");
+
+ static_assert(!IsOwnerAndNotView<std::array<std::string_view, 0>>::value,
+ "empty array is not an owner");
+ static_assert(!IsViewAndNotOwner<std::array<std::string_view, 0>>::value,
+ "empty array is not a view");
+
+ static_assert(IsOwnerAndNotView<std::array<std::string, 5>>::value,
+ "array of owners is an owner");
+ static_assert(IsViewAndNotOwner<std::array<std::string_view, 5>>::value,
+ "array of views is a view");
+}
+
+TEST(Ownership, Variant) {
+ static_assert(!IsOwnerAndNotView<std::variant<>>::value,
+ "empty variant is not an owner");
+ static_assert(!IsViewAndNotOwner<std::variant<>>::value,
+ "empty variant is not a view");
+
+ static_assert(IsOwnerAndNotView<std::variant<std::string, std::vector<char>,
+ std::vector<int>>>::value,
+ "aggregate of owners is an owner");
+ static_assert(IsViewAndNotOwner<
+ std::variant<std::wstring_view, std::string_view>>::value,
+ "aggregate of views is a view");
+
+ static_assert(
+ !IsOwnerAndNotView<std::variant<const char*, std::string>>::value,
+ "variant of mixed-ownership types is not considered an owner");
+ static_assert(
+ !IsViewAndNotOwner<std::variant<const char*, std::string>>::value,
+ "variant of mixed-ownership types is not considered a view");
+
+ static_assert(
+ IsViewAndNotOwner<std::variant<std::reference_wrapper<const int>>>::value,
+ "variant of reference is considered a view");
+}
+
+TEST(Ownership, Tuple) {
+ static_assert(!IsOwnerAndNotView<std::tuple<>>::value,
+ "empty tuple is not an owner");
+ static_assert(!IsViewAndNotOwner<std::tuple<>>::value,
+ "empty tuple is not a view");
+
+ static_assert(
+ IsOwnerAndNotView<
+ std::tuple<std::string, std::vector<char>, std::vector<int>>>::value,
+ "aggregate of owners is an owner");
+ static_assert(
+ IsViewAndNotOwner<std::tuple<std::wstring_view, std::string_view>>::value,
+ "aggregate of views is a view");
+
+ static_assert(!IsOwnerAndNotView<std::tuple<const char*, std::string>>::value,
+ "tuple of mixed-ownership types is not considered an owner");
+ static_assert(!IsViewAndNotOwner<std::tuple<const char*, std::string>>::value,
+ "tuple of mixed-ownership types is not considered a view");
+
+ static_assert(IsViewAndNotOwner<std::tuple<const int&>>::value,
+ "tuple of reference is considered a view");
}
#ifdef ABSL_HAVE_CONSTANT_EVALUATED
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 3473d052ff3..cae5a16677c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -16,6 +18,14 @@ absl_source_set("bits") {
]
}
+absl_test("bits_test") {
+ sources = [ "bits_test.cc" ]
+ deps = [
+ ":bits",
+ "//third_party/abseil-cpp/absl/random",
+ ]
+}
+
absl_source_set("int128") {
sources = [
"int128.cc",
@@ -48,5 +58,6 @@ absl_test("int128_test") {
absl_source_set("representation") {
public = [ "internal/representation.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/bits.h b/deps/v8/third_party/abseil-cpp/absl/numeric/bits.h
index 47e9901025d..8eca3927ffd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/bits.h
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/bits.h
@@ -41,6 +41,7 @@
#include <cstdint>
#include <limits>
#include <type_traits>
+#include <version>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/bits_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/numeric/bits_benchmark.cc
index 429b4cab298..3f8bed08178 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/bits_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/bits_benchmark.cc
@@ -12,7 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstddef>
#include <cstdint>
+#include <limits>
#include <vector>
#include "absl/base/optimization.h"
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 e2c64096658..30b59671cd7 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/numeric/internal/bits.h"
#include "absl/random/random.h"
namespace absl {
@@ -62,32 +63,32 @@ TYPED_TEST(IntegerTypesTest, HandlesTypes) {
EXPECT_EQ(rotl(UIntType{0x12}, 0), uint8_t{0x12});
EXPECT_EQ(rotr(UIntType{0x12}, -4), uint8_t{0x21});
- static_assert(rotl(UIntType{0x12}, 0) == uint8_t{0x12}, "");
+ static_assert(rotl(UIntType{0x12}, 0) == uint8_t{0x12});
- static_assert(rotr(UIntType{0x12}, 0) == uint8_t{0x12}, "");
+ static_assert(rotr(UIntType{0x12}, 0) == uint8_t{0x12});
EXPECT_EQ(rotr(UIntType{0x12}, 0), uint8_t{0x12});
#if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
- static_assert(countl_zero(UIntType{}) == 8, "");
- static_assert(countl_zero(static_cast<UIntType>(-1)) == 0, "");
+ static_assert(countl_zero(UIntType{}) == 8);
+ static_assert(countl_zero(static_cast<UIntType>(-1)) == 0);
- static_assert(countl_one(UIntType{}) == 0, "");
- static_assert(countl_one(static_cast<UIntType>(-1)) == 8, "");
+ static_assert(countl_one(UIntType{}) == 0);
+ static_assert(countl_one(static_cast<UIntType>(-1)) == 8);
- static_assert(countr_zero(UIntType{}) == 8, "");
- static_assert(countr_zero(static_cast<UIntType>(-1)) == 0, "");
+ static_assert(countr_zero(UIntType{}) == 8);
+ static_assert(countr_zero(static_cast<UIntType>(-1)) == 0);
- static_assert(countr_one(UIntType{}) == 0, "");
- static_assert(countr_one(static_cast<UIntType>(-1)) == 8, "");
+ static_assert(countr_one(UIntType{}) == 0);
+ static_assert(countr_one(static_cast<UIntType>(-1)) == 8);
- static_assert(popcount(UIntType{}) == 0, "");
- static_assert(popcount(UIntType{1}) == 1, "");
- static_assert(popcount(static_cast<UIntType>(-1)) == 8, "");
+ static_assert(popcount(UIntType{}) == 0);
+ static_assert(popcount(UIntType{1}) == 1);
+ static_assert(popcount(static_cast<UIntType>(-1)) == 8);
- static_assert(bit_width(UIntType{}) == 0, "");
- static_assert(bit_width(UIntType{1}) == 1, "");
- static_assert(bit_width(UIntType{3}) == 2, "");
- static_assert(bit_width(static_cast<UIntType>(-1)) == 8, "");
+ static_assert(bit_width(UIntType{}) == 0);
+ static_assert(bit_width(UIntType{1}) == 1);
+ static_assert(bit_width(UIntType{3}) == 2);
+ static_assert(bit_width(static_cast<UIntType>(-1)) == 8);
#endif
EXPECT_EQ(countl_zero(UIntType{}), 8);
@@ -115,12 +116,11 @@ TYPED_TEST(IntegerTypesTest, HandlesTypes) {
}
TEST(Rotate, Left) {
- static_assert(rotl(uint8_t{0x12}, 0) == uint8_t{0x12}, "");
- static_assert(rotl(uint16_t{0x1234}, 0) == uint16_t{0x1234}, "");
- static_assert(rotl(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}, "");
+ static_assert(rotl(uint8_t{0x12}, 0) == uint8_t{0x12});
+ static_assert(rotl(uint16_t{0x1234}, 0) == uint16_t{0x1234});
+ static_assert(rotl(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL});
static_assert(rotl(uint64_t{0x12345678ABCDEF01ULL}, 0) ==
- uint64_t{0x12345678ABCDEF01ULL},
- "");
+ uint64_t{0x12345678ABCDEF01ULL});
EXPECT_EQ(rotl(uint8_t{0x12}, 0), uint8_t{0x12});
EXPECT_EQ(rotl(uint16_t{0x1234}, 0), uint16_t{0x1234});
@@ -157,12 +157,11 @@ TEST(Rotate, Left) {
}
TEST(Rotate, Right) {
- static_assert(rotr(uint8_t{0x12}, 0) == uint8_t{0x12}, "");
- static_assert(rotr(uint16_t{0x1234}, 0) == uint16_t{0x1234}, "");
- static_assert(rotr(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL}, "");
+ static_assert(rotr(uint8_t{0x12}, 0) == uint8_t{0x12});
+ static_assert(rotr(uint16_t{0x1234}, 0) == uint16_t{0x1234});
+ static_assert(rotr(uint32_t{0x12345678UL}, 0) == uint32_t{0x12345678UL});
static_assert(rotr(uint64_t{0x12345678ABCDEF01ULL}, 0) ==
- uint64_t{0x12345678ABCDEF01ULL},
- "");
+ uint64_t{0x12345678ABCDEF01ULL});
EXPECT_EQ(rotr(uint8_t{0x12}, 0), uint8_t{0x12});
EXPECT_EQ(rotr(uint16_t{0x1234}, 0), uint16_t{0x1234});
@@ -242,14 +241,14 @@ TEST(Rotate, Symmetry) {
TEST(Counting, LeadingZeroes) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
- static_assert(countl_zero(uint8_t{}) == 8, "");
- static_assert(countl_zero(static_cast<uint8_t>(-1)) == 0, "");
- static_assert(countl_zero(uint16_t{}) == 16, "");
- static_assert(countl_zero(static_cast<uint16_t>(-1)) == 0, "");
- static_assert(countl_zero(uint32_t{}) == 32, "");
- static_assert(countl_zero(~uint32_t{}) == 0, "");
- static_assert(countl_zero(uint64_t{}) == 64, "");
- static_assert(countl_zero(~uint64_t{}) == 0, "");
+ static_assert(countl_zero(uint8_t{}) == 8);
+ static_assert(countl_zero(static_cast<uint8_t>(-1)) == 0);
+ static_assert(countl_zero(uint16_t{}) == 16);
+ static_assert(countl_zero(static_cast<uint16_t>(-1)) == 0);
+ static_assert(countl_zero(uint32_t{}) == 32);
+ static_assert(countl_zero(~uint32_t{}) == 0);
+ static_assert(countl_zero(uint64_t{}) == 64);
+ static_assert(countl_zero(~uint64_t{}) == 0);
#endif
EXPECT_EQ(countl_zero(uint8_t{}), 8);
@@ -280,14 +279,14 @@ TEST(Counting, LeadingZeroes) {
TEST(Counting, LeadingOnes) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
- static_assert(countl_one(uint8_t{}) == 0, "");
- static_assert(countl_one(static_cast<uint8_t>(-1)) == 8, "");
- static_assert(countl_one(uint16_t{}) == 0, "");
- static_assert(countl_one(static_cast<uint16_t>(-1)) == 16, "");
- static_assert(countl_one(uint32_t{}) == 0, "");
- static_assert(countl_one(~uint32_t{}) == 32, "");
- static_assert(countl_one(uint64_t{}) == 0, "");
- static_assert(countl_one(~uint64_t{}) == 64, "");
+ static_assert(countl_one(uint8_t{}) == 0);
+ static_assert(countl_one(static_cast<uint8_t>(-1)) == 8);
+ static_assert(countl_one(uint16_t{}) == 0);
+ static_assert(countl_one(static_cast<uint16_t>(-1)) == 16);
+ static_assert(countl_one(uint32_t{}) == 0);
+ static_assert(countl_one(~uint32_t{}) == 32);
+ static_assert(countl_one(uint64_t{}) == 0);
+ static_assert(countl_one(~uint64_t{}) == 64);
#endif
EXPECT_EQ(countl_one(uint8_t{}), 0);
@@ -302,14 +301,14 @@ TEST(Counting, LeadingOnes) {
TEST(Counting, TrailingZeroes) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CTZ
- static_assert(countr_zero(uint8_t{}) == 8, "");
- static_assert(countr_zero(static_cast<uint8_t>(-1)) == 0, "");
- static_assert(countr_zero(uint16_t{}) == 16, "");
- static_assert(countr_zero(static_cast<uint16_t>(-1)) == 0, "");
- static_assert(countr_zero(uint32_t{}) == 32, "");
- static_assert(countr_zero(~uint32_t{}) == 0, "");
- static_assert(countr_zero(uint64_t{}) == 64, "");
- static_assert(countr_zero(~uint64_t{}) == 0, "");
+ static_assert(countr_zero(uint8_t{}) == 8);
+ static_assert(countr_zero(static_cast<uint8_t>(-1)) == 0);
+ static_assert(countr_zero(uint16_t{}) == 16);
+ static_assert(countr_zero(static_cast<uint16_t>(-1)) == 0);
+ static_assert(countr_zero(uint32_t{}) == 32);
+ static_assert(countr_zero(~uint32_t{}) == 0);
+ static_assert(countr_zero(uint64_t{}) == 64);
+ static_assert(countr_zero(~uint64_t{}) == 0);
#endif
EXPECT_EQ(countr_zero(uint8_t{}), 8);
@@ -324,14 +323,14 @@ TEST(Counting, TrailingZeroes) {
TEST(Counting, TrailingOnes) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CTZ
- static_assert(countr_one(uint8_t{}) == 0, "");
- static_assert(countr_one(static_cast<uint8_t>(-1)) == 8, "");
- static_assert(countr_one(uint16_t{}) == 0, "");
- static_assert(countr_one(static_cast<uint16_t>(-1)) == 16, "");
- static_assert(countr_one(uint32_t{}) == 0, "");
- static_assert(countr_one(~uint32_t{}) == 32, "");
- static_assert(countr_one(uint64_t{}) == 0, "");
- static_assert(countr_one(~uint64_t{}) == 64, "");
+ static_assert(countr_one(uint8_t{}) == 0);
+ static_assert(countr_one(static_cast<uint8_t>(-1)) == 8);
+ static_assert(countr_one(uint16_t{}) == 0);
+ static_assert(countr_one(static_cast<uint16_t>(-1)) == 16);
+ static_assert(countr_one(uint32_t{}) == 0);
+ static_assert(countr_one(~uint32_t{}) == 32);
+ static_assert(countr_one(uint64_t{}) == 0);
+ static_assert(countr_one(~uint64_t{}) == 64);
#endif
EXPECT_EQ(countr_one(uint8_t{}), 0);
@@ -346,18 +345,18 @@ TEST(Counting, TrailingOnes) {
TEST(Counting, Popcount) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT
- static_assert(popcount(uint8_t{}) == 0, "");
- static_assert(popcount(uint8_t{1}) == 1, "");
- static_assert(popcount(static_cast<uint8_t>(-1)) == 8, "");
- static_assert(popcount(uint16_t{}) == 0, "");
- static_assert(popcount(uint16_t{1}) == 1, "");
- static_assert(popcount(static_cast<uint16_t>(-1)) == 16, "");
- static_assert(popcount(uint32_t{}) == 0, "");
- static_assert(popcount(uint32_t{1}) == 1, "");
- static_assert(popcount(~uint32_t{}) == 32, "");
- static_assert(popcount(uint64_t{}) == 0, "");
- static_assert(popcount(uint64_t{1}) == 1, "");
- static_assert(popcount(~uint64_t{}) == 64, "");
+ static_assert(popcount(uint8_t{}) == 0);
+ static_assert(popcount(uint8_t{1}) == 1);
+ static_assert(popcount(static_cast<uint8_t>(-1)) == 8);
+ static_assert(popcount(uint16_t{}) == 0);
+ static_assert(popcount(uint16_t{1}) == 1);
+ static_assert(popcount(static_cast<uint16_t>(-1)) == 16);
+ static_assert(popcount(uint32_t{}) == 0);
+ static_assert(popcount(uint32_t{1}) == 1);
+ static_assert(popcount(~uint32_t{}) == 32);
+ static_assert(popcount(uint64_t{}) == 0);
+ static_assert(popcount(uint64_t{1}) == 1);
+ static_assert(popcount(~uint64_t{}) == 64);
#endif // ABSL_INTERNAL_HAS_CONSTEXPR_POPCOUNT
EXPECT_EQ(popcount(uint8_t{}), 0);
@@ -452,15 +451,15 @@ TEST(IntegralPowersOfTwo, SingleBit) {
EXPECT_FALSE(has_single_bit(uint64_t{}));
EXPECT_FALSE(has_single_bit(~uint64_t{}));
- static_assert(!has_single_bit(0u), "");
- static_assert(has_single_bit(1u), "");
- static_assert(has_single_bit(2u), "");
- static_assert(!has_single_bit(3u), "");
- static_assert(has_single_bit(4u), "");
- static_assert(!has_single_bit(1337u), "");
- static_assert(has_single_bit(65536u), "");
- static_assert(has_single_bit(uint32_t{1} << 30), "");
- static_assert(has_single_bit(uint64_t{1} << 42), "");
+ static_assert(!has_single_bit(0u));
+ static_assert(has_single_bit(1u));
+ static_assert(has_single_bit(2u));
+ static_assert(!has_single_bit(3u));
+ static_assert(has_single_bit(4u));
+ static_assert(!has_single_bit(1337u));
+ static_assert(has_single_bit(65536u));
+ static_assert(has_single_bit(uint32_t{1} << 30));
+ static_assert(has_single_bit(uint64_t{1} << 42));
EXPECT_FALSE(has_single_bit(0u));
EXPECT_TRUE(has_single_bit(1u));
@@ -493,20 +492,18 @@ bool IsBitCeilConstantExpression(char) {
TEST(IntegralPowersOfTwo, Ceiling) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
- static_assert(bit_ceil(0u) == 1, "");
- static_assert(bit_ceil(1u) == 1, "");
- static_assert(bit_ceil(2u) == 2, "");
- static_assert(bit_ceil(3u) == 4, "");
- static_assert(bit_ceil(4u) == 4, "");
- static_assert(bit_ceil(1337u) == 2048, "");
- static_assert(bit_ceil(65536u) == 65536, "");
- static_assert(bit_ceil(65536u - 1337u) == 65536, "");
- static_assert(bit_ceil(uint32_t{0x80000000}) == uint32_t{0x80000000}, "");
- static_assert(bit_ceil(uint64_t{0x40000000000}) == uint64_t{0x40000000000},
- "");
- static_assert(
- bit_ceil(uint64_t{0x8000000000000000}) == uint64_t{0x8000000000000000},
- "");
+ static_assert(bit_ceil(0u) == 1);
+ static_assert(bit_ceil(1u) == 1);
+ static_assert(bit_ceil(2u) == 2);
+ static_assert(bit_ceil(3u) == 4);
+ static_assert(bit_ceil(4u) == 4);
+ static_assert(bit_ceil(1337u) == 2048);
+ static_assert(bit_ceil(65536u) == 65536);
+ static_assert(bit_ceil(65536u - 1337u) == 65536);
+ static_assert(bit_ceil(uint32_t{0x80000000}) == uint32_t{0x80000000});
+ static_assert(bit_ceil(uint64_t{0x40000000000}) == uint64_t{0x40000000000});
+ static_assert(bit_ceil(uint64_t{0x8000000000000000}) ==
+ uint64_t{0x8000000000000000});
EXPECT_TRUE((IsBitCeilConstantExpression<uint8_t, uint8_t{0x0}>(0)));
EXPECT_TRUE((IsBitCeilConstantExpression<uint8_t, uint8_t{0x80}>(0)));
@@ -547,16 +544,15 @@ TEST(IntegralPowersOfTwo, Ceiling) {
TEST(IntegralPowersOfTwo, Floor) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
- static_assert(bit_floor(0u) == 0, "");
- static_assert(bit_floor(1u) == 1, "");
- static_assert(bit_floor(2u) == 2, "");
- static_assert(bit_floor(3u) == 2, "");
- static_assert(bit_floor(4u) == 4, "");
- static_assert(bit_floor(1337u) == 1024, "");
- static_assert(bit_floor(65536u) == 65536, "");
- static_assert(bit_floor(65536u - 1337u) == 32768, "");
- static_assert(bit_floor(uint64_t{0x40000000000}) == uint64_t{0x40000000000},
- "");
+ static_assert(bit_floor(0u) == 0);
+ static_assert(bit_floor(1u) == 1);
+ static_assert(bit_floor(2u) == 2);
+ static_assert(bit_floor(3u) == 2);
+ static_assert(bit_floor(4u) == 4);
+ static_assert(bit_floor(1337u) == 1024);
+ static_assert(bit_floor(65536u) == 65536);
+ static_assert(bit_floor(65536u - 1337u) == 32768);
+ static_assert(bit_floor(uint64_t{0x40000000000}) == uint64_t{0x40000000000});
#endif
EXPECT_EQ(bit_floor(0u), 0);
@@ -604,22 +600,22 @@ TEST(IntegralPowersOfTwo, Floor) {
TEST(IntegralPowersOfTwo, Width) {
#if ABSL_INTERNAL_HAS_CONSTEXPR_CLZ
- static_assert(bit_width(uint8_t{}) == 0, "");
- static_assert(bit_width(uint8_t{1}) == 1, "");
- static_assert(bit_width(uint8_t{3}) == 2, "");
- static_assert(bit_width(static_cast<uint8_t>(-1)) == 8, "");
- static_assert(bit_width(uint16_t{}) == 0, "");
- static_assert(bit_width(uint16_t{1}) == 1, "");
- static_assert(bit_width(uint16_t{3}) == 2, "");
- static_assert(bit_width(static_cast<uint16_t>(-1)) == 16, "");
- static_assert(bit_width(uint32_t{}) == 0, "");
- static_assert(bit_width(uint32_t{1}) == 1, "");
- static_assert(bit_width(uint32_t{3}) == 2, "");
- static_assert(bit_width(~uint32_t{}) == 32, "");
- static_assert(bit_width(uint64_t{}) == 0, "");
- static_assert(bit_width(uint64_t{1}) == 1, "");
- static_assert(bit_width(uint64_t{3}) == 2, "");
- static_assert(bit_width(~uint64_t{}) == 64, "");
+ static_assert(bit_width(uint8_t{}) == 0);
+ static_assert(bit_width(uint8_t{1}) == 1);
+ static_assert(bit_width(uint8_t{3}) == 2);
+ static_assert(bit_width(static_cast<uint8_t>(-1)) == 8);
+ static_assert(bit_width(uint16_t{}) == 0);
+ static_assert(bit_width(uint16_t{1}) == 1);
+ static_assert(bit_width(uint16_t{3}) == 2);
+ static_assert(bit_width(static_cast<uint16_t>(-1)) == 16);
+ static_assert(bit_width(uint32_t{}) == 0);
+ static_assert(bit_width(uint32_t{1}) == 1);
+ static_assert(bit_width(uint32_t{3}) == 2);
+ static_assert(bit_width(~uint32_t{}) == 32);
+ static_assert(bit_width(uint64_t{}) == 0);
+ static_assert(bit_width(uint64_t{1}) == 1);
+ static_assert(bit_width(uint64_t{3}) == 2);
+ static_assert(bit_width(~uint64_t{}) == 64);
#endif
EXPECT_EQ(bit_width(uint8_t{}), 0);
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 9987c1595db..dc01c0fae8d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/int128.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/int128.cc
@@ -17,12 +17,16 @@
#include <stddef.h>
#include <cassert>
+#include <cstdint>
#include <iomanip>
+#include <ios>
+#include <limits>
#include <ostream> // NOLINT(readability/streams)
#include <sstream>
#include <string>
#include <type_traits>
+#include "absl/base/attributes.h"
#include "absl/base/optimization.h"
#include "absl/numeric/bits.h"
@@ -90,7 +94,7 @@ inline void DivModImpl(uint128 dividend, uint128 divisor, uint128* quotient_ret,
template <typename T>
uint128 MakeUint128FromFloat(T v) {
- static_assert(std::is_floating_point_v<T>, "");
+ static_assert(std::is_floating_point_v<T>);
// Rounding behavior is towards zero, same as for built-in types.
@@ -114,8 +118,8 @@ uint128 MakeUint128FromFloat(T v) {
// It is more work, so only use when we need the workaround.
uint128 MakeUint128FromFloat(long double v) {
// Go 50 bits at a time, that fits in a double
- static_assert(std::numeric_limits<double>::digits >= 50, "");
- static_assert(std::numeric_limits<long double>::digits <= 150, "");
+ static_assert(std::numeric_limits<double>::digits >= 50);
+ static_assert(std::numeric_limits<long double>::digits <= 150);
// Undefined behavior if v is not finite or cannot fit into uint128.
assert(std::isfinite(v) && v > -1 && v < std::ldexp(1.0L, 128));
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/int128.h b/deps/v8/third_party/abseil-cpp/absl/numeric/int128.h
index 32603b04ead..0078ab051e3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/int128.h
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/int128.h
@@ -35,6 +35,7 @@
#include <string>
#include <utility>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc b/deps/v8/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc
index 1b058e17852..f8eb431204a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/int128_stream_test.cc
@@ -12,12 +12,16 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/numeric/int128.h"
-
+#include <cstddef>
+#include <cstdint>
+#include <ios>
+#include <limits>
#include <sstream>
#include <string>
+#include <vector>
#include "gtest/gtest.h"
+#include "absl/numeric/int128.h"
#include "absl/strings/str_cat.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/int128_test.cc b/deps/v8/third_party/abseil-cpp/absl/numeric/int128_test.cc
index 35eacae17c1..93f0d73ee03 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/int128_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/int128_test.cc
@@ -15,6 +15,8 @@
#include "absl/numeric/int128.h"
#include <algorithm>
+#include <cmath>
+#include <cstdint>
#include <limits>
#include <random>
#include <tuple>
@@ -93,10 +95,10 @@ TEST(Uint128, IntrinsicTypeTraitsTest) {
#endif // ABSL_HAVE_INTRINSIC_INT128
TEST(Uint128, TrivialTraitsTest) {
- static_assert(std::is_trivially_default_constructible_v<absl::uint128>, "");
- static_assert(std::is_trivially_copy_constructible_v<absl::uint128>, "");
- static_assert(std::is_trivially_copy_assignable_v<absl::uint128>, "");
- static_assert(std::is_trivially_destructible_v<absl::uint128>, "");
+ static_assert(std::is_trivially_default_constructible_v<absl::uint128>);
+ static_assert(std::is_trivially_copy_constructible_v<absl::uint128>);
+ static_assert(std::is_trivially_copy_assignable_v<absl::uint128>);
+ static_assert(std::is_trivially_destructible_v<absl::uint128>);
}
TEST(Uint128, AllTests) {
@@ -483,9 +485,9 @@ TEST(Uint128, ConstexprTest) {
}
TEST(Uint128, NumericLimitsTest) {
- static_assert(std::numeric_limits<absl::uint128>::is_specialized, "");
- static_assert(!std::numeric_limits<absl::uint128>::is_signed, "");
- static_assert(std::numeric_limits<absl::uint128>::is_integer, "");
+ static_assert(std::numeric_limits<absl::uint128>::is_specialized);
+ static_assert(!std::numeric_limits<absl::uint128>::is_signed);
+ static_assert(std::numeric_limits<absl::uint128>::is_integer);
EXPECT_EQ(static_cast<int>(128 * std::log10(2)),
std::numeric_limits<absl::uint128>::digits10);
EXPECT_EQ(0, std::numeric_limits<absl::uint128>::min());
@@ -617,10 +619,10 @@ TEST(Int128, IntrinsicTypeTraitsTest) {
#endif // ABSL_HAVE_INTRINSIC_INT128
TEST(Int128, TrivialTraitsTest) {
- static_assert(std::is_trivially_default_constructible_v<absl::int128>, "");
- static_assert(std::is_trivially_copy_constructible_v<absl::int128>, "");
- static_assert(std::is_trivially_copy_assignable_v<absl::int128>, "");
- static_assert(std::is_trivially_destructible_v<absl::int128>, "");
+ static_assert(std::is_trivially_default_constructible_v<absl::int128>);
+ static_assert(std::is_trivially_copy_constructible_v<absl::int128>);
+ static_assert(std::is_trivially_copy_assignable_v<absl::int128>);
+ static_assert(std::is_trivially_destructible_v<absl::int128>);
}
TEST(Int128, BoolConversionTest) {
@@ -1345,9 +1347,9 @@ TEST(Int128, BitwiseShiftTest) {
}
TEST(Int128, NumericLimitsTest) {
- static_assert(std::numeric_limits<absl::int128>::is_specialized, "");
- static_assert(std::numeric_limits<absl::int128>::is_signed, "");
- static_assert(std::numeric_limits<absl::int128>::is_integer, "");
+ static_assert(std::numeric_limits<absl::int128>::is_specialized);
+ static_assert(std::numeric_limits<absl::int128>::is_signed);
+ static_assert(std::numeric_limits<absl::int128>::is_integer);
EXPECT_EQ(static_cast<int>(127 * std::log10(2)),
std::numeric_limits<absl::int128>::digits10);
EXPECT_EQ(absl::Int128Min(), std::numeric_limits<absl::int128>::min());
diff --git a/deps/v8/third_party/abseil-cpp/absl/numeric/internal/bits.h b/deps/v8/third_party/abseil-cpp/absl/numeric/internal/bits.h
index 82c577dea4b..58351868110 100644
--- a/deps/v8/third_party/abseil-cpp/absl/numeric/internal/bits.h
+++ b/deps/v8/third_party/abseil-cpp/absl/numeric/internal/bits.h
@@ -19,15 +19,15 @@
#include <limits>
#include <type_traits>
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+
// Clang on Windows has __builtin_clzll; otherwise we need to use the
// windows intrinsic functions.
#if defined(_MSC_VER) && !defined(__clang__)
#include <intrin.h>
#endif
-#include "absl/base/attributes.h"
-#include "absl/base/config.h"
-
#if defined(__GNUC__) && !defined(__clang__)
// GCC
#define ABSL_NUMERIC_INTERNAL_HAVE_BUILTIN_OR_GCC(x) 1
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 b88fc84a078..e958307e4ec 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.bazel
@@ -93,6 +93,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":exponential_biased",
+ "//absl/base:core_headers",
"//absl/strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -159,6 +160,7 @@ cc_library(
"//absl/base:raw_logging_internal",
"//absl/container:btree",
"//absl/container:flat_hash_map",
+ "//absl/container:hash_container_defaults",
"//absl/strings",
"//absl/strings:str_format",
"//absl/types:span",
@@ -176,6 +178,7 @@ cc_library(
],
deps = [
":profile_builder",
+ "//absl/base",
"//absl/base:config",
"//absl/container:hashtablez_sampler",
"//absl/status:statusor",
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 4ec50514176..d81253ad545 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/BUILD.gn
@@ -1,48 +1,41 @@
# Copyright 2021 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("sample_recorder") {
public = [ "internal/sample_recorder.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/time",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
-# TODO: Re-enable once the issue with gmock activating generic gtest
-# printers hitting issues with -Wmicrosoft-cast.
-# absl_test("sample_recorder_test") {
-# sources = [ "internal/sample_recorder_test.cc" ]
-# deps = [
-# ":sample_recorder",
-# "//third_party/abseil-cpp/absl/base:core_headers",
-# "//third_party/abseil-cpp/absl/random",
-# "//third_party/abseil-cpp/absl/synchronization",
-# "//third_party/abseil-cpp/absl/synchronization:thread_pool",
-# "//third_party/abseil-cpp/absl/time",
-# ]
-# }
+# TODO: Re-enable once the issue with gmock activating generic gtest printers
+# hitting issues with -Wmicrosoft-cast.
+# absl_test("sample_recorder_test")
absl_source_set("exponential_biased") {
sources = [ "internal/exponential_biased.cc" ]
public = [ "internal/exponential_biased.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_test("exponential_biased_test") {
sources = [ "internal/exponential_biased_test.cc" ]
deps = [
":exponential_biased",
+ "//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings",
]
}
@@ -50,6 +43,7 @@ absl_test("exponential_biased_test") {
absl_source_set("periodic_sampler") {
sources = [ "internal/periodic_sampler.cc" ]
public = [ "internal/periodic_sampler.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":exponential_biased",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -67,14 +61,17 @@ absl_test("periodic_sampler_test") {
absl_source_set("profile_builder") {
sources = [ "internal/profile_builder.cc" ]
public = [ "internal/profile_builder.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/container:btree",
"//third_party/abseil-cpp/absl/container:flat_hash_map",
+ "//third_party/abseil-cpp/absl/container:hash_container_defaults",
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
+ "//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:span",
]
}
@@ -82,8 +79,10 @@ absl_source_set("profile_builder") {
absl_source_set("hashtable") {
sources = [ "hashtable.cc" ]
public = [ "hashtable.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":profile_builder",
+ "//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/container:hashtablez_sampler",
"//third_party/abseil-cpp/absl/status:statusor",
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.cc
index f1dbe322994..7e5e4ea1fff 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/hashtable.cc
@@ -22,6 +22,7 @@
#include <utility>
#include <vector>
+#include "absl/base/casts.h"
#include "absl/base/config.h"
#include "absl/container/internal/hashtablez_sampler.h"
#include "absl/profiling/internal/profile_builder.h"
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 ebfbcad4f00..103b7d543d8 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
@@ -16,12 +16,16 @@
#include <stddef.h>
+#include <algorithm>
#include <cmath>
#include <cstdint>
+#include <cstdio>
+#include <string>
#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
#include "absl/strings/str_cat.h"
using ::testing::Ge;
@@ -132,6 +136,49 @@ TEST(ExponentialBiasedTest, CoinTossDemoWithGetSkipCount) {
printf("Heads = %d (%f%%)\n", heads, 100.0 * heads / 10000000);
}
+// In simplified idealized world, `GetSkipCount(m) == 0` translates to
+// `-log(X) * m + B <= 1/2`, where X is a uniform random number in (0, 1],
+// and B is uniform random number in [-0.5, 0.5). Let U = 0.5 - B, that makes
+// U a uniform random number in (0, 1]. After exponentiation we get
+// `X >= exp(-U / m)`. Probability of this is `1 - exp(-U / m)`, so we have to
+// integrate for all possible values of U: `1 - m * (1 - exp(-1 / m))`. For
+// simplicity take just two terms of Taylor series expansion:
+// `1/(2*m) - 1/(6*m^2)`. Reciprocal of that is `2*m + 2/3 + O(1/m)`. If we use
+// more math tricks we can get "exact" approximation, but result will still be
+// `2*m + 2/3 + O(1/m)`.
+TEST(ExponentialBiasedTest, OnePerNDemoWithGetSkipCount) {
+ ExponentialBiased eb;
+ int n = 22;
+ int rounds = 220000;
+ int hits = 0;
+ for (int i = 0; i < rounds; i++) {
+ if (eb.GetSkipCount(n / 2) == 0) ++hits;
+ }
+ double inverse_hit_rate = rounds / static_cast<double>(hits);
+ printf("N = %d, rounds = %d, inverse hit rate = %f (should be ~= N + 0.67)\n",
+ n, rounds, inverse_hit_rate);
+}
+
+// Large requested mean flattens density function near zero, making it almost
+// linear.
+TEST(ExponentialBiasedTest, OneOfNDemoWithGetSkipCount) {
+ ExponentialBiased eb;
+ int n = 6;
+ int large_mean = 10000000;
+ int rounds = n * 10000;
+ std::vector<int> hits(static_cast<size_t>(n), 0);
+ for (int i = 0; i < rounds; i++) {
+ int64_t v = eb.GetSkipCount(large_mean);
+ int64_t a = v % n;
+ ++hits[static_cast<size_t>(a)];
+ }
+ printf("N = %d, rounds = %d, mean = %d\n", n, rounds, large_mean);
+ for (int i = 0; i < n; i++) {
+ printf(" inverse hit rate for %d: %f (should be ~= N)\n", i,
+ rounds / static_cast<double>(hits[static_cast<size_t>(i)]));
+ }
+}
+
TEST(ExponentialBiasedTest, SampleDemoWithStride) {
ExponentialBiased eb;
int64_t stride = eb.GetStride(10);
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 a738a82c865..3e0fc2f13d2 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
@@ -15,7 +15,9 @@
#include "absl/profiling/internal/periodic_sampler.h"
#include <atomic>
+#include <cstdint>
+#include "absl/base/optimization.h"
#include "absl/profiling/internal/exponential_biased.h"
namespace absl {
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 8f0e5574c3b..2d6beca8d64 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/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 ef986f3878b..d89b21724cd 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
@@ -14,6 +14,7 @@
#include "absl/profiling/internal/periodic_sampler.h"
+#include <cstdint>
#include <thread> // NOLINT(build/c++11)
#include "gmock/gmock.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.cc b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.cc
index 54170c4e74d..6dc067791bc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/profile_builder.cc
@@ -15,11 +15,6 @@
#include "absl/profiling/internal/profile_builder.h"
-#ifdef __linux__
-#include <elf.h>
-#include <link.h>
-#endif // __linux__
-
#include <cassert>
#include <cstdint>
#include <cstring>
@@ -33,8 +28,14 @@
#include "absl/strings/escaping.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
#include "absl/types/span.h"
+#ifdef __linux__
+#include <elf.h>
+#include <link.h>
+#endif // __linux__
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace debugging_internal {
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 e4f29097d9f..243b927c541 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
@@ -18,11 +18,14 @@
#include <cstddef>
#include <cstdint>
+#include <memory>
#include <string>
+#include <utility>
#include <vector>
#include "absl/container/btree_map.h"
#include "absl/container/flat_hash_map.h"
+#include "absl/container/hash_container_defaults.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
index 88a4b271712..0d14027957e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
+++ b/deps/v8/third_party/abseil-cpp/absl/profiling/internal/sample_recorder.h
@@ -26,6 +26,7 @@
#include <atomic>
#include <cstddef>
+#include <cstdint>
#include <functional>
#include "absl/base/config.h"
@@ -168,7 +169,7 @@ void SampleRecorder<T>::PushDead(T* sample) {
template <typename T>
template <typename... Targs>
T* SampleRecorder<T>::PopDead(Targs... args) {
- absl::MutexLock graveyard_lock(graveyard_.init_mu);
+ absl::ReleasableMutexLock graveyard_lock(graveyard_.init_mu);
// The list is circular, so eventually it collapses down to
// graveyard_.dead == &graveyard_
@@ -178,6 +179,11 @@ T* SampleRecorder<T>::PopDead(Targs... args) {
absl::MutexLock sample_lock(sample->init_mu);
graveyard_.dead = sample->dead;
+ // Release the global graveyard lock early, before the potentially slow
+ // preparation.
+ graveyard_lock.Release();
+ // Prepare the sample while still holding the per-sample lock.
+ // `Iterate` will wait for the lock to be released.
sample->dead = nullptr;
sample->PrepareForSampling(std::forward<Targs>(args)...);
return sample;
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 31c72ed17dc..2401149c8e0 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
@@ -14,6 +14,7 @@
#include "absl/profiling/internal/sample_recorder.h"
+#include <algorithm>
#include <atomic>
#include <cassert>
#include <cstddef>
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 ab0312ab23f..7d62fa51932 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/random/BUILD.bazel
@@ -263,6 +263,7 @@ cc_test(
deps = [
":distributions",
":random",
+ "//absl/numeric:int128",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -282,6 +283,7 @@ cc_test(
deps = [
":distributions",
":random",
+ "//absl/base:core_headers",
"//absl/log",
"//absl/random/internal:distribution_test_util",
"//absl/random/internal:pcg_engine",
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 1954ae4b599..2b76e0bf95f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/random/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -17,6 +19,10 @@ absl_source_set("random") {
}
absl_source_set("distributions") {
+ sources = [
+ "discrete_distribution.cc",
+ "gaussian_distribution.cc",
+ ]
public = [
"bernoulli_distribution.h",
"beta_distribution.h",
@@ -30,10 +36,6 @@ absl_source_set("distributions") {
"uniform_real_distribution.h",
"zipf_distribution.h",
]
- sources = [
- "discrete_distribution.cc",
- "gaussian_distribution.cc",
- ]
deps = [
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
@@ -52,8 +54,8 @@ absl_source_set("distributions") {
}
absl_source_set("seed_gen_exception") {
- public = [ "seed_gen_exception.h" ]
sources = [ "seed_gen_exception.cc" ]
+ public = [ "seed_gen_exception.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
@@ -61,8 +63,8 @@ absl_source_set("seed_gen_exception") {
}
absl_source_set("seed_sequences") {
- public = [ "seed_sequences.h" ]
sources = [ "seed_sequences.cc" ]
+ public = [ "seed_sequences.h" ]
deps = [
":seed_gen_exception",
"//third_party/abseil-cpp/absl/base:config",
@@ -113,6 +115,7 @@ absl_source_set("mocking_bit_gen") {
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/random/internal:mock_helpers",
"//third_party/abseil-cpp/absl/utility",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -126,6 +129,31 @@ absl_source_set("mocking_access") {
]
}
+absl_test("bernoulli_distribution_test") {
+ sources = [ "bernoulli_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ ]
+}
+
+absl_test("beta_distribution_test") {
+ sources = [ "beta_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/numeric:representation",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:str_format",
+ ]
+}
+
absl_test("distributions_test") {
sources = [ "distributions_test.cc" ]
deps = [
@@ -137,6 +165,154 @@ absl_test("distributions_test") {
]
}
+absl_test("generators_test") {
+ sources = [ "generators_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/numeric:int128",
+ ]
+}
+
+absl_test("log_uniform_int_distribution_test") {
+ sources = [ "log_uniform_int_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:str_format",
+ ]
+}
+
+absl_test("discrete_distribution_test") {
+ sources = [ "discrete_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+absl_test("poisson_distribution_test") {
+ sources = [ "poisson_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/container:flat_hash_map",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:str_format",
+ ]
+}
+
+absl_test("exponential_distribution_test") {
+ sources = [ "exponential_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/numeric:representation",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:str_format",
+ ]
+}
+
+absl_test("gaussian_distribution_test") {
+ sources = [ "gaussian_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/numeric:representation",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:str_format",
+ ]
+}
+
+absl_test("uniform_int_distribution_test") {
+ sources = [ "uniform_int_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+absl_test("uniform_real_distribution_test") {
+ sources = [ "uniform_real_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/numeric:representation",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+ if (is_ios) {
+ sources = []
+ }
+}
+
+absl_test("zipf_distribution_test") {
+ sources = [ "zipf_distribution_test.cc" ]
+ deps = [
+ ":distributions",
+ ":random",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/random/internal:distribution_test_util",
+ "//third_party/abseil-cpp/absl/random/internal:pcg_engine",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ "//third_party/abseil-cpp/absl/strings",
+ ]
+}
+
+absl_test("bit_gen_ref_test") {
+ sources = [ "bit_gen_ref_test.cc" ]
+ deps = [
+ ":bit_gen_ref",
+ ":random",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/base:fast_type_id",
+ "//third_party/abseil-cpp/absl/random/internal:sequence_urbg",
+ ]
+}
+
+absl_test("mocking_bit_gen_test") {
+ sources = [ "mocking_bit_gen_test.cc" ]
+ deps = [
+ ":bit_gen_ref",
+ ":mock_distributions",
+ ":mocking_bit_gen",
+ ":random",
+ ]
+}
+
absl_test("mock_distributions_test") {
sources = [ "mock_distributions_test.cc" ]
deps = [
@@ -147,3 +323,17 @@ absl_test("mock_distributions_test") {
"//third_party/abseil-cpp/absl/numeric:int128",
]
}
+
+absl_test("examples_test") {
+ sources = [ "examples_test.cc" ]
+ deps = [ ":random" ]
+}
+
+absl_test("seed_sequences_test") {
+ sources = [ "seed_sequences_test.cc" ]
+ deps = [
+ ":random",
+ ":seed_sequences",
+ "//third_party/abseil-cpp/absl/random/internal:nonsecure_base",
+ ]
+}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/benchmarks.cc b/deps/v8/third_party/abseil-cpp/absl/random/benchmarks.cc
index 4cb16e6a044..c89388bf429 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/benchmarks.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/benchmarks.cc
@@ -74,13 +74,13 @@ class PrecompiledSeedSeq {
static size_t idx = 0;
for (; begin != end; begin++) {
*begin = kSeedData[idx++];
- if (idx >= ABSL_ARRAYSIZE(kSeedData)) {
+ if (idx >= std::size(kSeedData)) {
idx = 0;
}
}
}
- size_t size() const { return ABSL_ARRAYSIZE(kSeedData); }
+ size_t size() const { return std::size(kSeedData); }
template <typename OutIterator>
void param(OutIterator out) const {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/bernoulli_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/bernoulli_distribution_test.cc
index b250f8787c6..9c04bf6c657 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/bernoulli_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/bernoulli_distribution_test.cc
@@ -16,8 +16,10 @@
#include <cmath>
#include <cstddef>
+#include <limits>
#include <random>
#include <sstream>
+#include <string>
#include <utility>
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution.h b/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution.h
index 15311df3b7c..a2cdd255496 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution.h
@@ -23,7 +23,6 @@
#include <ostream>
#include <type_traits>
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/meta/type_traits.h"
#include "absl/random/internal/fast_uniform_bits.h"
@@ -387,7 +386,6 @@ beta_distribution<RealType>::operator()(URBG& g, // NOLINT(runtime/references)
case param_type::JOEHNK:
return AlgorithmJoehnk(g, p);
case param_type::CHENG_BA:
- ABSL_FALLTHROUGH_INTENDED;
case param_type::CHENG_BB:
return AlgorithmCheng(g, p);
default:
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution_test.cc
index 6839d5cf378..7e06cb28354 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/beta_distribution_test.cc
@@ -16,14 +16,18 @@
#include <algorithm>
#include <cfloat>
+#include <cmath>
#include <cstddef>
#include <cstdint>
+#include <cstdlib>
#include <iterator>
+#include <limits>
#include <random>
#include <sstream>
#include <string>
#include <type_traits>
#include <unordered_map>
+#include <utility>
#include <vector>
#include "gmock/gmock.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc
index f82ef8402c2..9d961f779da 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/discrete_distribution_test.cc
@@ -22,6 +22,7 @@
#include <random>
#include <sstream>
#include <string>
+#include <utility>
#include <vector>
#include "gmock/gmock.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/distributions_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/distributions_test.cc
index 16c9e2e9bc4..9b081e955ce 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/distributions_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/distributions_test.cc
@@ -82,15 +82,13 @@ void CheckArgsInferType() {
static_assert(
std::conjunction_v<
std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
- std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>,
- "");
+ std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>);
static_assert(
std::conjunction_v<
std::is_same<Expect, decltype(InferredTaggedUniformReturnT<
absl::IntervalOpenOpenTag, A, B>(0))>,
std::is_same<Expect, decltype(InferredTaggedUniformReturnT<
- absl::IntervalOpenOpenTag, B, A>(0))>>,
- "");
+ absl::IntervalOpenOpenTag, B, A>(0))>>);
}
template <typename A, typename B, typename ExplicitRet>
@@ -123,8 +121,7 @@ void CheckArgsReturnExpectedType() {
std::is_same<Expect,
decltype(ExplicitUniformReturnT<A, B, Expect>(0))>,
std::is_same<Expect,
- decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>,
- "");
+ decltype(ExplicitUniformReturnT<B, A, Expect>(0))>>);
static_assert(
std::conjunction_v<
std::is_same<Expect,
@@ -132,8 +129,7 @@ void CheckArgsReturnExpectedType() {
absl::IntervalOpenOpenTag, A, B, Expect>(0))>,
std::is_same<Expect,
decltype(ExplicitTaggedUniformReturnT<
- absl::IntervalOpenOpenTag, B, A, Expect>(0))>>,
- "");
+ absl::IntervalOpenOpenTag, B, A, Expect>(0))>>);
}
// Takes the type of `absl::Uniform<R>(gen)` if valid or `Invalid` otherwise.
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/examples_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/examples_test.cc
index 29c27f191fa..25c673f0f1a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/examples_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/examples_test.cc
@@ -12,7 +12,12 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <algorithm>
#include <cinttypes>
+#include <cstddef>
+#include <cstdint>
+#include <iostream>
+#include <ostream>
#include <random>
#include <sstream>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/exponential_distribution.h b/deps/v8/third_party/abseil-cpp/absl/random/exponential_distribution.h
index 67ab8663e63..21a02793911 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/exponential_distribution.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/exponential_distribution.h
@@ -17,8 +17,10 @@
#include <cassert>
#include <cmath>
+#include <cstdint>
#include <istream>
#include <limits>
+#include <ostream>
#include <type_traits>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc
index 4d076bb5e26..65fd85a1bdd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/gaussian_distribution_test.cc
@@ -17,9 +17,12 @@
#include <algorithm>
#include <cmath>
#include <cstddef>
+#include <cstdint>
#include <ios>
#include <iterator>
+#include <limits>
#include <random>
+#include <sstream>
#include <string>
#include <type_traits>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/generators_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/generators_test.cc
index c36756749de..3217a42edb0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/generators_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/generators_test.cc
@@ -18,6 +18,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/numeric/int128.h"
#include "absl/random/distributions.h"
#include "absl/random/random.h"
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 df91d9cb5fb..3ba8d9c541a 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
@@ -194,6 +194,7 @@ cc_library(
":platform",
":randen",
":seed_material",
+ "//absl/algorithm:container",
"//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
@@ -367,8 +368,9 @@ cc_library(
deps = [
":platform",
":randen_hwaes",
+ ":randen_hwaes_impl",
":randen_slow",
- "//absl/base:raw_logging_internal",
+ "//absl/base:config",
],
)
@@ -394,13 +396,11 @@ cc_library(
],
hdrs = [
"randen_detect.h",
- "randen_hwaes.h",
],
copts = ABSL_DEFAULT_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":platform",
- ":randen_hwaes_impl",
"//absl/base:config",
],
)
@@ -410,6 +410,8 @@ cc_library(
name = "randen_hwaes_impl",
srcs = [
"randen_hwaes.cc",
+ ],
+ hdrs = [
"randen_hwaes.h",
],
copts = ABSL_DEFAULT_COPTS + ABSL_RANDOM_RANDEN_COPTS + select({
@@ -421,7 +423,6 @@ cc_library(
deps = [
":platform",
"//absl/base:config",
- "//absl/base:core_headers",
"//absl/numeric:int128",
],
)
@@ -433,6 +434,7 @@ cc_binary(
],
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ "//absl/base:config",
"//absl/base:core_headers",
"//absl/random:distributions",
],
@@ -537,7 +539,8 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":explicit_seed_seq",
- "//absl/random:seed_sequences",
+ "//absl/base:config",
+ "//absl/base:core_headers",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -551,6 +554,8 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":salted_seed_seq",
+ ":seed_material",
+ "//absl/base:core_headers",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -566,6 +571,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":distribution_test_util",
+ "//absl/algorithm:container",
"//absl/base:core_headers",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -582,6 +588,7 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":fast_uniform_bits",
+ "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -621,8 +628,8 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":nonsecure_base",
+ "//absl/algorithm:container",
"//absl/container:flat_hash_set",
- "//absl/meta:type_traits",
"//absl/random",
"//absl/random:distributions",
"//absl/synchronization",
@@ -672,7 +679,6 @@ cc_test(
deps = [
":explicit_seed_seq",
":pcg_engine",
- "//absl/time",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -690,7 +696,6 @@ cc_test(
":explicit_seed_seq",
":randen_engine",
"//absl/log",
- "//absl/strings",
"//absl/time",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -705,7 +710,6 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":randen",
- "//absl/meta:type_traits",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -720,7 +724,6 @@ cc_test(
deps = [
":platform",
":randen_slow",
- "//absl/base:endian",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -738,7 +741,6 @@ cc_test(
":randen_hwaes",
":randen_hwaes_impl", # build_cleaner: keep
"//absl/log",
- "//absl/strings:str_format",
"@googletest//:gtest",
],
)
@@ -750,6 +752,7 @@ cc_test(
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":traits",
":wide_multiply",
"//absl/numeric:int128",
"@googletest//:gtest",
@@ -765,6 +768,7 @@ cc_library(
deps = [
":platform",
":randen_engine",
+ "//absl/algorithm:container",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
@@ -811,6 +815,7 @@ cc_test(
],
deps = [
":nanobenchmark",
+ "//absl/base:config",
"//absl/log",
"//absl/log:check",
"//absl/strings",
@@ -829,7 +834,6 @@ cc_test(
tags = ABSL_RANDOM_NONPORTABLE_TAGS + ["benchmark"],
deps = [
":nanobenchmark",
- ":platform",
":randen",
":randen_engine",
":randen_hwaes",
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 16df061a720..d0974f95bc7 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
@@ -1,22 +1,31 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("traits") {
public = [ "traits.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("distribution_caller") {
public = [ "distribution_caller.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
@@ -24,26 +33,28 @@ absl_source_set("distribution_caller") {
"//third_party/abseil-cpp/absl/random:mocking_access",
"//third_party/abseil-cpp/absl/utility",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("fast_uniform_bits") {
public = [ "fast_uniform_bits.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":traits",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("seed_material") {
- public = [ "seed_material.h" ]
sources = [ "seed_material.cc" ]
- if (is_win) {
- # TODO(mbonadei): In the bazel file this is -DEFAULTLIB:bcrypt.lib.
- libs = [ "bcrypt.lib" ]
- }
+ public = [ "seed_material.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":fast_uniform_bits",
"//third_party/abseil-cpp/absl/base:config",
@@ -54,44 +65,60 @@ absl_source_set("seed_material") {
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
+ if (is_win) {
+ libs = [ "bcrypt.lib" ]
+ }
}
absl_source_set("entropy_pool") {
- public = [ "entropy_pool.h" ]
sources = [ "entropy_pool.cc" ]
+ public = [ "entropy_pool.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":platform",
":randen",
":seed_material",
+ "//third_party/abseil-cpp/absl/algorithm:container",
"//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/random:seed_gen_exception",
"//third_party/abseil-cpp/absl/types:span",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("explicit_seed_seq") {
testonly = true
public = [ "explicit_seed_seq.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:endian",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("sequence_urbg") {
testonly = true
public = [ "sequence_urbg.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("salted_seed_seq") {
public = [ "salted_seed_seq.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":seed_material",
"//third_party/abseil-cpp/absl/container:inlined_vector",
@@ -99,49 +126,64 @@ absl_source_set("salted_seed_seq") {
"//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("iostream_state_saver") {
public = [ "iostream_state_saver.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("generate_real") {
public = [ "generate_real.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":fastmath",
":traits",
"//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/numeric:bits",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("fastmath") {
public = [ "fastmath.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [ "//third_party/abseil-cpp/absl/numeric:bits" ]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("wide_multiply") {
public = [ "wide_multiply.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":traits",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("nonsecure_base") {
public = [ "nonsecure_base.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":entropy_pool",
":salted_seed_seq",
@@ -150,11 +192,14 @@ absl_source_set("nonsecure_base") {
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("pcg_engine") {
public = [ "pcg_engine.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":fastmath",
":iostream_state_saver",
@@ -163,48 +208,58 @@ absl_source_set("pcg_engine") {
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("randen_engine") {
public = [ "randen_engine.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":iostream_state_saver",
":randen",
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/meta:type_traits",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("platform") {
+ sources = [ "randen_round_keys.cc" ]
public = [
"platform.h",
"randen_traits.h",
]
- sources = [ "randen_round_keys.cc" ]
- deps = [
- "//build:chromeos_buildflags",
- "//third_party/abseil-cpp/absl/base:config",
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
+ deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
absl_source_set("randen") {
- public = [ "randen.h" ]
sources = [ "randen.cc" ]
+ public = [ "randen.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":platform",
":randen_hwaes",
+ ":randen_hwaes_impl",
":randen_slow",
- "//third_party/abseil-cpp/absl/base:raw_logging_internal",
+ "//third_party/abseil-cpp/absl/base:config",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("randen_slow") {
- public = [ "randen_slow.h" ]
sources = [ "randen_slow.cc" ]
+ public = [ "randen_slow.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":platform",
"//third_party/abseil-cpp/absl/base:config",
@@ -212,55 +267,48 @@ absl_source_set("randen_slow") {
"//third_party/abseil-cpp/absl/base:endian",
"//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("randen_hwaes") {
- public = [
- "randen_detect.h",
- "randen_hwaes.h",
- ]
sources = [ "randen_detect.cc" ]
+ public = [ "randen_detect.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":platform",
- ":randen_hwaes_impl",
"//third_party/abseil-cpp/absl/base:config",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("randen_hwaes_impl") {
- sources = [
- "randen_hwaes.cc",
- "randen_hwaes.h",
+ sources = [ "randen_hwaes.cc" ]
+ public = [ "randen_hwaes.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
]
deps = [
":platform",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
-}
-
-executable("gaussian_distribution_gentables") {
- sources = [ "gaussian_distribution_gentables.cc" ]
- deps = [
- "//third_party/abseil-cpp/absl/base:core_headers",
- "//third_party/abseil-cpp/absl/random:distributions",
- ]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("distribution_test_util") {
testonly = true
+ sources = [
+ "chi_square.cc",
+ "distribution_test_util.cc",
+ ]
public = [
"chi_square.h",
"distribution_test_util.h",
]
- sources = [
- "chi_square.cc",
- "distribution_test_util.cc",
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
]
deps = [
"//third_party/abseil-cpp/absl/base:config",
@@ -271,11 +319,73 @@ absl_source_set("distribution_test_util") {
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:span",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
+}
+
+absl_test("traits_test") {
+ sources = [ "traits_test.cc" ]
+ deps = [ ":traits" ]
+}
+
+absl_test("generate_real_test") {
+ sources = [ "generate_real_test.cc" ]
+ deps = [
+ ":generate_real",
+ "//third_party/abseil-cpp/absl/flags:flag",
+ "//third_party/abseil-cpp/absl/numeric:bits",
+ ]
+}
+
+absl_test("distribution_test_util_test") {
+ sources = [ "distribution_test_util_test.cc" ]
+ deps = [ ":distribution_test_util" ]
+}
+
+absl_test("fastmath_test") {
+ sources = [ "fastmath_test.cc" ]
+ deps = [ ":fastmath" ]
+}
+
+absl_test("explicit_seed_seq_test") {
+ sources = [ "explicit_seed_seq_test.cc" ]
+ deps = [
+ ":explicit_seed_seq",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ ]
+}
+
+absl_test("salted_seed_seq_test") {
+ sources = [ "salted_seed_seq_test.cc" ]
+ deps = [
+ ":salted_seed_seq",
+ ":seed_material",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ ]
+}
+
+absl_test("chi_square_test") {
+ sources = [ "chi_square_test.cc" ]
+ deps = [
+ ":distribution_test_util",
+ "//third_party/abseil-cpp/absl/algorithm:container",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ ]
+}
+
+absl_test("fast_uniform_bits_test") {
+ sources = [ "fast_uniform_bits_test.cc" ]
+ deps = [
+ ":fast_uniform_bits",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
}
absl_source_set("mock_helpers") {
public = [ "mock_helpers.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:fast_type_id",
@@ -286,10 +396,15 @@ absl_source_set("mock_helpers") {
absl_source_set("mock_overload_set") {
testonly = true
public = [ "mock_overload_set.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":mock_helpers",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/random:mocking_bit_gen",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
@@ -298,27 +413,96 @@ absl_test("nonsecure_base_test") {
sources = [ "nonsecure_base_test.cc" ]
deps = [
":nonsecure_base",
+ "//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/container:flat_hash_set",
- "//third_party/abseil-cpp/absl/meta:type_traits",
"//third_party/abseil-cpp/absl/random",
"//third_party/abseil-cpp/absl/random:distributions",
"//third_party/abseil-cpp/absl/synchronization",
]
}
+absl_test("seed_material_test") {
+ sources = [ "seed_material_test.cc" ]
+ deps = [
+ ":seed_material",
+ "//third_party/abseil-cpp/absl/types:span",
+ ]
+}
+
+absl_test("entropy_pool_test") {
+ sources = [ "entropy_pool_test.cc" ]
+ deps = [
+ ":entropy_pool",
+ "//third_party/abseil-cpp/absl/container:flat_hash_set",
+ "//third_party/abseil-cpp/absl/synchronization",
+ ]
+}
+
+absl_test("pcg_engine_test") {
+ sources = [ "pcg_engine_test.cc" ]
+ deps = [
+ ":explicit_seed_seq",
+ ":pcg_engine",
+ ]
+}
+
+absl_test("randen_engine_test") {
+ sources = [ "randen_engine_test.cc" ]
+ deps = [
+ ":explicit_seed_seq",
+ ":randen_engine",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/time",
+ ]
+}
+
+absl_test("randen_test") {
+ sources = [ "randen_test.cc" ]
+ deps = [ ":randen" ]
+}
+
+absl_test("randen_slow_test") {
+ sources = [ "randen_slow_test.cc" ]
+ deps = [
+ ":platform",
+ ":randen_slow",
+ ]
+}
+
+# randen_hwaes_test is excluded because defines its own main function
+# absl_test("randen_hwaes_test")
+
+absl_test("wide_multiply_test") {
+ sources = [ "wide_multiply_test.cc" ]
+ deps = [
+ ":traits",
+ ":wide_multiply",
+ "//third_party/abseil-cpp/absl/numeric:int128",
+ ]
+}
+
+# Only used for benchmarking
+# absl_source_set("nanobenchmark")
+
absl_source_set("uniform_helper") {
public = [ "uniform_helper.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":traits",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/meta:type_traits",
- "//third_party/abseil-cpp/absl/numeric:int128",
]
- visibility = [ "//third_party/abseil-cpp/absl/random/*" ]
}
absl_source_set("mock_validators") {
public = [ "mock_validators.h" ]
+ visibility = [
+ ":*",
+ "//third_party/abseil-cpp/absl/random:*",
+ ]
deps = [
":iostream_state_saver",
":uniform_helper",
@@ -328,3 +512,19 @@ absl_source_set("mock_validators") {
"//third_party/abseil-cpp/absl/strings:string_view",
]
}
+
+# nanobenchmark_test is excluded because defines its own main function
+# absl_test("nanobenchmark_test")
+
+# randen_benchmarks is excluded because defines its own main function
+# absl_test("randen_benchmarks")
+
+absl_test("iostream_state_saver_test") {
+ sources = [ "iostream_state_saver_test.cc" ]
+ deps = [ ":iostream_state_saver" ]
+}
+
+absl_test("uniform_helper_test") {
+ sources = [ "uniform_helper_test.cc" ]
+ deps = [ ":uniform_helper" ]
+}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square.cc
index 4cfc4d7c528..481c1c3da32 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square.cc
@@ -16,6 +16,7 @@
#include <cmath>
+#include "absl/base/config.h"
#include "absl/random/internal/distribution_test_util.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square_test.cc
index 29fd988db1a..964cd222ad6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/chi_square_test.cc
@@ -22,6 +22,7 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/algorithm/container.h"
#include "absl/base/macros.h"
using absl::random_internal::ChiSquare;
@@ -160,7 +161,7 @@ TEST(ChiSquareTest, CalcChiSquare) {
for (const auto& spec : specs) {
SCOPED_TRACE(spec.line);
double chi_square = 0;
- for (int i = 0; i < spec.expected.size(); ++i) {
+ for (size_t i = 0; i < spec.expected.size(); ++i) {
const double diff = spec.actual[i] - spec.expected[i];
chi_square += (diff * diff) / spec.expected[i];
}
@@ -176,8 +177,8 @@ TEST(ChiSquareTest, CalcChiSquareInt64) {
// $ python -c "import scipy.stats
// > print scipy.stats.chisquare([910293487, 910292491, 910216780])[0]"
// 4.25410123524
- double sum = std::accumulate(std::begin(data), std::end(data), double{0});
- size_t n = std::distance(std::begin(data), std::end(data));
+ double sum = absl::c_accumulate(data, double{0});
+ size_t n = absl::c_distance(data);
double a = ChiSquareWithExpected(std::begin(data), std::end(data), sum / n);
EXPECT_NEAR(4.254101, a, 1e-6);
@@ -294,7 +295,7 @@ TEST(ChiSquareTest, TableData) {
/*100*/ {118.498, 124.342, 129.561, 135.807, 149.449} /**/};
// 0.90 0.95 0.975 0.99 0.999
- for (int i = 0; i < ABSL_ARRAYSIZE(data); i++) {
+ for (size_t i = 0; i < std::size(data); i++) {
const double E = 0.0001;
EXPECT_NEAR(ChiSquarePValue(data[i][0], i + 1), 0.10, E)
<< i << " " << data[i][0];
@@ -343,8 +344,8 @@ TEST(ChiSquareTest, DiceRolls) {
// The dof value of 4, @95% = 9.488 (see above test)
// The dof value of 5, @95% = 11.070
const int rolls[6] = {22, 11, 17, 14, 20, 18};
- double sum = std::accumulate(std::begin(rolls), std::end(rolls), double{0});
- size_t n = std::distance(std::begin(rolls), std::end(rolls));
+ double sum = absl::c_accumulate(rolls, double{0});
+ size_t n = absl::c_distance(rolls);
double a = ChiSquareWithExpected(std::begin(rolls), std::end(rolls), sum / n);
EXPECT_NEAR(a, 4.70588, 1e-5);
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util.cc
index 9fa37bd69a0..4ae6fcbfd75 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util.cc
@@ -14,15 +14,20 @@
#include "absl/random/internal/distribution_test_util.h"
+#include <algorithm>
#include <cassert>
#include <cmath>
+#include <limits>
+#include <ostream>
#include <string>
-#include <vector>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util_test.cc
index c49d44fb479..1b66879ffcb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/distribution_test_util_test.cc
@@ -14,6 +14,9 @@
#include "absl/random/internal/distribution_test_util.h"
+#include <utility>
+#include <vector>
+
#include "gtest/gtest.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc
index 13867005129..21f83052362 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/entropy_pool.cc
@@ -20,6 +20,7 @@
#include <cstring>
#include <iterator>
+#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
#include "absl/base/call_once.h"
#include "absl/base/config.h"
@@ -56,21 +57,21 @@ class alignas(std::max(size_t{ABSL_CACHELINE_SIZE}, size_t{32}))
void Init(absl::Span<const uint32_t> data) {
SpinLockHolder l(mu_); // Always uncontested.
- std::copy(data.begin(), data.end(), std::begin(state_));
+ absl::c_copy(data, std::begin(state_));
next_ = kState;
}
// Copy bytes into out.
void Fill(uint8_t* out, size_t bytes) ABSL_LOCKS_EXCLUDED(mu_);
- inline void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
+ void MaybeRefill() ABSL_EXCLUSIVE_LOCKS_REQUIRED(mu_) {
if (next_ >= kState) {
next_ = kCapacity;
impl_.Generate(state_);
}
}
- inline size_t available() const ABSL_SHARED_LOCKS_REQUIRED(mu_) {
+ size_t available() const ABSL_SHARED_LOCKS_REQUIRED(mu_) {
return kState - next_;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc
index 68c9ab2ff39..0052d41d43d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/explicit_seed_seq_test.cc
@@ -14,13 +14,17 @@
#include "absl/random/internal/explicit_seed_seq.h"
+#include <cstddef>
+#include <cstdint>
#include <iterator>
#include <random>
#include <utility>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
-#include "absl/random/seed_sequences.h"
+#include "absl/base/config.h"
+#include "absl/base/macros.h"
namespace {
@@ -44,13 +48,13 @@ bool ConformsToInterface() {
// Check that param() and size() return state provided to constructor.
{
uint32_t init_array[] = {1, 2, 3, 4, 5};
- Sseq seq(init_array, &init_array[ABSL_ARRAYSIZE(init_array)]);
- EXPECT_EQ(seq.size(), ABSL_ARRAYSIZE(init_array));
+ Sseq seq(init_array, &init_array[std::size(init_array)]);
+ EXPECT_EQ(seq.size(), std::size(init_array));
- uint32_t state_array[ABSL_ARRAYSIZE(init_array)];
+ uint32_t state_array[std::size(init_array)];
seq.param(state_array);
- for (int i = 0; i < ABSL_ARRAYSIZE(state_array); i++) {
+ for (int i = 0; i < std::size(state_array); i++) {
EXPECT_EQ(state_array[i], i + 1);
}
}
@@ -59,7 +63,7 @@ bool ConformsToInterface() {
Sseq seq;
uint32_t seeds[5];
- seq.generate(seeds, &seeds[ABSL_ARRAYSIZE(seeds)]);
+ seq.generate(seeds, &seeds[std::size(seeds)]);
}
return true;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc
index 34c25206b3b..3c33d417505 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/fast_uniform_bits_test.cc
@@ -14,9 +14,13 @@
#include "absl/random/internal/fast_uniform_bits.h"
+#include <cstddef>
+#include <cstdint>
+#include <limits>
#include <random>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc
index 0b9ae5e6df1..cd33d7a2110 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/fastmath_test.cc
@@ -14,6 +14,9 @@
#include "absl/random/internal/fastmath.h"
+#include <cmath>
+#include <cstdint>
+
#include "gtest/gtest.h"
#if defined(__EMSCRIPTEN__)
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc
index 3561251d4b8..967a327b7f0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/gaussian_distribution_gentables.cc
@@ -21,7 +21,9 @@
#include <iostream>
#include <limits>
#include <string>
+#include <type_traits>
+#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/random/gaussian_distribution.h"
@@ -79,10 +81,11 @@ TableGenerator::TableGenerator() {
// The constants here should match the values in gaussian_distribution.h
static constexpr int kC = kMask + 1;
- static_assert((ABSL_ARRAYSIZE(tables_.x) == kC + 1),
+ static_assert((std::extent_v<decltype(tables_.x)> == kC + 1),
"xArray must be length kMask + 2");
- static_assert((ABSL_ARRAYSIZE(tables_.x) == ABSL_ARRAYSIZE(tables_.f)),
+ static_assert((std::extent_v<decltype(tables_.x)> ==
+ std::extent_v<decltype(tables_.f)>),
"fx and x arrays must be identical length");
auto f = [](double x) { return std::exp(-0.5 * x * x); };
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 e016946eb41..6af0455e345 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
@@ -85,8 +85,7 @@ inline RealType GenerateRealFromBits(uint64_t bits, int exp_bias = 0) {
static_assert((std::is_same_v<SignedTag, GeneratePositiveTag> ||
std::is_same_v<SignedTag, GenerateNegativeTag> ||
- std::is_same_v<SignedTag, GenerateSignedTag>),
- "");
+ std::is_same_v<SignedTag, GenerateSignedTag>));
static constexpr int kExp = std::numeric_limits<real_type>::digits - 1;
static constexpr uint_type kMask = (static_cast<uint_type>(1) << kExp) - 1u;
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h
index fcd45a1c6c5..05d9f839e1a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver.h
@@ -39,7 +39,7 @@ class null_state_saver {
using flags_type = std::ios_base::fmtflags;
null_state_saver(T&, flags_type) {}
- ~null_state_saver() {}
+ ~null_state_saver() = default;
};
// ostream_state_saver is a RAII object to save and restore the common
@@ -186,7 +186,7 @@ struct stream_u128_helper;
template <>
struct stream_u128_helper<absl::uint128> {
template <typename IStream>
- inline absl::uint128 read(IStream& in) {
+ absl::uint128 read(IStream& in) {
uint64_t h = 0;
uint64_t l = 0;
in >> h >> l;
@@ -194,7 +194,7 @@ struct stream_u128_helper<absl::uint128> {
}
template <typename OStream>
- inline void write(absl::uint128 val, OStream& out) {
+ void write(absl::uint128 val, OStream& out) {
uint64_t h = absl::Uint128High64(val);
uint64_t l = absl::Uint128Low64(val);
out << h << out.fill() << l;
@@ -205,7 +205,7 @@ struct stream_u128_helper<absl::uint128> {
template <>
struct stream_u128_helper<__uint128_t> {
template <typename IStream>
- inline __uint128_t read(IStream& in) {
+ __uint128_t read(IStream& in) {
uint64_t h = 0;
uint64_t l = 0;
in >> h >> l;
@@ -213,7 +213,7 @@ struct stream_u128_helper<__uint128_t> {
}
template <typename OStream>
- inline void write(__uint128_t val, OStream& out) {
+ void write(__uint128_t val, OStream& out) {
uint64_t h = static_cast<uint64_t>(val >> 64u);
uint64_t l = static_cast<uint64_t>(val);
out << h << out.fill() << l;
@@ -223,7 +223,7 @@ struct stream_u128_helper<__uint128_t> {
template <typename FloatType, typename IStream>
inline FloatType read_floating_point(IStream& is) {
- static_assert(std::is_floating_point_v<FloatType>, "");
+ static_assert(std::is_floating_point_v<FloatType>);
FloatType dest;
is >> dest;
// Parsing a double value may report a subnormal value as an error
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc
index a9bf5fc373d..a196ace76ec 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/iostream_state_saver_test.cc
@@ -14,9 +14,13 @@
#include "absl/random/internal/iostream_state_saver.h"
-#include <errno.h>
#include <stdio.h>
+#include <cmath>
+#include <cstdint>
+#include <cstdlib>
+#include <ios>
+#include <limits>
#include <sstream>
#include <string>
#include <type_traits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc
index 0f31a7d5d2d..0cf657b4851 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.cc
@@ -17,7 +17,6 @@
#include <sys/types.h>
#include <algorithm> // sort
-#include <atomic>
#include <cstddef>
#include <cstdint>
#include <cstdlib>
@@ -27,7 +26,9 @@
#include <utility>
#include <vector>
+#include "absl/algorithm/container.h"
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_engine.h"
@@ -548,7 +549,7 @@ using InputVec = std::vector<FuncInput>;
// Returns vector of unique input values.
InputVec UniqueInputs(const FuncInput* inputs, const size_t num_inputs) {
InputVec unique(inputs, inputs + num_inputs);
- std::sort(unique.begin(), unique.end());
+ absl::c_sort(unique);
unique.erase(std::unique(unique.begin(), unique.end()), unique.end());
return unique;
}
@@ -607,7 +608,7 @@ InputVec ReplicateInputs(const FuncInput* inputs, const size_t num_inputs,
full.insert(full.end(), inputs, inputs + num_inputs);
}
absl::random_internal::randen_engine<uint32_t> rng;
- std::shuffle(full.begin(), full.end(), rng);
+ absl::c_shuffle(full, rng);
return full;
}
@@ -615,20 +616,20 @@ InputVec ReplicateInputs(const FuncInput* inputs, const size_t num_inputs,
// randomly selected occurrences of "input_to_skip" removed.
void FillSubset(const InputVec& full, const FuncInput input_to_skip,
const size_t num_skip, InputVec* subset) {
- const size_t count = std::count(full.begin(), full.end(), input_to_skip);
+ const ptrdiff_t count = absl::c_count(full, input_to_skip);
// Generate num_skip random indices: which occurrence to skip.
std::vector<uint32_t> omit;
// Replacement for std::iota, not yet available in MSVC builds.
omit.reserve(count);
- for (size_t i = 0; i < count; ++i) {
+ for (ptrdiff_t i = 0; i < count; ++i) {
omit.push_back(i);
}
// omit[] is the same on every call, but that's OK because they identify the
// Nth instance of input_to_skip, so the position within full[] differs.
absl::random_internal::randen_engine<uint32_t> rng;
- std::shuffle(omit.begin(), omit.end(), rng);
+ absl::c_shuffle(omit, rng);
omit.resize(num_skip);
- std::sort(omit.begin(), omit.end());
+ absl::c_sort(omit);
uint32_t occurrence = ~0u; // 0 after preincrement
size_t idx_omit = 0; // cursor within omit[]
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.h
index a5097ba27b0..9a1cb590894 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark.h
@@ -124,7 +124,7 @@ struct Result {
// Ensures the thread is running on the specified cpu, and no others.
// Reduces noise due to desynchronized socket RDTSC and context switches.
// If "cpu" is negative, pin to the currently running core.
-void PinThreadToCPU(const int cpu = -1);
+void PinThreadToCPU(int cpu = -1);
// Returns tick rate, useful for converting measurements to seconds. Invariant
// means the tick counter frequency is independent of CPU throttling or sleep.
@@ -143,9 +143,8 @@ double InvariantTicksPerSecond();
// uniform distribution over [0, 4) could be represented as {3,0,2,1}.
// Returns how many Result were written to "results": one per unique input, or
// zero if the measurement failed (an error message goes to stderr).
-size_t Measure(const Func func, const void* arg, const FuncInput* inputs,
- const size_t num_inputs, Result* results,
- const Params& p = Params());
+size_t Measure(Func func, const void* arg, const FuncInput* inputs,
+ size_t num_inputs, Result* results, const Params& p = Params());
// Calls operator() of the given closure (lambda function).
template <class Closure>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
index d4f1028dbd3..fc3f996c437 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/nanobenchmark_test.cc
@@ -14,6 +14,10 @@
#include "absl/random/internal/nanobenchmark.h"
+#include <cstddef>
+#include <cstdint>
+
+#include "absl/base/config.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
#include "absl/strings/numbers.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/nonsecure_base_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/nonsecure_base_test.cc
index 75f40bd9e7a..61f49cdfdb9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/nonsecure_base_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/nonsecure_base_test.cc
@@ -25,8 +25,8 @@
#include <vector>
#include "gtest/gtest.h"
+#include "absl/algorithm/container.h"
#include "absl/container/flat_hash_set.h"
-#include "absl/meta/type_traits.h"
#include "absl/random/distributions.h"
#include "absl/random/random.h"
#include "absl/synchronization/mutex.h"
@@ -213,7 +213,7 @@ TEST(NonsecureURBGBase, DistinctSequencesPerThread) {
absl::BitGen gen;
std::vector<result_type> v(kValuesPerThread);
- std::generate(v.begin(), v.end(), [&]() { return gen(); });
+ absl::c_generate(v, [&]() { return gen(); });
absl::MutexLock l(mu);
data.push_back(std::move(v));
});
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine.h
index 5184c866d46..f85a1acdd22 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine.h
@@ -15,6 +15,12 @@
#ifndef ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
#define ABSL_RANDOM_INTERNAL_PCG_ENGINE_H_
+#include <cstddef>
+#include <cstdint>
+#include <ios>
+#include <istream>
+#include <limits>
+#include <ostream>
#include <type_traits>
#include "absl/base/config.h"
@@ -176,12 +182,12 @@ class pcg_engine {
state_type state_;
// Returns the linear-congruential generator next state.
- static inline constexpr state_type lcg(state_type s) {
+ static constexpr state_type lcg(state_type s) {
return s * Params::multiplier() + Params::increment();
}
// Returns the linear-congruential arbitrary seek state.
- inline state_type advance(state_type s, uint64_t n) const {
+ state_type advance(state_type s, uint64_t n) const {
state_type mult = Params::multiplier();
state_type inc = Params::increment();
state_type m = 1;
@@ -221,10 +227,10 @@ template <uint64_t kMultA, uint64_t kMultB, uint64_t kIncA, uint64_t kIncB>
class pcg128_params {
public:
using state_type = absl::uint128;
- static inline constexpr state_type multiplier() {
+ static constexpr state_type multiplier() {
return absl::MakeUint128(kMultA, kMultB);
}
- static inline constexpr state_type increment() {
+ static constexpr state_type increment() {
return absl::MakeUint128(kIncA, kIncB);
}
};
@@ -235,7 +241,7 @@ struct pcg_xsl_rr_128_64 {
using state_type = absl::uint128;
using result_type = uint64_t;
- inline uint64_t operator()(state_type state) {
+ uint64_t operator()(state_type state) {
// This is equivalent to the xsl_rr_128_64 mixing function.
uint64_t rotate = static_cast<uint64_t>(state >> 122u);
state ^= state >> 64;
@@ -250,8 +256,8 @@ template <uint64_t kMult, uint64_t kInc>
class pcg64_params {
public:
using state_type = uint64_t;
- static inline constexpr state_type multiplier() { return kMult; }
- static inline constexpr state_type increment() { return kInc; }
+ static constexpr state_type multiplier() { return kMult; }
+ static constexpr state_type increment() { return kInc; }
};
// Implementation of the PCG xsh_rr_64_32 64-bit mixing function, which accepts
@@ -259,7 +265,7 @@ class pcg64_params {
struct pcg_xsh_rr_64_32 {
using state_type = uint64_t;
using result_type = uint32_t;
- inline uint32_t operator()(uint64_t state) {
+ uint32_t operator()(uint64_t state) {
return rotr(static_cast<uint32_t>(((state >> 18) ^ state) >> 27),
state >> 59);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine_test.cc
index 1861fb6fa08..9b34cfe7eb3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/pcg_engine_test.cc
@@ -16,14 +16,15 @@
#include <algorithm>
#include <bitset>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
#include <random>
#include <sstream>
#include <type_traits>
-#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/random/internal/explicit_seed_seq.h"
-#include "absl/time/clock.h"
#define UPDATE_GOLDEN 0
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.cc
index c1bc0444354..e42013c9e27 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen.cc
@@ -14,8 +14,11 @@
#include "absl/random/internal/randen.h"
-#include "absl/base/internal/raw_logging.h"
+#include "absl/base/config.h"
+#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_detect.h"
+#include "absl/random/internal/randen_hwaes.h"
+#include "absl/random/internal/randen_slow.h"
// RANDen = RANDom generator or beetroots in Swiss High German.
// 'Strong' (well-distributed, unpredictable, backtracking-resistant) random
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 9ff4a7a5547..619233337c2 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
@@ -44,7 +44,7 @@ class Randen {
// Generate updates the randen sponge. The outer portion of the sponge
// (kCapacityBytes .. kStateBytes) may be consumed as PRNG state.
// REQUIRES: state points to kStateBytes of state.
- inline void Generate(void* state) const {
+ void Generate(void* state) const {
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
// HW AES Dispatch.
if (has_crypto_) {
@@ -65,7 +65,7 @@ class Randen {
// absorb returns, Generate must be called before the state may be consumed.
// REQUIRES: seed points to kSeedBytes of seed.
// REQUIRES: state points to kStateBytes of state.
- inline void Absorb(const void* seed, void* state) const {
+ void Absorb(const void* seed, void* state) const {
#if ABSL_RANDOM_INTERNAL_AES_DISPATCH
// HW AES Dispatch.
if (has_crypto_) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_benchmarks.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_benchmarks.cc
index 1acc2c3d415..51e6a502de4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_benchmarks.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_benchmarks.cc
@@ -18,7 +18,6 @@
#include "absl/base/internal/raw_logging.h"
#include "absl/random/internal/nanobenchmark.h"
-#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen.h"
#include "absl/random/internal/randen_detect.h"
#include "absl/random/internal/randen_engine.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_detect.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
index fc8c6736032..83bde75f3c8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_detect.cc
@@ -19,22 +19,19 @@
#include "absl/random/internal/randen_detect.h"
+#include <optional> // IWYU pragma: keep
+
+#include "absl/base/config.h"
+#include "absl/random/internal/platform.h"
+
#if defined(__APPLE__) && defined(__aarch64__)
-#if defined(__has_include)
#if __has_include(<arm/cpu_capabilities_public.h>)
#include <arm/cpu_capabilities_public.h>
#endif
-#endif
#include <sys/sysctl.h>
#include <sys/types.h>
#endif
-#include <cstdint>
-#include <cstring>
-#include <optional> // IWYU pragma: keep
-
-#include "absl/random/internal/platform.h"
-
#if !defined(__UCLIBC__) && defined(__GLIBC__) && \
(__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 16))
#define ABSL_HAVE_GETAUXVAL
@@ -91,6 +88,8 @@ static uint32_t GetAuxval(uint32_t hwcap_type) {
#if defined(ABSL_INTERNAL_USE_ANDROID_GETAUXVAL)
#include <dlfcn.h>
+#include <cstring>
+
static uint32_t GetAuxval(uint32_t hwcap_type) {
// NOLINTNEXTLINE(runtime/int)
typedef unsigned long (*getauxval_func_t)(unsigned long);
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 525d40ac46d..a33736eca52 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
@@ -17,7 +17,9 @@
#include <algorithm>
#include <cinttypes>
+#include <cstdint>
#include <cstdlib>
+#include <cstring>
#include <istream>
#include <iterator>
#include <limits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc
index 9709cce8adc..5488bd522b6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_engine_test.cc
@@ -16,15 +16,16 @@
#include <algorithm>
#include <bitset>
+#include <cmath>
+#include <cstddef>
+#include <cstdint>
#include <random>
#include <sstream>
#include <type_traits>
-#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/log/log.h"
#include "absl/random/internal/explicit_seed_seq.h"
-#include "absl/strings/str_cat.h"
#include "absl/time/clock.h"
#define UPDATE_GOLDEN 0
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc
index f535f4c53aa..f8dd358c8f6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes.cc
@@ -19,10 +19,9 @@
#include "absl/random/internal/randen_hwaes.h"
-#include <cstdint>
#include <cstring>
-#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/numeric/int128.h"
#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_traits.h"
@@ -220,11 +219,11 @@ namespace {
class Vector128 {
public:
// Convert from/to intrinsics.
- inline explicit Vector128(const __m128i& v) : data_(v) {}
+ explicit Vector128(const __m128i& v) : data_(v) {}
- inline __m128i data() const { return data_; }
+ __m128i data() const { return data_; }
- inline Vector128& operator^=(const Vector128& other) {
+ Vector128& operator^=(const Vector128& other) {
data_ = _mm_xor_si128(data_, other.data());
return *this;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
index 037897292c3..956e9d69049 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_hwaes_test.cc
@@ -14,13 +14,14 @@
#include "absl/random/internal/randen_hwaes.h"
-#include "gmock/gmock.h"
+#include <cstdint>
+#include <cstring>
+
#include "gtest/gtest.h"
#include "absl/log/log.h"
#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_detect.h"
#include "absl/random/internal/randen_traits.h"
-#include "absl/strings/str_format.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc
index 5fb3ca556db..27a97b56451 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_round_keys.cc
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstddef>
+
+#include "absl/base/config.h"
#include "absl/random/internal/randen_traits.h"
// This file contains only the round keys for randen.
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow.cc
index 9bfd2a40922..d2b7da3c2cb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow.cc
@@ -19,7 +19,8 @@
#include <cstring>
#include "absl/base/attributes.h"
-#include "absl/base/internal/endian.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/endian.h" // IWYU pragma: keep
#include "absl/numeric/int128.h"
#include "absl/random/internal/platform.h"
#include "absl/random/internal/randen_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc
index ed6039586c0..b9d54aac751 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_slow_test.cc
@@ -14,10 +14,10 @@
#include "absl/random/internal/randen_slow.h"
+#include <cstdint>
#include <cstring>
#include "gtest/gtest.h"
-#include "absl/base/internal/endian.h"
#include "absl/random/internal/randen_traits.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_test.cc
index 44bd907a443..ff7365b3b29 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/randen_test.cc
@@ -14,11 +14,11 @@
#include "absl/random/internal/randen.h"
+#include <cstdint>
#include <cstring>
#include <type_traits>
#include "gtest/gtest.h"
-#include "absl/meta/type_traits.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq_test.cc
index 6f48c61915a..3e8dfeb8e26 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/salted_seed_seq_test.cc
@@ -14,6 +14,8 @@
#include "absl/random/internal/salted_seed_seq.h"
+#include <cstddef>
+#include <cstdint>
#include <iterator>
#include <random>
#include <utility>
@@ -21,6 +23,8 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/macros.h"
+#include "absl/random/internal/seed_material.h"
using absl::random_internal::GetSaltMaterial;
using absl::random_internal::MakeSaltedSeedSeq;
@@ -49,12 +53,12 @@ void ConformsToInterface() {
{
uint32_t init_array[] = {1, 2, 3, 4, 5};
Sseq seq(std::begin(init_array), std::end(init_array));
- EXPECT_EQ(seq.size(), ABSL_ARRAYSIZE(init_array));
+ EXPECT_EQ(seq.size(), std::size(init_array));
std::vector<uint32_t> state_vector;
seq.param(std::back_inserter(state_vector));
- EXPECT_EQ(state_vector.size(), ABSL_ARRAYSIZE(init_array));
+ EXPECT_EQ(state_vector.size(), std::size(init_array));
for (int i = 0; i < state_vector.size(); i++) {
EXPECT_EQ(state_vector[i], i + 1);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/seed_material.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/seed_material.cc
index f509926d538..75b9e295e92 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/seed_material.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/seed_material.cc
@@ -16,12 +16,6 @@
#include <fcntl.h>
-#ifndef _WIN32
-#include <unistd.h>
-#else
-#include <io.h>
-#endif
-
#include <algorithm>
#include <cassert>
#include <cerrno>
@@ -35,12 +29,16 @@
#include "absl/base/config.h"
#include "absl/base/dynamic_annotations.h"
#include "absl/base/internal/raw_logging.h"
-#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
#include "absl/strings/string_view.h"
-#include "absl/strings/strip.h"
#include "absl/types/span.h"
+#ifndef _WIN32
+#include <unistd.h>
+#else
+#include <io.h>
+#endif
+
#if defined(_WIN32)
#include <windows.h>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/sequence_urbg.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/sequence_urbg.h
index bc96a12cd29..a7acd9e6deb 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/sequence_urbg.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/sequence_urbg.h
@@ -17,6 +17,7 @@
#include <cstdint>
#include <cstring>
+#include <initializer_list>
#include <limits>
#include <type_traits>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/traits.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/traits.h
index 8bde0ce5430..8404d93fb70 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/traits.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/traits.h
@@ -15,6 +15,7 @@
#ifndef ABSL_RANDOM_INTERNAL_TRAITS_H_
#define ABSL_RANDOM_INTERNAL_TRAITS_H_
+#include <cstddef>
#include <cstdint>
#include <limits>
#include <type_traits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc
index f03bf2cd2e9..e38b3b1cb8f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/uniform_helper_test.cc
@@ -16,7 +16,7 @@
#include <cmath>
#include <cstdint>
-#include <random>
+#include <limits>
#include <type_traits>
#include "gtest/gtest.h"
@@ -217,8 +217,7 @@ void CheckArgsInferType() {
static_assert(
std::conjunction_v<
std::is_same<Expect, decltype(InferredUniformReturnT<A, B>(0))>,
- std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>,
- "");
+ std::is_same<Expect, decltype(InferredUniformReturnT<B, A>(0))>>);
}
TEST_F(UniformHelperTest, UniformTypeInference) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply.h b/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply.h
index f2a5033058a..9cf17a980ad 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply.h
@@ -15,21 +15,22 @@
#ifndef ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
#define ABSL_RANDOM_INTERNAL_WIDE_MULTIPLY_H_
+#include <cstddef>
#include <cstdint>
#include <limits>
#include <type_traits>
+#include "absl/base/config.h"
+#include "absl/numeric/bits.h"
+#include "absl/numeric/int128.h"
+#include "absl/random/internal/traits.h"
+
#if (defined(_WIN32) || defined(_WIN64)) && defined(_M_IA64)
#include <intrin.h> // NOLINT(build/include_order)
#pragma intrinsic(_umul128)
#define ABSL_INTERNAL_USE_UMUL128 1
#endif
-#include "absl/base/config.h"
-#include "absl/numeric/bits.h"
-#include "absl/numeric/int128.h"
-#include "absl/random/internal/traits.h"
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace random_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc
index f8ee35c03ea..caf5ab429f3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/internal/wide_multiply_test.cc
@@ -17,6 +17,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/numeric/int128.h"
+#include "absl/random/internal/traits.h"
using absl::random_internal::MultiplyU128ToU256;
using absl::random_internal::U256;
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc
index 2530c9ed294..591b5b37e48 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/log_uniform_int_distribution_test.cc
@@ -14,9 +14,12 @@
#include "absl/random/log_uniform_int_distribution.h"
+#include <algorithm>
+#include <cmath>
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <limits>
#include <random>
#include <sstream>
#include <string>
@@ -24,6 +27,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/base/macros.h"
#include "absl/log/log.h"
#include "absl/random/internal/chi_square.h"
#include "absl/random/internal/distribution_test_util.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc
index 3a1d238e4d8..e8ee3643628 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/poisson_distribution_test.cc
@@ -15,9 +15,11 @@
#include "absl/random/poisson_distribution.h"
#include <algorithm>
+#include <cmath>
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <limits>
#include <random>
#include <sstream>
#include <string>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/seed_gen_exception.cc b/deps/v8/third_party/abseil-cpp/absl/random/seed_gen_exception.cc
index 6fb4ad37665..2b6f0901837 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/seed_gen_exception.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/seed_gen_exception.cc
@@ -14,6 +14,8 @@
#include "absl/random/seed_gen_exception.h"
+#include <exception>
+
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences.h b/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences.h
index dacc5b90c02..a8d953b8111 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences.h
+++ b/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences.h
@@ -26,6 +26,7 @@
#define ABSL_RANDOM_SEED_SEQUENCES_H_
#include <iterator>
+#include <ostream>
#include <random>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences_test.cc
index fe1100bda0d..1a218a71d9d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/seed_sequences_test.cc
@@ -14,8 +14,12 @@
#include "absl/random/seed_sequences.h"
+#include <cstddef>
+#include <cstdint>
+#include <iostream>
#include <iterator>
#include <random>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc
index 98da12b56f6..b055833c23e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/uniform_int_distribution_test.cc
@@ -15,8 +15,10 @@
#include "absl/random/uniform_int_distribution.h"
#include <cmath>
+#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <limits>
#include <random>
#include <sstream>
#include <string>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc
index 5193b8cef77..11e1d6581bd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/uniform_real_distribution_test.cc
@@ -16,8 +16,10 @@
#include <cfloat>
#include <cmath>
+#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <limits>
#include <random>
#include <sstream>
#include <string>
diff --git a/deps/v8/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc b/deps/v8/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc
index 71548cada83..f29aca5935a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/random/zipf_distribution_test.cc
@@ -15,10 +15,14 @@
#include "absl/random/zipf_distribution.h"
#include <algorithm>
+#include <cassert>
+#include <cmath>
#include <cstddef>
#include <cstdint>
#include <iterator>
+#include <limits>
#include <random>
+#include <sstream>
#include <string>
#include <utility>
#include <vector>
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 287c9e8ffb7..5a611ec9f9e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/status/BUILD.bazel
@@ -164,6 +164,7 @@ cc_binary(
deps = [
":status",
":statusor",
+ "//absl/base:core_headers",
"@google_benchmark//:benchmark_main",
],
)
@@ -234,7 +235,6 @@ cc_test(
":status_builder",
":status_macros",
":statusor",
- "//absl/base:core_headers",
"//absl/strings:string_view",
"//absl/types:source_location",
"@googletest//:gtest",
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 47cfa2be331..1b7ba78353b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/status/BUILD.gn
@@ -1,20 +1,22 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("status") {
- public = [
- "status.h",
- "status_payload_printer.h",
- ]
sources = [
"internal/status_internal.cc",
"internal/status_internal.h",
"status.cc",
"status_payload_printer.cc",
]
+ public = [
+ "status.h",
+ "status_payload_printer.h",
+ ]
deps = [
"//third_party/abseil-cpp/absl/base:atomic_hook",
"//third_party/abseil-cpp/absl/base:config",
@@ -48,16 +50,17 @@ absl_test("status_test") {
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:str_format",
+ "//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:source_location",
]
}
absl_source_set("statusor") {
- public = [ "statusor.h" ]
sources = [
"internal/statusor_internal.h",
"statusor.cc",
]
+ public = [ "statusor.h" ]
deps = [
":status",
"//third_party/abseil-cpp/absl/base",
@@ -105,6 +108,7 @@ absl_source_set("status_builder") {
"//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:cord",
"//third_party/abseil-cpp/absl/strings:internal",
+ "//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/strings:stringify_stream",
"//third_party/abseil-cpp/absl/time",
"//third_party/abseil-cpp/absl/types:source_location",
@@ -124,6 +128,7 @@ absl_test("status_builder_test") {
"//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",
]
}
@@ -147,7 +152,6 @@ absl_test("status_macros_test") {
":status_builder",
":status_macros",
":statusor",
- "//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/strings:string_view",
"//third_party/abseil-cpp/absl/types:source_location",
]
@@ -155,11 +159,11 @@ absl_test("status_macros_test") {
absl_source_set("status_matchers") {
testonly = true
- public = [ "status_matchers.h" ]
sources = [
"internal/status_matchers.cc",
"internal/status_matchers.h",
]
+ public = [ "status_matchers.h" ]
deps = [
":status",
":statusor",
@@ -178,5 +182,17 @@ absl_test("status_matchers_test") {
":status_matchers",
":statusor",
"//third_party/abseil-cpp/absl/strings",
+ "//third_party/abseil-cpp/absl/strings:string_view",
+ ]
+}
+
+absl_test("status_matchers_with_unqualified_macros_test") {
+ sources = [ "status_matchers_test.cc" ]
+ deps = [
+ ":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/internal/status_internal.cc b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.cc
index f58519be0e6..77f3ff78ff0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.cc
@@ -20,6 +20,7 @@
#include <cstdint>
#include <cstdio>
#include <cstring>
+#include <iterator>
#include <memory>
#include <optional>
#include <string>
@@ -32,8 +33,8 @@
#include "absl/debugging/leak_check.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
+#include "absl/functional/function_ref.h"
#include "absl/hash/hash.h"
-#include "absl/memory/memory.h"
#include "absl/status/status.h"
#include "absl/status/status_payload_printer.h"
#include "absl/strings/cord.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.h b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.h
index 767f88f2485..1cc87aba4ea 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_internal.h
@@ -29,6 +29,7 @@
#include "absl/base/config.h"
#include "absl/base/nullability.h"
#include "absl/container/inlined_vector.h"
+#include "absl/functional/function_ref.h"
#include "absl/strings/cord.h"
#include "absl/strings/string_view.h"
#include "absl/types/optional.h"
@@ -73,6 +74,7 @@ class StatusPrivateAccessor;
class StatusPrivateAccessorForStatusBuilder;
#endif // !SWIG
+#ifndef SWIG
// Container for status payloads.
struct Payload {
std::string type_url;
@@ -81,6 +83,9 @@ struct Payload {
using Payloads = absl::InlinedVector<Payload, 1>;
+template <typename T>
+using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>>;
+
// Reference-counted representation of Status data.
class StatusRep {
public:
@@ -91,8 +96,7 @@ class StatusRep {
message_(message_arg),
payloads_(std::move(payloads_arg)) {}
- template <typename String,
- typename = std::enable_if_t<std::is_same_v<String, std::string>>>
+ template <typename String, typename = EnableIfString<String>>
StatusRep(absl::StatusCode code_arg, String&& message_arg,
std::unique_ptr<status_internal::Payloads> payloads_arg)
: ref_(int32_t{1}),
@@ -144,6 +148,8 @@ class StatusRep {
StatusRep* absl_nonnull CloneAndUnref() const;
private:
+ friend class absl::Status;
+
mutable std::atomic<int32_t> ref_;
absl::StatusCode code_;
@@ -172,6 +178,7 @@ const char* absl_nonnull MakeCheckFailString(
const absl::Status* absl_nonnull status, const char* absl_nonnull prefix);
} // namespace status_internal
+#endif // SWIG
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.cc b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.cc
index c2912bbbfcf..7252d187ee8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.cc
@@ -56,7 +56,7 @@ bool StatusIsMatcherCommonImpl::MatchAndExplain(
return false;
}
- if (!message_matcher_.Matches(std::string(status.message()))) {
+ if (!message_matcher_.Matches(status.message())) {
*result_listener << "whose error message is wrong";
return false;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.h b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.h
index 54468406075..b7425e1f57c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/internal/status_matchers.h
@@ -123,7 +123,7 @@ class StatusCode {
explicit operator int() const { return static_cast<int>(code_); }
- friend inline void PrintTo(const StatusCode& code, std::ostream* os) {
+ friend void PrintTo(const StatusCode& code, std::ostream* os) {
absl::string_view text =
absl::StatusCodeToStringView(static_cast<absl::StatusCode>(code.code_));
if (!text.empty()) {
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 c42891fd64a..b0862339b09 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
@@ -20,6 +20,7 @@
#include "absl/base/attributes.h"
#include "absl/base/nullability.h"
+#include "absl/base/optimization.h"
#include "absl/meta/type_traits.h"
#include "absl/status/status.h"
#include "absl/strings/string_view.h"
@@ -621,7 +622,7 @@ class StringifyRandom {
}
public:
- static inline absl::string_view OpenBrackets() {
+ static absl::string_view OpenBrackets() {
switch (RandomBraces()) {
case kBareParens:
return "(";
@@ -635,7 +636,7 @@ class StringifyRandom {
return "(";
}
- static inline absl::string_view CloseBrackets() {
+ static absl::string_view CloseBrackets() {
switch (RandomBraces()) {
case kBareParens:
return ")";
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 18adf513cef..80e84791f4b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status.cc
@@ -15,29 +15,19 @@
#include <errno.h>
-#include <atomic>
-#include <cstddef>
#include <cstdint>
-#include <cstring>
#include <memory>
#include <ostream>
#include <string>
#include <type_traits>
#include <utility>
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/strerror.h"
-#include "absl/base/macros.h"
#include "absl/base/no_destructor.h"
#include "absl/base/nullability.h"
-#include "absl/debugging/stacktrace.h"
-#include "absl/debugging/symbolize.h"
#include "absl/status/internal/status_internal.h"
#include "absl/strings/str_cat.h"
-#include "absl/strings/str_format.h"
-#include "absl/strings/str_split.h"
#include "absl/strings/string_view.h"
#include "absl/types/source_location.h"
@@ -140,11 +130,13 @@ uintptr_t Status::MakeRepFromStringView(uintptr_t inlined_rep,
return MakeStatusRepImpl<absl::string_view>(inlined_rep, msg, loc);
}
+#ifndef SWIG
uintptr_t Status::MakeRepFromStringRvalue(uintptr_t inlined_rep,
std::string&& msg,
absl::SourceLocation loc) {
return MakeStatusRepImpl<std::string&&>(inlined_rep, std::move(msg), loc);
}
+#endif // SWIG
uintptr_t Status::AddSourceLocationImpl(uintptr_t rep,
absl::SourceLocation loc) {
@@ -155,6 +147,17 @@ uintptr_t Status::AddSourceLocationImpl(uintptr_t rep,
return PointerToRep(rep_ptr);
}
+uintptr_t Status::WithContextImpl(uintptr_t rep, absl::string_view context) {
+ if (context.empty()) return rep;
+ status_internal::StatusRep* rep_ptr = PrepareToModify(rep);
+ if (rep_ptr->message_.empty()) {
+ rep_ptr->message_ = std::string(context);
+ } else {
+ absl::StrAppend(&rep_ptr->message_, "; ", context);
+ }
+ return PointerToRep(rep_ptr);
+}
+
status_internal::StatusRep* absl_nonnull Status::PrepareToModify(
uintptr_t rep) {
if (IsInlined(rep)) {
@@ -179,7 +182,7 @@ std::ostream& operator<<(std::ostream& os, const Status& x) {
namespace status_internal {
// We use an int in the template parameter to shorten mangled names.
template <int error_code>
-Status MakeErrorImpl(string_view message, SourceLocation loc) {
+Status MakeErrorStringViewImpl(string_view message, SourceLocation loc) {
return Status(static_cast<StatusCode>(error_code), message, loc);
}
@@ -187,23 +190,53 @@ Status MakeErrorImpl(string_view message, SourceLocation loc) {
// If we add more error code, we need to add their values on this list.
// Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier
// to see that the list is complete.
-template Status MakeErrorImpl<0>(string_view, SourceLocation);
-template Status MakeErrorImpl<1>(string_view, SourceLocation);
-template Status MakeErrorImpl<2>(string_view, SourceLocation);
-template Status MakeErrorImpl<3>(string_view, SourceLocation);
-template Status MakeErrorImpl<4>(string_view, SourceLocation);
-template Status MakeErrorImpl<5>(string_view, SourceLocation);
-template Status MakeErrorImpl<6>(string_view, SourceLocation);
-template Status MakeErrorImpl<7>(string_view, SourceLocation);
-template Status MakeErrorImpl<8>(string_view, SourceLocation);
-template Status MakeErrorImpl<9>(string_view, SourceLocation);
-template Status MakeErrorImpl<10>(string_view, SourceLocation);
-template Status MakeErrorImpl<11>(string_view, SourceLocation);
-template Status MakeErrorImpl<12>(string_view, SourceLocation);
-template Status MakeErrorImpl<13>(string_view, SourceLocation);
-template Status MakeErrorImpl<14>(string_view, SourceLocation);
-template Status MakeErrorImpl<15>(string_view, SourceLocation);
-template Status MakeErrorImpl<16>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<1>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<2>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<3>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<4>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<5>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<6>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<7>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<8>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<9>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<10>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<11>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<12>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<13>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<14>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<15>(string_view, SourceLocation);
+template Status MakeErrorStringViewImpl<16>(string_view, SourceLocation);
+
+// Same as above, but for rvalue strings.
+#ifndef SWIG
+// We use an int in the template parameter to shorten mangled names.
+template <int error_code>
+Status MakeErrorStringRvalueImpl(std::string&& message, SourceLocation loc) {
+ return Status(static_cast<StatusCode>(error_code), std::move(message), loc);
+}
+
+// Explicit instantiation for all the error codes.
+// If we add more error code, we need to add their values on this list.
+// Using ints here instead of static_cast<int>(StatusCode::kFoo) makes it easier
+// to see that the list is complete.
+template Status MakeErrorStringRvalueImpl<1>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<2>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<3>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<4>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<5>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<6>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<7>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<8>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<9>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<10>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<11>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<12>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<13>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<14>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<15>(std::string&&, SourceLocation);
+template Status MakeErrorStringRvalueImpl<16>(std::string&&, SourceLocation);
+#endif // SWIG
+
} // namespace status_internal
bool IsAborted(const Status& status) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status.h b/deps/v8/third_party/abseil-cpp/absl/status/status.h
index 0b39b9bc93b..4158de1c8b3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status.h
@@ -75,6 +75,10 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
+#ifndef SWIG // SWIG chokes on enum class
+// The following canonical error codes should always be in sync with
+// https://github.com/googleapis/googleapis/blob/master/google/rpc/code.proto.
+
// absl::StatusCode
//
// An `absl::StatusCode` is an enumerated type indicating either no error ("OK")
@@ -319,22 +323,22 @@ enum class StatusToStringMode : int {
// absl::StatusToStringMode is specified as a bitmask type, which means the
// following operations must be provided:
-inline constexpr StatusToStringMode operator&(StatusToStringMode lhs,
- StatusToStringMode rhs) {
+constexpr StatusToStringMode operator&(StatusToStringMode lhs,
+ StatusToStringMode rhs) {
return static_cast<StatusToStringMode>(static_cast<int>(lhs) &
static_cast<int>(rhs));
}
-inline constexpr StatusToStringMode operator|(StatusToStringMode lhs,
- StatusToStringMode rhs) {
+constexpr StatusToStringMode operator|(StatusToStringMode lhs,
+ StatusToStringMode rhs) {
return static_cast<StatusToStringMode>(static_cast<int>(lhs) |
static_cast<int>(rhs));
}
-inline constexpr StatusToStringMode operator^(StatusToStringMode lhs,
- StatusToStringMode rhs) {
+constexpr StatusToStringMode operator^(StatusToStringMode lhs,
+ StatusToStringMode rhs) {
return static_cast<StatusToStringMode>(static_cast<int>(lhs) ^
static_cast<int>(rhs));
}
-inline constexpr StatusToStringMode operator~(StatusToStringMode arg) {
+constexpr StatusToStringMode operator~(StatusToStringMode arg) {
return static_cast<StatusToStringMode>(~static_cast<int>(arg));
}
inline StatusToStringMode& operator&=(StatusToStringMode& lhs,
@@ -352,6 +356,7 @@ inline StatusToStringMode& operator^=(StatusToStringMode& lhs,
lhs = lhs ^ rhs;
return lhs;
}
+#endif // SWIG
// absl::Status
//
@@ -460,13 +465,14 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
Status(absl::StatusCode code, absl::string_view msg,
absl::SourceLocation loc = SourceLocation::current());
+#ifndef SWIG
// Same as above but for rvalue string.
// Note: using a template to disambiguate the case of matching string_view and
// string&& (e.g. char*) as a template lowers the priority of the overload.
- template <typename String,
- typename = std::enable_if_t<std::is_same_v<String, std::string>>>
+ template <typename String, typename = status_internal::EnableIfString<String>>
Status(absl::StatusCode code, String&& msg,
absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
// Create a status from a `base_status` and a `loc`. The `loc` will be
// appended to the location chain of the new status, iff the `base_status` is
@@ -475,19 +481,23 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
: Status(base_status) {
AddSourceLocation(loc);
}
+#ifndef SWIG
Status(Status&& base_status, absl::SourceLocation loc)
: Status(std::move(base_status)) {
AddSourceLocation(loc);
}
+#endif // SWIG
Status(const Status&);
Status& operator=(const Status& x);
+#ifndef SWIG
// Move operators
// The moved-from state is valid but unspecified.
Status(Status&&) noexcept;
Status& operator=(Status&&) noexcept;
+#endif // SWIG
~Status();
@@ -507,7 +517,9 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// overall_status.Update(new_status);
//
void Update(const Status& new_status);
+#ifndef SWIG
void Update(Status&& new_status);
+#endif // SWIG
// Status::ok()
//
@@ -533,6 +545,8 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// wire format. Use `Status::code()` for error handling.
int raw_code() const;
+#ifndef SWIG
+
// Status::message()
//
// Returns the error message associated with this error code, if available.
@@ -540,10 +554,15 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// for the error message to be the empty string. As a result, prefer
// `operator<<` or `Status::ToString()` for debug logging.
absl::string_view message() const;
+#endif // SWIG
friend bool operator==(const Status&, const Status&);
friend bool operator!=(const Status&, const Status&);
+#ifndef SWIG
+ // `ToString` has stubs in SWIG to remain backward compatible with the old
+ // format by calling `util::StatusToString`, to save migration cost.
+
// Status::ToString()
//
// Returns a string based on the `mode`. By default, it returns combination of
@@ -563,6 +582,7 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
friend void AbslStringify(Sink& sink, const Status& status) {
sink.Append(status.ToString(StatusToStringMode::kWithEverything));
}
+#endif // SWIG
// Status::IgnoreError()
//
@@ -574,7 +594,11 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// swap()
//
// Swap the contents of one status with another.
+#ifndef SWIG
friend void swap(Status& a, Status& b) noexcept;
+#else
+ friend void swap(Status& a, Status& b);
+#endif // SWIG
//----------------------------------------------------------------------------
// Payload Management APIs
@@ -639,9 +663,14 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
//
// NOTE: Any mutation on the same 'absl::Status' object during visitation is
// forbidden and could result in undefined behavior.
+ // FunctionRef doesn't work nicely with Swig.
+ // TODO(b/189736749): Consider making this available once FunctionRef is
+ // supported.
+#ifndef SWIG
void ForEachPayload(
absl::FunctionRef<void(absl::string_view, const absl::Cord&)> visitor)
const;
+#endif // SWIG
absl::Span<const absl::SourceLocation> GetSourceLocations() const {
if (IsInlined(rep_)) return {};
@@ -661,6 +690,8 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
ABSL_ASSUME(!okay);
}
+#ifndef SWIG
+
// Status::WithSourceLocation()
//
// Returns a copy of the current status, with `loc` appended to its location
@@ -695,6 +726,7 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
AddSourceLocation(loc);
return std::move(*this);
}
+#endif // SWIG
private:
friend Status CancelledError();
@@ -722,10 +754,12 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
absl::string_view msg,
absl::SourceLocation loc);
+#ifndef SWIG
// Same as above but for rvalue string.
static uintptr_t MakeRepFromStringRvalue(uintptr_t inlined_rep,
std::string&& msg,
absl::SourceLocation loc);
+#endif // SWIG
template <typename StringOrView>
friend uintptr_t MakeStatusRepImpl(uintptr_t inlined_rep, StringOrView msg,
@@ -737,6 +771,7 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// An out-of-line AddSourceLocation that mutates rep directly.
static uintptr_t AddSourceLocationImpl(uintptr_t rep,
absl::SourceLocation loc);
+ static uintptr_t WithContextImpl(uintptr_t rep, absl::string_view context);
static void Ref(uintptr_t rep);
static void Unref(uintptr_t rep);
@@ -769,9 +804,9 @@ class ABSL_ATTRIBUTE_TRIVIAL_ABI Status final {
// Converts between StatusRep* and the external uintptr_t representation used
// by rep_. See rep_ for details.
- static uintptr_t PointerToRep(status_internal::StatusRep* absl_nonnull r);
+ static uintptr_t PointerToRep(status_internal::StatusRep* absl_nonnull rep);
static const status_internal::StatusRep* absl_nonnull RepToPointer(
- uintptr_t r);
+ uintptr_t rep);
static std::string ToStringSlow(uintptr_t rep, StatusToStringMode mode);
@@ -855,45 +890,176 @@ ABSL_MUST_USE_RESULT bool IsUnknown(const Status& status);
// These convenience functions create an `absl::Status` object with an error
// code as indicated by the associated function name, using the error message
// passed in `message`.
+// Note: using a template for the rvalue message overload to disambiguate the
+// case of matching string_view and string&& (e.g. char*) as a template lowers
+// the priority of the overload.
+
+// AbortedError
Status AbortedError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status AbortedError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// AlreadyExistsError
Status AlreadyExistsError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status AlreadyExistsError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// CancelledError
Status CancelledError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status CancelledError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// DataLossError
Status DataLossError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status DataLossError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// DeadlineExceededError
Status DeadlineExceededError(
absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status DeadlineExceededError(
+ String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// FailedPreconditionError
Status FailedPreconditionError(
absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status FailedPreconditionError(
+ String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// InternalError
Status InternalError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status InternalError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// InvalidArgumentError
Status InvalidArgumentError(
absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status InvalidArgumentError(
+ String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// NotFoundError
Status NotFoundError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status NotFoundError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// OutOfRangeError
Status OutOfRangeError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status OutOfRangeError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// PermissionDeniedError
Status PermissionDeniedError(
absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status PermissionDeniedError(
+ String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// ResourceExhaustedError
Status ResourceExhaustedError(
absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status ResourceExhaustedError(
+ String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// UnauthenticatedError
Status UnauthenticatedError(
absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnauthenticatedError(
+ String&& message, absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// UnavailableError
Status UnavailableError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnavailableError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// UnimplementedError
Status UnimplementedError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnimplementedError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
+// UnknownError
Status UnknownError(absl::string_view message,
absl::SourceLocation loc = SourceLocation::current());
+#ifndef SWIG
+template <typename String, typename = status_internal::EnableIfString<String>>
+Status UnknownError(String&& message,
+ absl::SourceLocation loc = SourceLocation::current());
+#endif // SWIG
+
// ErrnoToStatusCode()
//
// Returns the StatusCode for `error_number`, which should be an `errno` value.
@@ -920,11 +1086,13 @@ inline Status::Status(absl::StatusCode code, absl::string_view msg,
absl::SourceLocation loc)
: Status(MakeRepFromStringView(CodeToInlinedRep(code), msg, loc)) {}
+#ifndef SWIG
template <typename String, typename>
inline Status::Status(absl::StatusCode code, String&& msg,
absl::SourceLocation loc)
: Status(MakeRepFromStringRvalue(CodeToInlinedRep(code),
std::forward<String>(msg), loc)) {}
+#endif // SWIG
inline Status::Status(const Status& x) : Status(x.rep_) { Ref(rep_); }
@@ -938,6 +1106,7 @@ inline Status& Status::operator=(const Status& x) {
return *this;
}
+#ifndef SWIG
inline Status::Status(Status&& x) noexcept : Status(x.rep_) {
x.rep_ = MovedFromRep();
}
@@ -951,6 +1120,7 @@ inline Status& Status::operator=(Status&& x) noexcept {
}
return *this;
}
+#endif // SWIG
inline void Status::Update(const Status& new_status) {
if (ok()) {
@@ -958,11 +1128,13 @@ inline void Status::Update(const Status& new_status) {
}
}
+#ifndef SWIG
inline void Status::Update(Status&& new_status) {
if (ok()) {
*this = std::move(new_status);
}
}
+#endif // SWIG
inline Status::~Status() { Unref(rep_); }
@@ -1005,10 +1177,17 @@ inline void Status::IgnoreError() const {
// no-op
}
+#ifndef SWIG
inline void swap(absl::Status& a, absl::Status& b) noexcept {
using std::swap;
swap(a.rep_, b.rep_);
}
+#else
+inline void swap(absl::Status& a, absl::Status& b) {
+ using std::swap;
+ swap(a.rep_, b.rep_);
+}
+#endif // SWIG
inline std::optional<absl::Cord> Status::GetPayload(
absl::string_view type_url) const {
@@ -1074,7 +1253,9 @@ inline void Status::Unref(uintptr_t rep) {
if (!IsInlined(rep)) RepToPointer(rep)->Unref();
}
+#ifndef SWIG
inline Status OkStatus() { return Status(); }
+#endif // SWIG
// Creates a `Status` object with the `absl::StatusCode::kCancelled` error code
// and an empty message. It is provided only for efficiency, given that
@@ -1093,107 +1274,337 @@ const char* absl_nonnull StatusMessageAsCStr(
namespace status_internal {
// We use an int in the template parameter to shorten mangled names.
template <int error_code>
-Status MakeErrorImpl(string_view message, SourceLocation loc);
+Status MakeErrorStringViewImpl(string_view message, SourceLocation loc);
// Make the instantiations extern to reduce bloat on callers.
-extern template Status MakeErrorImpl<0>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<1>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<2>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<3>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<4>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<5>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<6>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<7>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<8>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<9>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<10>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<11>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<12>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<13>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<14>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<15>(string_view, SourceLocation);
-extern template Status MakeErrorImpl<16>(string_view, SourceLocation);
+#ifndef SWIG
+extern template Status MakeErrorStringViewImpl<1>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<2>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<3>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<4>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<5>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<6>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<7>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<8>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<9>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<10>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<11>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<12>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<13>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<14>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<15>(string_view, SourceLocation);
+extern template Status MakeErrorStringViewImpl<16>(string_view, SourceLocation);
+#endif // SWIG
template <StatusCode error_code>
-Status MakeError(string_view message, SourceLocation loc) {
- Status out = MakeErrorImpl<static_cast<int>(error_code)>(message, loc);
+Status MakeErrorFromStringView(string_view message, SourceLocation loc) {
+ static_assert(error_code != StatusCode::kOk, "expecting non-OK code");
+ Status out =
+ MakeErrorStringViewImpl<static_cast<int>(error_code)>(message, loc);
+ // -Wassume warning complains about potential side effects of `ok()`, so use a
+ // local to avoid that.
+ [[maybe_unused]] bool ok = out.ok();
+ ABSL_ASSUME(!ok);
+ return out;
+}
+
+// Same as above, but for rvalue std::string.
+#ifndef SWIG
+// We use an int in the template parameter to shorten mangled names.
+template <int error_code>
+Status MakeErrorStringRvalueImpl(std::string&& message, SourceLocation loc);
+// Make the instantiations extern to reduce bloat on callers.
+extern template Status MakeErrorStringRvalueImpl<1>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<2>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<3>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<4>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<5>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<6>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<7>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<8>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<9>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<10>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<11>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<12>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<13>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<14>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<15>(std::string&&,
+ SourceLocation);
+extern template Status MakeErrorStringRvalueImpl<16>(std::string&&,
+ SourceLocation);
+
+template <StatusCode error_code, typename String>
+Status MakeErrorFromStringRvalue(String&& message, SourceLocation loc) {
+ static_assert(error_code != StatusCode::kOk, "expecting non-OK code");
+ static_assert(std::is_same_v<String&&, std::string&&>,
+ "`message` should be std::string&&");
+ Status out = MakeErrorStringRvalueImpl<static_cast<int>(error_code)>(
+ std::forward<String>(message), loc);
// -Wassume warning complains about potential side effects of `ok()`, so use a
// local to avoid that.
[[maybe_unused]] bool ok = out.ok();
ABSL_ASSUME(!ok);
return out;
}
+#endif // SWIG
+
} // namespace status_internal
// Inline implementations to give the compiler static knowledge about the
// objects.
+
+// AbortedError
inline Status AbortedError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kAborted>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kAborted>(message,
+ loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status AbortedError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kAborted>(
+ std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// AlreadyExistsError
inline Status AlreadyExistsError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kAlreadyExists>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kAlreadyExists>(
+ message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status AlreadyExistsError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kAlreadyExists>(
+ std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// CancelledError
inline Status CancelledError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kCancelled>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kCancelled>(
+ message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status CancelledError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kCancelled>(
+ std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// DataLossError
inline Status DataLossError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kDataLoss>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kDataLoss>(
+ message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status DataLossError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kDataLoss>(
+ std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// DeadlineExceededError
inline Status DeadlineExceededError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kDeadlineExceeded>(message,
- loc);
+ return status_internal::MakeErrorFromStringView<
+ StatusCode::kDeadlineExceeded>(message, loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status DeadlineExceededError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<
+ StatusCode::kDeadlineExceeded>(std::forward<String>(message), loc);
}
+#endif // SWIG
+
+// FailedPreconditionError
inline Status FailedPreconditionError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kFailedPrecondition>(message,
- loc);
+ return status_internal::MakeErrorFromStringView<
+ StatusCode::kFailedPrecondition>(message, loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status FailedPreconditionError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<
+ StatusCode::kFailedPrecondition>(std::forward<String>(message), loc);
}
+#endif // SWIG
+
+// InternalError
inline Status InternalError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kInternal>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kInternal>(
+ message, loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status InternalError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kInternal>(
+ std::forward<String>(message), loc);
}
+#endif // SWIG
+
+// InvalidArgumentError
inline Status InvalidArgumentError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kInvalidArgument>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kInvalidArgument>(
+ message, loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status InvalidArgumentError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<
+ StatusCode::kInvalidArgument>(std::forward<String>(message), loc);
}
+#endif // SWIG
+
+// NotFoundError
inline Status NotFoundError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kNotFound>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kNotFound>(
+ message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status NotFoundError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kNotFound>(
+ std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// OutOfRangeError
inline Status OutOfRangeError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kOutOfRange>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kOutOfRange>(
+ message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status OutOfRangeError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kOutOfRange>(
+ std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// PermissionDeniedError
inline Status PermissionDeniedError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kPermissionDenied>(message,
- loc);
+ return status_internal::MakeErrorFromStringView<
+ StatusCode::kPermissionDenied>(message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status PermissionDeniedError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<
+ StatusCode::kPermissionDenied>(std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// ResourceExhaustedError
inline Status ResourceExhaustedError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kResourceExhausted>(message,
- loc);
+ return status_internal::MakeErrorFromStringView<
+ StatusCode::kResourceExhausted>(message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status ResourceExhaustedError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<
+ StatusCode::kResourceExhausted>(std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// UnauthenticatedError
inline Status UnauthenticatedError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kUnauthenticated>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kUnauthenticated>(
+ message, loc);
}
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnauthenticatedError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<
+ StatusCode::kUnauthenticated>(std::forward<String>(message), loc);
+}
+#endif // SWIG
+
+// UnavailableError
inline Status UnavailableError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kUnavailable>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kUnavailable>(
+ message, loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnavailableError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnavailable>(
+ std::forward<String>(message), loc);
}
+#endif // SWIG
+
+// UnimplementedError
inline Status UnimplementedError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kUnimplemented>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kUnimplemented>(
+ message, loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnimplementedError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnimplemented>(
+ std::forward<String>(message), loc);
}
+#endif // SWIG
+
+// UnknownError
inline Status UnknownError(absl::string_view message,
absl::SourceLocation loc) {
- return status_internal::MakeError<StatusCode::kUnknown>(message, loc);
+ return status_internal::MakeErrorFromStringView<StatusCode::kUnknown>(message,
+ loc);
+}
+
+#ifndef SWIG
+template <typename String, typename>
+Status UnknownError(String&& message, absl::SourceLocation loc) {
+ return status_internal::MakeErrorFromStringRvalue<StatusCode::kUnknown>(
+ std::forward<String>(message), loc);
}
+#endif // SWIG
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/status/status_benchmark.cc
index 0404db16def..b001e6310ef 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status_benchmark.cc
@@ -57,4 +57,14 @@ void BM_LongMessageRValue(benchmark::State& state) {
}
BENCHMARK(BM_LongMessageRValue);
+void BM_LongMessageRValueConvenienceFn(benchmark::State& state) {
+ for (auto _ : state) {
+ std::string msg(100, 'X');
+ benchmark::DoNotOptimize(msg);
+ absl::Status s = absl::InvalidArgumentError(std::move(msg));
+ benchmark::DoNotOptimize(s);
+ }
+}
+BENCHMARK(BM_LongMessageRValueConvenienceFn);
+
} // namespace
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status_builder.cc b/deps/v8/third_party/abseil-cpp/absl/status/status_builder.cc
index 929deada5a7..8b30f618c53 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status_builder.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status_builder.cc
@@ -40,7 +40,7 @@ void StatusBuilder::Destroy(std::unique_ptr<Rep>) {
// These constructors are not-inlined and defined in the .cc file to reduce
// binary size. See cl/354351433 for a quantification.
-StatusBuilder::StatusBuilder() {}
+StatusBuilder::StatusBuilder() = default;
StatusBuilder::StatusBuilder(const absl::Status& original_status,
absl::SourceLocation location)
@@ -53,7 +53,7 @@ StatusBuilder::operator absl::Status() const& {
StatusBuilder::Rep::Rep(const absl::Status& s) : status(s) {}
StatusBuilder::Rep::Rep(absl::Status&& s) : status(std::move(s)) {}
-StatusBuilder::Rep::~Rep() {}
+StatusBuilder::Rep::~Rep() = default;
StatusBuilder::Rep* StatusBuilder::InitRepImpl(absl::Status s) {
if (s.ok()) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status_builder.h b/deps/v8/third_party/abseil-cpp/absl/status/status_builder.h
index 60b756212e7..55ab7a8355e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status_builder.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status_builder.h
@@ -704,13 +704,13 @@ std::ostream& operator<<(std::ostream& os, StatusBuilder&& builder);
// would prevent use of operator<<. For example:
//
// ABSL_RETURN_IF_ERROR(foo(val))
-// .With(util::ExtraMessage("when calling foo()"))
+// .With(absl::ExtraMessage("when calling foo()"))
// .With(util::TaskReturn(task));
//
// or
//
// ABSL_RETURN_IF_ERROR(foo(val))
-// .With(util::ExtraMessage() << "val: " << val)
+// .With(absl::ExtraMessage() << "val: " << val)
// .With(util::TaskReturn(task));
//
// Note in the above example, the ABSL_RETURN_IF_ERROR macro ensures the
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status_macros_test.cc b/deps/v8/third_party/abseil-cpp/absl/status/status_macros_test.cc
index 01ebdbf27f4..7b5751d1522 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status_macros_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status_macros_test.cc
@@ -24,8 +24,6 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
-#include "absl/base/attributes.h"
-#include "absl/base/optimization.h"
#include "absl/status/status.h"
#include "absl/status/status_builder.h"
#include "absl/status/statusor.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/status_test.cc b/deps/v8/third_party/abseil-cpp/absl/status/status_test.cc
index ddf0be0f0fe..c4679d68169 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/status_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/status_test.cc
@@ -19,6 +19,7 @@
#include <array>
#include <cstddef>
#include <sstream>
+#include <string>
#include <utility>
#include <vector>
@@ -46,41 +47,82 @@ TEST(StatusCode, InsertionOperator) {
}
// This structure holds the details for testing a single error code,
-// its creator, and its classifier.
+// its creator, its rvalue creator, and its classifier.
struct ErrorTest {
absl::StatusCode code;
using Creator = absl::Status (*)(absl::string_view, absl::SourceLocation);
- using Classifier = bool (*)(const absl::Status&);
Creator creator;
+ using CreatorRValue = absl::Status (*)(std::string&&, absl::SourceLocation);
+ CreatorRValue creator_rvalue;
+ using Classifier = bool (*)(const absl::Status&);
Classifier classifier;
};
constexpr ErrorTest kErrorTests[]{
- {absl::StatusCode::kCancelled, absl::CancelledError, absl::IsCancelled},
- {absl::StatusCode::kUnknown, absl::UnknownError, absl::IsUnknown},
- {absl::StatusCode::kInvalidArgument, absl::InvalidArgumentError,
- absl::IsInvalidArgument},
- {absl::StatusCode::kDeadlineExceeded, absl::DeadlineExceededError,
- absl::IsDeadlineExceeded},
- {absl::StatusCode::kNotFound, absl::NotFoundError, absl::IsNotFound},
- {absl::StatusCode::kAlreadyExists, absl::AlreadyExistsError,
- absl::IsAlreadyExists},
- {absl::StatusCode::kPermissionDenied, absl::PermissionDeniedError,
- absl::IsPermissionDenied},
- {absl::StatusCode::kResourceExhausted, absl::ResourceExhaustedError,
- absl::IsResourceExhausted},
- {absl::StatusCode::kFailedPrecondition, absl::FailedPreconditionError,
- absl::IsFailedPrecondition},
- {absl::StatusCode::kAborted, absl::AbortedError, absl::IsAborted},
- {absl::StatusCode::kOutOfRange, absl::OutOfRangeError, absl::IsOutOfRange},
- {absl::StatusCode::kUnimplemented, absl::UnimplementedError,
- absl::IsUnimplemented},
- {absl::StatusCode::kInternal, absl::InternalError, absl::IsInternal},
- {absl::StatusCode::kUnavailable, absl::UnavailableError,
- absl::IsUnavailable},
- {absl::StatusCode::kDataLoss, absl::DataLossError, absl::IsDataLoss},
- {absl::StatusCode::kUnauthenticated, absl::UnauthenticatedError,
- absl::IsUnauthenticated},
+ {absl::StatusCode::kCancelled, //
+ absl::CancelledError, //
+ absl::CancelledError, //
+ absl::IsCancelled}, //
+ {absl::StatusCode::kUnknown, //
+ absl::UnknownError, //
+ absl::UnknownError, //
+ absl::IsUnknown}, //
+ {absl::StatusCode::kInvalidArgument, //
+ absl::InvalidArgumentError, //
+ absl::InvalidArgumentError, //
+ absl::IsInvalidArgument}, //
+ {absl::StatusCode::kDeadlineExceeded, //
+ absl::DeadlineExceededError, //
+ absl::DeadlineExceededError, //
+ absl::IsDeadlineExceeded}, //
+ {absl::StatusCode::kNotFound, //
+ absl::NotFoundError, //
+ absl::NotFoundError, //
+ absl::IsNotFound}, //
+ {absl::StatusCode::kAlreadyExists, //
+ absl::AlreadyExistsError, //
+ absl::AlreadyExistsError, //
+ absl::IsAlreadyExists}, //
+ {absl::StatusCode::kPermissionDenied, //
+ absl::PermissionDeniedError, //
+ absl::PermissionDeniedError, //
+ absl::IsPermissionDenied}, //
+ {absl::StatusCode::kResourceExhausted, //
+ absl::ResourceExhaustedError, //
+ absl::ResourceExhaustedError, //
+ absl::IsResourceExhausted}, //
+ {absl::StatusCode::kFailedPrecondition, //
+ absl::FailedPreconditionError, //
+ absl::FailedPreconditionError, //
+ absl::IsFailedPrecondition}, //
+ {absl::StatusCode::kAborted, //
+ absl::AbortedError, //
+ absl::AbortedError, //
+ absl::IsAborted}, //
+ {absl::StatusCode::kOutOfRange, //
+ absl::OutOfRangeError, //
+ absl::OutOfRangeError, //
+ absl::IsOutOfRange}, //
+ {absl::StatusCode::kUnimplemented, //
+ absl::UnimplementedError, //
+ absl::UnimplementedError, //
+ absl::IsUnimplemented}, //
+ {absl::StatusCode::kInternal, //
+ absl::InternalError, //
+ absl::InternalError, //
+ absl::IsInternal}, //
+ {absl::StatusCode::kUnavailable, //
+ absl::UnavailableError, //
+ absl::UnavailableError, //
+ absl::IsUnavailable}, //
+ {absl::StatusCode::kDataLoss, //
+ absl::DataLossError, //
+ absl::DataLossError, //
+ absl::IsDataLoss}, //
+ {absl::StatusCode::kUnauthenticated, //
+ absl::UnauthenticatedError, //
+ absl::UnauthenticatedError, //
+ absl::IsUnauthenticated}, //
};
TEST(Status, CreateAndClassify) {
@@ -96,9 +138,16 @@ TEST(Status, CreateAndClassify) {
EXPECT_EQ(test.code, status.code());
EXPECT_EQ(message, status.message());
+ // Testing the rvalue creator.
+ absl::Status status_rvalue = test.creator_rvalue(
+ std::string(message), absl::SourceLocation::current());
+ EXPECT_EQ(test.code, status_rvalue.code());
+ EXPECT_EQ(message, status_rvalue.message());
+
// Ensure that the classifier returns true for a status produced by the
// creator.
EXPECT_TRUE(test.classifier(status));
+ EXPECT_TRUE(test.classifier(status_rvalue));
// Ensure that the classifier returns false for status with a different
// code.
@@ -111,6 +160,37 @@ TEST(Status, CreateAndClassify) {
}
}
+// Test that status convenience functions can be called with a string literal.
+// Doing so to make sure it's not ambiguous between the string_view and string&&
+// overloads.
+TEST(Status, StringLiteralCreation) {
+ EXPECT_EQ(absl::AbortedError("msg").code(), absl::StatusCode::kAborted);
+ EXPECT_EQ(absl::AlreadyExistsError("msg").code(),
+ absl::StatusCode::kAlreadyExists);
+ EXPECT_EQ(absl::CancelledError("msg").code(), absl::StatusCode::kCancelled);
+ EXPECT_EQ(absl::DataLossError("msg").code(), absl::StatusCode::kDataLoss);
+ EXPECT_EQ(absl::DeadlineExceededError("msg").code(),
+ absl::StatusCode::kDeadlineExceeded);
+ EXPECT_EQ(absl::FailedPreconditionError("msg").code(),
+ absl::StatusCode::kFailedPrecondition);
+ EXPECT_EQ(absl::InternalError("msg").code(), absl::StatusCode::kInternal);
+ EXPECT_EQ(absl::InvalidArgumentError("msg").code(),
+ absl::StatusCode::kInvalidArgument);
+ EXPECT_EQ(absl::NotFoundError("msg").code(), absl::StatusCode::kNotFound);
+ EXPECT_EQ(absl::OutOfRangeError("msg").code(), absl::StatusCode::kOutOfRange);
+ EXPECT_EQ(absl::PermissionDeniedError("msg").code(),
+ absl::StatusCode::kPermissionDenied);
+ EXPECT_EQ(absl::ResourceExhaustedError("msg").code(),
+ absl::StatusCode::kResourceExhausted);
+ EXPECT_EQ(absl::UnauthenticatedError("msg").code(),
+ absl::StatusCode::kUnauthenticated);
+ EXPECT_EQ(absl::UnavailableError("msg").code(),
+ absl::StatusCode::kUnavailable);
+ EXPECT_EQ(absl::UnimplementedError("msg").code(),
+ absl::StatusCode::kUnimplemented);
+ EXPECT_EQ(absl::UnknownError("msg").code(), absl::StatusCode::kUnknown);
+}
+
TEST(Status, DefaultConstructor) {
absl::Status status;
EXPECT_TRUE(status.ok());
@@ -340,37 +420,37 @@ TEST(Status, ToStringMode) {
TEST(Status, OstreamOperator) {
absl::Status status(absl::StatusCode::kInternal, "fail");
- { std::stringstream stream;
+ {
+ std::stringstream stream;
stream << status;
- EXPECT_THAT(stream.str(),
- AllOf(HasSubstr("INTERNAL: fail"),
- HasSubstr("status_test.cc:")));
+ EXPECT_THAT(stream.str(), AllOf(HasSubstr("INTERNAL: fail"),
+ HasSubstr("status_test.cc:")));
}
status.SetPayload("foo", absl::Cord("bar"));
- { std::stringstream stream;
+ {
+ std::stringstream stream;
stream << status;
EXPECT_THAT(stream.str(),
AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
HasSubstr("status_test.cc:")));
}
status.SetPayload("bar", absl::Cord("\377"));
- { std::stringstream stream;
+ {
+ std::stringstream stream;
stream << status;
- EXPECT_THAT(stream.str(),
- AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
- HasSubstr("[bar='\\xff']"),
- HasSubstr("status_test.cc:")));
+ EXPECT_THAT(
+ stream.str(),
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+ HasSubstr("[bar='\\xff']"), HasSubstr("status_test.cc:")));
}
}
TEST(Status, AbslStringify) {
absl::Status status(absl::StatusCode::kInternal, "fail");
EXPECT_THAT(absl::StrCat(status),
- AllOf(HasSubstr("INTERNAL: fail"),
- HasSubstr("status_test.cc:")));
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("status_test.cc:")));
EXPECT_THAT(absl::StrFormat("%v", status),
- AllOf(HasSubstr("INTERNAL: fail"),
- HasSubstr("status_test.cc:")));
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("status_test.cc:")));
EXPECT_EQ(absl::StrCat(status), absl::StrFormat("%v", status));
status.SetPayload("foo", absl::Cord("bar"));
EXPECT_THAT(absl::StrCat(status),
@@ -379,8 +459,7 @@ TEST(Status, AbslStringify) {
status.SetPayload("bar", absl::Cord("\377"));
EXPECT_THAT(absl::StrCat(status),
AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
- HasSubstr("[bar='\\xff']"),
- HasSubstr("status_test.cc:")));
+ HasSubstr("[bar='\\xff']"), HasSubstr("status_test.cc:")));
}
TEST(Status, OstreamEqStringify) {
@@ -867,8 +946,7 @@ TEST(Status, AddSourceLocation) {
{
// Status that ignores source location.
absl::Status status_ignores_source_location[] = {
- absl::Status(),
- absl::Status(absl::StatusCode::kInternal, "")};
+ absl::Status(), absl::Status(absl::StatusCode::kInternal, "")};
for (absl::Status& s : status_ignores_source_location) {
for (int i = 0; i < max_iter; ++i) {
s.AddSourceLocation(absl::SourceLocation::current());
@@ -967,27 +1045,27 @@ TEST(Status, SourceLocationToStringMode) {
s.SetPayload("bar", absl::Cord("\377"));
- EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithEverything),
- AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
- HasSubstr("[bar='\\xff']"),
- HasSubstr(source_location_string),
- HasSubstr(source_location_stack)));
- EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload |
- absl::StatusToStringMode::kWithSourceLocation),
- AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
- HasSubstr("[bar='\\xff']"),
- HasSubstr(source_location_string),
- HasSubstr(source_location_stack)));
- EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithSourceLocation),
- AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")),
- Not(HasSubstr("[bar='\\xff']")),
- HasSubstr(source_location_string),
- HasSubstr(source_location_stack)));
- EXPECT_THAT(s.ToString(absl::StatusToStringMode::kWithPayload),
- AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
- HasSubstr("[bar='\\xff']"),
- Not(HasSubstr(source_location_string)),
- Not(HasSubstr(source_location_stack))));
+ EXPECT_THAT(
+ s.ToString(absl::StatusToStringMode::kWithEverything),
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+ HasSubstr("[bar='\\xff']"), HasSubstr(source_location_string),
+ HasSubstr(source_location_stack)));
+ EXPECT_THAT(
+ s.ToString(absl::StatusToStringMode::kWithPayload |
+ absl::StatusToStringMode::kWithSourceLocation),
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+ HasSubstr("[bar='\\xff']"), HasSubstr(source_location_string),
+ HasSubstr(source_location_stack)));
+ EXPECT_THAT(
+ s.ToString(absl::StatusToStringMode::kWithSourceLocation),
+ AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")),
+ Not(HasSubstr("[bar='\\xff']")), HasSubstr(source_location_string),
+ HasSubstr(source_location_stack)));
+ EXPECT_THAT(
+ s.ToString(absl::StatusToStringMode::kWithPayload),
+ AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"),
+ HasSubstr("[bar='\\xff']"), Not(HasSubstr(source_location_string)),
+ Not(HasSubstr(source_location_stack))));
}
TEST(Status, StackTracePayloadOverflow) {
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 8d8247fffb5..3d7f8c48832 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/statusor.h
+++ b/deps/v8/third_party/abseil-cpp/absl/status/statusor.h
@@ -61,6 +61,7 @@
namespace absl {
ABSL_NAMESPACE_BEGIN
+#ifndef SWIG
// BadStatusOrAccess
//
@@ -111,8 +112,10 @@ class BadStatusOrAccess : public std::exception {
mutable absl::once_flag init_what_;
mutable std::string what_;
};
+#endif // !SWIG
// Returned StatusOr objects may not be ignored.
+#ifndef SWIG
template <typename T>
#if ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
// TODO(b/176172494): ABSL_MUST_USE_RESULT should expand to the more strict
@@ -121,6 +124,7 @@ class [[nodiscard]] StatusOr;
#else
class ABSL_MUST_USE_RESULT StatusOr;
#endif // ABSL_HAVE_CPP_ATTRIBUTE(nodiscard)
+#endif // !SWIG
// absl::StatusOr<T>
//
@@ -233,6 +237,8 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
// assignable.
StatusOr& operator=(const StatusOr&) = default;
+#ifndef SWIG
+
// `StatusOr<T>` is move constructible if `T` is move constructible.
StatusOr(StatusOr&&) = default;
// `StatusOr<T>` is moveAssignable if `T` is move constructible and move
@@ -362,8 +368,8 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
// of passing absl::StatusCode::kInternal as a fallback.
template <typename U = absl::Status,
std::enable_if_t<internal_statusor::IsConstructionFromStatusValid<
- false, T, U>::value,
- int> = 0>
+ false, T, U>::value,
+ int> = 0>
StatusOr(U&& v) : Base(std::forward<U>(v)) {}
template <typename U = absl::Status,
@@ -454,6 +460,8 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
explicit StatusOr(U&& u ABSL_ATTRIBUTE_LIFETIME_BOUND) // NOLINT
: StatusOr(std::in_place, std::forward<U>(u)) {}
+#endif // SWIG
+
// StatusOr<T>::ok()
//
// Returns whether or not this `absl::StatusOr<T>` holds a `T` value. This
@@ -475,8 +483,12 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
// Returns a reference to the current `absl::Status` contained within the
// `absl::StatusOr<T>`. If `absl::StatusOr<T>` contains a `T`, then this
// function returns `absl::OkStatus()`.
+#ifdef SWIG
+ ABSL_MUST_USE_RESULT const absl::Status& status() const;
+#else // SWIG
ABSL_MUST_USE_RESULT const Status& status() const&;
Status status() &&;
+#endif // SWIG
absl::Span<const absl::SourceLocation> GetSourceLocations() const {
return this->status_.GetSourceLocations();
@@ -488,6 +500,8 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
this->status_.AddSourceLocation(loc);
}
+#ifndef SWIG
+
// StatusOr<T>::WithSourceLocation()
//
// Appends the `loc` to the current location chain inside the status iff the
@@ -507,6 +521,7 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
AddSourceLocation(loc);
return std::move(*this);
}
+#endif // SWIG
// StatusOr<T>::value()
//
@@ -534,7 +549,13 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
//
// The `std::move` on statusor instead of on the whole expression enables
// warnings about possible uses of the statusor object after the move.
+#ifdef SWIG
+ const T& value() const ABSL_ATTRIBUTE_LIFETIME_BOUND;
+#else // SWIG
using StatusOr::OperatorBase::value;
+#endif // SWIG
+
+#ifndef SWIG
// StatusOr<T>:: operator*()
//
@@ -598,6 +619,7 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
T value_or(U&& default_value ABSL_ATTRIBUTE_LIFETIME_BOUND) && {
return std::move(*this).ValueOrImpl(std::forward<U>(default_value));
}
+#endif // SWIG
// StatusOr<T>::IgnoreError()
//
@@ -606,6 +628,8 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
// the floor.
void IgnoreError() const;
+#ifndef SWIG
+
// StatusOr<T>::emplace()
//
// Reconstructs the inner value T in-place using the provided args, using the
@@ -658,13 +682,16 @@ class StatusOr : private internal_statusor::OperatorBase<T>,
// In optimized builds, passing absl::OkStatus() here will have the effect
// of passing absl::StatusCode::kInternal as a fallback.
using internal_statusor::StatusOrData<T>::AssignStatus;
+#endif // SWIG
private:
+#ifndef SWIG
using internal_statusor::StatusOrData<T>::Assign;
template <typename U>
void Assign(const absl::StatusOr<U>& other);
template <typename U>
void Assign(absl::StatusOr<U>&& other);
+#endif // SWIG
};
// operator==()
@@ -722,6 +749,7 @@ void AbslStringify(Sink& sink, const StatusOr<T>& status_or) {
}
}
+#ifndef SWIG
//------------------------------------------------------------------------------
// Implementation details for StatusOr<T>
//------------------------------------------------------------------------------
@@ -774,6 +802,8 @@ void StatusOr<T>::IgnoreError() const {
// no-op
}
+#endif // SWIG
+
ABSL_NAMESPACE_END
} // namespace absl
diff --git a/deps/v8/third_party/abseil-cpp/absl/status/statusor_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/status/statusor_benchmark.cc
index bb9954775ba..ac353bb1562 100644
--- a/deps/v8/third_party/abseil-cpp/absl/status/statusor_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/status/statusor_benchmark.cc
@@ -12,8 +12,11 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstdint>
#include <string>
+#include <utility>
+#include "absl/base/attributes.h"
#include "absl/status/status.h"
#include "absl/status/statusor.h"
#include "benchmark/benchmark.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 d03e8be8dd4..8a9504909ec 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
@@ -38,7 +38,6 @@
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/source_location.h"
-#include "absl/utility/utility.h"
namespace {
@@ -87,26 +86,26 @@ testing::Matcher<const CopyDetector&> CopyDetectorHas(int a, bool b, bool c) {
class Base1 {
public:
- virtual ~Base1() {}
+ virtual ~Base1() = default;
int pad;
};
class Base2 {
public:
- virtual ~Base2() {}
+ virtual ~Base2() = default;
int yetotherpad;
};
class Derived : public Base1, public Base2 {
public:
- virtual ~Derived() {}
+ ~Derived() override = default;
int evenmorepad;
};
class CopyNoAssign {
public:
explicit CopyNoAssign(int value) : foo(value) {}
- CopyNoAssign(const CopyNoAssign& other) : foo(other.foo) {}
+ CopyNoAssign(const CopyNoAssign& other) = default;
int foo;
private:
@@ -119,8 +118,8 @@ absl::StatusOr<std::unique_ptr<int>> ReturnUniquePtr() {
}
TEST(StatusOr, ElementType) {
- static_assert(std::is_same<absl::StatusOr<int>::value_type, int>(), "");
- static_assert(std::is_same<absl::StatusOr<char>::value_type, char>(), "");
+ static_assert(std::is_same<absl::StatusOr<int>::value_type, int>());
+ static_assert(std::is_same<absl::StatusOr<char>::value_type, char>());
}
TEST(StatusOr, TestMoveOnlyInitialization) {
@@ -809,19 +808,19 @@ TEST(StatusOr, NestedStatusOrCopyAndMoveAssignment) {
}
struct Copyable {
- Copyable() {}
- Copyable(const Copyable&) {}
- Copyable& operator=(const Copyable&) { return *this; }
+ Copyable() = default;
+ Copyable(const Copyable&) = default;
+ Copyable& operator=(const Copyable&) = default;
};
struct MoveOnly {
- MoveOnly() {}
+ MoveOnly() = default;
MoveOnly(MoveOnly&&) {}
MoveOnly& operator=(MoveOnly&&) { return *this; }
};
struct NonMovable {
- NonMovable() {}
+ NonMovable() = default;
NonMovable(const NonMovable&) = delete;
NonMovable(NonMovable&&) = delete;
NonMovable& operator=(const NonMovable&) = delete;
@@ -1394,7 +1393,7 @@ TEST(StatusOr, TestPointerValueConst) {
TEST(StatusOr, StatusOrVectorOfUniquePointerCanReserveAndResize) {
using EvilType = std::vector<std::unique_ptr<int>>;
- static_assert(std::is_copy_constructible_v<EvilType>, "");
+ static_assert(std::is_copy_constructible_v<EvilType>);
std::vector<::absl::StatusOr<EvilType>> v(5);
v.reserve(v.capacity() + 10);
v.resize(v.capacity() + 10);
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 38c85cbcf7a..7f8ca5f090d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.bazel
@@ -217,6 +217,20 @@ cc_test(
],
)
+cc_binary(
+ name = "match_benchmark",
+ testonly = True,
+ srcs = ["match_benchmark.cc"],
+ copts = ABSL_TEST_COPTS,
+ tags = ["benchmark"],
+ visibility = ["//visibility:private"],
+ deps = [
+ ":strings",
+ "//absl/base:raw_logging_internal",
+ "@google_benchmark//:benchmark_main",
+ ],
+)
+
cc_test(
name = "escaping_test",
size = "small",
@@ -330,7 +344,7 @@ cc_test(
],
copts = ABSL_TEST_COPTS,
deps = [
- "//absl/strings",
+ ":strings",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -454,10 +468,10 @@ cc_test(
copts = ABSL_TEST_COPTS,
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ ":str_format",
":string_view",
":stringify_stream",
"//absl/base:config",
- "//absl/strings:str_format",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -580,6 +594,7 @@ cc_test(
"//absl/base:config",
"//absl/base:raw_logging_internal",
"//absl/cleanup",
+ "//absl/types:span",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -630,6 +645,7 @@ cc_test(
":cord_internal",
":cord_rep_test_util",
"//absl/base:config",
+ "//absl/crc:crc32c",
"//absl/crc:crc_cord_state",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -700,6 +716,7 @@ cc_library(
"//absl/types:compare",
"//absl/types:optional",
"//absl/types:span",
+ "@do_not_use_for_gloop_visibility_only//gloop/base:fprint",
],
)
@@ -712,6 +729,7 @@ cc_library(
visibility = ["//absl:__subpackages__"],
deps = [
"//absl/base:config",
+ "//absl/base:core_headers",
"//absl/base:no_destructor",
"//absl/base:raw_logging_internal",
"//absl/synchronization",
@@ -892,10 +910,12 @@ cc_test(
":cordz_statistics",
":cordz_update_scope",
":cordz_update_tracker",
+ ":string_view",
"//absl/base:config",
"//absl/crc:crc_cord_state",
"//absl/synchronization",
"//absl/synchronization:thread_pool",
+ "//absl/time",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -912,6 +932,7 @@ cc_test(
":cordz_info",
":cordz_sample_token",
":cordz_test_helpers",
+ ":cordz_update_tracker",
"//absl/base:config",
"//absl/memory",
"//absl/random",
@@ -951,6 +972,7 @@ cc_library(
":strings",
"//absl/base:config",
"//absl/base:raw_logging_internal",
+ "//absl/types:span",
],
)
@@ -966,6 +988,7 @@ cc_library(
deps = [
":cord",
":cord_internal",
+ ":cordz_functions",
":cordz_info",
":cordz_sample_token",
":cordz_statistics",
@@ -990,7 +1013,6 @@ cc_test(
":cord_rep_test_util",
":string_view",
"//absl/base:config",
- "//absl/base:hardening",
"//absl/types:span",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -1017,7 +1039,6 @@ cc_test(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:endian",
- "//absl/base:hardening",
"//absl/base:no_destructor",
"//absl/container:fixed_array",
"//absl/functional:function_ref",
@@ -1436,6 +1457,7 @@ cc_test(
deps = [
":cord",
":str_format",
+ ":str_format_internal",
":strings",
"//absl/base:config",
"//absl/base:core_headers",
@@ -1483,6 +1505,8 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":str_format_internal",
+ ":string_view",
+ "//absl/types:span",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1495,6 +1519,7 @@ cc_test(
visibility = ["//visibility:private"],
deps = [
":str_format",
+ ":string_view",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -1511,10 +1536,12 @@ cc_test(
":str_format",
":str_format_internal",
":strings",
+ "//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/log",
+ "//absl/log:absl_check",
"//absl/numeric:int128",
"//absl/types:span",
"@googletest//:gtest",
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 d967311dbf1..094e217d9b2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/BUILD.gn
@@ -1,12 +1,13 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
-import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("string_view") {
- sources = [ "string_view.h" ]
+ public = [ "string_view.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -54,14 +55,6 @@ absl_source_set("strings") {
"strip.h",
"substitute.h",
]
- public_deps = [
- # string_view.h was once part of :strings, so string_view.h is
- # re-exported for backwards compatibility.
- # New code should directly depend on :string_view.
- # TODO(crbug.com/1466243): Remove once all targets are migrated to
- # :string_view.
- ":string_view",
- ]
deps = [
":append_and_overwrite",
":charset",
@@ -83,6 +76,14 @@ absl_source_set("strings") {
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/types:source_location",
]
+ public_deps = [
+ # string_view.h was once part of :strings, so string_view.h is
+ # re-exported for backwards compatibility.
+ # New code should directly depend on :string_view.
+ # TODO(crbug.com/40276308): Remove once all targets are migrated to
+ # :string_view.
+ ":string_view",
+ ]
}
absl_source_set("internal") {
@@ -128,7 +129,8 @@ absl_test("resize_and_overwrite_test") {
}
absl_source_set("append_and_overwrite") {
- sources = [ "internal/append_and_overwrite.h" ]
+ public = [ "internal/append_and_overwrite.h" ]
+ visibility = [ ":*" ]
deps = [
":resize_and_overwrite",
"//third_party/abseil-cpp/absl/base:config",
@@ -148,7 +150,27 @@ absl_test("append_and_overwrite_test") {
absl_test("match_test") {
sources = [ "match_test.cc" ]
- deps = [ ":strings" ]
+ deps = [
+ ":string_view",
+ ":strings",
+ ]
+}
+
+absl_test("escaping_test") {
+ sources = [
+ "escaping_test.cc",
+ "internal/escaping_test_common.h",
+ ]
+ deps = [
+ ":charset",
+ ":cord",
+ ":str_format",
+ ":string_view",
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/container:fixed_array",
+ "//third_party/abseil-cpp/absl/log:check",
+ ]
}
absl_test("has_absl_stringify_test") {
@@ -169,6 +191,7 @@ absl_test("has_ostream_operator_test") {
absl_test("ascii_test") {
sources = [ "ascii_test.cc" ]
deps = [
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/base:core_headers",
]
@@ -179,9 +202,32 @@ absl_test("damerau_levenshtein_distance_test") {
deps = [ ":strings" ]
}
+absl_test("memutil_test") {
+ sources = [
+ "internal/memutil.h",
+ "internal/memutil_test.cc",
+ ]
+ deps = [
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ ]
+}
+
+absl_test("utf8_test") {
+ sources = [ "internal/utf8_test.cc" ]
+ deps = [
+ ":internal",
+ ":string_view",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ ]
+}
+
absl_test("string_constant_test") {
sources = [ "internal/string_constant_test.cc" ]
- deps = [ ":strings" ]
+ deps = [
+ ":string_view",
+ ":strings",
+ ]
}
absl_test("string_view_test") {
@@ -210,10 +256,10 @@ absl_source_set("stringify_stream") {
absl_test("stringify_stream_test") {
sources = [ "internal/stringify_stream_test.cc" ]
deps = [
+ ":str_format",
":string_view",
":stringify_stream",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/strings:str_format",
]
}
@@ -229,6 +275,7 @@ absl_test("charset_test") {
sources = [ "charset_test.cc" ]
deps = [
":charset",
+ ":string_view",
":strings",
]
}
@@ -275,6 +322,7 @@ absl_test("cord_data_edge_test") {
deps = [
":cord_internal",
":cord_rep_test_util",
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/base:config",
]
@@ -290,6 +338,7 @@ absl_test("cord_rep_btree_test") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/cleanup",
+ "//third_party/abseil-cpp/absl/types:span",
]
}
@@ -312,6 +361,7 @@ 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",
]
@@ -323,13 +373,14 @@ absl_test("cord_rep_crc_test") {
":cord_internal",
":cord_rep_test_util",
"//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/crc:crc32c",
"//third_party/abseil-cpp/absl/crc:crc_cord_state",
]
}
absl_source_set("cordz_update_tracker") {
public = [ "internal/cordz_update_tracker.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
@@ -386,9 +437,10 @@ absl_source_set("cord") {
absl_source_set("cordz_handle") {
sources = [ "internal/cordz_handle.cc" ]
public = [ "internal/cordz_handle.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//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/base:raw_logging_internal",
"//third_party/abseil-cpp/absl/synchronization",
@@ -398,7 +450,7 @@ absl_source_set("cordz_handle") {
absl_source_set("cordz_info") {
sources = [ "internal/cordz_info.cc" ]
public = [ "internal/cordz_info.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":cord_internal",
":cordz_functions",
@@ -420,7 +472,7 @@ absl_source_set("cordz_info") {
absl_source_set("cordz_update_scope") {
public = [ "internal/cordz_update_scope.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":cord_internal",
":cordz_info",
@@ -445,7 +497,7 @@ absl_test("cordz_update_scope_test") {
absl_source_set("cordz_sample_token") {
sources = [ "internal/cordz_sample_token.cc" ]
public = [ "internal/cordz_sample_token.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":cordz_handle",
":cordz_info",
@@ -456,7 +508,7 @@ absl_source_set("cordz_sample_token") {
absl_source_set("cordz_functions") {
sources = [ "internal/cordz_functions.cc" ]
public = [ "internal/cordz_functions.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -467,7 +519,7 @@ absl_source_set("cordz_functions") {
absl_source_set("cordz_statistics") {
public = [ "internal/cordz_statistics.h" ]
- visibility = [ "//third_party/abseil-cpp/*" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
@@ -524,10 +576,12 @@ absl_test("cordz_info_statistics_test") {
":cordz_statistics",
":cordz_update_scope",
":cordz_update_tracker",
+ ":string_view",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/crc:crc_cord_state",
"//third_party/abseil-cpp/absl/synchronization",
"//third_party/abseil-cpp/absl/synchronization:thread_pool",
+ "//third_party/abseil-cpp/absl/time",
]
}
@@ -539,6 +593,7 @@ absl_test("cordz_sample_token_test") {
":cordz_info",
":cordz_sample_token",
":cordz_test_helpers",
+ ":cordz_update_tracker",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/random",
@@ -555,6 +610,7 @@ absl_source_set("cord_test_helpers") {
":cord",
":cord_internal",
":string_view",
+ ":strings",
"//third_party/abseil-cpp/absl/base:config",
]
}
@@ -562,20 +618,25 @@ absl_source_set("cord_test_helpers") {
absl_source_set("cord_rep_test_util") {
testonly = true
public = [ "internal/cord_rep_test_util.h" ]
+ visibility = [ ":*" ]
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",
]
}
absl_source_set("cordz_test_helpers") {
testonly = true
public = [ "cordz_test_helpers.h" ]
+ visibility = [ ":*" ]
deps = [
":cord",
":cord_internal",
+ ":cordz_functions",
":cordz_info",
":cordz_sample_token",
":cordz_statistics",
@@ -584,25 +645,25 @@ absl_source_set("cordz_test_helpers") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:nullability",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
}
absl_test("cord_buffer_test") {
- public = [ "cord_buffer_test.cc" ]
+ sources = [ "cord_buffer_test.cc" ]
deps = [
":cord",
":cord_internal",
":cord_rep_test_util",
":string_view",
"//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/types:span",
]
}
absl_test("cord_test") {
- public = [ "cord_test.cc" ]
+ sources = [ "cord_test.cc" ]
deps = [
":cord",
":cord_internal",
@@ -612,11 +673,11 @@ absl_test("cord_test") {
":cordz_test_helpers",
":cordz_update_tracker",
":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/base:endian",
- "//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/base:no_destructor",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/functional:function_ref",
@@ -650,14 +711,27 @@ absl_test("cordz_test") {
]
}
+absl_test("substitute_test") {
+ sources = [ "substitute_test.cc" ]
+ deps = [
+ ":string_view",
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ ]
+}
+
absl_test("str_replace_test") {
sources = [ "str_replace_test.cc" ]
- deps = [ ":strings" ]
+ deps = [
+ ":string_view",
+ ":strings",
+ ]
}
absl_test("str_split_test") {
sources = [ "str_split_test.cc" ]
deps = [
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:dynamic_annotations",
@@ -668,10 +742,98 @@ absl_test("str_split_test") {
]
}
+absl_test("ostringstream_test") {
+ sources = [ "internal/ostringstream_test.cc" ]
+ deps = [ ":internal" ]
+}
+
+absl_test("resize_uninitialized_test") {
+ sources = [ "internal/resize_uninitialized_test.cc" ]
+ deps = [
+ ":internal",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/meta:type_traits",
+ ]
+}
+
+absl_test("str_join_test") {
+ sources = [ "str_join_test.cc" ]
+ deps = [
+ ":string_view",
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/memory",
+ ]
+}
+
absl_test("str_cat_test") {
sources = [ "str_cat_test.cc" ]
deps = [
":str_format",
+ ":string_view",
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+}
+
+absl_test("numbers_test") {
+ sources = [
+ "internal/numbers_test_common.h",
+ "numbers_test.cc",
+ ]
+ deps = [
+ ":internal",
+ ":pow10_helper",
+ ":string_view",
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/cleanup",
+ "//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/numeric:int128",
+ "//third_party/abseil-cpp/absl/random",
+ "//third_party/abseil-cpp/absl/random:distributions",
+ ]
+}
+
+absl_test("strip_test") {
+ sources = [ "strip_test.cc" ]
+ deps = [
+ ":string_view",
+ ":strings",
+ ]
+}
+
+absl_test("charconv_test") {
+ sources = [ "charconv_test.cc" ]
+ deps = [
+ ":pow10_helper",
+ ":str_format",
+ ":string_view",
+ ":strings",
+ ]
+}
+
+absl_test("charconv_parse_test") {
+ sources = [
+ "internal/charconv_parse.h",
+ "internal/charconv_parse_test.cc",
+ ]
+ deps = [
+ ":string_view",
+ ":strings",
+ "//third_party/abseil-cpp/absl/base:config",
+ "//third_party/abseil-cpp/absl/log:check",
+ ]
+}
+
+absl_test("charconv_bigint_test") {
+ sources = [
+ "internal/charconv_bigint.h",
+ "internal/charconv_bigint_test.cc",
+ "internal/charconv_parse.h",
+ ]
+ deps = [
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/base:config",
]
@@ -722,7 +884,6 @@ absl_source_set("str_format_internal") {
"//third_party/abseil-cpp/absl/numeric:bits",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/numeric:representation",
- "//third_party/abseil-cpp/absl/types:optional",
"//third_party/abseil-cpp/absl/types:span",
"//third_party/abseil-cpp/absl/utility",
]
@@ -733,6 +894,8 @@ absl_test("str_format_test") {
deps = [
":cord",
":str_format",
+ ":str_format_internal",
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -745,6 +908,7 @@ absl_test("str_format_extension_test") {
deps = [
":str_format",
":str_format_internal",
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/random",
]
@@ -761,32 +925,40 @@ absl_test("str_format_arg_test") {
absl_test("str_format_bind_test") {
sources = [ "internal/str_format/bind_test.cc" ]
- deps = [ ":str_format_internal" ]
+ deps = [
+ ":str_format_internal",
+ ":string_view",
+ "//third_party/abseil-cpp/absl/types:span",
+ ]
}
absl_test("str_format_checker_test") {
sources = [ "internal/str_format/checker_test.cc" ]
- deps = [ ":str_format" ]
+ deps = [
+ ":str_format",
+ ":string_view",
+ ]
}
absl_test("str_format_convert_test") {
- if (is_fuchsia) {
- # This test fails to compile on fuchsia x64 bot
- sources = []
- } else {
- sources = [ "internal/str_format/convert_test.cc" ]
- }
+ sources = [ "internal/str_format/convert_test.cc" ]
deps = [
":str_format",
":str_format_internal",
+ ":string_view",
":strings",
+ "//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:raw_logging_internal",
"//third_party/abseil-cpp/absl/log",
+ "//third_party/abseil-cpp/absl/log:absl_check",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/types:span",
]
+ if (is_fuchsia) {
+ sources = []
+ }
}
absl_test("str_format_output_test") {
@@ -815,6 +987,14 @@ absl_source_set("pow10_helper") {
deps = [ "//third_party/abseil-cpp/absl/base:config" ]
}
+absl_test("pow10_helper_test") {
+ sources = [ "internal/pow10_helper_test.cc" ]
+ deps = [
+ ":pow10_helper",
+ ":str_format",
+ ]
+}
+
absl_test("char_formatting_test") {
sources = [ "char_formatting_test.cc" ]
deps = [
@@ -832,6 +1012,7 @@ absl_source_set("generic_printer") {
visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":str_format",
+ ":string_view",
":strings",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/log/internal:container",
@@ -839,29 +1020,12 @@ absl_source_set("generic_printer") {
]
}
-absl_test("numbers_test") {
- sources = [
- "internal/numbers_test_common.h",
- "numbers_test.cc",
- ]
- deps = [
- ":internal",
- ":pow10_helper",
- ":strings",
- "//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/cleanup",
- "//third_party/abseil-cpp/absl/log",
- "//third_party/abseil-cpp/absl/numeric:int128",
- "//third_party/abseil-cpp/absl/random",
- "//third_party/abseil-cpp/absl/random:distributions",
- ]
-}
-
absl_test("generic_printer_test") {
sources = [ "internal/generic_printer_test.cc" ]
deps = [
":generic_printer",
":str_format",
+ ":string_view",
":strings",
"//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/strings/CMakeLists.txt b/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt
index a9fa1f9e0c1..3ea24fea105 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/CMakeLists.txt
@@ -1165,7 +1165,6 @@ absl_cc_test(
absl::endian
absl::fixed_array
absl::function_ref
- absl::hardening
absl::hash
absl::hash_testing
absl::no_destructor
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/ascii_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/ascii_test.cc
index fe1083a5783..6afae493790 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/ascii_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/ascii_test.cc
@@ -18,6 +18,7 @@
#include <cctype>
#include <clocale>
#include <cstring>
+#include <iterator>
#include <string>
#include "gtest/gtest.h"
@@ -362,7 +363,7 @@ TEST(RemoveExtraAsciiWhitespace, InPlace) {
"",
"a\nb",
};
- const int NUM_TESTS = ABSL_ARRAYSIZE(inputs);
+ const int NUM_TESTS = std::size(inputs);
for (int i = 0; i < NUM_TESTS; i++) {
std::string s(inputs[i]);
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 7e80259c77d..fad5d976f86 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord.h
@@ -177,7 +177,7 @@ enum class CordMemoryAccounting {
// Additionally, the API provides iterator utilities to iterate through Cord
// data via chunks or character bytes.
//
-class Cord {
+class ABSL_ATTRIBUTE_TRIVIAL_ABI Cord {
private:
template <typename T>
using EnableIfString = std::enable_if_t<std::is_same_v<T, std::string>, int>;
@@ -915,10 +915,10 @@ class Cord {
// to the representation.
//
// InlineRep holds either a tree pointer, or an array of kMaxInline bytes.
- class InlineRep {
+ class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineRep {
public:
static constexpr unsigned char kMaxInline = cord_internal::kMaxInline;
- static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*), "");
+ static_assert(kMaxInline >= sizeof(absl::cord_internal::CordRep*));
constexpr InlineRep() : data_() {}
explicit InlineRep(InlineData::DefaultInitType init) : data_(init) {}
@@ -1124,7 +1124,6 @@ class Cord {
void CopyToArrayImpl(char* absl_nonnull dst) const;
};
-
// allow a Cord to be logged
extern std::ostream& operator<<(std::ostream& out, const Cord& cord);
@@ -1285,7 +1284,7 @@ inline size_t Cord::InlineRep::size() const {
inline cord_internal::CordRepFlat* absl_nonnull
Cord::InlineRep::MakeFlatWithExtraCapacity(size_t extra) {
- static_assert(cord_internal::kMinFlatLength >= sizeof(data_), "");
+ static_assert(cord_internal::kMinFlatLength >= sizeof(data_));
size_t len = data_.inline_size();
auto* result = CordRepFlat::New(len + extra);
result->length = len;
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer.h b/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer.h
index fc806bb4676..c3803eb1fcd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer.h
@@ -37,6 +37,7 @@
#include "absl/numeric/bits.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_flat.h"
+#include "absl/strings/string_view.h"
#include "absl/types/span.h"
namespace absl {
@@ -290,7 +291,7 @@ class CordBuffer {
private:
// Make sure we don't accidentally over promise.
- static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize, "");
+ static_assert(kCustomLimit <= cord_internal::kMaxLargeFlatSize);
// Assume the cost of an 'uprounded' allocation to CeilPow2(size) versus
// the cost of allocating at least 1 extra flat <= 4KB:
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer_test.cc
index ab628081b0e..c1b2396536e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord_buffer_test.cc
@@ -14,7 +14,6 @@
#include "absl/strings/cord_buffer.h"
-
#include <algorithm>
#include <cstring>
#include <limits>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cord_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/cord_test.cc
index d748ff01a72..1ff172ee244 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord_test.cc
@@ -38,7 +38,6 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/macros.h"
#include "absl/base/no_destructor.h"
#include "absl/base/options.h"
@@ -277,9 +276,9 @@ INSTANTIATE_TEST_SUITE_P(WithParam, CordTest, testing::Bool(),
TEST(CordRepFlat, AllFlatCapacities) {
// Explicitly and redundantly assert built-in min/max limits
- static_assert(absl::cord_internal::kFlatOverhead < 32, "");
- static_assert(absl::cord_internal::kMinFlatSize == 32, "");
- static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10, "");
+ static_assert(absl::cord_internal::kFlatOverhead < 32);
+ static_assert(absl::cord_internal::kMinFlatSize == 32);
+ static_assert(absl::cord_internal::kMaxLargeFlatSize == 256 << 10);
EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(FLAT), 32);
EXPECT_EQ(absl::cord_internal::TagToAllocatedSize(MAX_FLAT_TAG), 256 << 10);
@@ -1629,8 +1628,8 @@ TEST_P(CordTest, CompareRandomComparisons) {
for (int i = 0; i < kIters; i++) {
absl::Cord c, d;
for (int j = 0; j < (i % 7) + 1; j++) {
- c.Append(a[GetUniformRandomUpTo(&rng, ABSL_ARRAYSIZE(a))]);
- d.Append(a[GetUniformRandomUpTo(&rng, ABSL_ARRAYSIZE(a))]);
+ c.Append(a[GetUniformRandomUpTo(&rng, std::size(a))]);
+ d.Append(a[GetUniformRandomUpTo(&rng, std::size(a))]);
}
std::bernoulli_distribution coin_flip(0.5);
MaybeHarden(c);
@@ -2364,35 +2363,30 @@ TEST_P(CordTest, MakeFragmentedCordFromVector) {
}
TEST_P(CordTest, CordChunkIteratorTraits) {
- static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>, "");
- static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>, "");
+ static_assert(std::is_copy_constructible_v<absl::Cord::ChunkIterator>);
+ static_assert(std::is_copy_assignable_v<absl::Cord::ChunkIterator>);
// Move semantics to satisfy swappable via std::swap
- static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>, "");
- static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>, "");
+ static_assert(std::is_move_constructible_v<absl::Cord::ChunkIterator>);
+ static_assert(std::is_move_assignable_v<absl::Cord::ChunkIterator>);
static_assert(
std::is_same_v<
std::iterator_traits<absl::Cord::ChunkIterator>::iterator_category,
- std::input_iterator_tag>,
- "");
+ std::input_iterator_tag>);
static_assert(std::is_same_v<
- std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
- absl::string_view>,
- "");
+ std::iterator_traits<absl::Cord::ChunkIterator>::value_type,
+ absl::string_view>);
static_assert(
std::is_same_v<
std::iterator_traits<absl::Cord::ChunkIterator>::difference_type,
- ptrdiff_t>,
- "");
+ ptrdiff_t>);
static_assert(
std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::pointer,
- const absl::string_view*>,
- "");
+ const absl::string_view*>);
static_assert(
std::is_same_v<std::iterator_traits<absl::Cord::ChunkIterator>::reference,
- absl::string_view>,
- "");
+ absl::string_view>);
}
static void VerifyChunkIterator(const absl::Cord& cord,
@@ -2551,35 +2545,29 @@ TEST_P(CordTest, AdvanceAndReadOnSubstringDataEdge) {
}
TEST_P(CordTest, CharIteratorTraits) {
- static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>, "");
- static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>, "");
+ static_assert(std::is_copy_constructible_v<absl::Cord::CharIterator>);
+ static_assert(std::is_copy_assignable_v<absl::Cord::CharIterator>);
// Move semantics to satisfy swappable via std::swap
- static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>, "");
- static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>, "");
+ static_assert(std::is_move_constructible_v<absl::Cord::CharIterator>);
+ static_assert(std::is_move_assignable_v<absl::Cord::CharIterator>);
static_assert(
std::is_same_v<
std::iterator_traits<absl::Cord::CharIterator>::iterator_category,
- std::input_iterator_tag>,
- "");
+ std::input_iterator_tag>);
static_assert(
std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::value_type,
- char>,
- "");
- static_assert(
- std::is_same_v<
- std::iterator_traits<absl::Cord::CharIterator>::difference_type,
- ptrdiff_t>,
- "");
+ char>);
+ static_assert(std::is_same_v<
+ std::iterator_traits<absl::Cord::CharIterator>::difference_type,
+ ptrdiff_t>);
static_assert(
std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::pointer,
- const char*>,
- "");
+ const char*>);
static_assert(
std::is_same_v<std::iterator_traits<absl::Cord::CharIterator>::reference,
- const char&>,
- "");
+ const char&>);
}
static void VerifyCharIterator(const absl::Cord& cord) {
@@ -2827,7 +2815,6 @@ TEST_P(CordTest, Hardening) {
}());
if (!test_hardening) return;
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH_IF_SUPPORTED(cord[5], "");
EXPECT_DEATH_IF_SUPPORTED(*cord.chunk_end(), "");
EXPECT_DEATH_IF_SUPPORTED(static_cast<void>(cord.chunk_end()->empty()), "");
@@ -3425,69 +3412,3 @@ TEST(CordThreeWayComparisonTest, CompareCordsAndStringViews) {
std::strong_ordering::greater);
#endif
}
-
-#if defined(GTEST_HAS_DEATH_TEST) && defined(ABSL_INTERNAL_CORD_HAVE_SANITIZER)
-
-// Returns an expected poison / uninitialized death message expression.
-const char* MASanDeathExpr() {
- return "(use-after-poison|use-of-uninitialized-value)";
-}
-
-TEST(CordSanitizerTest, SanitizesEmptyCord) {
- absl::Cord cord;
- const char* data = cord.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[0], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesSmallCord) {
- absl::Cord cord("Hello");
- const char* data = cord.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesCordOnSetSSOValue) {
- absl::Cord cord("String that is too big to be an SSO value");
- cord = "Hello";
- const char* data = cord.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesCordOnCopyCtor) {
- absl::Cord src("hello");
- absl::Cord dst(src);
- const char* data = dst.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesCordOnMoveCtor) {
- absl::Cord src("hello");
- absl::Cord dst(std::move(src));
- const char* data = dst.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesCordOnAssign) {
- absl::Cord src("hello");
- absl::Cord dst;
- dst = src;
- const char* data = dst.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesCordOnMoveAssign) {
- absl::Cord src("hello");
- absl::Cord dst;
- dst = std::move(src);
- const char* data = dst.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-TEST(CordSanitizerTest, SanitizesCordOnSsoAssign) {
- absl::Cord src("hello");
- absl::Cord dst("String that is too big to be an SSO value");
- dst = src;
- const char* data = dst.Flatten().data();
- EXPECT_DEATH(EXPECT_EQ(data[5], 0), MASanDeathExpr());
-}
-
-#endif // GTEST_HAS_DEATH_TEST && ABSL_INTERNAL_CORD_HAVE_SANITIZER
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cord_test_helpers.h b/deps/v8/third_party/abseil-cpp/absl/strings/cord_test_helpers.h
index ca52240a146..715e980a0b7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cord_test_helpers.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cord_test_helpers.h
@@ -17,13 +17,16 @@
#ifndef ABSL_STRINGS_CORD_TEST_HELPERS_H_
#define ABSL_STRINGS_CORD_TEST_HELPERS_H_
+#include <cstddef>
#include <cstdint>
+#include <initializer_list>
#include <iostream>
#include <string>
#include "absl/base/config.h"
#include "absl/strings/cord.h"
#include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/string_view.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/cordz_test_helpers.h b/deps/v8/third_party/abseil-cpp/absl/strings/cordz_test_helpers.h
index 66232db7caa..6a290307c50 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/cordz_test_helpers.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/cordz_test_helpers.h
@@ -15,6 +15,8 @@
#ifndef ABSL_STRINGS_CORDZ_TEST_HELPERS_H_
#define ABSL_STRINGS_CORDZ_TEST_HELPERS_H_
+#include <cstdint>
+#include <cstring>
#include <utility>
#include "gmock/gmock.h"
@@ -24,6 +26,7 @@
#include "absl/base/nullability.h"
#include "absl/strings/cord.h"
#include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/internal/cordz_functions.h"
#include "absl/strings/internal/cordz_info.h"
#include "absl/strings/internal/cordz_sample_token.h"
#include "absl/strings/internal/cordz_statistics.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/escaping.cc b/deps/v8/third_party/abseil-cpp/absl/strings/escaping.cc
index 1ed7c24cafd..efe90412e6f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/escaping.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/escaping.cc
@@ -389,39 +389,35 @@ constexpr std::array<unsigned char, 256> kCEscapedLen = {
};
/* clang-format on */
-constexpr uint32_t MakeCEscapedLittleEndianUint32(size_t c) {
- size_t char_len = kCEscapedLen[c];
- if (char_len == 1) {
- return static_cast<uint32_t>(c);
- }
- if (char_len == 2) {
- switch (c) {
- case '\n':
- return '\\' | (static_cast<uint32_t>('n') << 8);
- case '\r':
- return '\\' | (static_cast<uint32_t>('r') << 8);
- case '\t':
- return '\\' | (static_cast<uint32_t>('t') << 8);
- case '\"':
- return '\\' | (static_cast<uint32_t>('\"') << 8);
- case '\'':
- return '\\' | (static_cast<uint32_t>('\'') << 8);
- case '\\':
- return '\\' | (static_cast<uint32_t>('\\') << 8);
+constexpr std::array<std::array<char, 4>, 256> kCEscapedSequence = []() {
+ std::array<std::array<char, 4>, 256> a{};
+ for (size_t c = 0; c < 256; ++c) {
+ size_t char_len = kCEscapedLen[c];
+ if (char_len == 1) {
+ a[c][0] = static_cast<char>(c);
+ } else if (char_len == 2) {
+ a[c][0] = '\\';
+ // clang-format off
+ switch (c) {
+ case '\n': a[c][1] = 'n'; break;
+ case '\r': a[c][1] = 'r'; break;
+ case '\t': a[c][1] = 't'; break;
+ case '\"': a[c][1] = '\"'; break;
+ case '\'': a[c][1] = '\''; break;
+ case '\\': a[c][1] = '\\'; break;
+ }
+ // clang-format on
+ } else {
+ assert(char_len == 4);
+ // A backslash followed by the octal value of the byte.
+ a[c][0] = '\\';
+ a[c][1] = static_cast<char>('0' + (c / 64));
+ a[c][2] = static_cast<char>('0' + ((c % 64) / 8));
+ a[c][3] = static_cast<char>('0' + (c % 8));
}
}
- return static_cast<uint32_t>('\\' | (('0' + (c / 64)) << 8) |
- (('0' + ((c % 64) / 8)) << 16) |
- (('0' + (c % 8)) << 24));
-}
-
-template <size_t... indexes>
-inline constexpr std::array<uint32_t, sizeof...(indexes)>
-MakeCEscapedLittleEndianUint32Array(std::index_sequence<indexes...>) {
- return {MakeCEscapedLittleEndianUint32(indexes)...};
-}
-constexpr std::array<uint32_t, 256> kCEscapedLittleEndianUint32Array =
- MakeCEscapedLittleEndianUint32Array(std::make_index_sequence<256>());
+ return a;
+}();
// Calculates the length of the C-style escaped version of 'src'.
// Assumes that non-printable characters are escaped using octal sequences, and
@@ -456,8 +452,8 @@ void CEscapeAndAppendInternal(absl::string_view src,
return;
}
- // We keep 3 slop bytes so that we can call `little_endian::Store32`
- // invariably regardless of the length of the escaped character.
+ // The small `memcpy` is faster when the size is a compile-time constant, so
+ // keep 3 slop bytes so that we can call memcpy with size=4.
constexpr size_t kSlopBytes = 3;
ABSL_INTERNAL_CHECK(
escaped_len <= std::numeric_limits<size_t>::max() - kSlopBytes,
@@ -467,10 +463,8 @@ void CEscapeAndAppendInternal(absl::string_view src,
*dest, append_buf_len, [src, escaped_len](char* append_ptr, size_t) {
for (char c : src) {
unsigned char uc = static_cast<unsigned char>(c);
- size_t char_len = kCEscapedLen[uc];
- uint32_t little_endian_uint32 = kCEscapedLittleEndianUint32Array[uc];
- little_endian::Store32(append_ptr, little_endian_uint32);
- append_ptr += char_len;
+ memcpy(append_ptr, kCEscapedSequence[uc].data(), 4);
+ append_ptr += kCEscapedLen[uc];
}
return escaped_len;
});
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 fdbc3933421..103492be1c9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/escaping.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/escaping.h
@@ -23,6 +23,7 @@
#ifndef ABSL_STRINGS_ESCAPING_H_
#define ABSL_STRINGS_ESCAPING_H_
+#include <cassert>
#include <cstddef>
#include <optional>
#include <string>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/escaping_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/escaping_test.cc
index a564e832aac..e4a3868f7e6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/escaping_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/escaping_test.cc
@@ -19,6 +19,7 @@
#include <cstdio>
#include <cstring>
#include <initializer_list>
+#include <iterator>
#include <memory>
#include <optional>
#include <string>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/has_absl_stringify.h b/deps/v8/third_party/abseil-cpp/absl/strings/has_absl_stringify.h
index 45843ae1697..5bc87914f12 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/has_absl_stringify.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/has_absl_stringify.h
@@ -15,6 +15,7 @@
#ifndef ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
#define ABSL_STRINGS_HAS_ABSL_STRINGIFY_H_
+#include <cstddef>
#include <type_traits>
#include <utility>
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 9185f1f9f17..e91e90bd4ef 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
@@ -16,8 +16,12 @@
#include <algorithm>
#include <cassert>
+#include <cstdint>
+#include <iterator>
#include <string>
+#include "absl/strings/internal/charconv_parse.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace strings_internal {
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 7bbf16df121..8d9f62d5abb 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
@@ -14,6 +14,8 @@
#include "absl/strings/internal/charconv_bigint.h"
+#include <cstdint>
+#include <limits>
#include <string>
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
index 2b7b082114b..c10b77ba0c7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/charconv_parse_test.cc
@@ -14,13 +14,16 @@
#include "absl/strings/internal/charconv_parse.h"
+#include <cstdint>
#include <string>
#include <utility>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/log/check.h"
+#include "absl/strings/charconv.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
using absl::chars_format;
using absl::strings_internal::FloatType;
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 8fce3bc6a97..58046febbb0 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
@@ -18,6 +18,7 @@
#include "gtest/gtest.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_test_util.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 becfc6aa769..79e446181b3 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
@@ -17,6 +17,7 @@
#include <cassert>
#include <memory>
+#include "absl/base/attributes.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 98dc4b524b2..cf45907d109 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
@@ -22,6 +22,7 @@
#include <cstring>
#include <limits>
#include <string>
+#include <type_traits>
#include "absl/base/attributes.h"
#include "absl/base/config.h"
@@ -34,16 +35,6 @@
#include "absl/container/internal/container_memory.h"
#include "absl/strings/string_view.h"
-// We can only add poisoning if we can detect consteval executions.
-#if defined(ABSL_HAVE_CONSTANT_EVALUATED) && \
- (defined(ABSL_HAVE_ADDRESS_SANITIZER) || \
- defined(ABSL_HAVE_MEMORY_SANITIZER))
-#define ABSL_INTERNAL_CORD_HAVE_SANITIZER 1
-#endif
-
-#define ABSL_CORD_INTERNAL_NO_SANITIZE \
- ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NO_SANITIZE_MEMORY
-
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace cord_internal {
@@ -465,8 +456,8 @@ using cordz_info_t = int64_t;
// Assert that the `cordz_info` pointer value perfectly overlaps the last half
// of `data` and can hold a pointer value.
-static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1, "");
-static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t), "");
+static_assert(sizeof(cordz_info_t) * 2 == kMaxInline + 1);
+static_assert(sizeof(cordz_info_t) >= sizeof(intptr_t));
// LittleEndianByte() creates a little endian representation of 'value', i.e.:
// a little endian value where the first byte in the host's representation
@@ -479,7 +470,7 @@ static constexpr cordz_info_t LittleEndianByte(unsigned char value) {
#endif
}
-class InlineData {
+class ABSL_ATTRIBUTE_TRIVIAL_ABI InlineData {
public:
// DefaultInitType forces the use of the default initialization constructor.
enum DefaultInitType { kDefaultInit };
@@ -495,18 +486,9 @@ class InlineData {
// is actively inspected and used by gdb pretty printing code.
static constexpr size_t kTagOffset = 0;
- // Implement `~InlineData()` conditionally: we only need this destructor to
- // unpoison poisoned instances under *SAN, and it will only compile correctly
- // if the current compiler supports `absl::is_constant_evaluated()`.
-#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
- ~InlineData() noexcept { unpoison(); }
-#endif
-
- constexpr InlineData() noexcept { poison_this(); }
+ InlineData() = default;
- explicit InlineData(DefaultInitType) noexcept : rep_(kDefaultInit) {
- poison_this();
- }
+ explicit InlineData(DefaultInitType) noexcept : rep_(kDefaultInit) {}
explicit InlineData(CordRep* rep) noexcept : rep_(rep) {
ABSL_ASSERT(rep != nullptr);
@@ -516,37 +498,20 @@ class InlineData {
// value. Creates an inlined SSO value if `rep` is null, otherwise
// creates a tree instance value.
constexpr InlineData(absl::string_view sv, CordRep* rep) noexcept
- : rep_(rep ? Rep(rep) : Rep(sv)) {
- poison();
- }
+ : rep_(rep != nullptr ? Rep(rep) : Rep(sv)) {}
- constexpr InlineData(const InlineData& rhs) noexcept;
- InlineData& operator=(const InlineData& rhs) noexcept;
+ constexpr InlineData(const InlineData& rhs) noexcept = default;
+ InlineData& operator=(const InlineData& rhs) noexcept = default;
friend void swap(InlineData& lhs, InlineData& rhs) noexcept;
friend bool operator==(const InlineData& lhs, const InlineData& rhs) {
-#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
- const Rep l = lhs.rep_.SanitizerSafeCopy();
- const Rep r = rhs.rep_.SanitizerSafeCopy();
- return memcmp(&l, &r, sizeof(l)) == 0;
-#else
return memcmp(&lhs, &rhs, sizeof(lhs)) == 0;
-#endif
}
+
friend bool operator!=(const InlineData& lhs, const InlineData& rhs) {
return !operator==(lhs, rhs);
}
- // Poisons the unused inlined SSO data if the current instance
- // is inlined, else un-poisons the entire instance.
- constexpr void poison();
-
- // Un-poisons this instance.
- constexpr void unpoison();
-
- // Poisons the current instance. This is used on default initialization.
- constexpr void poison_this();
-
// Returns true if the current instance is empty.
// The 'empty value' is an inlined data value of zero length.
bool is_empty() const { return rep_.tag() == 0; }
@@ -631,10 +596,8 @@ class InlineData {
void set_inline_data(const char* data, size_t n) {
ABSL_ASSERT(n <= kMaxInline);
- unpoison();
rep_.set_tag(static_cast<int8_t>(n << 1));
SmallMemmove<true>(rep_.as_chars(), data, n);
- poison();
}
void CopyInlineToString(std::string* dst) const {
@@ -658,7 +621,6 @@ class InlineData {
// Initialize this instance to holding the tree value `rep`,
// initializing the cordz_info to null, i.e.: 'not profiled'.
void make_tree(CordRep* rep) {
- unpoison();
rep_.make_tree(rep);
}
@@ -678,9 +640,7 @@ class InlineData {
// Requires `size` to be <= kMaxInline.
// See the documentation on 'as_chars()' for more information and examples.
void set_inline_size(size_t size) {
- unpoison();
rep_.set_inline_size(size);
- poison();
}
// Compares 'this' inlined data with rhs. The comparison is a straightforward
@@ -728,73 +688,36 @@ class InlineData {
GetOrNull(chars, 13),
GetOrNull(chars, 14)} {}
-#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
- // Break compiler optimization for cases when value is allocated on the
- // stack. Compiler assumes that the the variable is fully accessible
- // regardless of our poisoning.
- // Missing report: https://github.com/llvm/llvm-project/issues/100640
- const Rep* self() const {
- const Rep* volatile ptr = this;
- return ptr;
- }
- Rep* self() {
- Rep* volatile ptr = this;
- return ptr;
- }
-#else
- constexpr const Rep* self() const { return this; }
- constexpr Rep* self() { return this; }
-#endif
-
- // Disable sanitizer as we must always be able to read `tag`.
- ABSL_CORD_INTERNAL_NO_SANITIZE
int8_t tag() const { return reinterpret_cast<const int8_t*>(this)[0]; }
- void set_tag(int8_t rhs) { reinterpret_cast<int8_t*>(self())[0] = rhs; }
+ void set_tag(int8_t rhs) { reinterpret_cast<int8_t*>(this)[0] = rhs; }
- char* as_chars() { return self()->data + 1; }
- const char* as_chars() const { return self()->data + 1; }
+ char* as_chars() { return this->data + 1; }
+ const char* as_chars() const { return this->data + 1; }
- bool is_tree() const { return (self()->tag() & 1) != 0; }
+ bool is_tree() const { return (this->tag() & 1) != 0; }
size_t inline_size() const {
- ABSL_ASSERT(!self()->is_tree());
- return static_cast<size_t>(self()->tag()) >> 1;
+ ABSL_ASSERT(!this->is_tree());
+ return static_cast<size_t>(this->tag()) >> 1;
}
void set_inline_size(size_t size) {
ABSL_ASSERT(size <= kMaxInline);
- self()->set_tag(static_cast<int8_t>(size << 1));
+ this->set_tag(static_cast<int8_t>(size << 1));
}
- CordRep* tree() const { return self()->as_tree.rep; }
- void set_tree(CordRep* rhs) { self()->as_tree.rep = rhs; }
+ CordRep* tree() const { return this->as_tree.rep; }
+ void set_tree(CordRep* rhs) { this->as_tree.rep = rhs; }
- cordz_info_t cordz_info() const { return self()->as_tree.cordz_info; }
- void set_cordz_info(cordz_info_t rhs) { self()->as_tree.cordz_info = rhs; }
+ cordz_info_t cordz_info() const { return this->as_tree.cordz_info; }
+ void set_cordz_info(cordz_info_t rhs) { this->as_tree.cordz_info = rhs; }
void make_tree(CordRep* tree) {
- self()->as_tree.rep = tree;
- self()->as_tree.cordz_info = kNullCordzInfo;
+ this->as_tree.rep = tree;
+ this->as_tree.cordz_info = kNullCordzInfo;
}
-#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
- constexpr Rep SanitizerSafeCopy() const {
- if (!absl::is_constant_evaluated()) {
- Rep res;
- if (is_tree()) {
- res = *this;
- } else {
- res.set_tag(tag());
- memcpy(res.as_chars(), as_chars(), inline_size());
- }
- return res;
- } else {
- return *this;
- }
- }
-#else
constexpr const Rep& SanitizerSafeCopy() const { return *this; }
-#endif
// If the data has length <= kMaxInline, we store it in `data`, and
// store the size in the first char of `data` shifted left + 1.
@@ -833,59 +756,7 @@ class InlineData {
Rep rep_;
};
-static_assert(sizeof(InlineData) == kMaxInline + 1, "");
-
-#ifdef ABSL_INTERNAL_CORD_HAVE_SANITIZER
-
-constexpr InlineData::InlineData(const InlineData& rhs) noexcept
- : rep_(rhs.rep_.SanitizerSafeCopy()) {
- poison();
-}
-
-inline InlineData& InlineData::operator=(const InlineData& rhs) noexcept {
- unpoison();
- rep_ = rhs.rep_.SanitizerSafeCopy();
- poison();
- return *this;
-}
-
-constexpr void InlineData::poison_this() {
- if (!absl::is_constant_evaluated()) {
- container_internal::SanitizerPoisonObject(this);
- }
-}
-
-constexpr void InlineData::unpoison() {
- if (!absl::is_constant_evaluated()) {
- container_internal::SanitizerUnpoisonObject(this);
- }
-}
-
-constexpr void InlineData::poison() {
- if (!absl::is_constant_evaluated()) {
- if (is_tree()) {
- container_internal::SanitizerUnpoisonObject(this);
- } else if (const size_t size = inline_size()) {
- if (size < kMaxInline) {
- const char* end = rep_.as_chars() + size;
- container_internal::SanitizerPoisonMemoryRegion(end, kMaxInline - size);
- }
- } else {
- container_internal::SanitizerPoisonObject(this);
- }
- }
-}
-
-#else // ABSL_INTERNAL_CORD_HAVE_SANITIZER
-
-constexpr InlineData::InlineData(const InlineData&) noexcept = default;
-inline InlineData& InlineData::operator=(const InlineData&) noexcept = default;
-
-constexpr void InlineData::poison_this() {}
-constexpr void InlineData::unpoison() {}
-constexpr void InlineData::poison() {}
-
-#endif // ABSL_INTERNAL_CORD_HAVE_SANITIZER
+static_assert(sizeof(InlineData) == kMaxInline + 1);
inline CordRepSubstring* CordRep::substring() {
assert(IsSubstring());
@@ -923,16 +794,12 @@ inline void CordRep::Unref(CordRep* rep) {
}
inline void swap(InlineData& lhs, InlineData& rhs) noexcept {
- lhs.unpoison();
- rhs.unpoison();
// TODO(b/145829486): `std::swap(lhs.rep_, rhs.rep_)` results in bad codegen
// on clang, spilling the temporary swap value on the stack. Since `Rep` is
// trivial, we can make clang DTRT by calling a hand-rolled `SwapValue` where
// we pass `rhs` both by value (register allocated) and by reference. The IR
// then folds and inlines correctly into an optimized swap without spill.
lhs.rep_.SwapValue(rhs.rep_, rhs.rep_);
- rhs.poison();
- lhs.poison();
}
} // namespace cord_internal
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc
index 92e64509f83..7de2a137894 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.cc
@@ -14,9 +14,12 @@
#include "absl/strings/internal/cord_rep_btree.h"
+#include <algorithm>
#include <atomic>
#include <cassert>
+#include <cstddef>
#include <cstdint>
+#include <cstring>
#include <iostream>
#include <ostream>
#include <string>
@@ -31,6 +34,7 @@
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -278,7 +282,7 @@ struct StackOperations {
return tree;
case CordRepBtree::kCopied:
CordRep::Unref(tree);
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case CordRepBtree::kSelf:
return result.tree;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h
index ab259afe64a..f65373526ed 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree.h
@@ -15,8 +15,11 @@
#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_H_
+#include <algorithm>
#include <cassert>
+#include <cstddef>
#include <cstdint>
+#include <cstring>
#include <iosfwd>
#include "absl/base/config.h"
@@ -865,16 +868,16 @@ inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) {
tree = tree->Edge(kBack)->btree();
if (!tree->refcount.IsOne()) return {};
n2 = tree;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 2:
tree = tree->Edge(kBack)->btree();
if (!tree->refcount.IsOne()) return {};
n1 = tree;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 1:
tree = tree->Edge(kBack)->btree();
if (!tree->refcount.IsOne()) return {};
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 0:
CordRep* edge = tree->Edge(kBack);
if (!edge->refcount.IsOne()) return {};
@@ -887,13 +890,13 @@ inline Span<char> CordRepBtree::GetAppendBuffer(size_t size) {
switch (height) {
case 3:
n3->length += delta;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 2:
n2->length += delta;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 1:
n1->length += delta;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 0:
tree->length += delta;
return span;
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 6ed20c23a7f..707e5c8effb 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
@@ -15,6 +15,8 @@
#include "absl/strings/internal/cord_rep_btree_navigator.h"
#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.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 3d581c877e2..1024525d4a7 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
@@ -16,8 +16,11 @@
#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_NAVIGATOR_H_
#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <iostream>
+#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_btree_navigator_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator_test.cc
index bed7550823c..6e4a79b6536 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_navigator_test.cc
@@ -14,6 +14,7 @@
#include "absl/strings/internal/cord_rep_btree_navigator.h"
+#include <cstddef>
#include <string>
#include <vector>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc
index 0d0e860139e..660f2406728 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.cc
@@ -15,6 +15,7 @@
#include "absl/strings/internal/cord_rep_btree_reader.h"
#include <cassert>
+#include <cstddef>
#include "absl/base/config.h"
#include "absl/strings/internal/cord_data_edge.h"
@@ -22,6 +23,7 @@
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_btree_navigator.h"
#include "absl/strings/internal/cord_rep_flat.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h
index 8db8f8dd171..46ed3523d92 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader.h
@@ -16,13 +16,16 @@
#define ABSL_STRINGS_INTERNAL_CORD_REP_BTREE_READER_H_
#include <cassert>
+#include <cstddef>
#include "absl/base/config.h"
+#include "absl/base/optimization.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_btree_navigator.h"
#include "absl/strings/internal/cord_rep_flat.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader_test.cc
index b4cdd8e58ba..684da35416e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_reader_test.cc
@@ -14,6 +14,8 @@
#include "absl/strings/internal/cord_rep_btree_reader.h"
+#include <algorithm>
+#include <cstddef>
#include <iostream>
#include <random>
#include <string>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_test.cc
index 0950617cc6c..6b8e628806f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_btree_test.cc
@@ -14,9 +14,14 @@
#include "absl/strings/internal/cord_rep_btree.h"
+#include <cassert>
#include <cmath>
+#include <cstddef>
+#include <cstdint>
#include <deque>
#include <iostream>
+#include <random>
+#include <sstream>
#include <string>
#include <vector>
@@ -27,9 +32,11 @@
#include "absl/cleanup/cleanup.h"
#include "absl/strings/internal/cord_data_edge.h"
#include "absl/strings/internal/cord_internal.h"
+#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cord_rep_test_util.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 db7d4fefc4b..8b6af152f8e 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
@@ -15,6 +15,7 @@
#include "absl/strings/internal/cord_rep_consume.h"
#include <array>
+#include <cstddef>
#include <utility>
#include "absl/container/inlined_vector.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 bece1874ac4..cdb06ba17f5 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
@@ -15,6 +15,7 @@
#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_CONSUME_H_
+#include <cstddef>
#include <functional>
#include "absl/functional/function_ref.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc
index dbe54cc4006..50e1cb99dcd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc.cc
@@ -19,6 +19,7 @@
#include <utility>
#include "absl/base/config.h"
+#include "absl/crc/internal/crc_cord_state.h"
#include "absl/strings/internal/cord_internal.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc_test.cc
index 3d27c33c179..feeaac678bc 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_crc_test.cc
@@ -14,9 +14,12 @@
#include "absl/strings/internal/cord_rep_crc.h"
+#include <cstdint>
+
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/config.h"
+#include "absl/crc/crc32c.h"
#include "absl/crc/internal/crc_cord_state.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_test_util.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 27c4b21eb5f..34da171199e 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
@@ -15,9 +15,11 @@
#ifndef ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_
#define ABSL_STRINGS_INTERNAL_CORD_REP_FLAT_H_
+#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
+#include <cstring>
#include <memory>
#include "absl/base/config.h"
@@ -69,9 +71,8 @@ constexpr size_t TagToAllocatedSize(uint8_t tag) {
((512 / 8) + ((8192 - 512) / 64)) * 4096;
}
-static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT, "");
-static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG,
- "");
+static_assert(AllocatedSizeToTagUnchecked(kMinFlatSize) == FLAT);
+static_assert(AllocatedSizeToTagUnchecked(kMaxLargeFlatSize) == MAX_FLAT_TAG);
// RoundUp logically performs `((n + m - 1) / m) * m` to round up to the nearest
// multiple of `m`, optimized for the invariant that `m` is a power of 2.
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_test_util.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_test_util.h
index 18a0a195447..9a6744c7228 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_test_util.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cord_rep_test_util.h
@@ -16,6 +16,8 @@
#define ABSL_STRINGS_INTERNAL_CORD_REP_TEST_UTIL_H_
#include <cassert>
+#include <cstddef>
+#include <cstring>
#include <memory>
#include <random>
#include <string>
@@ -27,6 +29,7 @@
#include "absl/strings/internal/cord_rep_btree.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions.cc
index 6033d046969..50948170db3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions.cc
@@ -16,6 +16,7 @@
#include <atomic>
#include <cmath>
+#include <cstdint>
#include <limits>
#include <random>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions_test.cc
index 8fb93d53dd2..3949bf3ae7a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_functions_test.cc
@@ -14,6 +14,7 @@
#include "absl/strings/internal/cordz_functions.h"
+#include <cstdint>
#include <thread> // NOLINT we need real clean new threads
#include "gmock/gmock.h"
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 a4f47f0a133..4fa8183898c 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
@@ -14,9 +14,13 @@
#include "absl/strings/internal/cordz_handle.h"
#include <atomic>
+#include <cassert>
+#include <vector>
#include "absl/base/internal/raw_logging.h" // For ABSL_RAW_CHECK
+#include "absl/base/macros.h"
#include "absl/base/no_destructor.h"
+#include "absl/base/thread_annotations.h"
#include "absl/synchronization/mutex.h"
namespace absl {
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 fd68e06b3ec..f2deea2b05a 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
@@ -13,7 +13,9 @@
// limitations under the License.
#include "absl/strings/internal/cordz_handle.h"
+#include <atomic>
#include <random>
+#include <vector>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc
index 38fb473160d..321d15ddf07 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.cc
@@ -14,11 +14,18 @@
#include "absl/strings/internal/cordz_info.h"
+#include <atomic>
+#include <cassert>
+#include <cstddef>
#include <cstdint>
+#include <cstring>
#include "absl/base/config.h"
#include "absl/base/const_init.h"
+#include "absl/base/macros.h"
#include "absl/base/no_destructor.h"
+#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
#include "absl/container/inlined_vector.h"
#include "absl/debugging/stacktrace.h"
#include "absl/strings/internal/cord_internal.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.h
index ccbe4144e40..04609cd3092 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info.h
@@ -16,12 +16,15 @@
#define ABSL_STRINGS_INTERNAL_CORDZ_INFO_H_
#include <atomic>
+#include <cstddef>
#include <cstdint>
#include <functional>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/const_init.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/optimization.h"
#include "absl/base/thread_annotations.h"
#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cordz_functions.h"
@@ -29,6 +32,7 @@
#include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/cordz_update_tracker.h"
#include "absl/synchronization/mutex.h"
+#include "absl/time/time.h"
#include "absl/types/span.h"
namespace absl {
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 3e6a8a09d73..859bb20b360 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
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cassert>
+#include <cstddef>
+#include <cstdint>
#include <iostream>
#include <random>
#include <vector>
@@ -30,8 +33,11 @@
#include "absl/strings/internal/cordz_statistics.h"
#include "absl/strings/internal/cordz_update_scope.h"
#include "absl/strings/internal/cordz_update_tracker.h"
+#include "absl/strings/string_view.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/notification.h"
+#include "absl/time/clock.h"
+#include "absl/time/time.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_test.cc
index 81ecce2cd1f..10de80bccb8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_info_test.cc
@@ -14,6 +14,9 @@
#include "absl/strings/internal/cordz_info.h"
+#include <cstddef>
+#include <memory>
+#include <string>
#include <vector>
#include "gmock/gmock.h"
@@ -22,6 +25,7 @@
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
#include "absl/strings/cordz_test_helpers.h"
+#include "absl/strings/internal/cord_internal.h"
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_statistics.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token.h
index 2a86bc3b141..aaf260e7ed6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_sample_token.h
@@ -12,6 +12,9 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstddef>
+#include <iterator>
+
#include "absl/base/config.h"
#include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_info.h"
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 22ef21caf86..8386b2cf4da 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
@@ -14,6 +14,8 @@
#include "absl/strings/internal/cordz_sample_token.h"
+#include <cstddef>
+#include <iterator>
#include <memory>
#include <type_traits>
#include <vector>
@@ -26,6 +28,7 @@
#include "absl/strings/internal/cord_rep_flat.h"
#include "absl/strings/internal/cordz_handle.h"
#include "absl/strings/internal/cordz_info.h"
+#include "absl/strings/internal/cordz_update_tracker.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/notification.h"
#include "absl/time/clock.h"
@@ -44,33 +47,27 @@ using ::testing::Ne;
auto constexpr kTrackCordMethod = CordzUpdateTracker::kConstructorString;
TEST(CordzSampleTokenTest, IteratorTraits) {
- static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>, "");
- static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>, "");
- static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>, "");
- static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>, "");
+ static_assert(std::is_copy_constructible_v<CordzSampleToken::Iterator>);
+ static_assert(std::is_copy_assignable_v<CordzSampleToken::Iterator>);
+ static_assert(std::is_move_constructible_v<CordzSampleToken::Iterator>);
+ static_assert(std::is_move_assignable_v<CordzSampleToken::Iterator>);
static_assert(
std::is_same_v<
std::iterator_traits<CordzSampleToken::Iterator>::iterator_category,
- std::input_iterator_tag>,
- "");
- static_assert(
- std::is_same_v<
- std::iterator_traits<CordzSampleToken::Iterator>::value_type,
- const CordzInfo&>,
- "");
+ std::input_iterator_tag>);
+ static_assert(std::is_same_v<
+ std::iterator_traits<CordzSampleToken::Iterator>::value_type,
+ const CordzInfo&>);
static_assert(
std::is_same_v<
std::iterator_traits<CordzSampleToken::Iterator>::difference_type,
- ptrdiff_t>,
- "");
+ ptrdiff_t>);
static_assert(
std::is_same_v<std::iterator_traits<CordzSampleToken::Iterator>::pointer,
- const CordzInfo*>,
- "");
+ const CordzInfo*>);
static_assert(std::is_same_v<
- std::iterator_traits<CordzSampleToken::Iterator>::reference,
- const CordzInfo&>,
- "");
+ std::iterator_traits<CordzSampleToken::Iterator>::reference,
+ const CordzInfo&>);
}
TEST(CordzSampleTokenTest, IteratorEmpty) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h
index 9f558df4941..c024d11b9e4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_statistics.h
@@ -15,6 +15,7 @@
#ifndef ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_
#define ABSL_STRINGS_INTERNAL_CORDZ_STATISTICS_H_
+#include <cstddef>
#include <cstdint>
#include "absl/base/config.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_update_tracker_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_update_tracker_test.cc
index 9b1f798659f..fb89a37385a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_update_tracker_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/cordz_update_tracker_test.cc
@@ -15,6 +15,7 @@
#include "absl/strings/internal/cordz_update_tracker.h"
#include <array>
+#include <cstdint>
#include <thread> // NOLINT
#include "gmock/gmock.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
index 76d6db470ae..e10c05590ac 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_benchmark.cc
@@ -12,6 +12,7 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <cstddef>
#include <string>
#include "absl/strings/internal/damerau_levenshtein_distance.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_test.cc
index 49dd105bfdc..4d6674d1ef3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/damerau_levenshtein_distance_test.cc
@@ -15,6 +15,7 @@
#include "absl/strings/internal/damerau_levenshtein_distance.h"
#include <cstdint>
+#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.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 a70b5dc8149..3c206b40beb 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
@@ -14,6 +14,7 @@
#include "absl/strings/internal/escaping.h"
+#include <cstddef>
#include <limits>
#include "absl/base/internal/endian.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.cc
index 6535e1c57fa..267213a7533 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer.cc
@@ -16,6 +16,7 @@
#include <cstddef>
#include <cstdlib>
+#include <limits>
#include <ostream>
#include <string>
@@ -24,6 +25,7 @@
#include "absl/strings/escaping.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer_test.cc
index be6e003b6fd..e7ecc09d8a4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/generic_printer_test.cc
@@ -17,6 +17,8 @@
#include <array>
#include <cinttypes>
#include <clocale>
+#include <cmath>
+#include <cstddef>
#include <cstdint>
#include <limits>
#include <map>
@@ -25,6 +27,7 @@
#include <ostream>
#include <sstream>
#include <string>
+#include <tuple>
#include <type_traits>
#include <utility>
#include <variant>
@@ -40,6 +43,7 @@
#include "absl/status/statusor.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
namespace generic_logging_test {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc
index 1186752c6db..fb4f21f12b2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/memutil_benchmark.cc
@@ -13,6 +13,7 @@
// limitations under the License.
#include <algorithm>
+#include <cstdint>
#include <cstdlib>
#include "absl/strings/ascii.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc
index ef3ad573e90..c0f88c1de70 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/ostringstream_test.cc
@@ -27,8 +27,7 @@ namespace {
TEST(OStringStream, IsOStream) {
static_assert(
- std::is_base_of<std::ostream, absl::strings_internal::OStringStream>(),
- "");
+ std::is_base_of<std::ostream, absl::strings_internal::OStringStream>());
}
TEST(OStringStream, ConstructNullptr) {
@@ -83,8 +82,8 @@ TEST(OStringStream, Str) {
absl::strings_internal::OStringStream strm(&s1);
const absl::strings_internal::OStringStream& c_strm(strm);
- static_assert(std::is_same<decltype(strm.str()), std::string*>(), "");
- static_assert(std::is_same<decltype(c_strm.str()), const std::string*>(), "");
+ static_assert(std::is_same<decltype(strm.str()), std::string*>());
+ static_assert(std::is_same<decltype(c_strm.str()), const std::string*>());
EXPECT_EQ(&s1, strm.str());
EXPECT_EQ(&s1, c_strm.str());
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 a4ff76d31e1..4e1f34b3dcc 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
@@ -15,6 +15,7 @@
#include "absl/strings/internal/pow10_helper.h"
#include <cmath>
+#include <cstdint>
#include "gtest/gtest.h"
#include "absl/strings/str_format.h"
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 ff2009b5dfd..a2fcab1a790 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
@@ -18,6 +18,7 @@
#define ABSL_STRINGS_INTERNAL_RESIZE_UNINITIALIZED_H_
#include <algorithm>
+#include <cstddef>
#include <string>
#include <type_traits>
#include <utility>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc
index dd5547c9c64..d7d22ca2dfd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/resize_uninitialized_test.cc
@@ -16,6 +16,7 @@
#include <cstddef>
#include <limits>
+#include <string>
#include "gtest/gtest.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc
index 0687b4e056d..2125be31c6b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.cc
@@ -82,7 +82,7 @@ class IntDigits {
// Supports unsigned integral types and uint128.
template <typename T>
void PrintAsOct(T v) {
- static_assert(!IsSigned<T>::value, "");
+ static_assert(!IsSigned<T>::value);
char *p = storage_ + sizeof(storage_);
do {
*--p = static_cast<char>('0' + (static_cast<size_t>(v) & 7));
@@ -96,7 +96,7 @@ class IntDigits {
// Supports all integral types.
template <typename T>
void PrintAsDec(T v) {
- static_assert(std::is_integral_v<T>, "");
+ static_assert(std::is_integral_v<T>);
start_ = storage_;
size_ = static_cast<size_t>(numbers_internal::FastIntToBuffer(v, storage_) -
storage_);
@@ -136,7 +136,7 @@ class IntDigits {
// Supports unsigned integral types and uint128.
template <typename T>
void PrintAsHexLower(T v) {
- static_assert(!IsSigned<T>::value, "");
+ static_assert(!IsSigned<T>::value);
char *p = storage_ + sizeof(storage_);
do {
@@ -158,7 +158,7 @@ class IntDigits {
// Supports unsigned integral types and uint128.
template <typename T>
void PrintAsHexUpper(T v) {
- static_assert(!IsSigned<T>::value, "");
+ static_assert(!IsSigned<T>::value);
char *p = storage_ + sizeof(storage_);
// kHexTable is only lowercase, so do it manually for uppercase.
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h
index a48a76f5e5e..d8fef301d49 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/arg.h
@@ -440,10 +440,10 @@ class FormatArgImpl {
template <typename T>
struct store_by_value
- : std::integral_constant<
- bool, (sizeof(T) <= kInlinedSpace) &&
- (std::is_integral_v<T> || std::is_floating_point_v<T> ||
- std::is_pointer_v<T> || std::is_same_v<VoidPtr, T>)> {};
+ : std::bool_constant<
+ (sizeof(T) <= kInlinedSpace) &&
+ (std::is_integral_v<T> || std::is_floating_point_v<T> ||
+ std::is_pointer_v<T> || std::is_same_v<VoidPtr, T>)> {};
enum StoragePolicy { ByPointer, ByVolatilePointer, ByValue };
template <typename T>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc
index 87e23b565cf..689fa5ca4c2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.cc
@@ -251,7 +251,7 @@ int FprintF(std::FILE* output, const UntypedFormatSpecImpl format,
errno = sink.error();
return -1;
}
- if (sink.count() > static_cast<size_t>(std::numeric_limits<int>::max())) {
+ if (sink.count() > size_t{std::numeric_limits<int>::max()}) {
errno = EFBIG;
return -1;
}
@@ -267,6 +267,10 @@ int SnprintF(char* output, size_t size, const UntypedFormatSpecImpl format,
}
size_t total = sink.total_written();
if (size) output[std::min(total, size - 1)] = 0;
+ if (total > size_t{std::numeric_limits<int>::max()}) {
+ errno = EFBIG;
+ return -1;
+ }
return static_cast<int>(total);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h
index 075a9d529ad..1c87e1edaa0 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/bind.h
@@ -19,6 +19,7 @@
#include <cstdio>
#include <ostream>
#include <string>
+#include <utility>
#include "absl/base/config.h"
#include "absl/container/inlined_vector.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 1eef9c4326e..c4fb200ca4a 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
@@ -15,9 +15,14 @@
#include "absl/strings/internal/str_format/bind.h"
#include <string.h>
+
#include <limits>
#include "gtest/gtest.h"
+#include "absl/strings/internal/str_format/arg.h"
+#include "absl/strings/internal/str_format/constexpr_parser.h"
+#include "absl/strings/string_view.h"
+#include "absl/types/span.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 ee3df2687d8..14e9a237c2d 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
@@ -16,11 +16,14 @@
#define ABSL_STRINGS_INTERNAL_STR_FORMAT_CHECKER_H_
#include <algorithm>
+#include <cstddef>
#include "absl/base/attributes.h"
+#include "absl/base/const_init.h"
#include "absl/strings/internal/str_format/arg.h"
#include "absl/strings/internal/str_format/constexpr_parser.h"
#include "absl/strings/internal/str_format/extension.h"
+#include "absl/strings/string_view.h"
// Compile time check support for entry points.
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 a86bed381a7..21f1a7f4e61 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
@@ -17,6 +17,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/strings/str_format.h"
+#include "absl/strings/string_view.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 5e860163910..46b8588045e 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
@@ -20,6 +20,7 @@
#include <algorithm>
#include <climits>
#include <cmath>
+#include <cstdint>
#include <cstdlib>
#include <cstring>
#include <cwctype>
@@ -37,6 +38,7 @@
#include "gtest/gtest.h"
#include "absl/base/attributes.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/log/absl_check.h"
#include "absl/log/log.h"
#include "absl/numeric/int128.h"
#include "absl/strings/ascii.h"
@@ -315,14 +317,17 @@ void TestStringConvert(const T& str) {
TEST_F(FormatConvertTest, BasicString) {
TestStringConvert("hello"); // As char array.
- TestStringConvert(L"hello");
TestStringConvert(static_cast<const char*>("hello"));
- TestStringConvert(static_cast<const wchar_t*>(L"hello"));
TestStringConvert(std::string("hello"));
- TestStringConvert(std::wstring(L"hello"));
TestStringConvert(string_view("hello"));
TestStringConvert(std::string_view("hello"));
+
+#if GTEST_HAS_STD_WSTRING
+ TestStringConvert(L"hello");
+ TestStringConvert(static_cast<const wchar_t*>(L"hello"));
+ TestStringConvert(std::wstring(L"hello"));
TestStringConvert(std::wstring_view(L"hello"));
+#endif // GTEST_HAS_STD_WSTRING
}
TEST_F(FormatConvertTest, NullString) {
@@ -330,9 +335,11 @@ TEST_F(FormatConvertTest, NullString) {
UntypedFormatSpecImpl format("%s");
EXPECT_EQ("", FormatPack(format, {FormatArgImpl(p)}));
+#if GTEST_HAS_STD_WSTRING
const wchar_t* wp = nullptr;
UntypedFormatSpecImpl wformat("%ls");
EXPECT_EQ("", FormatPack(wformat, {FormatArgImpl(wp)}));
+#endif // GTEST_HAS_STD_WSTRING
}
TEST_F(FormatConvertTest, StringPrecision) {
@@ -342,19 +349,23 @@ TEST_F(FormatConvertTest, StringPrecision) {
UntypedFormatSpecImpl format("%.1s");
EXPECT_EQ("a", FormatPack(format, {FormatArgImpl(p)}));
+ // We cap at the NUL-terminator.
+ p = "ABC";
+ UntypedFormatSpecImpl format2("%.10s");
+ EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)}));
+
+#if GTEST_HAS_STD_WSTRING
+ // We cap at the precision.
wchar_t wc = L'a';
const wchar_t* wp = &wc;
UntypedFormatSpecImpl wformat("%.1ls");
EXPECT_EQ("a", FormatPack(wformat, {FormatArgImpl(wp)}));
// We cap at the NUL-terminator.
- p = "ABC";
- UntypedFormatSpecImpl format2("%.10s");
- EXPECT_EQ("ABC", FormatPack(format2, {FormatArgImpl(p)}));
-
wp = L"ABC";
UntypedFormatSpecImpl wformat2("%.10ls");
EXPECT_EQ("ABC", FormatPack(wformat2, {FormatArgImpl(wp)}));
+#endif // GTEST_HAS_STD_WSTRING
}
TEST_F(FormatConvertTest, WideStringUnpairedSurrogate) {
@@ -411,29 +422,38 @@ MATCHER_P(MatchesPointerString, ptr, "") {
TEST_F(FormatConvertTest, Pointer) {
static int x = 0;
const int *xp = &x;
+ const int* inil = nullptr;
+
+ using VoidF = void (*)();
+ VoidF fp = [] {};
+ VoidF fnil = nullptr;
+
char c = 'h';
char *mcp = &c;
const char *cp = "hi";
const char *cnil = nullptr;
+ volatile char vc;
+ volatile char* vcp = &vc;
+ volatile char* vcnil = nullptr;
+
+#if GTEST_HAS_STD_WSTRING
wchar_t wc = L'h';
wchar_t *mwcp = &wc;
const wchar_t *wcp = L"hi";
const wchar_t *wcnil = nullptr;
- const int *inil = nullptr;
- using VoidF = void (*)();
- VoidF fp = [] {}, fnil = nullptr;
- volatile char vc;
- volatile char *vcp = &vc;
- volatile char *vcnil = nullptr;
volatile wchar_t vwc;
volatile wchar_t *vwcp = &vwc;
volatile wchar_t *vwcnil = nullptr;
+#endif // GTEST_HAS_STD_WSTRING
+
const FormatArgImpl args_array[] = {
- FormatArgImpl(xp), FormatArgImpl(cp), FormatArgImpl(wcp),
- FormatArgImpl(inil), FormatArgImpl(cnil), FormatArgImpl(wcnil),
- FormatArgImpl(mcp), FormatArgImpl(mwcp), FormatArgImpl(fp),
- FormatArgImpl(fnil), FormatArgImpl(vcp), FormatArgImpl(vwcp),
- FormatArgImpl(vcnil), FormatArgImpl(vwcnil),
+ FormatArgImpl(xp), FormatArgImpl(inil), FormatArgImpl(fp),
+ FormatArgImpl(fnil), FormatArgImpl(mcp), FormatArgImpl(cp),
+ FormatArgImpl(cnil), FormatArgImpl(vcp), FormatArgImpl(vcnil),
+#if GTEST_HAS_STD_WSTRING
+ FormatArgImpl(mwcp), FormatArgImpl(wcp), FormatArgImpl(wcnil),
+ FormatArgImpl(vwcp), FormatArgImpl(vwcnil),
+#endif // GTEST_HAS_STD_WSTRING
};
auto args = absl::MakeConstSpan(args_array);
@@ -462,47 +482,52 @@ TEST_F(FormatConvertTest, Pointer) {
// const int*
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%1$p"), args),
MatchesPointerString(xp));
- // const char*
+ // null const int*
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%2$p"), args),
- MatchesPointerString(cp));
- // const wchar_t*
+ MatchesPointerString(nullptr));
+
+ // function pointer
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%3$p"), args),
- MatchesPointerString(wcp));
- // null const int*
+ MatchesPointerString(reinterpret_cast<const void*>(fp)));
+ // null function pointer
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%4$p"), args),
MatchesPointerString(nullptr));
- // null const char*
+
+ // nonconst char*
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%5$p"), args),
- MatchesPointerString(nullptr));
- // null const wchar_t*
+ MatchesPointerString(mcp));
+ // const char*
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%6$p"), args),
- MatchesPointerString(nullptr));
- // nonconst char*
+ MatchesPointerString(cp));
+ // null const char*
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%7$p"), args),
- MatchesPointerString(mcp));
- // nonconst wchar_t*
- EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%8$p"), args),
- MatchesPointerString(mwcp));
- // function pointer
- EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%9$p"), args),
- MatchesPointerString(reinterpret_cast<const void *>(fp)));
- // null function pointer
- EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%10$p"), args),
MatchesPointerString(nullptr));
// volatile char*
EXPECT_THAT(
- FormatPack(UntypedFormatSpecImpl("%11$p"), args),
- MatchesPointerString(reinterpret_cast<volatile const void *>(vcp)));
+ FormatPack(UntypedFormatSpecImpl("%8$p"), args),
+ MatchesPointerString(reinterpret_cast<volatile const void*>(vcp)));
+ // null volatile char*
+ EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%9$p"), args),
+ MatchesPointerString(nullptr));
+
+#if GTEST_HAS_STD_WSTRING
+ // nonconst wchar_t*
+ EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%10$p"), args),
+ MatchesPointerString(mwcp));
+ // const wchar_t*
+ EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%11$p"), args),
+ MatchesPointerString(wcp));
+ // null const wchar_t*
+ EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%12$p"), args),
+ MatchesPointerString(nullptr));
// volatile wchar_t*
EXPECT_THAT(
- FormatPack(UntypedFormatSpecImpl("%12$p"), args),
+ FormatPack(UntypedFormatSpecImpl("%13$p"), args),
MatchesPointerString(reinterpret_cast<volatile const void *>(vwcp)));
- // null volatile char*
- EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%13$p"), args),
- MatchesPointerString(nullptr));
// null volatile wchar_t*
EXPECT_THAT(FormatPack(UntypedFormatSpecImpl("%14$p"), args),
MatchesPointerString(nullptr));
+#endif // GTEST_HAS_STD_WSTRING
}
struct Cardinal {
@@ -741,6 +766,7 @@ TEST_F(FormatConvertTest, VectorBool) {
FormatArgImpl(cv[0]), FormatArgImpl(cv[1])})));
}
+#if GTEST_HAS_STD_WSTRING
TEST_F(FormatConvertTest, UnicodeWideString) {
// StrFormat() should be able to convert wide strings containing Unicode
// characters (to UTF-8).
@@ -757,6 +783,7 @@ TEST_F(FormatConvertTest, UnicodeWideString) {
EXPECT_EQ(output,
FormatPack(UntypedFormatSpecImpl("%ls"), absl::MakeSpan(args)));
}
+#endif // GTEST_HAS_STD_WSTRING
TEST_F(FormatConvertTest, Int128) {
absl::int128 positive = static_cast<absl::int128>(0x1234567890abcdef) * 1979;
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 2d441c21c56..5b16a862e97 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
@@ -16,9 +16,13 @@
#include "absl/strings/internal/str_format/extension.h"
#include <errno.h>
+
#include <algorithm>
+#include <cstddef>
#include <string>
+#include "absl/strings/string_view.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace str_format_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h
index 173284c6c7b..0e0b262faa8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/extension.h
@@ -290,7 +290,7 @@ class FormatConversionSpecImpl {
FormatConversionChar conversion_char() const {
// Keep this field first in the struct . It generates better code when
// accessing it when ConversionSpec is passed by value in registers.
- static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0, "");
+ static_assert(offsetof(FormatConversionSpecImpl, conv_) == 0);
return conv_;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc
index f69b8ef643e..137e159d710 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/float_conversion.cc
@@ -149,8 +149,7 @@ class BinaryToDecimal {
assert(exp <= std::numeric_limits<MaxFloatType>::max_exponent);
static_assert(
StackArray::kMaxCapacity >=
- ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent),
- "");
+ ChunksNeeded(std::numeric_limits<MaxFloatType>::max_exponent));
StackArray::RunWithCapacity(
ChunksNeeded(exp),
@@ -267,8 +266,7 @@ class FractionalDigitGenerator {
const int margin = Limits::digits + 128;
assert(-exp >= Limits::min_exponent - margin);
static_assert(StackArray::kMaxCapacity >=
- ChunksNeeded(margin - Limits::min_exponent),
- "");
+ ChunksNeeded(margin - Limits::min_exponent));
StackArray::RunWithCapacity(
ChunksNeeded(exp), [=](absl::Span<uint32_t> input) {
f(FractionalDigitGenerator(input, v, exp));
@@ -1178,8 +1176,7 @@ template <typename Float>
struct Decomposed {
using MantissaType =
std::conditional_t<std::is_same_v<long double, Float>, uint128, uint64_t>;
- static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8,
- "");
+ static_assert(std::numeric_limits<Float>::digits <= sizeof(MantissaType) * 8);
MantissaType mantissa;
int exponent;
};
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 068091c1a8b..1e61d194bef 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
@@ -15,8 +15,13 @@
#include "absl/strings/internal/str_format/output.h"
#include <errno.h>
+
+#include <algorithm>
+#include <cstdio>
#include <cstring>
+#include "absl/strings/string_view.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace str_format_internal {
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 ce2e91a0bbe..83c9589d571 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
@@ -14,6 +14,7 @@
#include "absl/strings/internal/str_format/output.h"
+#include <algorithm>
#include <sstream>
#include <string>
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 5aaab6983f5..475d22132d4 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
@@ -17,16 +17,21 @@
#include <assert.h>
#include <string.h>
#include <wchar.h>
-#include <cctype>
-#include <cstdint>
#include <algorithm>
+#include <cctype>
+#include <cstdint>
#include <initializer_list>
#include <limits>
#include <ostream>
#include <string>
#include <unordered_set>
+#include "absl/base/attributes.h"
+#include "absl/strings/internal/str_format/constexpr_parser.h"
+#include "absl/strings/internal/str_format/extension.h"
+#include "absl/strings/string_view.h"
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace str_format_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc
index e2225c60183..b62742efe4e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/str_format/parser_test.cc
@@ -15,15 +15,16 @@
#include "absl/strings/internal/str_format/parser.h"
#include <string.h>
+
#include <algorithm>
#include <initializer_list>
+#include <iterator>
#include <string>
#include <utility>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/base/config.h"
-#include "absl/base/macros.h"
#include "absl/strings/internal/str_format/constexpr_parser.h"
#include "absl/strings/internal/str_format/extension.h"
#include "absl/strings/string_view.h"
@@ -54,7 +55,7 @@ TEST(LengthModTest, Names) {
{__LINE__, LengthMod::t, "t" },
{__LINE__, LengthMod::q, "q" },
};
- EXPECT_EQ(ABSL_ARRAYSIZE(kExpect), 10);
+ EXPECT_EQ(std::size(kExpect), 10);
for (auto e : kExpect) {
SCOPED_TRACE(e.line);
EXPECT_EQ(e.name, LengthModToString(e.mod));
@@ -275,7 +276,7 @@ TEST_F(ConsumeUnboundConversionTest, WidthAndPrecision) {
TEST_F(ConsumeUnboundConversionTest, Flags) {
static const char kAllFlags[] = "-+ #0";
- static const int kNumFlags = ABSL_ARRAYSIZE(kAllFlags) - 1;
+ static const int kNumFlags = std::size(kAllFlags) - 1;
for (int rev = 0; rev < 2; ++rev) {
for (int i = 0; i < 1 << kNumFlags; ++i) {
std::string fmt;
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 bda084b57cb..b36eac1ced5 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
@@ -34,11 +34,13 @@
#include <cstddef>
#include <initializer_list>
#include <iterator>
+#include <string>
#include <tuple>
#include <type_traits>
#include <utility>
#include <vector>
+#include "absl/base/attributes.h"
#include "absl/base/macros.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
@@ -244,16 +246,14 @@ struct ShouldUseLifetimeBound<
template <typename StringType, typename First, typename Second>
using ShouldUseLifetimeBoundForPair =
- std::integral_constant<bool,
- std::is_same_v<StringType, std::string> &&
- (std::is_same_v<First, absl::string_view> ||
- std::is_same_v<Second, absl::string_view>)>;
+ std::bool_constant<std::is_same_v<StringType, std::string> &&
+ (std::is_same_v<First, absl::string_view> ||
+ std::is_same_v<Second, absl::string_view>)>;
template <typename StringType, typename ElementType, std::size_t Size>
using ShouldUseLifetimeBoundForArray =
- std::integral_constant<bool,
- std::is_same_v<StringType, std::string> &&
- std::is_same_v<ElementType, absl::string_view>>;
+ std::bool_constant<std::is_same_v<StringType, std::string> &&
+ std::is_same_v<ElementType, absl::string_view>>;
// This class implements the range that is returned by absl::StrSplit(). This
// class has templated conversion operators that allow it to be implicitly
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant_test.cc
index 86914d6b6dc..9743c52735f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/internal/string_constant_test.cc
@@ -18,6 +18,7 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/strings/string_view.h"
namespace {
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 7c6995abb14..4efe80f8f85 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
@@ -13,6 +13,10 @@
// limitations under the License.
#include "absl/strings/internal/stringify_sink.h"
+
+#include <cstddef>
+
+#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 6478ea520a7..b2e75d92856 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
@@ -16,6 +16,7 @@
#define ABSL_STRINGS_INTERNAL_STRINGIFY_SINK_H_
#include <array>
+#include <cstddef>
#include <string>
#include <type_traits>
#include <utility>
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/match.cc b/deps/v8/third_party/abseil-cpp/absl/strings/match.cc
index 72ae6a430a8..ac7cf0d8249 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/match.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/match.cc
@@ -15,8 +15,10 @@
#include "absl/strings/match.h"
#include <algorithm>
+#include <cstddef>
#include <cstdint>
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/endian.h"
#include "absl/base/optimization.h"
@@ -36,13 +38,101 @@ bool EqualsIgnoreCase(absl::string_view piece1,
// memcasecmp uses absl::ascii_tolower().
}
+namespace {
+
+// For larger haystacks (n >= 256), Case-Insensitive Boyer-Moore-Horspool
+// provides sub-linear O(N / M) average-case performance, although it still has
+// O(N * M) theoretical worst-case scaling.
+// Scans the haystack from left to right using a search window of size `m`.
+// For each window offset, Horspool inspects the rightmost character of the
+// window (`haystack[pos + m - 1]`) first, enabling multi-byte shifts when
+// mismatches occur and reducing average search time to O(N / M).
+ABSL_ATTRIBUTE_NOINLINE bool StrContainsIgnoreCaseBMH(
+ absl::string_view haystack, absl::string_view needle) noexcept {
+ const size_t n = haystack.size();
+ const size_t m = needle.size();
+
+ // Step 1: Initialize the 256-entry shift table.
+ // Unknown characters default to full window shift of `m` bytes.
+ size_t shift[256];
+ for (size_t i = 0; i < 256; ++i) {
+ shift[i] = m;
+ }
+
+ // Populate shift distances for needle[0..m-2]. Dual assignment for
+ // ascii_tolower and ascii_toupper stores distance from rightmost occurrence
+ // to end of needle.
+ for (size_t i = 0; i < m - 1; ++i) {
+ const unsigned char c = static_cast<unsigned char>(needle[i]);
+ shift[static_cast<unsigned char>(absl::ascii_tolower(c))] = m - 1 - i;
+ shift[static_cast<unsigned char>(absl::ascii_toupper(c))] = m - 1 - i;
+ }
+
+ // Step 2: Search loop across candidate window offsets.
+ size_t pos = 0;
+ while (pos <= n - m) {
+ const unsigned char last_hay =
+ static_cast<unsigned char>(haystack[pos + m - 1]);
+ const unsigned char last_needle = static_cast<unsigned char>(needle[m - 1]);
+
+ // Check 1: Inspect right-most character of window first.
+ if (last_hay == last_needle ||
+ absl::ascii_tolower(last_hay) == absl::ascii_tolower(last_needle)) {
+ // Check 2: Pre-filter on first character of window.
+ const unsigned char first_hay = static_cast<unsigned char>(haystack[pos]);
+ const unsigned char first_needle = static_cast<unsigned char>(needle[0]);
+ if (first_hay == first_needle ||
+ absl::ascii_tolower(first_hay) == absl::ascii_tolower(first_needle)) {
+ // Check 3: Compare interior (m - 2) bytes.
+ if (EqualsIgnoreCase(haystack.substr(pos + 1, m - 2),
+ needle.substr(1, m - 2))) {
+ return true;
+ }
+ }
+ }
+
+ // Advance window by shift distance determined by right-most haystack byte.
+ pos += shift[last_hay];
+ }
+ return false;
+}
+
+} // namespace
+
bool StrContainsIgnoreCase(absl::string_view haystack,
absl::string_view needle) noexcept {
- while (haystack.size() >= needle.size()) {
- if (StartsWithIgnoreCase(haystack, needle)) return true;
- haystack.remove_prefix(1);
+ const size_t n = haystack.size();
+ const size_t m = needle.size();
+ if (m == 0) return true;
+ if (n < m) return false;
+ if (m == 1) return StrContainsIgnoreCase(haystack, needle[0]);
+
+ // For short haystacks (n < 256) or small needles (m == 2), avoid the
+ // initialization overhead of a 256-entry shift table. Instead, use a fast
+ // first-and-last character prefilter before inspecting interior bytes.
+ if (n < 256 || m == 2) {
+ const char first_needle =
+ absl::ascii_tolower(static_cast<unsigned char>(needle[0]));
+ const char last_needle =
+ absl::ascii_tolower(static_cast<unsigned char>(needle[m - 1]));
+
+ for (size_t pos = 0; pos <= n - m; ++pos) {
+ const unsigned char first_hay = static_cast<unsigned char>(haystack[pos]);
+ if (absl::ascii_tolower(first_hay) != first_needle) continue;
+
+ const unsigned char last_hay =
+ static_cast<unsigned char>(haystack[pos + m - 1]);
+ if (absl::ascii_tolower(last_hay) != last_needle) continue;
+
+ if (m == 2 || EqualsIgnoreCase(haystack.substr(pos + 1, m - 2),
+ needle.substr(1, m - 2))) {
+ return true;
+ }
+ }
+ return false;
}
- return false;
+
+ return StrContainsIgnoreCaseBMH(haystack, needle);
}
bool StrContainsIgnoreCase(absl::string_view haystack,
@@ -51,10 +141,15 @@ bool StrContainsIgnoreCase(absl::string_view haystack,
char lower_needle = absl::ascii_tolower(static_cast<unsigned char>(needle));
if (upper_needle == lower_needle) {
return StrContains(haystack, needle);
- } else {
- const char both_cstr[3] = {lower_needle, upper_needle, '\0'};
- return haystack.find_first_of(both_cstr) != absl::string_view::npos;
}
+ if (haystack.size() < 64) {
+ for (char c : haystack) {
+ if (c == lower_needle || c == upper_needle) return true;
+ }
+ return false;
+ }
+ const char both_cstr[3] = {lower_needle, upper_needle, '\0'};
+ return haystack.find_first_of(both_cstr) != absl::string_view::npos;
}
bool StartsWithIgnoreCase(absl::string_view text,
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/match_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/strings/match_benchmark.cc
new file mode 100644
index 00000000000..d2c32c064c0
--- /dev/null
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/match_benchmark.cc
@@ -0,0 +1,97 @@
+// Copyright 2026 The Abseil Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include <cstddef>
+#include <cstdint>
+#include <string>
+
+#include "absl/base/internal/raw_logging.h"
+#include "absl/strings/match.h"
+#include "benchmark/benchmark.h"
+
+namespace {
+
+void BM_ContainsIgnoreCase_Match(benchmark::State& state) {
+ const size_t haystack_size = static_cast<size_t>(state.range(0));
+ const size_t needle_size = static_cast<size_t>(state.range(1));
+ std::string haystack(haystack_size, 'a');
+ std::string needle(needle_size, 'b');
+
+ // Place a case-insensitive match at the very end of the haystack
+ haystack.replace(haystack_size - needle_size, needle_size, needle_size, 'B');
+
+ ABSL_RAW_CHECK(absl::StrContainsIgnoreCase(haystack, needle),
+ "BM_ContainsIgnoreCase_Match must return true");
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(absl::StrContainsIgnoreCase(haystack, needle));
+ }
+ state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
+ static_cast<int64_t>(haystack_size));
+}
+BENCHMARK(BM_ContainsIgnoreCase_Match)
+ ->Args({4, 1})
+ ->Args({64, 1})
+ ->Args({64, 8})
+ ->Args({1024, 16})
+ ->Args({65536, 1})
+ ->Args({65536, 64})
+ ->Args({65536, 1024})
+ ->Args({65536, 16384});
+
+void BM_ContainsIgnoreCase_Mismatch(benchmark::State& state) {
+ const size_t haystack_size = static_cast<size_t>(state.range(0));
+ const size_t needle_size = static_cast<size_t>(state.range(1));
+ const std::string haystack(haystack_size, 'a');
+ const std::string needle(needle_size, 'b');
+
+ ABSL_RAW_CHECK(!absl::StrContainsIgnoreCase(haystack, needle),
+ "BM_ContainsIgnoreCase_Mismatch must return false");
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(absl::StrContainsIgnoreCase(haystack, needle));
+ }
+ state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
+ static_cast<int64_t>(haystack_size));
+}
+BENCHMARK(BM_ContainsIgnoreCase_Mismatch)
+ ->Args({4, 1})
+ ->Args({64, 1})
+ ->Args({64, 8})
+ ->Args({1024, 16})
+ ->Args({65536, 1})
+ ->Args({65536, 64})
+ ->Args({65536, 1024})
+ ->Args({65536, 16384});
+
+void BM_ContainsIgnoreCase_Adversarial(benchmark::State& state) {
+ const size_t haystack_size = static_cast<size_t>(state.range(0));
+ const std::string haystack(haystack_size, 'a');
+ std::string needle(haystack_size / 2, 'a');
+
+ // Make the needle not match the haystack due to just the last character.
+ needle.push_back('b');
+
+ ABSL_RAW_CHECK(!absl::StrContainsIgnoreCase(haystack, needle),
+ "BM_ContainsIgnoreCase_Adversarial must return false");
+
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(absl::StrContainsIgnoreCase(haystack, needle));
+ }
+ state.SetBytesProcessed(static_cast<int64_t>(state.iterations()) *
+ static_cast<int64_t>(haystack_size));
+}
+BENCHMARK(BM_ContainsIgnoreCase_Adversarial)->Range(16 << 10, 128 << 10);
+
+} // namespace
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/match_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/match_test.cc
index 6218ce4e797..76bad73614b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/match_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/match_test.cc
@@ -14,9 +14,11 @@
#include "absl/strings/match.h"
+#include <cstddef>
#include <string>
#include "gtest/gtest.h"
+#include "absl/strings/ascii.h"
#include "absl/strings/string_view.h"
namespace {
@@ -171,6 +173,261 @@ TEST(MatchTest, ContainsCharIgnoreCase) {
EXPECT_FALSE(absl::StrContainsIgnoreCase("", '0'));
}
+TEST(MatchTest, ContainsIgnoreCaseLinearScaling) {
+ // Adversarial case where naive shift-by-one substring scan exhibits
+ // quadratic O(N * M) time: haystack = 'a' * N, needle = 'a' * (M - 1) + 'b'.
+ //
+ // Boyer-Moore-Horspool inspects the last byte first, immediately detecting
+ // the mismatch ('a' != 'b') at each window offset and shifting by 1,
+ // completing in linear O(N) time.
+ const std::string haystack(1 << 17, 'a'); // 128 KiB
+ std::string needle(1 << 16, 'a'); // 64 KiB
+ needle.push_back('b');
+
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, needle));
+
+ std::string matching_needle(1 << 16, 'A');
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, matching_needle));
+}
+
+std::string MakeBMHNeedle(size_t m) {
+ std::string needle(m, 'y');
+ for (size_t i = 0; i < m; i += 2) {
+ needle[i] = static_cast<char>('A' + (i % 26));
+ needle[i + 1] = static_cast<char>('a' + ((i + 1) % 26));
+ }
+ return needle;
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHMatchAtStart) {
+ // Test BMH search (N >= 256, M >= 256) when match occurs at pos == 0.
+ constexpr size_t n = 1000;
+ constexpr size_t m = 300;
+ std::string needle = MakeBMHNeedle(m);
+ std::string haystack(n, 'x');
+ haystack.replace(0, m, needle);
+
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHMatchInMiddle) {
+ // Test BMH search (N >= 256, M >= 256) when match occurs in the middle of
+ // haystack.
+ constexpr size_t n = 1000;
+ constexpr size_t m = 300;
+ std::string needle = MakeBMHNeedle(m);
+ std::string haystack(n, 'x');
+ haystack.replace(200, m, needle);
+
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHMatchAtEnd) {
+ // Test BMH search (N >= 256, M >= 256) when match occurs at the very end (pos
+ // == n - m). Verifies that while (pos <= n - m) boundary condition includes
+ // the final window.
+ constexpr size_t n = 1000;
+ constexpr size_t m = 300;
+ std::string needle = MakeBMHNeedle(m);
+ std::string haystack(n, 'x');
+ haystack.replace(n - m, m, needle);
+
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHMismatchAtEnd) {
+ // Test BMH search (N >= 256, M >= 256) when needle is placed at pos == n - m
+ // but fails on the last character.
+ constexpr size_t n = 1000;
+ constexpr size_t m = 300;
+ std::string needle = MakeBMHNeedle(m);
+ std::string haystack(n, 'x');
+ haystack.replace(n - m, m, needle);
+ haystack.back() = 'Z';
+
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHInteriorMismatch) {
+ // Test BMH search (N >= 256, M >= 256) when the first and last characters
+ // of a window match, but interior bytes mismatch.
+ // This exercises the false branch of EqualsIgnoreCase(...) inside BMH,
+ // falling through line 91 to advance the window.
+ constexpr size_t n = 1000;
+ constexpr size_t m = 300;
+ std::string needle = MakeBMHNeedle(m);
+
+ // 1. First and last chars match at pos == 100, but interior byte 10
+ // mismatches.
+ std::string haystack(n, 'x');
+ haystack.replace(100, m, needle);
+ haystack[100 + 10] = (needle[10] == 'Q') ? 'W' : 'Q';
+
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, needle));
+
+ // 2. Add a valid match at the end to verify BMH continues scanning after
+ // falling through an interior mismatch.
+ haystack.replace(n - m, m, needle);
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHMixedCaseAndShifts) {
+ // Test large needle (M >= 256) with mixed casing and partial matches
+ // triggering multi-byte skip shifts during BMH scanning.
+ std::string needle;
+ needle.reserve(300);
+ for (size_t i = 0; i < 300; ++i) {
+ needle.push_back(static_cast<char>('a' + (i % 10)));
+ }
+
+ std::string haystack;
+ haystack.reserve(2000);
+ for (int i = 0; i < 5; ++i) {
+ haystack.append(needle.substr(0, 250));
+ haystack.append("XYZ");
+ }
+
+ std::string needle_upper = needle;
+ for (char& c : needle_upper) {
+ c = static_cast<char>(absl::ascii_toupper(static_cast<unsigned char>(c)));
+ }
+
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, needle_upper));
+
+ haystack.append(needle_upper);
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseHaystackThresholdBoundary) {
+ // Test haystack threshold boundary N = 255 (prefilter branch) vs N = 256 (BMH
+ // branch).
+ std::string needle = "AbC";
+
+ // N = 255 (prefilter branch)
+ std::string h255(255, '.');
+ h255.replace(100, 3, "aBc");
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h255, needle));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h255, "abc"));
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(std::string(255, '.'), needle));
+
+ // N = 256 (BMH branch)
+ std::string h256(256, '.');
+ h256.replace(100, 3, "aBc");
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h256, needle));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h256, "abc"));
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(std::string(256, '.'), needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseSmallNeedleFastPath) {
+ // Test small needle (M = 2) fast path, which uses prefilter regardless of
+ // haystack size (N >= 256).
+ std::string needle = "xY";
+ std::string h1000(1000, 'a');
+
+ // Match at start
+ h1000.replace(0, 2, "Xy");
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h1000, needle));
+
+ // Match at end (pos == 998)
+ h1000 = std::string(1000, 'a');
+ h1000.replace(998, 2, "Xy");
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h1000, needle));
+
+ // Mismatch
+ h1000 = std::string(1000, 'a');
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(h1000, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseNeedleThresholdBoundary) {
+ // Test needle length boundaries M = 255, M = 256, and M = 257 in N = 300
+ // haystack.
+ std::string h300(300, 'a');
+ std::string n255(255, 'A');
+ std::string n256(256, 'A');
+ std::string n257(257, 'A');
+
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h300, n255));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h300, n256));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(h300, n257));
+
+ n255.back() = 'B';
+ n256.back() = 'B';
+ n257.back() = 'B';
+
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(h300, n255));
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(h300, n256));
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(h300, n257));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHNonAsciiBytes) {
+ // Test BMH algorithm handling of high-bit non-ASCII bytes (values > 127) in
+ // needle and haystack.
+ std::string needle(300, '\0');
+ for (size_t i = 0; i < 300; ++i) {
+ needle[i] = static_cast<char>(128 + (i % 128));
+ }
+ std::string haystack(1000, '\x7F');
+ haystack.replace(500, 300, needle);
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+
+ haystack[799] = '\x00';
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHExactLengthMatch) {
+ // Test BMH search when haystack size equals needle size (N == M == 300).
+ std::string needle(300, 'X');
+ std::string haystack(300, 'x');
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+
+ haystack.back() = 'y';
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, needle));
+}
+
+TEST(MatchTest, ContainsIgnoreCaseBMHAllIdenticalCharNeedle) {
+ // Test BMH search with needle consisting of all identical characters (M >=
+ // 256).
+ std::string needle(300, 'K');
+ std::string haystack(1000, 'k');
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, needle));
+
+ std::string short_haystack(299, 'k');
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(short_haystack, needle));
+}
+
+TEST(MatchTest, ContainsCharIgnoreCaseLargeHaystack) {
+ // Test StrContainsIgnoreCase(haystack, char) for N >= 64, exercising the
+ // find_first_of fallback branch.
+ constexpr size_t sizes[] = {64, 100, 1000};
+ for (size_t n : sizes) {
+ std::string haystack(n, '.');
+
+ // 1. Alphabetic character (exercises find_first_of fallback branch)
+ haystack[0] = 'z';
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, 'Z'));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, 'z'));
+
+ haystack = std::string(n, '.');
+ haystack[n / 2] = 'Z';
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, 'z'));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, 'Z'));
+
+ haystack = std::string(n, '.');
+ haystack[n - 1] = 'z';
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, 'Z'));
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, 'z'));
+
+ haystack = std::string(n, '.');
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, 'z'));
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, 'Z'));
+
+ // 2. Non-alphabetic character (upper_needle == lower_needle)
+ haystack[n / 2] = '9';
+ EXPECT_TRUE(absl::StrContainsIgnoreCase(haystack, '9'));
+ EXPECT_FALSE(absl::StrContainsIgnoreCase(haystack, '8'));
+ }
+}
+
TEST(MatchTest, FindLongestCommonPrefix) {
EXPECT_EQ(absl::FindLongestCommonPrefix("", ""), "");
EXPECT_EQ(absl::FindLongestCommonPrefix("", "abc"), "");
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/numbers.cc b/deps/v8/third_party/abseil-cpp/absl/strings/numbers.cc
index 479c07e3cd8..924c9122f99 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/numbers.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/numbers.cc
@@ -1124,15 +1124,15 @@ size_t numbers_internal::SixDigitsToBuffer(double d,
case -4:
out[2] = '0';
++out;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case -3:
out[2] = '0';
++out;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case -2:
out[2] = '0';
++out;
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case -1:
out += 2;
memcpy(out, &digits[0], 6);
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/numbers.h b/deps/v8/third_party/abseil-cpp/absl/strings/numbers.h
index 7e9c6bbcac4..87d146b309e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/numbers.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/numbers.h
@@ -23,14 +23,6 @@
#ifndef ABSL_STRINGS_NUMBERS_H_
#define ABSL_STRINGS_NUMBERS_H_
-#ifdef __SSSE3__
-#include <tmmintrin.h>
-#endif
-
-#ifdef _MSC_VER
-#include <intrin.h>
-#endif
-
#include <cstddef>
#include <cstdint>
#include <cstdlib>
@@ -50,6 +42,14 @@
#include "absl/numeric/int128.h"
#include "absl/strings/string_view.h"
+#ifdef __SSSE3__
+#include <tmmintrin.h>
+#endif
+
+#ifdef _MSC_VER
+#include <intrin.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_cat.h b/deps/v8/third_party/abseil-cpp/absl/strings/str_cat.h
index d682cea6232..3ae1197d75b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_cat.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_cat.h
@@ -109,6 +109,7 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
+#include "absl/base/macros.h"
#include "absl/base/nullability.h"
#include "absl/base/port.h"
#include "absl/meta/type_traits.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_format.h b/deps/v8/third_party/abseil-cpp/absl/strings/str_format.h
index d02fe202a6e..6ec289ebaf7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_format.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_format.h
@@ -309,9 +309,8 @@ using FormatSpec = str_format_internal::FormatSpecTemplate<
// ... error case ...
// }
-#if defined(__cpp_nontype_template_parameter_auto)
-// If C++17 is available, an 'extended' format is also allowed that can specify
-// multiple conversion characters per format argument, using a combination of
+// An 'extended' format is also allowed that can specify multiple conversion
+// characters per format argument, using a combination of
// `absl::FormatConversionCharSet` enum values (logically a set union)
// via the `|` operator. (Single character-based arguments are still accepted,
// but cannot be combined). Some common conversions also have predefined enum
@@ -333,11 +332,6 @@ using FormatSpec = str_format_internal::FormatSpecTemplate<
template <auto... Conv>
using ParsedFormat = absl::str_format_internal::ExtendedParsedFormat<
absl::str_format_internal::ToFormatConversionCharSet(Conv)...>;
-#else
-template <char... Conv>
-using ParsedFormat = str_format_internal::ExtendedParsedFormat<
- absl::str_format_internal::ToFormatConversionCharSet(Conv)...>;
-#endif // defined(__cpp_nontype_template_parameter_auto)
// StrFormat()
//
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_format_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/str_format_test.cc
index a4c877a8e38..cbe5ff9a653 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_format_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_format_test.cc
@@ -18,6 +18,7 @@
#include <cstdarg>
#include <cstdint>
#include <cstdio>
+#include <iterator>
#include <ostream>
#include <sstream>
#include <string>
@@ -27,6 +28,7 @@
#include "absl/base/config.h"
#include "absl/base/macros.h"
#include "absl/strings/cord.h"
+#include "absl/strings/internal/str_format/constexpr_parser.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
#include "absl/types/span.h"
@@ -300,7 +302,7 @@ TEST_F(FormatEntryPointTest, StreamWithV) {
};
std::string buf(4096, '\0');
- for (auto i = 0; i < ABSL_ARRAYSIZE(formats); ++i) {
+ for (auto i = 0; i < std::size(formats); ++i) {
const auto parsed =
ParsedFormat<'v', 'u', 'c', 'v', 'f', 'v'>::NewAllowIgnored(formats[i]);
std::ostringstream oss;
@@ -523,6 +525,19 @@ TEST_F(FormatEntryPointTest, SNPrintF) {
EXPECT_EQ(buffer[0], '\0');
}
+TEST_F(FormatEntryPointTest, SNPrintFTooLarge) {
+ // Formatting more than INT_MAX bytes cannot be represented in the int return
+ // value, so the call reports an error via errno rather than returning a
+ // truncated (and possibly negative) count, matching FPrintF. A zero size
+ // means nothing is written to the buffer.
+ char buffer[16];
+ int width = 2000000000;
+ errno = 0;
+ int result = SNPrintF(buffer, 0, "%*d %*d", width, 0, width, 0);
+ EXPECT_LT(result, 0);
+ EXPECT_EQ(errno, EFBIG);
+}
+
TEST_F(FormatEntryPointTest, SNPrintFWithV) {
char buffer[16];
int result =
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_join_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/str_join_test.cc
index 1c0ffe1f242..66572489b29 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_join_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_join_test.cc
@@ -94,7 +94,7 @@ TEST(StrJoin, APIExamples) {
{
// Array of ints
const int a[] = {1, 2, 3, -4};
- EXPECT_EQ("1-2-3--4", absl::StrJoin(a, a + ABSL_ARRAYSIZE(a), "-"));
+ EXPECT_EQ("1-2-3--4", absl::StrJoin(a, a + std::size(a), "-"));
}
{
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 91b920bcaae..ac1dcac0948 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
@@ -38,6 +38,8 @@
#ifndef ABSL_STRINGS_STR_REPLACE_H_
#define ABSL_STRINGS_STR_REPLACE_H_
+#include <cstddef>
+#include <initializer_list>
#include <string>
#include <utility>
#include <vector>
@@ -160,7 +162,7 @@ template <typename StrToStrMapping>
std::vector<ViableSubstitution> FindSubstitutions(
absl::string_view s, const StrToStrMapping& replacements) {
std::vector<ViableSubstitution> subs;
- subs.reserve(replacements.size());
+ subs.reserve(std::size(replacements));
for (const auto& rep : replacements) {
using std::get;
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_replace_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/str_replace_test.cc
index 04b23af6f89..8922856735f 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_replace_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_replace_test.cc
@@ -156,6 +156,14 @@ TEST(StrReplaceAll, ManyReplacementsInMap) {
EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
}
+TEST(StrReplaceAll, ManyReplacementsInArray) {
+ std::pair<std::string, std::string> replacements[] = {
+ {"$who", "Bob"}, {"$count", "5"}, {"#Noun", "Apples"}};
+ std::string s = absl::StrReplaceAll("$who bought $count #Noun. Thanks $who!",
+ replacements);
+ EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
+}
+
TEST(StrReplaceAll, ReplacementsInPlace) {
std::string s = std::string("$who bought $count #Noun. Thanks $who!");
int count;
@@ -178,6 +186,16 @@ TEST(StrReplaceAll, ReplacementsInPlaceInMap) {
EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
}
+TEST(StrReplaceAll, ReplacementsInPlaceInArray) {
+ std::string s = std::string("$who bought $count #Noun. Thanks $who!");
+ std::pair<std::string, std::string> replacements[] = {
+ {"$who", "Bob"}, {"$count", "5"}, {"#Noun", "Apples"}};
+ int count;
+ count = absl::StrReplaceAll(replacements, &s);
+ EXPECT_EQ(count, 4);
+ EXPECT_EQ("Bob bought 5 Apples. Thanks Bob!", s);
+}
+
struct Cont {
Cont() = default;
explicit Cont(absl::string_view src) : data(src) {}
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 a0931a83b7d..b72b44634b5 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
@@ -40,11 +40,13 @@
#include <map>
#include <set>
#include <string>
+#include <type_traits>
#include <utility>
#include <vector>
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
+#include "absl/strings/ascii.h"
#include "absl/strings/internal/str_split_internal.h"
#include "absl/strings/string_view.h"
#include "absl/strings/strip.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/str_split_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/str_split_test.cc
index aa22ca4a1db..81553112957 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/str_split_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/str_split_test.cc
@@ -19,6 +19,7 @@
#include <cstdint>
#include <deque>
#include <initializer_list>
+#include <iterator>
#include <list>
#include <map>
#include <memory>
@@ -47,31 +48,23 @@ using ::testing::Pair;
using ::testing::UnorderedElementsAre;
TEST(Split, TraitsTest) {
- static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value,
- "");
+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<int>::value);
static_assert(
- !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value, "");
+ !absl::strings_internal::SplitterIsConvertibleTo<std::string>::value);
static_assert(absl::strings_internal::SplitterIsConvertibleTo<
- std::vector<std::string>>::value,
- "");
- static_assert(
- !absl::strings_internal::SplitterIsConvertibleTo<std::vector<int>>::value,
- "");
+ std::vector<std::string>>::value);
+ static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
+ std::vector<int>>::value);
static_assert(absl::strings_internal::SplitterIsConvertibleTo<
- std::vector<absl::string_view>>::value,
- "");
+ std::vector<absl::string_view>>::value);
static_assert(absl::strings_internal::SplitterIsConvertibleTo<
- std::map<std::string, std::string>>::value,
- "");
+ std::map<std::string, std::string>>::value);
static_assert(absl::strings_internal::SplitterIsConvertibleTo<
- std::map<absl::string_view, absl::string_view>>::value,
- "");
+ std::map<absl::string_view, absl::string_view>>::value);
static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
- std::map<int, std::string>>::value,
- "");
+ std::map<int, std::string>>::value);
static_assert(!absl::strings_internal::SplitterIsConvertibleTo<
- std::map<std::string, int>>::value,
- "");
+ std::map<std::string, int>>::value);
}
// This tests the overall split API, which is made up of the absl::StrSplit()
@@ -666,7 +659,7 @@ TEST(Split, Temporary) {
// destroyed, if the splitter keeps a reference to the string's contents,
// it'll reference freed memory instead of just dead on-stack memory.
const char input[] = "a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u";
- EXPECT_LT(sizeof(std::string), ABSL_ARRAYSIZE(input))
+ EXPECT_LT(sizeof(std::string), std::size(input))
<< "Input should be larger than fits on the stack.";
// This happens more often in C++11 as part of a range-based for loop.
diff --git a/deps/v8/third_party/abseil-cpp/absl/strings/strip_test.cc b/deps/v8/third_party/abseil-cpp/absl/strings/strip_test.cc
index e4e00cb66eb..b5cda6c5058 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/strip_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/strip_test.cc
@@ -20,9 +20,11 @@
#include <cassert>
#include <cstdio>
#include <cstring>
+#include <string>
#include "gmock/gmock.h"
#include "gtest/gtest.h"
+#include "absl/strings/ascii.h"
#include "absl/strings/string_view.h"
namespace {
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 626d52da15d..accf26ec020 100644
--- a/deps/v8/third_party/abseil-cpp/absl/strings/substitute.h
+++ b/deps/v8/third_party/abseil-cpp/absl/strings/substitute.h
@@ -73,6 +73,7 @@
#define ABSL_STRINGS_SUBSTITUTE_H_
#include <cstring>
+#include <iterator>
#include <string>
#include <type_traits>
#include <vector>
@@ -82,6 +83,7 @@
#include "absl/base/port.h"
#include "absl/strings/ascii.h"
#include "absl/strings/escaping.h"
+#include "absl/strings/has_absl_stringify.h"
#include "absl/strings/internal/stringify_sink.h"
#include "absl/strings/numbers.h"
#include "absl/strings/str_cat.h"
@@ -283,7 +285,7 @@ inline void SubstituteAndAppend(std::string* absl_nonnull output,
const substitute_internal::Arg& a0) {
const absl::string_view args[] = {a0.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(std::string* absl_nonnull output,
@@ -292,7 +294,7 @@ inline void SubstituteAndAppend(std::string* absl_nonnull output,
const substitute_internal::Arg& a1) {
const absl::string_view args[] = {a0.piece(), a1.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(std::string* absl_nonnull output,
@@ -302,7 +304,7 @@ inline void SubstituteAndAppend(std::string* absl_nonnull output,
const substitute_internal::Arg& a2) {
const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(std::string* absl_nonnull output,
@@ -314,7 +316,7 @@ inline void SubstituteAndAppend(std::string* absl_nonnull output,
const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(),
a3.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(std::string* absl_nonnull output,
@@ -327,7 +329,7 @@ inline void SubstituteAndAppend(std::string* absl_nonnull output,
const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(),
a3.piece(), a4.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(
@@ -338,7 +340,7 @@ inline void SubstituteAndAppend(
const absl::string_view args[] = {a0.piece(), a1.piece(), a2.piece(),
a3.piece(), a4.piece(), a5.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(
@@ -351,7 +353,7 @@ inline void SubstituteAndAppend(
a3.piece(), a4.piece(), a5.piece(),
a6.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(
@@ -364,7 +366,7 @@ inline void SubstituteAndAppend(
a3.piece(), a4.piece(), a5.piece(),
a6.piece(), a7.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(
@@ -378,7 +380,7 @@ inline void SubstituteAndAppend(
a3.piece(), a4.piece(), a5.piece(),
a6.piece(), a7.piece(), a8.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
inline void SubstituteAndAppend(
@@ -392,7 +394,7 @@ inline void SubstituteAndAppend(
a0.piece(), a1.piece(), a2.piece(), a3.piece(), a4.piece(),
a5.piece(), a6.piece(), a7.piece(), a8.piece(), a9.piece()};
substitute_internal::SubstituteAndAppendArray(output, format, args,
- ABSL_ARRAYSIZE(args));
+ std::size(args));
}
#if defined(ABSL_BAD_CALL_IF)
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 942fc0384b0..57740efa5ef 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.bazel
@@ -49,6 +49,7 @@ cc_library(
}),
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
+ "//absl/algorithm:container",
"//absl/base",
"//absl/base:base_internal",
"//absl/base:config",
@@ -69,9 +70,7 @@ cc_library(
"@do_not_use_for_gloop_visibility_only//gloop/thread:__subpackages__",
],
deps = [
- "//absl/base",
"//absl/base:config",
- "//absl/base:core_headers",
"//absl/base:raw_logging_internal",
"//absl/time",
],
@@ -85,8 +84,6 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":kernel_timeout_internal",
- "//absl/base:config",
- "//absl/random",
"//absl/time",
"@googletest//:gtest",
"@googletest//:gtest_main",
@@ -215,7 +212,9 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":graphcycles_internal",
+ "//absl/base:config",
"//absl/base:core_headers",
+ "//absl/container:flat_hash_set",
"//absl/log",
"//absl/log:check",
"@googletest//:gtest",
@@ -264,12 +263,10 @@ cc_test(
deps = [
":synchronization",
":thread_pool",
- "//absl/base",
"//absl/base:config",
"//absl/base:core_headers",
"//absl/log",
"//absl/log:check",
- "//absl/memory",
"//absl/random",
"//absl/time",
"@googletest//:gtest",
@@ -284,7 +281,6 @@ cc_test(
linkopts = ABSL_DEFAULT_LINKOPTS,
deps = [
":synchronization",
- "//absl/base:config",
"@googletest//:gtest",
"@googletest//:gtest_main",
],
@@ -302,8 +298,8 @@ cc_library(
":synchronization",
":thread_pool",
"//absl/base",
- "//absl/base:config",
"//absl/base:no_destructor",
+ "//absl/base:raw_logging_internal",
"@google_benchmark//:benchmark_main",
],
alwayslink = 1,
@@ -348,9 +344,11 @@ cc_library(
"@do_not_use_for_gloop_visibility_only//gloop/base:__subpackages__",
],
deps = [
+ ":kernel_timeout_internal",
":synchronization",
"//absl/base",
"//absl/base:config",
+ "//absl/base:core_headers",
"//absl/strings",
"//absl/time",
"@googletest//:gtest",
@@ -386,7 +384,6 @@ cc_test(
":kernel_timeout_internal",
":synchronization",
":thread_pool",
- "//absl/base:config",
"//absl/random",
"//absl/time",
"@googletest//:gtest",
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 34274bc145a..a2c63e56fcf 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/BUILD.gn
@@ -1,13 +1,17 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("graphcycles_internal") {
sources = [ "internal/graphcycles.cc" ]
public = [ "internal/graphcycles.h" ]
+ visibility = [ ":*" ]
deps = [
+ "//third_party/abseil-cpp/absl/algorithm:container",
"//third_party/abseil-cpp/absl/base",
"//third_party/abseil-cpp/absl/base:base_internal",
"//third_party/abseil-cpp/absl/base:config",
@@ -15,28 +19,23 @@ absl_source_set("graphcycles_internal") {
"//third_party/abseil-cpp/absl/base:malloc_internal",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
- visibility = [ ":*" ]
}
absl_source_set("kernel_timeout_internal") {
sources = [ "internal/kernel_timeout.cc" ]
public = [ "internal/kernel_timeout.h" ]
+ visibility = [ ":*" ]
deps = [
- "//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:raw_logging_internal",
"//third_party/abseil-cpp/absl/time",
]
- visibility = [ ":*" ]
}
absl_test("kernel_timeout_internal_test") {
sources = [ "internal/kernel_timeout_test.cc" ]
deps = [
":kernel_timeout_internal",
- "//third_party/abseil-cpp/absl/base:config",
- "//third_party/abseil-cpp/absl/random",
"//third_party/abseil-cpp/absl/time",
]
}
@@ -100,24 +99,17 @@ absl_test("barrier_test") {
]
}
-# Conflicts at link time with "tracing_strong_test" because also defines
-# strong functions for AbslInternalTraceWait and alike
-# absl_test("blocking_counter_test") {
-# sources = [ "blocking_counter_test.cc" ]
-# deps = [
-# ":synchronization",
-# "//third_party/abseil-cpp/absl/base:config",
-# "//third_party/abseil-cpp/absl/base:core_headers",
-# "//third_party/abseil-cpp/absl/base:tracing_internal",
-# "//third_party/abseil-cpp/absl/time",
-# ]
-# }
+# Conflicts at link time with "tracing_strong_test" because also defines strong
+# functions for AbslInternalTraceWait and alike
+# absl_test("blocking_counter_test")
absl_test("graphcycles_test") {
sources = [ "internal/graphcycles_test.cc" ]
deps = [
":graphcycles_internal",
+ "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
+ "//third_party/abseil-cpp/absl/container:flat_hash_set",
"//third_party/abseil-cpp/absl/log",
"//third_party/abseil-cpp/absl/log:check",
]
@@ -126,12 +118,12 @@ absl_test("graphcycles_test") {
absl_source_set("thread_pool") {
testonly = true
public = [ "internal/thread_pool.h" ]
+ visibility = [ "//third_party/abseil-cpp/absl/*" ]
deps = [
":synchronization",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/functional:any_invocable",
]
- visibility = [ "//third_party/abseil-cpp/absl/*" ]
}
absl_test("mutex_test") {
@@ -139,51 +131,37 @@ absl_test("mutex_test") {
deps = [
":synchronization",
":thread_pool",
- "//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/log",
"//third_party/abseil-cpp/absl/log:check",
- "//third_party/abseil-cpp/absl/memory",
"//third_party/abseil-cpp/absl/random",
"//third_party/abseil-cpp/absl/time",
]
}
# Doesn't compile.
-# absl_test("mutex_method_pointer_test") {
-# sources = [ "mutex_method_pointer_test.cc" ]
-# deps = [
-# ":synchronization",
-# "//third_party/abseil-cpp/absl/base:config",
-# ]
-# }
+# absl_test("mutex_method_pointer_test")
-# Conflicts at link time with "tracing_strong_test" because also defines
-# strong functions for AbslInternalTraceWait and alike
-# absl_test("notification_test") {
-# sources = [ "notification_test.cc" ]
-# deps = [
-# ":synchronization",
-# "//third_party/abseil-cpp/absl/base:config",
-# "//third_party/abseil-cpp/absl/base:core_headers",
-# "//third_party/abseil-cpp/absl/base:tracing_internal",
-# "//third_party/abseil-cpp/absl/time",
-# ]
-# }
+# Conflicts at link time with "tracing_strong_test" because also defines strong
+# functions for AbslInternalTraceWait and alike
+# absl_test("notification_test")
absl_source_set("per_thread_sem_test_common") {
testonly = true
sources = [ "internal/per_thread_sem_test.cc" ]
+ visibility = [ ":*" ]
deps = [
+ ":kernel_timeout_internal",
":synchronization",
"//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/time",
+ "//third_party/googletest:gmock",
"//third_party/googletest:gtest",
]
- visibility = [ ":*" ]
}
absl_test("per_thread_sem_test") {
@@ -201,17 +179,9 @@ absl_test("waiter_test") {
":kernel_timeout_internal",
":synchronization",
":thread_pool",
- "//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/random",
"//third_party/abseil-cpp/absl/time",
]
}
-# Has it's own main function and thus can't be included into absl_tests target
-# absl_test("lifetime_test") {
-# sources = [ "lifetime_test.cc" ]
-# deps = [
-# ":synchronization",
-# "//third_party/abseil-cpp/absl/base:core_headers",
-# "//third_party/abseil-cpp/absl/log:check",
-# ]
-# }
+# lifetime_test is excluded because defines its own main function
+# absl_test("lifetime_test")
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 9c4a0b1fe90..2805000d6e9 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/CMakeLists.txt
@@ -157,6 +157,7 @@ absl_cc_test(
DEPS
absl::check
absl::core_headers
+ absl::flat_hash_map
absl::graphcycles_internal
absl::log
GTest::gmock_main
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.cc
index f5dad22203f..e5cbdc60b86 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier.cc
@@ -14,6 +14,7 @@
#include "absl/synchronization/barrier.h"
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/synchronization/mutex.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier_test.cc
index 2aed2724076..2cfb57c4f6d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/barrier_test.cc
@@ -20,7 +20,7 @@
#include "gtest/gtest.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/clock.h"
-
+#include "absl/time/time.h"
TEST(Barrier, SanityTest) {
constexpr int kNumThreads = 10;
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc
index 9468469afab..d38b260928b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/blocking_counter.cc
@@ -16,8 +16,10 @@
#include <atomic>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/tracing.h"
+#include "absl/synchronization/mutex.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
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 d0504a19bf0..46c010bb971 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
@@ -91,7 +91,7 @@ class BlockingCounter {
private:
// Convenience helper to reduce verbosity at call sites.
- static inline constexpr base_internal::ObjectKind TraceObjectKind() {
+ static constexpr base_internal::ObjectKind TraceObjectKind() {
return base_internal::ObjectKind::kBlockingCounter;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
index e10d3bc0ee0..d7168da55c1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/create_thread_identity.cc
@@ -12,18 +12,18 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include <stdint.h>
-
-#include <new>
+#include "absl/base/internal/low_level_alloc.h" // IWYU pragma: keep
// This file is a no-op if the required LowLevelAlloc support is missing.
-#include "absl/base/internal/low_level_alloc.h"
-#include "absl/synchronization/internal/waiter.h"
#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
-#include <string.h>
+#include <atomic>
+#include <cstdint>
+#include <new>
#include "absl/base/attributes.h"
+#include "absl/base/config.h"
+#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/internal/thread_identity.h"
#include "absl/synchronization/internal/per_thread_sem.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 4cfde0913c9..f8bfbe986a9 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
@@ -26,6 +26,7 @@
#define ABSL_SYNCHRONIZATION_INTERNAL_CREATE_THREAD_IDENTITY_H_
#include "absl/base/internal/thread_identity.h"
+#include "absl/base/optimization.h"
#include "absl/base/port.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex.h
index 573c01b74c2..b4a0cf41dfd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex.h
@@ -14,7 +14,17 @@
#ifndef ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_FUTEX_H_
+#include <errno.h>
+#include <stdio.h>
+#include <time.h>
+
+#include <atomic>
+#include <cstdint>
+#include <limits>
+
#include "absl/base/config.h"
+#include "absl/base/optimization.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
#ifndef _WIN32
#include <sys/time.h>
@@ -26,17 +36,6 @@
#include <sys/syscall.h>
#endif
-#include <errno.h>
-#include <stdio.h>
-#include <time.h>
-
-#include <atomic>
-#include <cstdint>
-#include <limits>
-
-#include "absl/base/optimization.h"
-#include "absl/synchronization/internal/kernel_timeout.h"
-
#ifdef ABSL_INTERNAL_HAVE_FUTEX
#error ABSL_INTERNAL_HAVE_FUTEX may not be set on the command line
#elif defined(__BIONIC__)
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc
index 8945c176e6e..d7666d9db40 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/futex_waiter.cc
@@ -17,15 +17,14 @@
#ifdef ABSL_INTERNAL_HAVE_FUTEX_WAITER
#include <atomic>
-#include <cstdint>
#include <cerrno>
+#include <cstdint>
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
#include "absl/base/optimization.h"
-#include "absl/synchronization/internal/kernel_timeout.h"
#include "absl/synchronization/internal/futex.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc
index f58fb0a7772..25b51ffe0b8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.cc
@@ -28,19 +28,25 @@
// (2) When a new edge (x->y) is inserted, do nothing if rank[x] < rank[y].
// (3) Otherwise: adjust ranks in the neighborhood of x and y.
-#include "absl/base/attributes.h"
+#include "absl/base/internal/low_level_alloc.h" // IWYU pragma: keep
// This file is a no-op if the required LowLevelAlloc support is missing.
-#include "absl/base/internal/low_level_alloc.h"
#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
#include <algorithm>
#include <array>
#include <cinttypes>
+#include <cstddef>
+#include <cstdint>
#include <limits>
+#include "absl/algorithm/container.h"
+#include "absl/base/attributes.h"
+#include "absl/base/config.h"
#include "absl/base/internal/hide_ptr.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/spinlock.h"
+#include "absl/base/macros.h"
#include "absl/synchronization/internal/graphcycles.h"
// Do not use STL. This module does not use standard memory allocation.
@@ -622,7 +628,7 @@ static void Sort(const Vec<Node*>& nodes, Vec<int32_t>* delta) {
};
ByRank cmp;
cmp.nodes = &nodes;
- std::sort(delta->begin(), delta->end(), cmp);
+ absl::c_sort(*delta, cmp);
}
static void MoveToList(GraphCycles::Rep* r, Vec<int32_t>* src,
@@ -692,7 +698,8 @@ void GraphCycles::UpdateStackTrace(GraphId id, int priority,
if (n == nullptr || n->priority >= priority) {
return;
}
- n->nstack = (*get_stack_trace)(n->stack, ABSL_ARRAYSIZE(n->stack));
+ n->nstack =
+ (*get_stack_trace)(n->stack, static_cast<int>(std::size(n->stack)));
n->priority = priority;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h
index 08f304bce1b..da065040530 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles.h
@@ -80,20 +80,20 @@ class GraphCycles {
// Attempt to insert an edge from source_node to dest_node. If the
// edge would introduce a cycle, return false without making any
// changes. Otherwise add the edge and return true.
- bool InsertEdge(GraphId source_node, GraphId dest_node);
+ bool InsertEdge(GraphId idx, GraphId idy);
// Remove any edge that exists from source_node to dest_node.
- void RemoveEdge(GraphId source_node, GraphId dest_node);
+ void RemoveEdge(GraphId x, GraphId y);
// Return whether node exists in the graph.
bool HasNode(GraphId node);
// Return whether there is an edge directly from source_node to dest_node.
- bool HasEdge(GraphId source_node, GraphId dest_node) const;
+ bool HasEdge(GraphId x, GraphId y) const;
// Return whether dest_node is reachable from source_node
// by following edges.
- bool IsReachable(GraphId source_node, GraphId dest_node) const;
+ bool IsReachable(GraphId x, GraphId y) const;
// Find a path from "source" to "dest". If such a path exists,
// place the nodes on the path in the array path[], and return
@@ -107,7 +107,7 @@ class GraphCycles {
// source and destination node if they are identical; therefore, the
// return value is at most one greater than the number of nodes in
// the graph.
- int FindPath(GraphId source, GraphId dest, int max_path_len,
+ int FindPath(GraphId idx, GraphId idy, int max_path_len,
GraphId path[]) const;
// Update the stack trace recorded for id with the current stack
@@ -143,4 +143,4 @@ class GraphCycles {
ABSL_NAMESPACE_END
} // namespace absl
-#endif
+#endif // ABSL_SYNCHRONIZATION_INTERNAL_GRAPHCYCLES_H_
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc
index b7988c4d235..d4ba0f6edd8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/graphcycles_test.cc
@@ -16,14 +16,19 @@
#include <climits>
#include <cstdint>
+#include <cstdio>
+#include <iterator>
#include <map>
#include <random>
+#include <string>
#include <unordered_set>
#include <utility>
#include <vector>
#include "gtest/gtest.h"
+#include "absl/base/config.h"
#include "absl/base/macros.h"
+#include "absl/container/flat_hash_set.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
@@ -50,8 +55,8 @@ static GraphId Get(const IdMap& id, int num) {
}
// Return whether "to" is reachable from "from".
-static bool IsReachable(Edges *edges, int from, int to,
- std::unordered_set<int> *seen) {
+static bool IsReachable(Edges* edges, int from, int to,
+ absl::flat_hash_set<int>* seen) {
seen->insert(from); // we are investigating "from"; don't do it again
if (from == to) return true;
for (const auto &edge : *edges) {
@@ -93,7 +98,7 @@ static void PrintTransitiveClosure(Nodes *nodes, Edges *edges) {
LOG(INFO) << "Transitive closure";
for (int a : *nodes) {
for (int b : *nodes) {
- std::unordered_set<int> seen;
+ absl::flat_hash_set<int> seen;
if (IsReachable(edges, a, b, &seen)) {
LOG(INFO) << a << " " << b;
}
@@ -117,7 +122,7 @@ static void PrintGCTransitiveClosure(Nodes *nodes, const IdMap &id,
static void CheckTransitiveClosure(Nodes *nodes, Edges *edges, const IdMap &id,
GraphCycles *gc) {
- std::unordered_set<int> seen;
+ absl::flat_hash_set<int> seen;
for (const auto &a : *nodes) {
for (const auto &b : *nodes) {
seen.clear();
@@ -226,7 +231,7 @@ TEST(GraphCycles, RandomizedTest) {
break;
case 1: // Remove a node
- if (nodes.size() > 0) {
+ if (!nodes.empty()) {
int node_index = RandomNode(&rng, &nodes);
int node = nodes[node_index];
nodes[node_index] = nodes.back();
@@ -247,7 +252,7 @@ TEST(GraphCycles, RandomizedTest) {
break;
case 2: // Add an edge
- if (nodes.size() > 0) {
+ if (!nodes.empty()) {
int from = RandomNode(&rng, &nodes);
int to = RandomNode(&rng, &nodes);
if (EdgeIndex(&edges, nodes[from], nodes[to]) == -1) {
@@ -257,7 +262,7 @@ TEST(GraphCycles, RandomizedTest) {
new_edge.to = nodes[to];
edges.push_back(new_edge);
} else {
- std::unordered_set<int> seen;
+ absl::flat_hash_set<int> seen;
ASSERT_TRUE(IsReachable(&edges, nodes[to], nodes[from], &seen))
<< "Edge " << nodes[to] << "->" << nodes[from];
}
@@ -266,7 +271,7 @@ TEST(GraphCycles, RandomizedTest) {
break;
case 3: // Remove an edge
- if (edges.size() > 0) {
+ if (!edges.empty()) {
int i = RandomEdge(&rng, &edges);
int from = edges[i].from;
int to = edges[i].to;
@@ -279,13 +284,13 @@ TEST(GraphCycles, RandomizedTest) {
break;
case 4: // Check a path
- if (nodes.size() > 0) {
+ if (!nodes.empty()) {
int from = RandomNode(&rng, &nodes);
int to = RandomNode(&rng, &nodes);
GraphId path[2*kMaxNodes];
int path_len = graph_cycles.FindPath(id[nodes[from]], id[nodes[to]],
- ABSL_ARRAYSIZE(path), path);
- std::unordered_set<int> seen;
+ std::size(path), path);
+ absl::flat_hash_set<int> seen;
bool reachable = IsReachable(&edges, nodes[from], nodes[to], &seen);
bool gc_reachable =
graph_cycles.IsReachable(Get(id, nodes[from]), Get(id, nodes[to]));
@@ -388,10 +393,10 @@ class GraphCyclesTest : public ::testing::Test {
std::string Path(int x, int y) {
GraphId path[5];
- int np = g_.FindPath(Get(id_, x), Get(id_, y), ABSL_ARRAYSIZE(path), path);
+ int np = g_.FindPath(Get(id_, x), Get(id_, y), std::size(path), path);
std::string result;
for (int i = 0; i < np; i++) {
- if (i >= ABSL_ARRAYSIZE(path)) {
+ if (i >= int{std::size(path)}) {
result += " ...";
break;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc
index 252397ab54d..e359cfcb084 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.cc
@@ -14,23 +14,21 @@
#include "absl/synchronization/internal/kernel_timeout.h"
-#ifndef _WIN32
-#include <sys/types.h>
-#endif
-
#include <algorithm>
#include <chrono> // NOLINT(build/c++11)
#include <cstdint>
-#include <cstdlib>
-#include <cstring>
#include <ctime>
#include <limits>
-#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/time/clock.h"
#include "absl/time/time.h"
+#ifndef _WIN32
+#include <sys/types.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace synchronization_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h
index c24fa865b30..7fc42915881 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout.h
@@ -15,10 +15,6 @@
#ifndef ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
#define ABSL_SYNCHRONIZATION_INTERNAL_KERNEL_TIMEOUT_H_
-#ifndef _WIN32
-#include <sys/types.h>
-#endif
-
#include <algorithm>
#include <chrono> // NOLINT(build/c++11)
#include <cstdint>
@@ -30,6 +26,10 @@
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#ifndef _WIN32
+#include <sys/types.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
namespace synchronization_internal {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout_test.cc
index 811246c2623..dc5bfc925f4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/kernel_timeout_test.cc
@@ -14,15 +14,16 @@
#include "absl/synchronization/internal/kernel_timeout.h"
-#include <ctime>
+#include <algorithm>
#include <chrono> // NOLINT(build/c++11)
+#include <cstdint>
+#include <ctime>
#include <limits>
-#include "absl/base/config.h"
-#include "absl/random/random.h"
+#include "gtest/gtest.h"
+#include "absl/time/civil_time.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
-#include "gtest/gtest.h"
#if 0 // All supported platforms currently have steady clocks.
#define ABSL_INTERNAL_KERNEL_TIMEOUT_SUPPORTS_STEADY_CLOCK 0
@@ -68,6 +69,20 @@ constexpr absl::Duration kTimingBound = absl::Microseconds(250);
using absl::synchronization_internal::KernelTimeout;
+// Returns a time far in the future.
+// On 32-bit time_t systems, the maximum representable time is in January 2038.
+// On 64-bit systems, the maximum representable time in KernelTimeout is in
+// April 2262 (int64_t max nanoseconds).
+absl::Time FarFuture() {
+ static const absl::Time far_future =
+ sizeof(time_t) <= 4
+ ? absl::FromCivil(absl::CivilSecond(2038, 1, 1, 0, 0, 0),
+ absl::UTCTimeZone())
+ : absl::FromCivil(absl::CivilSecond(2262, 1, 1, 0, 0, 0),
+ absl::UTCTimeZone());
+ return far_future;
+}
+
// TODO(b/348224897): re-enabled when the flakiness is fixed.
TEST(KernelTimeout, DISABLED_FiniteTimes) {
constexpr absl::Duration kDurationsToTest[] = {
@@ -127,16 +142,14 @@ TEST(KernelTimeout, InfiniteFuture) {
// below, but we do try to do something reasonable if they don't. We may not
// be able to round-trip back to absl::InfiniteDuration() or
// absl::InfiniteFuture(), but we should return a very large value.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_EQ(t.InMillisecondsFromNow(),
std::numeric_limits<KernelTimeout::DWord>::max());
EXPECT_EQ(t.ToChronoTimePoint(),
@@ -152,16 +165,14 @@ TEST(KernelTimeout, DefaultConstructor) {
// below, but we do try to do something reasonable if they don't. We may not
// be able to round-trip back to absl::InfiniteDuration() or
// absl::InfiniteFuture(), but we should return a very large value.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_EQ(t.InMillisecondsFromNow(),
std::numeric_limits<KernelTimeout::DWord>::max());
EXPECT_EQ(t.ToChronoTimePoint(),
@@ -177,16 +188,14 @@ TEST(KernelTimeout, TimeMaxNanos) {
// below, but we do try to do something reasonable if they don't. We may not
// be able to round-trip back to absl::InfiniteDuration() or
// absl::InfiniteFuture(), but we should return a very large value.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_EQ(t.InMillisecondsFromNow(),
std::numeric_limits<KernelTimeout::DWord>::max());
EXPECT_EQ(t.ToChronoTimePoint(),
@@ -202,16 +211,14 @@ TEST(KernelTimeout, Never) {
// below, but we do try to do something reasonable if they don't. We may not
// be able to round-trip back to absl::InfiniteDuration() or
// absl::InfiniteFuture(), but we should return a very large value.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_EQ(t.InMillisecondsFromNow(),
std::numeric_limits<KernelTimeout::DWord>::max());
EXPECT_EQ(t.ToChronoTimePoint(),
@@ -336,16 +343,14 @@ TEST(KernelTimeout, InfiniteDuration) {
// below, but we do try to do something reasonable if they don't. We may not
// be able to round-trip back to absl::InfiniteDuration() or
// absl::InfiniteFuture(), but we should return a very large value.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_EQ(t.InMillisecondsFromNow(),
std::numeric_limits<KernelTimeout::DWord>::max());
EXPECT_EQ(t.ToChronoTimePoint(),
@@ -361,16 +366,14 @@ TEST(KernelTimeout, DurationMaxNanos) {
// below, but we do try to do something reasonable if they don't. We may not
// be able to round-trip back to absl::InfiniteDuration() or
// absl::InfiniteFuture(), but we should return a very large value.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_EQ(t.InMillisecondsFromNow(),
std::numeric_limits<KernelTimeout::DWord>::max());
EXPECT_EQ(t.ToChronoTimePoint(),
@@ -386,16 +389,14 @@ TEST(KernelTimeout, OverflowNanos) {
absl::Duration duration = absl::Nanoseconds(limit) + absl::Seconds(1);
KernelTimeout t(duration);
// Timeouts should still be far in the future.
- EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::TimeFromTimespec(t.MakeAbsTimespec()), FarFuture());
#ifndef _WIN32
EXPECT_GT(absl::TimeFromTimespec(t.MakeClockAbsoluteTimespec(CLOCK_REALTIME)),
- absl::Now() + absl::Hours(100000));
+ FarFuture());
#endif
EXPECT_GT(absl::DurationFromTimespec(t.MakeRelativeTimespec()),
absl::Hours(100000));
- EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()),
- absl::Now() + absl::Hours(100000));
+ EXPECT_GT(absl::FromUnixNanos(t.MakeAbsNanos()), FarFuture());
EXPECT_LE(absl::Milliseconds(t.InMillisecondsFromNow()) - duration,
absl::Milliseconds(5));
EXPECT_GT(t.ToChronoTimePoint(),
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc
index c9b8dc1eb56..8ba2a20e983 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem.cc
@@ -12,16 +12,19 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include "absl/base/internal/low_level_alloc.h" // IWYU pragma: keep
+
// This file is a no-op if the required LowLevelAlloc support is missing.
-#include "absl/base/internal/low_level_alloc.h"
#ifndef ABSL_LOW_LEVEL_ALLOC_MISSING
-#include "absl/synchronization/internal/per_thread_sem.h"
-
#include <atomic>
#include "absl/base/attributes.h"
+#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"
+#include "absl/synchronization/internal/per_thread_sem.h"
#include "absl/synchronization/internal/waiter.h"
namespace absl {
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 704f3dac6b5..7d1099efc6e 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
@@ -30,6 +30,7 @@
#include "absl/base/internal/thread_identity.h"
#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/kernel_timeout.h"
+#include "absl/time/time.h"
namespace gloop_do_not_use {
struct SynchronizationBenchmarkPeer;
@@ -78,6 +79,10 @@ class PerThreadSem {
// !t.has_timeout() => Wait(t) will return true.
static inline bool Wait(KernelTimeout t);
+ // Waits until either our count > 0 or the absolute time t has passed.
+ // If count > 0, decrements count and returns true. Otherwise returns false.
+ static inline bool WaitAbsolute(absl::Time t);
+
// Permitted callers.
friend class PerThreadSemTest;
friend class absl::Mutex;
@@ -121,4 +126,8 @@ bool absl::synchronization_internal::PerThreadSem::Wait(
return ABSL_INTERNAL_C_SYMBOL(AbslInternalPerThreadSemWait)(t);
}
+bool absl::synchronization_internal::PerThreadSem::WaitAbsolute(absl::Time t) {
+ return Wait(KernelTimeout(t));
+}
+
#endif // ABSL_SYNCHRONIZATION_INTERNAL_PER_THREAD_SEM_H_
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc
index e3cf41d7425..4c5ca694607 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/per_thread_sem_test.cc
@@ -14,19 +14,25 @@
#include "absl/synchronization/internal/per_thread_sem.h"
+#include <algorithm>
#include <atomic>
#include <condition_variable> // NOLINT(build/c++11)
+#include <cstdint>
+#include <cstdio>
#include <functional>
#include <limits>
-#include <mutex> // NOLINT(build/c++11)
+#include <mutex> // NOLINT(build/c++11)
#include <string>
-#include <thread> // NOLINT(build/c++11)
+#include <thread> // NOLINT(build/c++11)
#include "gtest/gtest.h"
+#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/cycleclock.h"
#include "absl/base/internal/thread_identity.h"
#include "absl/strings/str_cat.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
@@ -132,9 +138,9 @@ class PerThreadSemTest : public testing::Test {
return PerThreadSem::Wait(t);
}
- // convenience overload
+ // absl::Time overload, absolute expiry
static bool Wait(absl::Time t) {
- return Wait(KernelTimeout(t));
+ return PerThreadSem::WaitAbsolute(t);
}
static void Tick(base_internal::ThreadIdentity *identity) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc
index eead9de05b4..5b27d0fa7f8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/pthread_waiter.cc
@@ -25,7 +25,6 @@
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
#include "absl/base/optimization.h"
#include "absl/synchronization/internal/kernel_timeout.h"
@@ -59,12 +58,12 @@ class PthreadMutexHolder {
} // namespace
PthreadWaiter::PthreadWaiter() : waiter_count_(0), wakeup_count_(0) {
- const int err = pthread_mutex_init(&mu_, 0);
+ const int err = pthread_mutex_init(&mu_, nullptr);
if (err != 0) {
ABSL_RAW_LOG(FATAL, "pthread_mutex_init failed: %d", err);
}
- const int err2 = pthread_cond_init(&cv_, 0);
+ const int err2 = pthread_cond_init(&cv_, nullptr);
if (err2 != 0) {
ABSL_RAW_LOG(FATAL, "pthread_cond_init failed: %d", err2);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc
index 2119290d530..50f5960d7b7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/sem_waiter.cc
@@ -20,13 +20,10 @@
#include <atomic>
#include <cassert>
-#include <cstdint>
#include <cerrno>
#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
-#include "absl/base/optimization.h"
#include "absl/synchronization/internal/kernel_timeout.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc
index 607d683ffe6..c9368d5dc2a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/stdcpp_waiter.cc
@@ -16,14 +16,10 @@
#ifdef ABSL_INTERNAL_HAVE_STDCPP_WAITER
-#include <chrono> // NOLINT(build/c++11)
#include <condition_variable> // NOLINT(build/c++11)
#include <mutex> // NOLINT(build/c++11)
#include "absl/base/config.h"
-#include "absl/base/internal/raw_logging.h"
-#include "absl/base/internal/thread_identity.h"
-#include "absl/base/optimization.h"
#include "absl/synchronization/internal/kernel_timeout.h"
namespace absl {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc
index e9797f8b141..011de18a8ff 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_base.cc
@@ -14,6 +14,9 @@
#include "absl/synchronization/internal/waiter_base.h"
+#include <atomic>
+#include <cassert>
+
#include "absl/base/config.h"
#include "absl/base/internal/thread_identity.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_test.cc
index 80a6985769b..44f0d6fa89c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/internal/waiter_test.cc
@@ -18,7 +18,7 @@
#include <iostream>
#include <ostream>
-#include "absl/base/config.h"
+#include "gtest/gtest.h"
#include "absl/random/random.h"
#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/futex_waiter.h"
@@ -27,10 +27,8 @@
#include "absl/synchronization/internal/sem_waiter.h"
#include "absl/synchronization/internal/stdcpp_waiter.h"
#include "absl/synchronization/internal/thread_pool.h"
-#include "absl/synchronization/internal/win32_waiter.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
-#include "gtest/gtest.h"
// Test go/btm support by randomizing the value of clock_gettime() for
// CLOCK_MONOTONIC. This works by overriding a weak symbol in glibc.
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc
index 1c11431b3a9..a659bcfbba6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/lifetime_test.cc
@@ -14,7 +14,6 @@
#include <cstdlib>
#include <thread> // NOLINT(build/c++11), Abseil test
-#include <type_traits>
#include "absl/base/attributes.h"
#include "absl/base/const_init.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 20164352620..68782564443 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.cc
@@ -14,20 +14,7 @@
#include "absl/synchronization/mutex.h"
-#ifdef _WIN32
-#include <windows.h>
-#ifdef ERROR
-#undef ERROR
-#endif
-#else
-#include <fcntl.h>
-#include <pthread.h>
-#include <sched.h>
-#include <sys/time.h>
-#endif
-
#include <assert.h>
-#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
@@ -36,8 +23,10 @@
#include <algorithm>
#include <atomic>
#include <cstddef>
+#include <cstdint>
#include <cstdlib>
#include <cstring>
+#include <iterator>
#include <thread> // NOLINT(build/c++11)
#include "absl/base/attributes.h"
@@ -48,18 +37,37 @@
#include "absl/base/internal/cycleclock.h"
#include "absl/base/internal/hide_ptr.h"
#include "absl/base/internal/low_level_alloc.h"
+#include "absl/base/internal/low_level_scheduling.h"
#include "absl/base/internal/raw_logging.h"
+#include "absl/base/internal/scheduling_mode.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/internal/sysinfo.h"
#include "absl/base/internal/thread_identity.h"
#include "absl/base/internal/tsan_mutex_interface.h"
+#include "absl/base/macros.h"
#include "absl/base/optimization.h"
+#include "absl/base/thread_annotations.h"
#include "absl/debugging/stacktrace.h"
#include "absl/debugging/symbolize.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/graphcycles.h"
+#include "absl/synchronization/internal/kernel_timeout.h"
#include "absl/synchronization/internal/per_thread_sem.h"
+#include "absl/time/clock.h"
#include "absl/time/time.h"
+#ifdef _WIN32
+#include <windows.h>
+#ifdef ERROR
+#undef ERROR
+#endif
+#else
+#include <fcntl.h>
+#include <pthread.h>
+#include <sched.h>
+#include <sys/time.h>
+#endif
+
using absl::base_internal::CurrentThreadIdentityIfPresent;
using absl::base_internal::CycleClock;
using absl::base_internal::PerThreadSynch;
@@ -434,10 +442,10 @@ static void PostSynchEvent(void* obj, int ev) {
// or it explicitly says to log
if (e == nullptr || e->log) {
void* pcs[40];
- int n = absl::GetStackTrace(pcs, ABSL_ARRAYSIZE(pcs), 1);
+ int n = absl::GetStackTrace(pcs, std::size(pcs), 1);
// A buffer with enough space for the ASCII for all the PCs, even on a
// 64-bit machine.
- char buffer[ABSL_ARRAYSIZE(pcs) * 24];
+ char buffer[std::size(pcs) * 24];
int pos = snprintf(buffer, sizeof(buffer), " @");
for (int i = 0; i != n; i++) {
int b = snprintf(&buffer[pos], sizeof(buffer) - static_cast<size_t>(pos),
@@ -1239,7 +1247,7 @@ static void LockEnter(Mutex* mu, GraphId id, SynchLocksHeld* held_locks) {
i++;
}
if (i == n) {
- if (n == ABSL_ARRAYSIZE(held_locks->locks)) {
+ if (n == static_cast<int>(std::size(held_locks->locks))) {
held_locks->overflow = true; // lost some data
} else { // we have room for lock
held_locks->locks[i].mu = mu;
@@ -1345,7 +1353,7 @@ static char* StackString(void** pcs, int n, char* buf, int maxlen,
static char* CurrentStackString(char* buf, int maxlen, bool symbolize) {
void* pcs[40];
- return StackString(pcs, absl::GetStackTrace(pcs, ABSL_ARRAYSIZE(pcs), 2), buf,
+ return StackString(pcs, absl::GetStackTrace(pcs, std::size(pcs), 2), buf,
maxlen, symbolize);
}
@@ -1436,9 +1444,10 @@ static GraphId DeadlockCheck(Mutex* mu) {
"historical lock ordering graph has been observed",
static_cast<void*>(mu), b->buf);
ABSL_RAW_LOG(ERROR, "Cycle: ");
- int path_len = deadlock_graph->FindPath(mu_id, other_node_id,
- ABSL_ARRAYSIZE(b->path), b->path);
- for (int j = 0; j != path_len && j != ABSL_ARRAYSIZE(b->path); j++) {
+ int path_len = deadlock_graph->FindPath(
+ mu_id, other_node_id, static_cast<int>(std::size(b->path)), b->path);
+ for (int j = 0;
+ j != path_len && j != static_cast<int>(std::size(b->path)); j++) {
GraphId id = b->path[j];
Mutex* path_mu = static_cast<Mutex*>(deadlock_graph->Ptr(id));
if (path_mu == nullptr) continue;
@@ -1451,7 +1460,7 @@ static GraphId DeadlockCheck(Mutex* mu) {
symbolize);
ABSL_RAW_LOG(ERROR, "%s", b->buf);
}
- if (path_len > static_cast<int>(ABSL_ARRAYSIZE(b->path))) {
+ if (path_len > static_cast<int>(std::size(b->path))) {
ABSL_RAW_LOG(ERROR, "(long cycle; list truncated)");
}
if (synch_deadlock_detection.load(std::memory_order_acquire) ==
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.h
index 6489025d2ad..a2ac32f3eb6 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex.h
@@ -961,7 +961,7 @@ class Condition {
// Helper methods for storing, validating, and reading callback arguments.
template <typename T>
- inline void StoreCallback(T callback) {
+ void StoreCallback(T callback) {
static_assert(
sizeof(callback) <= sizeof(callback_),
"An overlarge pointer was passed as a callback to Condition.");
@@ -969,7 +969,7 @@ class Condition {
}
template <typename T>
- inline void ReadCallback(T* absl_nonnull callback) const {
+ void ReadCallback(T* absl_nonnull callback) const {
std::memcpy(callback, callback_, sizeof(*callback));
}
@@ -1184,7 +1184,7 @@ inline Mutex::Mutex() : mu_(0) {
ABSL_TSAN_MUTEX_CREATE(this, __tsan_mutex_not_static);
}
-inline constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
+constexpr Mutex::Mutex(absl::ConstInitType) : mu_(0) {}
#if !defined(__APPLE__) && !defined(ABSL_BUILD_DLL)
ABSL_ATTRIBUTE_ALWAYS_INLINE
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc
index d2c64956f09..2df1d678aa4 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_benchmark.cc
@@ -12,15 +12,20 @@
// See the License for the specific language governing permissions and
// limitations under the License.
+#include <atomic>
#include <cstdint>
+#include <limits>
#include <mutex> // NOLINT(build/c++11)
#include <vector>
-#include "absl/base/config.h"
#include "absl/base/internal/cycleclock.h"
+#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/spinlock.h"
+#include "absl/base/internal/thread_identity.h"
#include "absl/base/no_destructor.h"
#include "absl/synchronization/blocking_counter.h"
+#include "absl/synchronization/internal/create_thread_identity.h"
+#include "absl/synchronization/internal/per_thread_sem.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/synchronization/mutex.h"
#include "benchmark/benchmark.h"
@@ -30,7 +35,7 @@ namespace {
void BM_Mutex(benchmark::State& state) {
static absl::NoDestructor<absl::Mutex> mu;
for (auto _ : state) {
- absl::MutexLock lock(*mu.get());
+ absl::MutexLock lock(*mu);
}
}
BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu();
@@ -38,7 +43,7 @@ BENCHMARK(BM_Mutex)->UseRealTime()->Threads(1)->ThreadPerCpu();
void BM_ReaderLock(benchmark::State& state) {
static absl::NoDestructor<absl::Mutex> mu;
for (auto _ : state) {
- absl::ReaderMutexLock lock(*mu.get());
+ absl::ReaderMutexLock lock(*mu);
}
}
BENCHMARK(BM_ReaderLock)->UseRealTime()->Threads(1)->ThreadPerCpu();
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_method_pointer_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_method_pointer_test.cc
index f4c82d276e4..420750b6c3e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_method_pointer_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_method_pointer_test.cc
@@ -12,13 +12,13 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/synchronization/mutex.h"
-
-#include <cstdlib>
#include <string>
#include "gtest/gtest.h"
-#include "absl/base/config.h"
+
+#ifdef _MSC_VER
+#include "absl/synchronization/mutex.h"
+#endif
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
index 5663cf6638b..a96bcff7ebf 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/mutex_test.cc
@@ -14,16 +14,13 @@
#include "absl/synchronization/mutex.h"
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
#include <algorithm>
#include <atomic>
#include <cstdlib>
#include <functional>
#include <memory>
#include <mutex> // NOLINT(build/c++11)
+#include <ostream>
#include <random>
#include <shared_mutex> // NOLINT(build/c++14)
#include <string>
@@ -32,18 +29,20 @@
#include <vector>
#include "gtest/gtest.h"
-#include "absl/base/attributes.h"
#include "absl/base/config.h"
-#include "absl/base/internal/sysinfo.h"
+#include "absl/base/thread_annotations.h"
#include "absl/log/check.h"
#include "absl/log/log.h"
-#include "absl/memory/memory.h"
#include "absl/random/random.h"
#include "absl/synchronization/internal/create_thread_identity.h"
#include "absl/synchronization/internal/thread_pool.h"
#include "absl/time/clock.h"
#include "absl/time/time.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
#ifdef ABSL_HAVE_PTHREAD_GETSCHEDPARAM
#include <pthread.h>
#include <string.h>
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.cc
index a890c1bcd55..63da068cbbd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.cc
@@ -16,8 +16,10 @@
#include <atomic>
+#include "absl/base/config.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/internal/tracing.h"
+#include "absl/base/optimization.h"
#include "absl/synchronization/mutex.h"
#include "absl/time/time.h"
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.h b/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.h
index 12df31b7aa6..420b82003fd 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.h
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/notification.h
@@ -114,12 +114,11 @@ class Notification {
private:
// Convenience helper to reduce verbosity at call sites.
- static inline constexpr base_internal::ObjectKind TraceObjectKind() {
+ static constexpr base_internal::ObjectKind TraceObjectKind() {
return base_internal::ObjectKind::kNotification;
}
- static inline bool HasBeenNotifiedInternal(
- const std::atomic<bool>* notified_yet) {
+ static bool HasBeenNotifiedInternal(const std::atomic<bool>* notified_yet) {
return notified_yet->load(std::memory_order_acquire);
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/synchronization/notification_test.cc b/deps/v8/third_party/abseil-cpp/absl/synchronization/notification_test.cc
index ac5dccd5687..ded80a5f667 100644
--- a/deps/v8/third_party/abseil-cpp/absl/synchronization/notification_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/synchronization/notification_test.cc
@@ -23,6 +23,7 @@
#include "absl/base/config.h"
#include "absl/base/internal/tracing.h"
#include "absl/synchronization/mutex.h"
+#include "absl/time/clock.h"
#include "absl/time/time.h"
namespace absl {
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 cca77dab2bf..073c229d480 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/time/BUILD.bazel
@@ -148,6 +148,7 @@ cc_test(
"//absl/hash:hash_testing",
"//absl/numeric:int128",
"//absl/random",
+ "//absl/strings",
"//absl/strings:str_format",
"//absl/time/internal/cctz:time_zone",
"@googletest//:gtest",
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 4655eed3ad8..4a10c420138 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/time/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -65,12 +67,12 @@ absl_source_set("test_util") {
testonly = true
sources = [ "internal/test_util.cc" ]
public = [ "internal/test_util.h" ]
+ visibility = [ ":*" ]
deps = [
":time",
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:raw_logging_internal",
]
- visibility = [ ":*" ]
}
absl_test("time_test") {
@@ -90,6 +92,7 @@ absl_test("time_test") {
"//third_party/abseil-cpp/absl/hash:hash_testing",
"//third_party/abseil-cpp/absl/numeric:int128",
"//third_party/abseil-cpp/absl/random",
+ "//third_party/abseil-cpp/absl/strings",
"//third_party/abseil-cpp/absl/strings:str_format",
"//third_party/abseil-cpp/absl/time/internal/cctz:time_zone",
]
@@ -118,3 +121,12 @@ absl_test("simulated_clock_test") {
"//third_party/abseil-cpp/absl/synchronization",
]
}
+
+absl_test("flag_test") {
+ sources = [ "flag_test.cc" ]
+ deps = [
+ ":time",
+ "//third_party/abseil-cpp/absl/flags:flag",
+ "//third_party/abseil-cpp/absl/flags:reflection",
+ ]
+}
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 d1d0d955014..865a99bf591 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
@@ -462,32 +462,6 @@ std::string FormatCivilTime(CivilDay c);
std::string FormatCivilTime(CivilMonth c);
std::string FormatCivilTime(CivilYear c);
-// Support for StrFormat(), StrCat(), etc
-template <typename Sink>
-void AbslStringify(Sink& sink, CivilSecond c) {
- sink.Append(FormatCivilTime(c));
-}
-template <typename Sink>
-void AbslStringify(Sink& sink, CivilMinute c) {
- sink.Append(FormatCivilTime(c));
-}
-template <typename Sink>
-void AbslStringify(Sink& sink, CivilHour c) {
- sink.Append(FormatCivilTime(c));
-}
-template <typename Sink>
-void AbslStringify(Sink& sink, CivilDay c) {
- sink.Append(FormatCivilTime(c));
-}
-template <typename Sink>
-void AbslStringify(Sink& sink, CivilMonth c) {
- sink.Append(FormatCivilTime(c));
-}
-template <typename Sink>
-void AbslStringify(Sink& sink, CivilYear c) {
- sink.Append(FormatCivilTime(c));
-}
-
// absl::ParseCivilTime()
//
// Parses a civil-time value from the specified `absl::string_view` into the
@@ -551,6 +525,32 @@ bool ParseLenientCivilTime(absl::string_view s, CivilYear* c);
namespace time_internal { // For functions found via ADL on civil-time tags.
+// Support for StrFormat(), StrCat(), etc
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilSecond c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilMinute c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilHour c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilDay c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilMonth c) {
+ sink.Append(FormatCivilTime(c));
+}
+template <typename Sink>
+void AbslStringify(Sink& sink, CivilYear c) {
+ sink.Append(FormatCivilTime(c));
+}
+
// Streaming Operators
//
// Each civil-time type may be sent to an output stream using operator<<().
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 3ad8e14b7d6..fed0c30b25b 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
@@ -14,14 +14,17 @@
#include "absl/time/civil_time.h"
+#include <cstddef>
#include <iomanip>
+#include <iterator>
#include <limits>
#include <sstream>
#include <type_traits>
#include "gtest/gtest.h"
-#include "absl/base/macros.h"
#include "absl/hash/hash_testing.h"
+#include "absl/strings/has_absl_stringify.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
namespace {
@@ -293,33 +296,33 @@ struct HasDiff {
TEST(CivilTime, DisallowCrossAlignedDifference) {
// Difference is allowed between types with the same alignment.
- static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value, "");
- static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value, "");
- static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value, "");
- static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value, "");
- static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value, "");
- static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value, "");
+ static_assert(HasDiff<absl::CivilSecond, absl::CivilSecond>::value);
+ static_assert(HasDiff<absl::CivilMinute, absl::CivilMinute>::value);
+ static_assert(HasDiff<absl::CivilHour, absl::CivilHour>::value);
+ static_assert(HasDiff<absl::CivilDay, absl::CivilDay>::value);
+ static_assert(HasDiff<absl::CivilMonth, absl::CivilMonth>::value);
+ static_assert(HasDiff<absl::CivilYear, absl::CivilYear>::value);
// Difference is disallowed between types with different alignments.
- static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value, "");
- static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value, "");
- static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value, "");
- static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value, "");
- static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value, "");
+ static_assert(!HasDiff<absl::CivilSecond, absl::CivilMinute>::value);
+ static_assert(!HasDiff<absl::CivilSecond, absl::CivilHour>::value);
+ static_assert(!HasDiff<absl::CivilSecond, absl::CivilDay>::value);
+ static_assert(!HasDiff<absl::CivilSecond, absl::CivilMonth>::value);
+ static_assert(!HasDiff<absl::CivilSecond, absl::CivilYear>::value);
- static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value, "");
- static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value, "");
- static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value, "");
- static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value, "");
+ static_assert(!HasDiff<absl::CivilMinute, absl::CivilHour>::value);
+ static_assert(!HasDiff<absl::CivilMinute, absl::CivilDay>::value);
+ static_assert(!HasDiff<absl::CivilMinute, absl::CivilMonth>::value);
+ static_assert(!HasDiff<absl::CivilMinute, absl::CivilYear>::value);
- static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value, "");
- static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value, "");
- static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value, "");
+ static_assert(!HasDiff<absl::CivilHour, absl::CivilDay>::value);
+ static_assert(!HasDiff<absl::CivilHour, absl::CivilMonth>::value);
+ static_assert(!HasDiff<absl::CivilHour, absl::CivilYear>::value);
- static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value, "");
- static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value, "");
+ static_assert(!HasDiff<absl::CivilDay, absl::CivilMonth>::value);
+ static_assert(!HasDiff<absl::CivilDay, absl::CivilYear>::value);
- static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value, "");
+ static_assert(!HasDiff<absl::CivilMonth, absl::CivilYear>::value);
}
TEST(CivilTime, ValueSemantics) {
@@ -870,19 +873,34 @@ TEST(CivilTime, ParseFieldNormalizationCarriesYear) {
}
TEST(CivilTime, AbslStringify) {
+ static_assert(absl::HasAbslStringify<absl::CivilSecond>::value);
+ static_assert(absl::HasAbslStringify<absl::CivilMinute>::value);
+ static_assert(absl::HasAbslStringify<absl::CivilHour>::value);
+ static_assert(absl::HasAbslStringify<absl::CivilDay>::value);
+ static_assert(absl::HasAbslStringify<absl::CivilMonth>::value);
+ static_assert(absl::HasAbslStringify<absl::CivilYear>::value);
+
+ EXPECT_EQ("2015-01-02T03:04:05",
+ absl::StrCat(absl::CivilSecond(2015, 1, 2, 3, 4, 5)));
EXPECT_EQ("2015-01-02T03:04:05",
absl::StrFormat("%v", absl::CivilSecond(2015, 1, 2, 3, 4, 5)));
+ EXPECT_EQ("2015-01-02T03:04",
+ absl::StrCat(absl::CivilMinute(2015, 1, 2, 3, 4)));
EXPECT_EQ("2015-01-02T03:04",
absl::StrFormat("%v", absl::CivilMinute(2015, 1, 2, 3, 4)));
+ EXPECT_EQ("2015-01-02T03", absl::StrCat(absl::CivilHour(2015, 1, 2, 3)));
EXPECT_EQ("2015-01-02T03",
absl::StrFormat("%v", absl::CivilHour(2015, 1, 2, 3)));
+ EXPECT_EQ("2015-01-02", absl::StrCat(absl::CivilDay(2015, 1, 2)));
EXPECT_EQ("2015-01-02", absl::StrFormat("%v", absl::CivilDay(2015, 1, 2)));
+ EXPECT_EQ("2015-01", absl::StrCat(absl::CivilMonth(2015, 1)));
EXPECT_EQ("2015-01", absl::StrFormat("%v", absl::CivilMonth(2015, 1)));
+ EXPECT_EQ("2015", absl::StrCat(absl::CivilYear(2015)));
EXPECT_EQ("2015", absl::StrFormat("%v", absl::CivilYear(2015)));
}
@@ -1188,7 +1206,7 @@ TEST(CivilTime, LeapYears) {
{2009, 365, {3, 1}}, {2100, 365, {3, 1}},
};
- for (int i = 0; i < ABSL_ARRAYSIZE(kLeapYearTable); ++i) {
+ for (size_t i = 0; i < std::size(kLeapYearTable); ++i) {
const int y = kLeapYearTable[i].year;
const int m = kLeapYearTable[i].leap_day.month;
const int d = kLeapYearTable[i].leap_day.day;
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 2a5f41bc2d4..b87611aca8c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/clock.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/clock.cc
@@ -14,13 +14,6 @@
#include "absl/time/clock.h"
-#include "absl/base/attributes.h"
-#include "absl/base/optimization.h"
-
-#ifdef _WIN32
-#include <windows.h>
-#endif
-
#include <algorithm>
#include <atomic>
#include <cerrno>
@@ -28,12 +21,18 @@
#include <ctime>
#include <limits>
+#include "absl/base/attributes.h"
#include "absl/base/internal/spinlock.h"
#include "absl/base/internal/unscaledcycleclock.h"
#include "absl/base/macros.h"
+#include "absl/base/optimization.h"
#include "absl/base/port.h"
#include "absl/base/thread_annotations.h"
+#ifdef _WIN32
+#include <windows.h>
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
Time Now() {
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 c5c795ecbd2..df14ce6ff5d 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
@@ -13,15 +13,16 @@
#include "absl/time/clock.h"
+#include <cstdio>
+
+#include "absl/base/internal/cycleclock.h"
+#include "benchmark/benchmark.h"
+
#if !defined(_WIN32)
#include <sys/time.h>
#else
#include <winsock2.h>
#endif // _WIN32
-#include <cstdio>
-
-#include "absl/base/internal/cycleclock.h"
-#include "benchmark/benchmark.h"
namespace {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/clock_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/clock_test.cc
index fb1452aefee..9370a88270d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/clock_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/clock_test.cc
@@ -14,7 +14,10 @@
#include "absl/time/clock.h"
+#include "gtest/gtest.h"
#include "absl/base/config.h"
+#include "absl/time/time.h"
+
#if defined(ABSL_HAVE_ALARM)
#include <signal.h>
#include <unistd.h>
@@ -26,9 +29,6 @@ typedef void (*sig_t)(int);
#error all known Linux and Apple targets have alarm
#endif
-#include "gtest/gtest.h"
-#include "absl/time/time.h"
-
namespace {
TEST(Time, Now) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/duration.cc b/deps/v8/third_party/abseil-cpp/absl/time/duration.cc
index fb7c90a2d74..487ccdd87b2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/duration.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/duration.cc
@@ -49,10 +49,6 @@
//
// Arithmetic overflows/underflows to +/- infinity and saturates.
-#if defined(_MSC_VER)
-#include <winsock2.h> // for timeval
-#endif
-
#include <algorithm>
#include <cassert>
#include <chrono> // NOLINT(build/c++11)
@@ -73,6 +69,10 @@
#include "absl/strings/strip.h"
#include "absl/time/time.h"
+#if defined(_MSC_VER)
+#include <winsock2.h> // for timeval
+#endif
+
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -834,7 +834,7 @@ bool ConsumeDurationUnit(const char** start, const char* end, Duration* unit) {
default:
break;
}
- ABSL_FALLTHROUGH_INTENDED;
+ [[fallthrough]];
case 1:
switch (**start) {
case 's':
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 e2dd4d28573..5a33c65850f 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
@@ -15,6 +15,7 @@
#include <cstddef>
#include <cstdint>
#include <ctime>
+#include <iterator>
#include <string>
#include "absl/base/attributes.h"
@@ -571,7 +572,7 @@ const char* const kDurations[] = {
"-2h3m4.005006007s", // 3
"2562047788015215h30m7.99999999975s", // 4
};
-const int kNumDurations = sizeof(kDurations) / sizeof(kDurations[0]);
+const int kNumDurations = std::size(kDurations);
void BM_Duration_FormatDuration(benchmark::State& state) {
const std::string s = kDurations[state.range(0)];
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/duration_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/duration_test.cc
index f56df40c0ed..8fffa954f1c 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/duration_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/duration_test.cc
@@ -12,10 +12,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#if defined(_MSC_VER)
-#include <winsock2.h> // for timeval
-#endif
-
#include "absl/base/config.h"
// For feature testing and determining which headers can be included.
@@ -44,6 +40,10 @@
#include "absl/strings/str_format.h"
#include "absl/time/time.h"
+#if defined(_MSC_VER)
+#include <winsock2.h> // for timeval
+#endif
+
namespace {
constexpr int64_t kint64max = std::numeric_limits<int64_t>::max();
@@ -228,12 +228,12 @@ void TestFromChronoBasicEquality() {
using std::chrono::nanoseconds;
using std::chrono::seconds;
- static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N)), "");
- static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N)), "");
- static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N)), "");
- static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N)), "");
- static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N)), "");
- static_assert(absl::Hours(N) == absl::FromChrono(hours(N)), "");
+ static_assert(absl::Nanoseconds(N) == absl::FromChrono(nanoseconds(N)));
+ static_assert(absl::Microseconds(N) == absl::FromChrono(microseconds(N)));
+ static_assert(absl::Milliseconds(N) == absl::FromChrono(milliseconds(N)));
+ static_assert(absl::Seconds(N) == absl::FromChrono(seconds(N)));
+ static_assert(absl::Minutes(N) == absl::FromChrono(minutes(N)));
+ static_assert(absl::Hours(N) == absl::FromChrono(hours(N)));
}
TEST(Duration, FromChrono) {
@@ -907,15 +907,15 @@ TEST(Duration, Range) {
}
TEST(Duration, RelationalOperators) {
-#define TEST_REL_OPS(UNIT) \
- static_assert(UNIT(2) == UNIT(2), ""); \
- static_assert(UNIT(1) != UNIT(2), ""); \
- static_assert(UNIT(1) < UNIT(2), ""); \
- static_assert(UNIT(3) > UNIT(2), ""); \
- static_assert(UNIT(1) <= UNIT(2), ""); \
- static_assert(UNIT(2) <= UNIT(2), ""); \
- static_assert(UNIT(3) >= UNIT(2), ""); \
- static_assert(UNIT(2) >= UNIT(2), "");
+#define TEST_REL_OPS(UNIT) \
+ static_assert(UNIT(2) == UNIT(2)); \
+ static_assert(UNIT(1) != UNIT(2)); \
+ static_assert(UNIT(1) < UNIT(2)); \
+ static_assert(UNIT(3) > UNIT(2)); \
+ static_assert(UNIT(1) <= UNIT(2)); \
+ static_assert(UNIT(2) <= UNIT(2)); \
+ static_assert(UNIT(3) >= UNIT(2)); \
+ static_assert(UNIT(2) >= UNIT(2));
TEST_REL_OPS(absl::Nanoseconds);
TEST_REL_OPS(absl::Microseconds);
@@ -930,10 +930,10 @@ TEST(Duration, RelationalOperators) {
#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
TEST(Duration, SpaceshipOperators) {
-#define TEST_REL_OPS(UNIT) \
- static_assert(UNIT(2) <=> UNIT(2) == std::strong_ordering::equal, ""); \
- static_assert(UNIT(1) <=> UNIT(2) == std::strong_ordering::less, ""); \
- static_assert(UNIT(3) <=> UNIT(2) == std::strong_ordering::greater, "");
+#define TEST_REL_OPS(UNIT) \
+ static_assert(UNIT(2) <=> UNIT(2) == std::strong_ordering::equal); \
+ static_assert(UNIT(1) <=> UNIT(2) == std::strong_ordering::less); \
+ static_assert(UNIT(3) <=> UNIT(2) == std::strong_ordering::greater);
TEST_REL_OPS(absl::Nanoseconds);
TEST_REL_OPS(absl::Microseconds);
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 19e481dbd1a..45109faf674 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
@@ -12,6 +12,7 @@
// limitations under the License.
#include <cstddef>
+#include <iterator>
#include <string>
#include "absl/time/internal/test_util.h"
@@ -29,7 +30,7 @@ const char* const kFormats[] = {
"%Y-%m-%d%ET%H:%M:%S", // 4
"%Y-%m-%d", // 5
};
-const int kNumFormats = sizeof(kFormats) / sizeof(kFormats[0]);
+const int kNumFormats = std::size(kFormats);
} // namespace
void BM_Format_FormatTime(benchmark::State& state) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel
index 3b478770475..edec2820737 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.bazel
@@ -140,7 +140,10 @@ cc_test(
name = "time_zone_lookup_test",
size = "small",
timeout = "moderate",
- srcs = ["src/time_zone_lookup_test.cc"],
+ srcs = [
+ "src/time_zone_lookup_test.cc",
+ "src/tzfile.h",
+ ],
copts = ABSL_TEST_COPTS,
data = [":zoneinfo"],
linkopts = ABSL_DEFAULT_LINKOPTS,
@@ -177,6 +180,24 @@ cc_test(
],
)
+cc_test(
+ name = "time_zone_posix_test",
+ size = "small",
+ srcs = [
+ "src/time_zone_posix.h",
+ "src/time_zone_posix_test.cc",
+ ],
+ copts = ABSL_TEST_COPTS,
+ linkopts = ABSL_DEFAULT_LINKOPTS,
+ deps = [
+ ":civil_time",
+ ":time_zone",
+ "//absl/base:config",
+ "@googletest//:gtest",
+ "@googletest//:gtest_main",
+ ],
+)
+
### benchmarks
cc_test(
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn
index 592c8351fe2..ba7cc14f44a 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/BUILD.gn
@@ -1,6 +1,8 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
@@ -32,16 +34,19 @@ absl_source_set("time_zone") {
"src/tzfile.h",
"src/zone_info_source.cc",
]
- if (is_win) {
- sources += [
- "src/time_zone_name_win.cc",
- "src/time_zone_name_win.h",
- ]
- }
public = [
"include/cctz/time_zone.h",
"include/cctz/zone_info_source.h",
]
+ deps = [
+ ":civil_time",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+
+ if (is_win) {
+ sources += [ "src/time_zone_name_win.cc" ]
+ public += [ "src/time_zone_name_win.h" ]
+ }
defines = []
if (is_apple) {
frameworks = [ "Foundation.framework" ]
@@ -49,10 +54,6 @@ absl_source_set("time_zone") {
# Work-around for https://github.com/llvm/llvm-project/issues/117630
defines += [ "_XOPEN_SOURCE=700" ]
}
- deps = [
- ":civil_time",
- "//third_party/abseil-cpp/absl/base:config",
- ]
if (is_fuchsia) {
deps += [
"//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl:fuchsia.intl_hlcpp",
@@ -63,3 +64,63 @@ absl_source_set("time_zone") {
]
}
}
+
+absl_source_set("test_time_zone_names") {
+ testonly = true
+ sources = [ "src/test_time_zone_names.cc" ]
+ public = [ "src/test_time_zone_names.h" ]
+ visibility = [ ":*" ]
+ deps = [ "//third_party/abseil-cpp/absl/base:config" ]
+}
+
+absl_test("civil_time_test") {
+ sources = [ "src/civil_time_test.cc" ]
+ deps = [
+ ":civil_time",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+}
+
+absl_test("time_zone_format_test") {
+ sources = [ "src/time_zone_format_test.cc" ]
+ deps = [
+ ":civil_time",
+ ":time_zone",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+}
+
+absl_test("time_zone_lookup_test") {
+ sources = [
+ "src/time_zone_lookup_test.cc",
+ "src/tzfile.h",
+ ]
+ deps = [
+ ":civil_time",
+ ":test_time_zone_names",
+ ":time_zone",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+}
+
+absl_test("time_zone_name_win_test") {
+ deps = [
+ ":time_zone",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+ if (is_win) {
+ sources = [ "src/time_zone_name_win_test.cc" ]
+ }
+}
+
+absl_test("time_zone_posix_test") {
+ sources = [
+ "src/time_zone_posix.h",
+ "src/time_zone_posix_test.cc",
+ ]
+ deps = [
+ ":civil_time",
+ ":time_zone",
+ "//third_party/abseil-cpp/absl/base:config",
+ ]
+}
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc
index ce2781871d4..17ff576f79e 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/cctz_benchmark.cc
@@ -28,6 +28,7 @@
namespace {
+// SKIP_ABSL_INLINE_NAMESPACE_CHECK
namespace cctz = absl::time_internal::cctz;
void BM_Difference_Days(benchmark::State& state) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc
index ed7f9cb97ac..b33410d2ca2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_fixed.cc
@@ -40,12 +40,19 @@ char* Format02d(char* p, int v) {
return p;
}
+// Returns the value of the decimal digit ch, or -1 if ch is not a digit.
+// Note that std::strchr() also matches kDigits' terminating '\0', which
+// would otherwise be taken for a tenth digit.
+int ParseDigit(char ch) {
+ const char* const dp = std::strchr(kDigits, ch);
+ return (dp == nullptr || *dp == '\0') ? -1 : static_cast<int>(dp - kDigits);
+}
+
int Parse02d(const char* p) {
- if (const char* ap = std::strchr(kDigits, *p)) {
- int v = static_cast<int>(ap - kDigits);
- if (const char* bp = std::strchr(kDigits, *++p)) {
- return (v * 10) + static_cast<int>(bp - kDigits);
- }
+ const int hi = ParseDigit(p[0]);
+ if (hi >= 0) {
+ const int lo = ParseDigit(p[1]);
+ if (lo >= 0) return (hi * 10) + lo;
}
return -1;
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc
index 91b46219d2d..f97de2f9592 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format.cc
@@ -58,6 +58,16 @@ namespace detail {
namespace {
+// The ctype functions have undefined behavior for negative char values,
+// so these helpers ensure the argument is always in the unsigned-char domain.
+bool isdigit(char ch) {
+ return std::isdigit(static_cast<unsigned char>(ch)) != 0;
+}
+
+bool isspace(char ch) {
+ return std::isspace(static_cast<unsigned char>(ch)) != 0;
+}
+
#if !HAS_STRPTIME
// Build a strptime() using C++11's std::get_time().
char* strptime(const char* s, const char* fmt, std::tm* tm) {
@@ -553,7 +563,7 @@ std::string format(const std::string& format, const time_point<seconds>& tp,
bp = Format64(ep, 4, al.cs.year());
result.append(bp, ep);
pending = cur += 2;
- } else if (std::isdigit(*cur)) {
+ } else if (isdigit(*cur)) {
// Possibly found %E#S or %E#f.
int n = 0;
if (const char* np = ParseInt(cur, 0, 0, 1024, &n)) {
@@ -620,7 +630,7 @@ const char* ParseOffset(const char* dp, const char* mode, int* offset) {
const char* ParseZone(const char* dp, std::string* zone) {
zone->clear();
if (dp != nullptr) {
- while (*dp != '\0' && !std::isspace(*dp)) zone->push_back(*dp++);
+ while (*dp != '\0' && !isspace(*dp)) zone->push_back(*dp++);
if (zone->empty()) dp = nullptr;
}
return dp;
@@ -706,7 +716,7 @@ bool parse(const std::string& format, const std::string& input,
const char* const edata = data + input.size();
// Skips leading whitespace.
- while (std::isspace(*data)) ++data;
+ while (isspace(*data)) ++data;
const year_t kyearmax = std::numeric_limits<year_t>::max();
const year_t kyearmin = std::numeric_limits<year_t>::min();
@@ -744,9 +754,9 @@ bool parse(const std::string& format, const std::string& input,
// Steps through format, one specifier at a time.
while (data != nullptr && fmt != efmt) {
- if (std::isspace(*fmt)) {
- while (std::isspace(*data)) ++data;
- while (std::isspace(*++fmt)) continue;
+ if (isspace(*fmt)) {
+ while (isspace(*data)) ++data;
+ while (isspace(*++fmt)) continue;
continue;
}
@@ -898,7 +908,7 @@ bool parse(const std::string& format, const std::string& input,
continue;
}
if (fmt[0] == '*' && fmt[1] == 'f') {
- if (data != nullptr && std::isdigit(*data)) {
+ if (data != nullptr && isdigit(*data)) {
data = ParseSubSeconds(data, &subseconds);
}
fmt += 2;
@@ -917,7 +927,7 @@ bool parse(const std::string& format, const std::string& input,
fmt += 2;
continue;
}
- if (std::isdigit(*fmt)) {
+ if (isdigit(*fmt)) {
int n = 0; // value ignored
if (const char* np = ParseInt(fmt, 0, 0, 1024, &n)) {
if (*np == 'S') {
@@ -929,7 +939,7 @@ bool parse(const std::string& format, const std::string& input,
continue;
}
if (*np == 'f') {
- if (data != nullptr && std::isdigit(*data)) {
+ if (data != nullptr && isdigit(*data)) {
data = ParseSubSeconds(data, &subseconds);
}
fmt = ++np;
@@ -977,7 +987,7 @@ bool parse(const std::string& format, const std::string& input,
}
// Skip any remaining whitespace.
- while (std::isspace(*data)) ++data;
+ while (isspace(*data)) ++data;
// parse() must consume the entire input string.
if (data != edata) {
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc
index f047d93a726..8793a805c66 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_format_test.cc
@@ -1002,6 +1002,27 @@ TEST(Parse, ErrorCases) {
EXPECT_FALSE(parse("%Ez", "-00:-0", tz, &tp));
}
+TEST(Parse, NonAsciiInput) {
+ const time_zone tz = utc_time_zone();
+ auto tp = chrono::system_clock::from_time_t(0);
+
+ // High-bit-set bytes reach the ctype functions during parsing. 0xA0 is not
+ // ASCII whitespace, so the leading-whitespace skip must not consume it and
+ // the parse must fail rather than pass a negative char to std::isspace().
+ EXPECT_FALSE(parse("%Y-%m-%d",
+ "\xA0"
+ "2016-01-02",
+ tz, &tp));
+ EXPECT_FALSE(parse("%Y",
+ "\xA0"
+ "2016",
+ tz, &tp));
+
+ // A leading ASCII space is still skipped as before.
+ EXPECT_TRUE(parse("%Y-%m-%d", " 2016-01-02", tz, &tp));
+ EXPECT_EQ(2016, convert(tp, utc_time_zone()).year());
+}
+
TEST(Parse, PosixConversions) {
time_zone tz = utc_time_zone();
auto tp = chrono::system_clock::from_time_t(0);
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc
index 5f2f49e424f..5cf38e780a2 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_impl.cc
@@ -76,9 +76,18 @@ bool time_zone::Impl::LoadTimeZone(const std::string& name, time_zone* tz) {
// Add the new time zone to the map.
std::lock_guard<std::mutex> lock(TimeZoneMutex());
if (time_zone_map == nullptr) time_zone_map = new TimeZoneImplByName;
+ if (!new_impl->zone_) {
+ // Load failed, but a successful insertion may have happened concurrently.
+ // Check it now that we have the lock. Otherwise, avoid caching negative
+ // entries to avoid unbounded growth and DoS attacks.
+ auto itr = time_zone_map->find(name);
+ const Impl* impl = (itr != time_zone_map->end()) ? itr->second : utc_impl;
+ *tz = time_zone(impl);
+ return impl != utc_impl;
+ }
const Impl*& impl = (*time_zone_map)[name];
if (impl == nullptr) { // this thread won any load race
- impl = new_impl->zone_ ? new_impl.release() : utc_impl;
+ impl = new_impl.release();
}
*tz = time_zone(impl);
return impl != utc_impl;
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc
index f8484c9050a..9abbde72d62 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_info.cc
@@ -32,6 +32,16 @@
#include "absl/time/internal/cctz/src/time_zone_info.h"
+#include "absl/base/config.h"
+
+#if !defined(_MSC_VER)
+#include <fcntl.h>
+#if !defined(__APPLE__)
+#include <sys/stat.h>
+#endif
+#include <unistd.h>
+#endif
+
#include <algorithm>
#include <cassert>
#include <chrono>
@@ -41,16 +51,17 @@
#include <cstring>
#include <fstream>
#include <functional>
+#include <limits>
#include <memory>
#include <sstream>
#include <string>
#include <utility>
#include <vector>
-#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
#include "absl/time/internal/cctz/src/time_zone_fixed.h"
#include "absl/time/internal/cctz/src/time_zone_posix.h"
+#include "absl/time/internal/cctz/src/tzfile.h"
namespace absl {
ABSL_NAMESPACE_BEGIN
@@ -338,6 +349,14 @@ bool TimeZoneInfo::ExtendTransitions() {
return EquivTransitions(transitions_.back().type_index, dst_ti);
}
+ // We require that zoneinfo data with a rule for future transitions
+ // ends with a non-negative transition. This removes the need to add
+ // any "second-half" transition to ensure differences between adjacent
+ // transitions are always representable, while also guaranteeing that
+ // the arithmetic used to shift between 400-year cycles never overflows.
+ // All valid zones easily meet this requirement.
+ if (transitions_.back().unix_time < 0) return false;
+
// Extend the transitions for an additional 401 years using the future
// specification. Years beyond those can be handled by mapping back to
// a cycle-equivalent year within that range. Note that we need 401
@@ -382,18 +401,71 @@ namespace {
using FilePtr = std::unique_ptr<FILE, int (*)(FILE*)>;
-// fopen(3) adaptor.
-inline FilePtr FOpen(const char* path, const char* mode) {
+// fopen(3) adaptor for reading zoneinfo files (read-only binary mode).
+inline FilePtr FOpen(const char* path) {
#if defined(_MSC_VER)
FILE* fp;
- if (fopen_s(&fp, path, mode) != 0) fp = nullptr;
+ if (fopen_s(&fp, path, "rb") != 0) fp = nullptr;
return FilePtr(fp, fclose);
#else
- // TODO: Enable the close-on-exec flag.
- return FilePtr(fopen(path, mode), fclose);
+ // Open non-blocking and verify the target is a regular file before handing it
+ // to stdio. Zone names are potentially attacker-controlled, and a plain
+ // fopen() on a FIFO or device node (reachable via the "file:" prefix or an
+ // absolute path) would block indefinitely or read unbounded data.
+#ifndef O_CLOEXEC
+#define O_CLOEXEC 0
+#endif
+ const int fd = open(path, O_RDONLY | O_NONBLOCK | O_CLOEXEC);
+ if (fd >= 0) {
+#if defined(__APPLE__)
+ // On Apple platforms, avoid fstat() to prevent triggering Apple's Required
+ // Reason API (NSPrivacyAccessedAPICategoryFileTimestamp) scanner.
+ // Security implications of skipping this check on Apple platforms:
+ // - FIFO hangs are mitigated by O_NONBLOCK
+ // - Path traversal is handled by UnsafePath()
+ // - /usr/share/zoneinfo is a read-only system volume on iOS
+ // On general POSIX operating systems, the check remains as
+ // defense-in-depth.
+ auto is_regular = [](int) { return true; };
+#else
+ auto is_regular = [](int stat_fd) {
+ struct stat st;
+ return fstat(stat_fd, &st) == 0 && S_ISREG(st.st_mode);
+ };
+#endif
+ if (is_regular(fd)) {
+ FILE* fp = fdopen(fd, "rb");
+ if (fp != nullptr) return FilePtr(fp, fclose);
+ }
+ close(fd);
+ }
+ return FilePtr(nullptr, fclose);
#endif
}
+// Returns true if c separates path components. Windows accepts either
+// form, so a "..\" component walks up a directory just like a "../" one.
+inline bool IsPathSeparator(char c) {
+#if defined(_WIN32)
+ return c == '/' || c == '\\';
+#else
+ return c == '/';
+#endif
+}
+
+// Returns true if the zone name starting at pos contains an unsafe path.
+bool UnsafePath(const std::string& name, std::size_t pos) {
+ // Path traversal: a ".." component that is at the beginning or preceded
+ // by a separator, and at the end or followed by a separator.
+ for (auto i = pos; (i = name.find("..", i)) != std::string::npos; i += 2) {
+ if ((i == pos || IsPathSeparator(name[i - 1])) &&
+ (i == name.size() - 2 || IsPathSeparator(name[i + 2]))) {
+ return true;
+ }
+ }
+ return false;
+}
+
// A stdio(3)-backed implementation of ZoneInfoSource.
class FileZoneInfoSource : public ZoneInfoSource {
public:
@@ -431,6 +503,11 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
// Use of the "file:" prefix is intended for testing purposes only.
const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
+ // Reject unsafe paths (e.g., "../../etc/passwd").
+ if (UnsafePath(name, pos)) {
+ return nullptr;
+ }
+
// Map the time-zone name to a path name.
std::string path;
if (pos == name.size() || name[pos] != '/') {
@@ -451,7 +528,7 @@ std::unique_ptr<ZoneInfoSource> FileZoneInfoSource::Open(
path.append(name, pos, std::string::npos);
// Open the zoneinfo file.
- auto fp = FOpen(path.c_str(), "rb");
+ auto fp = FOpen(path.c_str());
if (fp == nullptr) return nullptr;
return std::unique_ptr<ZoneInfoSource>(new FileZoneInfoSource(std::move(fp)));
}
@@ -477,7 +554,7 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
for (const char* tzdata : {"/apex/com.android.tzdata/etc/tz/tzdata",
"/data/misc/zoneinfo/current/tzdata",
"/system/usr/share/zoneinfo/tzdata"}) {
- auto fp = FOpen(tzdata, "rb");
+ auto fp = FOpen(tzdata);
if (fp == nullptr) continue;
char hbuf[24]; // covers header.zonetab_offset too
@@ -497,9 +574,12 @@ std::unique_ptr<ZoneInfoSource> AndroidZoneInfoSource::Open(
if (zonecnt * sizeof(ebuf) != index_size) continue;
for (std::size_t i = 0; i != zonecnt; ++i) {
if (fread(ebuf, 1, sizeof(ebuf), fp.get()) != sizeof(ebuf)) break;
- const std::int_fast32_t start = data_offset + Decode32(ebuf + 40);
+ const std::int_fast64_t start =
+ std::int_fast64_t{data_offset} + Decode32(ebuf + 40);
const std::int_fast32_t length = Decode32(ebuf + 44);
if (start < 0 || length < 0) break;
+ // fseek() takes a long
+ if (start > std::numeric_limits<long>::max()) break;
ebuf[40] = '\0'; // ensure zone name is NUL terminated
if (strcmp(name.c_str() + pos, ebuf) == 0) {
if (fseek(fp.get(), static_cast<long>(start), SEEK_SET) != 0) break;
@@ -537,6 +617,11 @@ std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open(
// Use of the "file:" prefix is intended for testing purposes only.
const std::size_t pos = (name.compare(0, 5, "file:") == 0) ? 5 : 0;
+ // Reject unsafe paths (e.g., "../../etc/passwd").
+ if (UnsafePath(name, pos)) {
+ return nullptr;
+ }
+
// Prefixes where a Fuchsia component might find zoneinfo files,
// in descending order of preference.
const auto kTzdataPrefixes = {
@@ -561,7 +646,7 @@ std::unique_ptr<ZoneInfoSource> FuchsiaZoneInfoSource::Open(
if (!prefix.empty()) path += "zoneinfo/tzif2/"; // format
path.append(name, pos, std::string::npos);
- auto fp = FOpen(path.c_str(), "rb");
+ auto fp = FOpen(path.c_str());
if (fp == nullptr) continue;
std::string version;
@@ -662,6 +747,12 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
if (hdr.ttisstdcnt != 0 && hdr.ttisstdcnt != hdr.typecnt) return false;
if (hdr.ttisutcnt != 0 && hdr.ttisutcnt != hdr.typecnt) return false;
+ // Bound the header counts before sizing tbuf so that a hostile TZif blob
+ // cannot force a very large zero-filled allocation from a tiny input.
+ if (hdr.timecnt > TZ_MAX_TIMES) return false;
+ if (hdr.typecnt > TZ_MAX_TYPES) return false;
+ if (hdr.charcnt > TZ_MAX_CHARS) return false;
+
// Read the data into a local buffer.
std::size_t len = hdr.DataLength(time_len);
std::vector<char> tbuf(len);
@@ -674,11 +765,14 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
for (std::size_t i = 0; i != hdr.timecnt; ++i) {
transitions_[i].unix_time = (time_len == 4) ? Decode32(bp) : Decode64(bp);
bp += time_len;
- if (i != 0) {
- // Check that the transitions are ordered by time (as zic guarantees).
- if (!Transition::ByUnixTime()(transitions_[i - 1], transitions_[i]))
- return false; // out of order
- }
+ // A valid zoneinfo file keeps transition times far from the int64 limits.
+ // A hostile one can place them at the extremes, where the
+ // reverse-conversion arithmetic in MakeTime() (tr.unix_time +/- a sub-day
+ // civil delta, see MakeSkipped()/MakeRepeated()) overflows. Bound them to
+ // +/-(1<<59), the times used by the no-op transitions added below.
+ if (transitions_[i].unix_time < -(1LL << 59) ||
+ transitions_[i].unix_time > (1LL << 59))
+ return false; // out of range
}
bool seen_type_0 = false;
for (std::size_t i = 0; i != hdr.timecnt; ++i) {
@@ -705,16 +799,22 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
// Determine the before-first-transition type.
default_transition_type_ = 0;
if (seen_type_0 && hdr.timecnt != 0) {
- std::uint_fast8_t index = 0;
+ std::size_t index = 0;
if (transition_types_[0].is_dst) {
index = transitions_[0].type_index;
while (index != 0 && transition_types_[index].is_dst) --index;
}
while (index != hdr.typecnt && transition_types_[index].is_dst) ++index;
- if (index != hdr.typecnt) default_transition_type_ = index;
+ if (index != hdr.typecnt)
+ default_transition_type_ = static_cast<std::uint_fast8_t>(index);
}
- // Copy all the abbreviations.
+ // Copy all the abbreviations. The area holds NUL-terminated strings, and
+ // LocalTime() hands out a pointer into it, so the final abbreviation has
+ // to be terminated within the area itself. Otherwise an abbreviation runs
+ // on into whatever ExtendTransitions() later appends. (hdr.charcnt != 0
+ // because every abbr_index was validated to be less than it.)
+ if (bp[hdr.charcnt - 1] != '\0') return false;
abbreviations_.reserve(hdr.charcnt + 10);
abbreviations_.assign(bp, hdr.charcnt);
bp += hdr.charcnt;
@@ -771,6 +871,7 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
// previous transition is always representable, without overflow.
const Transition& last(transitions_.back());
if (last.unix_time < 0) {
+ assert(!extended_);
const std::uint_fast8_t type_index = last.type_index;
Transition& tr(*transitions_.emplace(transitions_.end()));
tr.unix_time = 2147483647; // 2038-01-19T03:14:07+00:00
@@ -786,11 +887,13 @@ bool TimeZoneInfo::Load(ZoneInfoSource* zip) {
ttp = &transition_types_[tr.type_index];
tr.civil_sec = LocalTime(tr.unix_time, *ttp).cs;
if (i != 0) {
- // Check that the transitions are ordered by civil time. Essentially
- // this means that an offset change cannot cross another such change.
- // No one does this in practice, and we depend on it in MakeTime().
- if (!Transition::ByCivilTime()(transitions_[i - 1], tr))
+ // Check that offset changes don't cross each other. No one
+ // does this in practice, and we depend on increasing absolute
+ // and civil times in BreakTime() and MakeTime() respectively.
+ if (!Transition::ByUnixTime()(transitions_[i - 1], tr) ||
+ !Transition::ByCivilTime()(transitions_[i - 1], tr)) {
return false; // out of order
+ }
}
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
index cd08a358f41..f53ac03eaf8 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_lookup_test.cc
@@ -15,21 +15,27 @@
#include <chrono>
#include <cstddef>
#include <cstdlib>
+#include <cstring>
#include <future>
#include <limits>
+#include <memory>
#include <string>
#include <thread>
+#include <utility>
#include <vector>
#include "absl/base/config.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
+
#if defined(__linux__)
#include <features.h>
#endif
#include "gtest/gtest.h"
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
+#include "absl/time/internal/cctz/include/cctz/zone_info_source.h"
#include "absl/time/internal/cctz/src/test_time_zone_names.h"
+#include "absl/time/internal/cctz/src/tzfile.h"
namespace chrono = std::chrono;
@@ -180,6 +186,36 @@ TEST(TimeZone, Failures) {
EXPECT_FALSE(load_time_zone("", &tz));
EXPECT_EQ(chrono::system_clock::from_time_t(0),
convert(civil_second(1970, 1, 1, 0, 0, 0), tz)); // UTC
+
+ // Reject a fixed-offset name with a NUL where a digit belongs.
+ for (const int i : {10, 11, 13, 14, 16, 17}) {
+ std::string name = "Fixed/UTC+00:00:00";
+ name[static_cast<std::size_t>(i)] = '\0';
+ EXPECT_FALSE(load_time_zone(name, &tz)) << "NUL at offset " << i;
+ }
+
+ // Reject path-traversal components.
+ EXPECT_FALSE(load_time_zone("file:../etc/passwd", &tz));
+ EXPECT_FALSE(load_time_zone("file:../../etc/passwd", &tz));
+ EXPECT_FALSE(load_time_zone("file:/../etc/passwd", &tz));
+ EXPECT_FALSE(load_time_zone("file:America/../America/Los_Angeles", &tz));
+
+#if defined(_WIN32)
+ // Windows accepts '\' as a path separator, so these escape as well.
+ // If they were admitted, the second would resolve back into the zoneinfo
+ // directory and load, failing the test. Elsewhere '\' is an ordinary
+ // filename character, so these would only fail as nonexistent names.
+ EXPECT_FALSE(load_time_zone("file:..\\etc\\passwd", &tz));
+ EXPECT_FALSE(load_time_zone("file:America\\..\\America/Los_Angeles", &tz));
+#endif
+
+#if !defined(_MSC_VER)
+ // Reject non-regular files and directories. The check lives in the
+ // non-MSVC FOpen(), so only expect it there.
+ EXPECT_FALSE(load_time_zone("file:/dev/null", &tz));
+ EXPECT_FALSE(load_time_zone("file:/dev/stdin", &tz));
+ EXPECT_FALSE(load_time_zone("file:/tmp", &tz));
+#endif
}
TEST(TimeZone, Equality) {
@@ -912,6 +948,204 @@ TEST(TimeZoneEdgeCase, UTC5DigitYear) {
ExpectTime(tp, tz, 10000, 1, 1, 0, 0, 0, 0 * 3600, false, "UTC");
}
+// A ZoneInfoSource implementation backed by an in-memory string buffer.
+class StringZoneInfoSource : public ZoneInfoSource {
+ public:
+ explicit StringZoneInfoSource(std::string data)
+ : data_(std::move(data)), offset_(0) {}
+
+ std::size_t Read(void* ptr, std::size_t size) override {
+ std::size_t n = (std::min)(size, data_.size() - offset_);
+ std::memcpy(ptr, data_.data() + offset_, n);
+ offset_ += n;
+ return n;
+ }
+
+ int Skip(std::size_t offset) override {
+ if (offset > data_.size() - offset_) return -1;
+ offset_ += offset;
+ return 0;
+ }
+
+ private:
+ std::string data_;
+ std::size_t offset_;
+};
+
+// Constructs a minimal TZif2 string with a single 64-bit transition
+// at the given transition time and a future POSIX rule. The abbreviation
+// area holds abbr verbatim, so a valid file's abbr must include the
+// trailing '\0' (e.g., std::string{"EST", 4}).
+std::string MakeExtendedTzif(std::int_fast64_t unix_time,
+ std::int_fast32_t utc_offset,
+ const std::string& abbr,
+ const std::string& future_spec) {
+ std::string s;
+ auto append32 = [&s](std::int_fast32_t v) {
+ const std::int_fast32_t s32max = 0x7fffffff;
+ const auto s32maxU = static_cast<std::uint_fast32_t>(s32max);
+ std::uint_fast32_t uv;
+ if (v >= 0) {
+ uv = static_cast<std::uint_fast32_t>(v);
+ } else {
+ uv = static_cast<std::uint_fast32_t>(v + s32max + 1) + s32maxU + 1;
+ }
+ for (int i = 3; i >= 0; --i) {
+ s.push_back(static_cast<char>((uv >> (i * 8)) & 0xff));
+ }
+ };
+ auto append64 = [&s](std::int_fast64_t v) {
+ const std::int_fast64_t s64max = 0x7fffffffffffffff;
+ const auto s64maxU = static_cast<std::uint_fast64_t>(s64max);
+ std::uint_fast64_t uv;
+ if (v >= 0) {
+ uv = static_cast<std::uint_fast64_t>(v);
+ } else {
+ uv = static_cast<std::uint_fast64_t>(v + s64max + 1) + s64maxU + 1;
+ }
+ for (int i = 7; i >= 0; --i) {
+ s.push_back(static_cast<char>((uv >> (i * 8)) & 0xff));
+ }
+ };
+
+ const std::size_t charcnt = abbr.size();
+
+ // 32-bit header
+ s.append(TZ_MAGIC, 4);
+ s.push_back('2'); // tzh_version
+ s.append(15, '\0'); // tzh_reserved
+ append32(0); // tzh_ttisutcnt
+ append32(0); // tzh_ttisstdcnt
+ append32(0); // tzh_leapcnt
+ append32(0); // tzh_timecnt (0 32-bit transitions)
+ append32(1); // tzh_typecnt (1 ttinfo record)
+ append32(static_cast<std::int_fast32_t>(charcnt)); // tzh_charcnt
+
+ // 32-bit data block
+ append32(utc_offset); // tt_utoff
+ s.push_back(0); // tt_isdst (standard time)
+ s.push_back(0); // tt_desigidx
+ s.append(abbr); // abbreviation table
+
+ // 64-bit header
+ s.append(TZ_MAGIC, 4);
+ s.push_back('2'); // tzh_version
+ s.append(15, '\0'); // tzh_reserved
+ append32(0); // tzh_ttisutcnt
+ append32(0); // tzh_ttisstdcnt
+ append32(0); // tzh_leapcnt
+ append32(1); // tzh_timecnt (1 64-bit transition)
+ append32(1); // tzh_typecnt (1 ttinfo record)
+ append32(static_cast<std::int_fast32_t>(charcnt)); // tzh_charcnt
+
+ // 64-bit data block
+ append64(unix_time); // transition time
+ s.push_back(0); // type index for transition
+ append32(utc_offset); // tt_utoff
+ s.push_back(0); // tt_isdst (standard time)
+ s.push_back(0); // tt_desigidx
+ s.append(abbr); // abbreviation table
+
+ // POSIX footer
+ s.push_back('\n');
+ s.append(future_spec);
+ s.push_back('\n');
+ return s;
+}
+
+std::unique_ptr<ZoneInfoSource> ExtendedTestFactory(
+ const std::string& name,
+ const std::function<std::unique_ptr<ZoneInfoSource>(const std::string&)>&
+ fallback) {
+ if (name == "test:ExtendedBeforeEpoch") {
+ // -1 (1969-12-31T23:59:59Z) is the latest final transition before the
+ // epoch, so the zone is rejected despite the future specification.
+ return std::unique_ptr<ZoneInfoSource>(
+ new StringZoneInfoSource(MakeExtendedTzif(
+ -1, -5 * 3600, std::string{"EST", 4}, "EST5EDT,M3.2.0,M11.1.0")));
+ }
+ if (name == "test:ExtendedFarFuture") {
+ // 0 (1970-01-01T00:00:00Z) is the earliest final transition an extended
+ // zone may have, which maximizes the 400-year shift that BreakTime()
+ // needs for a lookup at the maximum time.
+ return std::unique_ptr<ZoneInfoSource>(
+ new StringZoneInfoSource(MakeExtendedTzif(
+ 0, -5 * 3600, std::string{"EST", 4}, "EST5EDT,M3.2.0,M11.1.0")));
+ }
+ if (name == "test:ExtendedOverlappingRules") {
+ // The daylight time of one year starts more than four days after its
+ // nominal date, while the next year's ends more than five days before
+ // its own, so the two years' generated transitions overlap.
+ return std::unique_ptr<ZoneInfoSource>(
+ new StringZoneInfoSource(MakeExtendedTzif(
+ 0, -5 * 3600, std::string{"STD", 4},
+ "STD-12:00:00DST12:00:00,358/100:00:00,1/-139:00:00")));
+ }
+ if (name == "test:UnterminatedAbbreviation") {
+ // The abbreviation area is missing its final NUL, so the abbreviation
+ // would run into whatever ExtendTransitions() appends behind it.
+ return std::unique_ptr<ZoneInfoSource>(new StringZoneInfoSource(
+ MakeExtendedTzif(0, -5 * 3600, "EST", "EST5EDT,M3.2.0,M11.1.0")));
+ }
+ return fallback(name);
+}
+
+// Tests that a TZif file whose abbreviation area is not NUL-terminated
+// is rejected.
+TEST(TimeZoneEdgeCase, UnterminatedAbbreviation) {
+ auto prev_factory = cctz_extension::zone_info_source_factory;
+ cctz_extension::zone_info_source_factory = ExtendedTestFactory;
+
+ time_zone tz;
+ EXPECT_FALSE(load_time_zone("test:UnterminatedAbbreviation", &tz));
+
+ cctz_extension::zone_info_source_factory = prev_factory;
+}
+
+// Tests that a TZif file whose explicit transitions end before epoch
+// is rejected when it has a POSIX DST footer string.
+TEST(TimeZoneEdgeCase, ExtendedBeforeEpoch) {
+ auto prev_factory = cctz_extension::zone_info_source_factory;
+ cctz_extension::zone_info_source_factory = ExtendedTestFactory;
+
+ // Extended zones must end with a non-negative explicit transition.
+ time_zone tz;
+ EXPECT_FALSE(load_time_zone("test:ExtendedBeforeEpoch", &tz));
+
+ cctz_extension::zone_info_source_factory = prev_factory;
+}
+
+// A transition time may include a day offset of up to +/-167 hours, so the
+// rules for consecutive years can overlap, producing transitions that go
+// backward in unix time. BreakTime() binary searches the transitions by
+// unix time, so such a zone must be rejected.
+TEST(TimeZoneEdgeCase, ExtendedOverlappingRules) {
+ auto prev_factory = cctz_extension::zone_info_source_factory;
+ cctz_extension::zone_info_source_factory = ExtendedTestFactory;
+
+ time_zone tz;
+ EXPECT_FALSE(load_time_zone("test:ExtendedOverlappingRules", &tz));
+
+ cctz_extension::zone_info_source_factory = prev_factory;
+}
+
+// Looking up the maximum time in an extended zone must fold back through the
+// 400-year cycle without overflowing when BreakTime() computes the shift.
+TEST(TimeZoneEdgeCase, ExtendedFarFuture) {
+ auto prev_factory = cctz_extension::zone_info_source_factory;
+ cctz_extension::zone_info_source_factory = ExtendedTestFactory;
+
+ time_zone tz;
+ ASSERT_TRUE(load_time_zone("test:ExtendedFarFuture", &tz));
+
+ auto tp_max = time_point<absl::time_internal::cctz::seconds>::max();
+ ExpectTime(tp_max, tz, 292277026596, 12, 4, 10, 30, 7, -5 * 3600, false,
+ "EST");
+ EXPECT_STREQ("EST", tz.lookup(tp_max).abbr);
+
+ cctz_extension::zone_info_source_factory = prev_factory;
+}
+
} // namespace cctz
} // namespace time_internal
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc
index efea080470d..62c5e870dd1 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.cc
@@ -47,10 +47,11 @@ const char* ParseInt(const char* p, int min, int max, int* vp) {
return p;
}
-// abbr = <.*?> | [^-+,\d]{3,}
+// abbr = <.+?> | [^-+,\d]{3,}
const char* ParseAbbr(const char* p, std::string* abbr) {
const char* op = p;
if (*p == '<') { // special zoneinfo <...> form
+ if (*++p == '>' || *p == '\0') return nullptr; // no "<>"
while (*++p != '>') {
if (*p == '\0') return nullptr;
}
@@ -92,14 +93,17 @@ const char* ParseOffset(const char* p, int min_hour, int max_hour, int sign,
return p;
}
-// datetime = ( Jn | n | Mm.w.d ) [ / offset ]
+// datetime = , ( Jn | n | Mm.w.d ) [ / offset ]
const char* ParseDateTime(const char* p, PosixTransition* res) {
- if (p != nullptr && *p == ',') {
+ if (p != nullptr) {
+ if (*p != ',') return nullptr;
if (*++p == 'M') {
int month = 0;
- if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr && *p == '.') {
+ if ((p = ParseInt(p + 1, 1, 12, &month)) != nullptr) {
+ if (*p != '.') return nullptr;
int week = 0;
- if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr && *p == '.') {
+ if ((p = ParseInt(p + 1, 1, 5, &week)) != nullptr) {
+ if (*p != '.') return nullptr;
int weekday = 0;
if ((p = ParseInt(p + 1, 0, 6, &weekday)) != nullptr) {
res->date.fmt = PosixTransition::M;
@@ -122,17 +126,17 @@ const char* ParseDateTime(const char* p, PosixTransition* res) {
res->date.n.day = static_cast<std::int_fast16_t>(day);
}
}
- }
- if (p != nullptr) {
- res->time.offset = 2 * 60 * 60; // default offset is 02:00:00
- if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset);
+ if (p != nullptr) {
+ res->time.offset = 2 * 60 * 60; // default offset is 02:00:00
+ if (*p == '/') p = ParseOffset(p + 1, -167, 167, 1, &res->time.offset);
+ }
}
return p;
}
} // namespace
-// spec = std offset [ dst [ offset ] , datetime , datetime ]
+// spec = std offset [ dst [ offset ] datetime datetime ]
bool ParsePosixSpec(const std::string& spec, PosixTimeZone* res) {
const char* p = spec.c_str();
if (*p == ':') return false;
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h
index 7fd2b9ecfbb..23f569945be 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix.h
@@ -13,7 +13,7 @@
// limitations under the License.
// Parsing of a POSIX zone spec as described in the TZ part of section 8.3 in
-// http://pubs.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html.
+// https://pubs.opengroup.org/onlinepubs/9799919799/basedefs/V1_chap08.html.
//
// The current POSIX spec for America/Los_Angeles is "PST8PDT,M3.2.0,M11.1.0",
// which would be broken down as ...
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix_test.cc b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix_test.cc
new file mode 100644
index 00000000000..83b4b9d2124
--- /dev/null
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/src/time_zone_posix_test.cc
@@ -0,0 +1,198 @@
+// Copyright 2026 Google Inc. All Rights Reserved.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// https://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+#include "absl/time/internal/cctz/src/time_zone_posix.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/base/config.h"
+
+namespace absl {
+ABSL_NAMESPACE_BEGIN
+namespace time_internal {
+namespace cctz {
+
+using ::testing::Eq;
+using ::testing::IsEmpty;
+
+// We only support the second POSIX format (that is, neither the
+// "first character is a <colon>" format, nor the "geographical
+// or a special timezone" format). We also require DST start/end
+// rules whenever a DST abbreviation is given (zic always provides
+// them). So, ...
+//
+// spec = abbr offset [ abbr [ offset ] datetime datetime ]
+// abbr = <.+?> | [^-+,\d]{3,}
+// offset = [+|-]hh[:mm[:ss]]
+// datetime = , ( Jn | n | Mm.w.d ) [ / offset ]
+
+TEST(ParsePosixSpec, UnsupportedFormats) {
+ PosixTimeZone zone;
+ EXPECT_FALSE(ParsePosixSpec(":characters", &zone));
+ EXPECT_FALSE(ParsePosixSpec("Area/Location", &zone));
+}
+
+TEST(ParsePosixSpec, StdOnly) {
+ PosixTimeZone zone;
+
+ // America/Cancun
+ EXPECT_TRUE(ParsePosixSpec("EST5", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("EST"));
+ EXPECT_THAT(zone.std_offset, Eq(-5 * 60 * 60));
+ EXPECT_THAT(zone.dst_abbr, IsEmpty());
+
+ // Australia/Darwin
+ EXPECT_TRUE(ParsePosixSpec("ACST-9:30", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("ACST"));
+ EXPECT_THAT(zone.std_offset, Eq((9 * 60 + 30) * 60));
+ EXPECT_THAT(zone.dst_abbr, IsEmpty());
+
+ // Australia/Eucla
+ EXPECT_TRUE(ParsePosixSpec("<+0845>-8:45", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("+0845"));
+ EXPECT_THAT(zone.std_offset, Eq((8 * 60 + 45) * 60));
+ EXPECT_THAT(zone.dst_abbr, IsEmpty());
+}
+
+TEST(ParsePosixSpec, WithDst) {
+ PosixTimeZone zone;
+
+ // America/New_York
+ EXPECT_TRUE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.0", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("EST"));
+ EXPECT_THAT(zone.std_offset, Eq(-5 * 60 * 60));
+ EXPECT_THAT(zone.dst_abbr, Eq("EDT"));
+ EXPECT_THAT(zone.dst_offset, Eq(-4 * 60 * 60));
+ EXPECT_THAT(zone.dst_start.date.fmt, Eq(PosixTransition::M));
+ EXPECT_THAT(zone.dst_start.date.m.month, Eq(3));
+ EXPECT_THAT(zone.dst_start.date.m.week, Eq(2));
+ EXPECT_THAT(zone.dst_start.date.m.weekday, Eq(0));
+ EXPECT_THAT(zone.dst_start.time.offset, Eq(2 * 60 * 60));
+ EXPECT_THAT(zone.dst_end.date.fmt, Eq(PosixTransition::M));
+ EXPECT_THAT(zone.dst_end.date.m.month, Eq(11));
+ EXPECT_THAT(zone.dst_end.date.m.week, Eq(1));
+ EXPECT_THAT(zone.dst_end.date.m.weekday, Eq(0));
+ EXPECT_THAT(zone.dst_end.time.offset, Eq(2 * 60 * 60));
+
+ // Australia/Adelaide
+ EXPECT_TRUE(ParsePosixSpec("ACST-9:30ACDT,M10.1.0,M4.1.0/3", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("ACST"));
+ EXPECT_THAT(zone.std_offset, Eq((9 * 60 + 30) * 60));
+ EXPECT_THAT(zone.dst_abbr, Eq("ACDT"));
+ EXPECT_THAT(zone.dst_offset, Eq((10 * 60 + 30) * 60));
+ EXPECT_THAT(zone.dst_start.date.fmt, Eq(PosixTransition::M));
+ EXPECT_THAT(zone.dst_start.date.m.month, Eq(10));
+ EXPECT_THAT(zone.dst_start.date.m.week, Eq(1));
+ EXPECT_THAT(zone.dst_start.date.m.weekday, Eq(0));
+ EXPECT_THAT(zone.dst_start.time.offset, Eq(2 * 60 * 60));
+ EXPECT_THAT(zone.dst_end.date.fmt, Eq(PosixTransition::M));
+ EXPECT_THAT(zone.dst_end.date.m.month, Eq(4));
+ EXPECT_THAT(zone.dst_end.date.m.week, Eq(1));
+ EXPECT_THAT(zone.dst_end.date.m.weekday, Eq(0));
+ EXPECT_THAT(zone.dst_end.time.offset, Eq(3 * 60 * 60));
+
+ // Australia/Lord_Howe
+ EXPECT_TRUE(ParsePosixSpec("<+1030>-10:30<+11>-11,M10.1.0,M4.1.0", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("+1030"));
+ EXPECT_THAT(zone.std_offset, Eq((10 * 60 + 30) * 60));
+ EXPECT_THAT(zone.dst_abbr, Eq("+11"));
+ EXPECT_THAT(zone.dst_offset, Eq(11 * 60 * 60));
+ EXPECT_THAT(zone.dst_start.date.fmt, Eq(PosixTransition::M));
+ EXPECT_THAT(zone.dst_start.date.m.month, Eq(10));
+ EXPECT_THAT(zone.dst_start.date.m.week, Eq(1));
+ EXPECT_THAT(zone.dst_start.date.m.weekday, Eq(0));
+ EXPECT_THAT(zone.dst_start.time.offset, Eq(2 * 60 * 60));
+ EXPECT_THAT(zone.dst_end.date.fmt, Eq(PosixTransition::M));
+ EXPECT_THAT(zone.dst_end.date.m.month, Eq(4));
+ EXPECT_THAT(zone.dst_end.date.m.week, Eq(1));
+ EXPECT_THAT(zone.dst_end.date.m.weekday, Eq(0));
+ EXPECT_THAT(zone.dst_end.time.offset, Eq(2 * 60 * 60));
+
+ // Africa/Casablanca (year-round DST)
+ EXPECT_TRUE(ParsePosixSpec("<+00>0<+01>,0/0,J365/25", &zone));
+ EXPECT_THAT(zone.std_abbr, Eq("+00"));
+ EXPECT_THAT(zone.std_offset, Eq(0));
+ EXPECT_THAT(zone.dst_abbr, Eq("+01"));
+ EXPECT_THAT(zone.dst_offset, Eq(1 * 60 * 60));
+ EXPECT_THAT(zone.dst_start.date.fmt, Eq(PosixTransition::N));
+ EXPECT_THAT(zone.dst_start.date.n.day, Eq(0));
+ EXPECT_THAT(zone.dst_start.time.offset, Eq(0));
+ EXPECT_THAT(zone.dst_end.date.fmt, Eq(PosixTransition::J));
+ EXPECT_THAT(zone.dst_end.date.n.day, Eq(365));
+ EXPECT_THAT(zone.dst_end.time.offset, Eq(25 * 60 * 60));
+}
+
+TEST(TimeZonePosix, ParseErrors) {
+ PosixTimeZone zone;
+
+ // STD abbreviation errors.
+ EXPECT_FALSE(ParsePosixSpec("ET5", &zone));
+ EXPECT_FALSE(ParsePosixSpec("ET+", &zone));
+ EXPECT_FALSE(ParsePosixSpec("ET-", &zone));
+ EXPECT_FALSE(ParsePosixSpec("ET,", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<00", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<>0", &zone));
+
+ // STD offset errors.
+ EXPECT_FALSE(ParsePosixSpec("<00>", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<00>+", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<00>-", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<00>?", &zone));
+
+ // DST abbreviation errors.
+ EXPECT_FALSE(ParsePosixSpec("EST5DT,M3.2.0,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT+,M3.2.0,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT-,M3.2.0,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<00>0<-01", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5<>,M3.2.0,M11.1.0", &zone));
+
+ // DST offset errors.
+ EXPECT_FALSE(ParsePosixSpec("<01>1<00>?,0,0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<01>1<00>+?,0,0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("<01>1<00>-?,0,0", &zone));
+
+ // Malformed DST start date/time.
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M13.2.0,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.6.0,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.7,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,J0,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,366,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0/,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0/?,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0/1:?,M11.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0/1:2:?,M11.1.0", &zone));
+
+ // Malformed DST end date/time.
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M?.1.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.?.0", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.?", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,J?", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,?", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.0/", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.0/168", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.0/167:60", &zone));
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.0/167:59:60", &zone));
+
+ // Trailing data.
+ EXPECT_FALSE(ParsePosixSpec("EST5EDT,M3.2.0,M11.1.0junk", &zone));
+}
+
+} // namespace cctz
+} // namespace time_internal
+ABSL_NAMESPACE_END
+} // namespace absl
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version
index 75d34ee3893..9217a2da674 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/version
@@ -1 +1 @@
-2026b
+2026c
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca
index 240ebb2bfb2..fb2f5cc0893 100644
Binary files a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca and b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/Casablanca differ
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun
index 909c5f96829..46286b94b53 100644
Binary files a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun and b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Africa/El_Aaiun differ
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton
index 645ee945307..379e36540fc 100644
Binary files a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton and b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Edmonton differ
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife
index 645ee945307..379e36540fc 100644
Binary files a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife and b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/America/Yellowknife differ
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain
index 645ee945307..379e36540fc 100644
Binary files a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain and b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/Canada/Mountain differ
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab
index a9b47bcb309..635eabcbf2d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zone1970.tab
@@ -112,7 +112,7 @@ CA +744144-0944945 America/Resolute Central - NU (Resolute)
CA +624900-0920459 America/Rankin_Inlet Central - NU (central)
CA +5024-10439 America/Regina CST - SK (most areas)
CA +5017-10750 America/Swift_Current CST - SK (midwest)
-CA +5333-11328 America/Edmonton Mountain - AB, BC(E), NT(E), SK(W)
+CA +5333-11328 America/Edmonton CST - AB, BC(E), NT(E), SK(W)
CA +690650-1050310 America/Cambridge_Bay Mountain - NU (west)
CA +682059-1334300 America/Inuvik Mountain - NT (west)
CA +4916-12307 America/Vancouver MST - BC (most areas)
diff --git a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab
index 54e4485d744..9c3a8cf3c1b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab
+++ b/deps/v8/third_party/abseil-cpp/absl/time/internal/cctz/testdata/zoneinfo/zonenow.tab
@@ -56,16 +56,19 @@ XX +611305-1495401 America/Anchorage most of Alaska (AKST/AKDT)
XX -2504-13005 Pacific/Pitcairn Pitcairn
#
# -08/-07 - PST/PDT (North America DST)
-XX +340308-1181434 America/Los_Angeles Pacific (PST/PDT) - US & Canada; Mexico near US border
+XX +340308-1181434 America/Los_Angeles Pacific (PST/PDT) - US; Mexico near US border
#
# -08/-07 - PST/PDT (North America DST) until 2026-11-01 02:00; then MST
-XX +4916-12307 America/Vancouver MST - BC (most areas)
+XX +4916-12307 America/Vancouver Mountain Standard (MST) - British Columbia (most areas)
#
# -07 - MST
XX +332654-1120424 America/Phoenix Mountain Standard (MST) - Arizona; western Mexico; Yukon
#
# -07/-06 - MST/MDT (North America DST)
-XX +394421-1045903 America/Denver Mountain (MST/MDT) - US & Canada; Mexico near US border
+XX +394421-1045903 America/Denver Mountain (MST/MDT) - US; Mexico near US border; northern Canada
+#
+# -07/-06 - MST/MDT (North America DST) until 2026-11-01 02:00; then CST
+XX +5333-11328 America/Edmonton Central Standard (CST) - Alberta and some neighbors
#
# -06
XX -0054-08936 Pacific/Galapagos Galápagos
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 faef864e8ca..4be13cf5661 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,6 @@
#include "absl/time/time.h"
-#if defined(_MSC_VER)
-#include <winsock2.h> // for timeval
-#endif
-
#include <cstring>
#include <ctime>
#include <limits>
@@ -44,6 +40,10 @@
#include "absl/time/internal/cctz/include/cctz/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
+#if defined(_MSC_VER)
+#include <winsock2.h> // for timeval
+#endif
+
namespace cctz = absl::time_internal::cctz;
namespace absl {
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 fc1456bed6f..ea9be32062b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/time/time.h
+++ b/deps/v8/third_party/abseil-cpp/absl/time/time.h
@@ -62,19 +62,6 @@
#ifndef ABSL_TIME_TIME_H_
#define ABSL_TIME_TIME_H_
-#if !defined(_MSC_VER)
-#include <sys/time.h>
-#else
-// We don't include `winsock2.h` because it drags in `windows.h` and friends,
-// and they define conflicting macros like OPAQUE, ERROR, and more. This has the
-// potential to break Abseil users.
-//
-// Instead we only forward declare `timeval` and require Windows users include
-// `winsock2.h` themselves. This is both inconsistent and troublesome, but so is
-// including 'windows.h' so we are picking the lesser of two evils here.
-struct timeval;
-#endif
-
#include "absl/base/config.h"
// For feature testing and determining which headers can be included.
@@ -102,6 +89,19 @@ struct timeval;
#include "absl/time/civil_time.h"
#include "absl/time/internal/cctz/include/cctz/time_zone.h"
+#if !defined(_MSC_VER)
+#include <sys/time.h>
+#else
+// We don't include `winsock2.h` because it drags in `windows.h` and friends,
+// and they define conflicting macros like OPAQUE, ERROR, and more. This has the
+// potential to break Abseil users.
+//
+// Instead we only forward declare `timeval` and require Windows users include
+// `winsock2.h` themselves. This is both inconsistent and troublesome, but so is
+// including 'windows.h' so we are picking the lesser of two evils here.
+struct timeval;
+#endif
+
#if defined(__cpp_impl_three_way_comparison) && \
defined(__cpp_lib_three_way_comparison)
#define ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON 1
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 93a7c41b232..db8090a7589 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
@@ -11,11 +11,6 @@
// See the License for the specific language governing permissions and
// limitations under the License.
-#include "absl/time/time.h"
-
-#if !defined(_WIN32)
-#include <sys/time.h>
-#endif // _WIN32
#include <algorithm>
#include <cmath>
#include <cstddef>
@@ -26,8 +21,13 @@
#include "absl/time/clock.h"
#include "absl/time/internal/test_util.h"
+#include "absl/time/time.h"
#include "benchmark/benchmark.h"
+#if !defined(_WIN32)
+#include <sys/time.h>
+#endif // _WIN32
+
namespace {
//
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 35b1f0e1990..d53198a0acd 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,12 +14,6 @@
#include "absl/time/time.h"
-#include "absl/time/civil_time.h"
-
-#if defined(_MSC_VER)
-#include <winsock2.h> // for timeval
-#endif
-
#include "absl/base/config.h"
// For feature testing and determining which headers can be included.
@@ -45,9 +39,14 @@
#include "absl/hash/hash_testing.h"
#include "absl/numeric/int128.h"
#include "absl/strings/str_format.h"
+#include "absl/time/civil_time.h"
#include "absl/time/clock.h"
#include "absl/time/internal/test_util.h"
+#if defined(_MSC_VER)
+#include <winsock2.h> // for timeval
+#endif
+
namespace {
#if defined(GTEST_USES_SIMPLE_RE) && GTEST_USES_SIMPLE_RE
@@ -194,46 +193,46 @@ TEST(Time, RelationalOperators) {
constexpr absl::Time t2 = absl::FromUnixNanos(1);
constexpr absl::Time t3 = absl::FromUnixNanos(2);
- static_assert(absl::UnixEpoch() == t1, "");
- static_assert(t1 == t1, "");
- static_assert(t2 == t2, "");
- static_assert(t3 == t3, "");
-
- static_assert(t1 < t2, "");
- static_assert(t2 < t3, "");
- static_assert(t1 < t3, "");
-
- static_assert(t1 <= t1, "");
- static_assert(t1 <= t2, "");
- static_assert(t2 <= t2, "");
- static_assert(t2 <= t3, "");
- static_assert(t3 <= t3, "");
- static_assert(t1 <= t3, "");
-
- static_assert(t2 > t1, "");
- static_assert(t3 > t2, "");
- static_assert(t3 > t1, "");
-
- static_assert(t2 >= t2, "");
- static_assert(t2 >= t1, "");
- static_assert(t3 >= t3, "");
- static_assert(t3 >= t2, "");
- static_assert(t1 >= t1, "");
- static_assert(t3 >= t1, "");
+ static_assert(absl::UnixEpoch() == t1);
+ static_assert(t1 == t1);
+ static_assert(t2 == t2);
+ static_assert(t3 == t3);
+
+ static_assert(t1 < t2);
+ static_assert(t2 < t3);
+ static_assert(t1 < t3);
+
+ static_assert(t1 <= t1);
+ static_assert(t1 <= t2);
+ static_assert(t2 <= t2);
+ static_assert(t2 <= t3);
+ static_assert(t3 <= t3);
+ static_assert(t1 <= t3);
+
+ static_assert(t2 > t1);
+ static_assert(t3 > t2);
+ static_assert(t3 > t1);
+
+ static_assert(t2 >= t2);
+ static_assert(t2 >= t1);
+ static_assert(t3 >= t3);
+ static_assert(t3 >= t2);
+ static_assert(t1 >= t1);
+ static_assert(t3 >= t1);
#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
- static_assert((t1 <=> t1) == std::strong_ordering::equal, "");
- static_assert((t2 <=> t2) == std::strong_ordering::equal, "");
- static_assert((t3 <=> t3) == std::strong_ordering::equal, "");
+ static_assert((t1 <=> t1) == std::strong_ordering::equal);
+ static_assert((t2 <=> t2) == std::strong_ordering::equal);
+ static_assert((t3 <=> t3) == std::strong_ordering::equal);
- static_assert((t1 <=> t2) == std::strong_ordering::less, "");
- static_assert((t2 <=> t3) == std::strong_ordering::less, "");
- static_assert((t1 <=> t3) == std::strong_ordering::less, "");
+ static_assert((t1 <=> t2) == std::strong_ordering::less);
+ static_assert((t2 <=> t3) == std::strong_ordering::less);
+ static_assert((t1 <=> t3) == std::strong_ordering::less);
- static_assert((t2 <=> t1) == std::strong_ordering::greater, "");
- static_assert((t3 <=> t2) == std::strong_ordering::greater, "");
- static_assert((t3 <=> t1) == std::strong_ordering::greater, "");
+ static_assert((t2 <=> t1) == std::strong_ordering::greater);
+ static_assert((t3 <=> t2) == std::strong_ordering::greater);
+ static_assert((t3 <=> t1) == std::strong_ordering::greater);
#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
}
@@ -242,17 +241,17 @@ TEST(Time, Infinity) {
constexpr absl::Time ifuture = absl::InfiniteFuture();
constexpr absl::Time ipast = absl::InfinitePast();
- static_assert(ifuture == ifuture, "");
- static_assert(ipast == ipast, "");
- static_assert(ipast < ifuture, "");
- static_assert(ifuture > ipast, "");
+ static_assert(ifuture == ifuture);
+ static_assert(ipast == ipast);
+ static_assert(ipast < ifuture);
+ static_assert(ifuture > ipast);
#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
- static_assert((ifuture <=> ifuture) == std::strong_ordering::equal, "");
- static_assert((ipast <=> ipast) == std::strong_ordering::equal, "");
- static_assert((ipast <=> ifuture) == std::strong_ordering::less, "");
- static_assert((ifuture <=> ipast) == std::strong_ordering::greater, "");
+ static_assert((ifuture <=> ifuture) == std::strong_ordering::equal);
+ static_assert((ipast <=> ipast) == std::strong_ordering::equal);
+ static_assert((ipast <=> ifuture) == std::strong_ordering::less);
+ static_assert((ifuture <=> ipast) == std::strong_ordering::greater);
#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
@@ -268,15 +267,15 @@ TEST(Time, Infinity) {
EXPECT_EQ(-absl::InfiniteDuration(), ipast - ipast);
constexpr absl::Time t = absl::UnixEpoch(); // Any finite time.
- static_assert(t < ifuture, "");
- static_assert(t > ipast, "");
+ static_assert(t < ifuture);
+ static_assert(t > ipast);
#ifdef ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
- static_assert((t <=> ifuture) == std::strong_ordering::less, "");
- static_assert((t <=> ipast) == std::strong_ordering::greater, "");
- static_assert((ipast <=> t) == std::strong_ordering::less, "");
- static_assert((ifuture <=> t) == std::strong_ordering::greater, "");
+ static_assert((t <=> ifuture) == std::strong_ordering::less);
+ static_assert((t <=> ipast) == std::strong_ordering::greater);
+ static_assert((ipast <=> t) == std::strong_ordering::less);
+ static_assert((ifuture <=> t) == std::strong_ordering::greater);
#endif // ABSL_INTERNAL_TIME_HAS_THREE_WAY_COMPARISON
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 d38d4c7af5e..7ded8da6b40 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/BUILD.bazel
+++ b/deps/v8/third_party/abseil-cpp/absl/types/BUILD.bazel
@@ -110,7 +110,6 @@ cc_test(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:exception_testing",
- "//absl/base:hardening",
"//absl/container:fixed_array",
"//absl/container:inlined_vector",
"//absl/hash",
@@ -154,7 +153,6 @@ cc_test(
"//absl/base:config",
"//absl/base:core_headers",
"//absl/base:exception_testing",
- "//absl/base:hardening",
"//absl/base:raw_logging_internal",
"//absl/hash:hash_testing",
"//absl/meta:type_traits",
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 6fc49c63509..789f09283b7 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/types/BUILD.gn
@@ -1,8 +1,9 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
-import("//build_overrides/build.gni")
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("any") {
@@ -15,8 +16,8 @@ absl_source_set("any") {
}
absl_source_set("source_location") {
- public = [ "source_location.h" ]
sources = [ "source_location.cc" ]
+ public = [ "source_location.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -34,8 +35,8 @@ absl_test("source_location_test") {
}
absl_source_set("span") {
- public = [ "span.h" ]
sources = [ "internal/span.h" ]
+ public = [ "span.h" ]
deps = [
"//third_party/abseil-cpp/absl/algorithm",
"//third_party/abseil-cpp/absl/base:config",
@@ -55,7 +56,6 @@ absl_test("span_test") {
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
"//third_party/abseil-cpp/absl/base:exception_testing",
- "//third_party/abseil-cpp/absl/base:hardening",
"//third_party/abseil-cpp/absl/container:fixed_array",
"//third_party/abseil-cpp/absl/container:inlined_vector",
"//third_party/abseil-cpp/absl/hash",
@@ -66,8 +66,8 @@ absl_test("span_test") {
}
absl_source_set("any_span") {
- public = [ "any_span.h" ]
sources = [ "internal/any_span.h" ]
+ public = [ "any_span.h" ]
deps = [
"//third_party/abseil-cpp/absl/base:config",
"//third_party/abseil-cpp/absl/base:core_headers",
@@ -80,6 +80,7 @@ absl_source_set("any_span") {
}
# any_span_test is not ported because relies on RTTI
+# absl_test("any_span_test")
absl_source_set("optional") {
public = [ "optional.h" ]
@@ -99,6 +100,11 @@ absl_source_set("variant") {
]
}
+absl_test("variant_test") {
+ sources = [ "variant_test.cc" ]
+ deps = [ ":variant" ]
+}
+
absl_source_set("compare") {
public = [ "compare.h" ]
deps = [
@@ -108,9 +114,12 @@ absl_source_set("compare") {
]
}
-absl_test("variant_test") {
- sources = [ "variant_test.cc" ]
- deps = [ ":variant" ]
+absl_test("compare_test") {
+ sources = [ "compare_test.cc" ]
+ deps = [
+ ":compare",
+ "//third_party/abseil-cpp/absl/base",
+ ]
}
absl_source_set("optional_ref") {
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 28e1fe82deb..79a4c19f649 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/CMakeLists.txt
+++ b/deps/v8/third_party/abseil-cpp/absl/types/CMakeLists.txt
@@ -58,7 +58,6 @@ absl_cc_test(
absl::config
absl::core_headers
absl::exception_testing
- absl::hardening
absl::hash_testing
absl::raw_logging_internal
absl::span
@@ -102,7 +101,6 @@ absl_cc_test(
absl::core_headers
absl::exception_testing
absl::fixed_array
- absl::hardening
absl::hash
absl::inlined_vector
absl::hash_testing
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/any_span.h b/deps/v8/third_party/abseil-cpp/absl/types/any_span.h
index 04e64dcd0da..5c858926e73 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/any_span.h
+++ b/deps/v8/third_party/abseil-cpp/absl/types/any_span.h
@@ -390,7 +390,7 @@ class ABSL_ATTRIBUTE_VIEW AnySpan {
using difference_type = std::ptrdiff_t;
using absl_internal_is_view = std::true_type;
- static const size_type npos = static_cast<size_type>(-1); // NOLINT
+ static constexpr size_type npos = static_cast<size_type>(-1); // NOLINT
using reference = T&;
using const_reference = std::add_const_t<T>&;
@@ -893,9 +893,6 @@ AnySpan<const T> MakeConstAnySpan(const T* absl_nullable ptr,
// Implementation details follow.
//
-template <typename T>
-const typename AnySpan<T>::size_type AnySpan<T>::npos;
-
// Iterator base class. Uses CRTP (Iter should be the child class). Constness of
// the iterator is determined by the constness of Value.
template <typename T>
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 fe12b749dd5..e5960c6aa8a 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
@@ -30,7 +30,6 @@
#include "gtest/gtest.h"
#include "absl/base/config.h"
#include "absl/base/internal/exception_testing.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/internal/raw_logging.h"
#include "absl/base/macros.h"
#include "absl/hash/hash_testing.h"
@@ -1042,7 +1041,6 @@ TYPED_TEST(AnySpanTest, SubspanToEnd) {
EXPECT_THAT(span.subspan(3, AnySpan<int>::npos), ElementsAre());
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- auto hardener = absl::base_internal::ScopedSetAbslHardeningForTesting(true);
EXPECT_DEATH(span.subspan(4, AnySpan<int>::npos), "");
EXPECT_DEATH(span.subspan(AnySpan<int>::npos, AnySpan<int>::npos), "");
}
@@ -1054,7 +1052,6 @@ TEST(MutableAnySpanTest, NonTruncatingSubspan) {
AnySpan<int> span(v);
#if GTEST_HAS_DEATH_TEST
if (IsHardened()) {
- auto hardener = absl::base_internal::ScopedSetAbslHardeningForTesting(true);
EXPECT_DEATH(span.subspan(5, 0), "");
EXPECT_DEATH(span.subspan(5, 1), "");
EXPECT_DEATH(span.subspan(AnySpan<int>::npos, 0), "");
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/compare.h b/deps/v8/third_party/abseil-cpp/absl/types/compare.h
index be59d924b8f..e6a2a5728c3 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/compare.h
+++ b/deps/v8/third_party/abseil-cpp/absl/types/compare.h
@@ -23,7 +23,7 @@
// Example:
// absl::weak_ordering compare(const std::string& a, const std::string& b);
//
-// These are C++11 compatible versions of the C++20 corresponding types
+// These are C++17 compatible versions of the C++20 corresponding types
// (`std::partial_ordering`, etc.) and are designed to be drop-in replacements
// for code compliant with C++20.
@@ -110,71 +110,15 @@ enum class ord : value_type { less = -1, greater = 1 };
enum class ncmp : value_type { unordered = -127 };
-// Define macros to allow for creation or emulation of C++17 inline variables
-// based on whether the feature is supported. Note: we can't use
-// ABSL_INTERNAL_INLINE_CONSTEXPR here because the variables here are of
-// incomplete types so they need to be defined after the types are complete.
-#ifdef __cpp_inline_variables
-
-// A no-op expansion that can be followed by a semicolon at class level.
-#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) static_assert(true, "")
-
-#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static const type name
-
-#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
- inline constexpr type type::name(init)
-
-#else // __cpp_inline_variables
-
-#define ABSL_COMPARE_INLINE_BASECLASS_DECL(name) \
- ABSL_CONST_INIT static const T name
-
-// A no-op expansion that can be followed by a semicolon at class level.
-#define ABSL_COMPARE_INLINE_SUBCLASS_DECL(type, name) static_assert(true, "")
-
-#define ABSL_COMPARE_INLINE_INIT(type, name, init) \
- template <typename T> \
- const T compare_internal::type##_base<T>::name(init)
-
-#endif // __cpp_inline_variables
-
-// These template base classes allow for defining the values of the constants
-// in the header file (for performance) without using inline variables (which
-// aren't available in C++11).
-template <typename T>
-struct partial_ordering_base {
- ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(unordered);
-};
-
-template <typename T>
-struct weak_ordering_base {
- ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
-};
-
-template <typename T>
-struct strong_ordering_base {
- ABSL_COMPARE_INLINE_BASECLASS_DECL(less);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equal);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(equivalent);
- ABSL_COMPARE_INLINE_BASECLASS_DECL(greater);
-};
-
} // namespace compare_internal
-class partial_ordering
- : public compare_internal::partial_ordering_base<partial_ordering> {
+class partial_ordering {
explicit constexpr partial_ordering(compare_internal::eq v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
explicit constexpr partial_ordering(compare_internal::ord v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
explicit constexpr partial_ordering(compare_internal::ncmp v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
- friend struct compare_internal::partial_ordering_base<partial_ordering>;
constexpr bool is_ordered() const noexcept {
return value_ !=
@@ -182,10 +126,10 @@ class partial_ordering
}
public:
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, less);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, equivalent);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, greater);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(partial_ordering, unordered);
+ static const partial_ordering less;
+ static const partial_ordering equivalent;
+ static const partial_ordering greater;
+ static const partial_ordering unordered;
// Comparisons
friend constexpr bool operator==(partial_ordering v,
@@ -248,26 +192,25 @@ class partial_ordering
private:
compare_internal::value_type value_;
};
-ABSL_COMPARE_INLINE_INIT(partial_ordering, less, compare_internal::ord::less);
-ABSL_COMPARE_INLINE_INIT(partial_ordering, equivalent,
- compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(partial_ordering, greater,
- compare_internal::ord::greater);
-ABSL_COMPARE_INLINE_INIT(partial_ordering, unordered,
- compare_internal::ncmp::unordered);
-
-class weak_ordering
- : public compare_internal::weak_ordering_base<weak_ordering> {
+inline constexpr partial_ordering partial_ordering::less(
+ compare_internal::ord::less);
+inline constexpr partial_ordering partial_ordering::equivalent(
+ compare_internal::eq::equivalent);
+inline constexpr partial_ordering partial_ordering::greater(
+ compare_internal::ord::greater);
+inline constexpr partial_ordering partial_ordering::unordered(
+ compare_internal::ncmp::unordered);
+
+class weak_ordering {
explicit constexpr weak_ordering(compare_internal::eq v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
explicit constexpr weak_ordering(compare_internal::ord v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
- friend struct compare_internal::weak_ordering_base<weak_ordering>;
public:
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, less);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, equivalent);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(weak_ordering, greater);
+ static const weak_ordering less;
+ static const weak_ordering equivalent;
+ static const weak_ordering greater;
// Conversions
constexpr operator partial_ordering() const noexcept { // NOLINT
@@ -336,25 +279,23 @@ class weak_ordering
private:
compare_internal::value_type value_;
};
-ABSL_COMPARE_INLINE_INIT(weak_ordering, less, compare_internal::ord::less);
-ABSL_COMPARE_INLINE_INIT(weak_ordering, equivalent,
- compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(weak_ordering, greater,
- compare_internal::ord::greater);
-
-class strong_ordering
- : public compare_internal::strong_ordering_base<strong_ordering> {
+inline constexpr weak_ordering weak_ordering::less(compare_internal::ord::less);
+inline constexpr weak_ordering weak_ordering::equivalent(
+ compare_internal::eq::equivalent);
+inline constexpr weak_ordering weak_ordering::greater(
+ compare_internal::ord::greater);
+
+class strong_ordering {
explicit constexpr strong_ordering(compare_internal::eq v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
explicit constexpr strong_ordering(compare_internal::ord v) noexcept
: value_(static_cast<compare_internal::value_type>(v)) {}
- friend struct compare_internal::strong_ordering_base<strong_ordering>;
public:
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, less);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equal);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, equivalent);
- ABSL_COMPARE_INLINE_SUBCLASS_DECL(strong_ordering, greater);
+ static const strong_ordering less;
+ static const strong_ordering equal;
+ static const strong_ordering equivalent;
+ static const strong_ordering greater;
// Conversions
constexpr operator partial_ordering() const noexcept { // NOLINT
@@ -428,16 +369,14 @@ class strong_ordering
private:
compare_internal::value_type value_;
};
-ABSL_COMPARE_INLINE_INIT(strong_ordering, less, compare_internal::ord::less);
-ABSL_COMPARE_INLINE_INIT(strong_ordering, equal, compare_internal::eq::equal);
-ABSL_COMPARE_INLINE_INIT(strong_ordering, equivalent,
- compare_internal::eq::equivalent);
-ABSL_COMPARE_INLINE_INIT(strong_ordering, greater,
- compare_internal::ord::greater);
-
-#undef ABSL_COMPARE_INLINE_BASECLASS_DECL
-#undef ABSL_COMPARE_INLINE_SUBCLASS_DECL
-#undef ABSL_COMPARE_INLINE_INIT
+inline constexpr strong_ordering strong_ordering::less(
+ compare_internal::ord::less);
+inline constexpr strong_ordering strong_ordering::equal(
+ compare_internal::eq::equal);
+inline constexpr strong_ordering strong_ordering::equivalent(
+ compare_internal::eq::equivalent);
+inline constexpr strong_ordering strong_ordering::greater(
+ compare_internal::ord::greater);
#endif // ABSL_USES_STD_ORDERING
@@ -479,7 +418,8 @@ constexpr absl::weak_ordering compare_result_as_ordering(
template <
typename Compare, typename K, typename LK,
std::enable_if_t<
- !std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>,
+ !std::is_same_v<bool,
+ std::invoke_result_t<Compare, const K&, const LK&>>,
int> = 0>
constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
const K& x, const LK& y) {
@@ -488,7 +428,8 @@ constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
template <
typename Compare, typename K, typename LK,
std::enable_if_t<
- std::is_same_v<bool, absl::result_of_t<Compare(const K&, const LK&)>>,
+ std::is_same_v<bool,
+ std::invoke_result_t<Compare, const K&, const LK&>>,
int> = 0>
constexpr absl::weak_ordering do_three_way_comparison(const Compare& compare,
const K& x, const LK& y) {
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 352c9f131cb..ae73eca50a3 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
@@ -277,23 +277,21 @@ TEST(DoThreeWayComparison, SanityTest) {
absl::compare_internal::do_three_way_comparison(weak, 10, 5) > 0));
}
-#ifdef __cpp_inline_variables
TEST(Compare, StaticAsserts) {
- static_assert(partial_ordering::less < 0, "");
- static_assert(partial_ordering::equivalent == 0, "");
- static_assert(partial_ordering::greater > 0, "");
- static_assert(partial_ordering::unordered != 0, "");
+ static_assert(partial_ordering::less < 0);
+ static_assert(partial_ordering::equivalent == 0);
+ static_assert(partial_ordering::greater > 0);
+ static_assert(partial_ordering::unordered != 0);
- static_assert(weak_ordering::less < 0, "");
- static_assert(weak_ordering::equivalent == 0, "");
- static_assert(weak_ordering::greater > 0, "");
+ static_assert(weak_ordering::less < 0);
+ static_assert(weak_ordering::equivalent == 0);
+ static_assert(weak_ordering::greater > 0);
- static_assert(strong_ordering::less < 0, "");
- static_assert(strong_ordering::equal == 0, "");
- static_assert(strong_ordering::equivalent == 0, "");
- static_assert(strong_ordering::greater > 0, "");
+ static_assert(strong_ordering::less < 0);
+ static_assert(strong_ordering::equal == 0);
+ static_assert(strong_ordering::equivalent == 0);
+ static_assert(strong_ordering::greater > 0);
}
-#endif // __cpp_inline_variables
} // namespace
ABSL_NAMESPACE_END
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/internal/any_span.h b/deps/v8/third_party/abseil-cpp/absl/types/internal/any_span.h
index cd0e4c4a97d..00ee7420134 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/internal/any_span.h
+++ b/deps/v8/third_party/abseil-cpp/absl/types/internal/any_span.h
@@ -68,8 +68,7 @@ constexpr bool kIsTransformCopied =
// Type to pass as extra argument to TransformPtr to ensure that our
// assumption about Transform copyability is valid.
template <typename Transform>
-using IsTransformCopied =
- std::integral_constant<bool, kIsTransformCopied<Transform>>;
+using IsTransformCopied = std::bool_constant<kIsTransformCopied<Transform>>;
// A pointer to the transform function or functor that should be applied to
// elements of the container.
@@ -466,7 +465,7 @@ bool IsCheap(AnySpan<T> s) {
template <typename T>
bool EqualImpl(AnySpan<T> a, AnySpan<T> b) {
- static_assert(std::is_const_v<T>, "");
+ static_assert(std::is_const_v<T>);
return std::equal(a.begin(), a.end(), b.begin(), b.end());
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/internal/span.h b/deps/v8/third_party/abseil-cpp/absl/types/internal/span.h
index 148c957eefd..f0f1af67706 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/internal/span.h
+++ b/deps/v8/third_party/abseil-cpp/absl/types/internal/span.h
@@ -39,12 +39,6 @@ constexpr auto GetDataImpl(C& c, char) noexcept // NOLINT(runtime/references)
return c.data();
}
-// Before C++17, std::string::data returns a const char* in all cases.
-inline char* GetDataImpl(std::string& s, // NOLINT(runtime/references)
- int) noexcept {
- return &s[0];
-}
-
template <typename C>
constexpr auto GetData(C& c) noexcept // NOLINT(runtime/references)
-> decltype(GetDataImpl(c, 0)) {
@@ -86,7 +80,7 @@ using EnableIfMutable = std::enable_if_t<!std::is_const_v<T>, int>;
template <template <typename> class SpanT, typename T>
constexpr bool EqualImpl(SpanT<T> a, SpanT<T> b) {
- static_assert(std::is_const_v<T>, "");
+ static_assert(std::is_const_v<T>);
return std::equal(a.begin(), a.end(), b.begin(), b.end());
}
@@ -94,7 +88,7 @@ template <template <typename> class SpanT, typename T>
constexpr bool LessThanImpl(SpanT<T> a, SpanT<T> b) {
// We can't use value_type since that is remove_cv_t<T>, so we go the long way
// around.
- static_assert(std::is_const_v<T>, "");
+ static_assert(std::is_const_v<T>);
return std::lexicographical_compare(a.begin(), a.end(), b.begin(), b.end());
}
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/optional_ref_test.cc b/deps/v8/third_party/abseil-cpp/absl/types/optional_ref_test.cc
index dda162460f3..c6f2e761746 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/optional_ref_test.cc
+++ b/deps/v8/third_party/abseil-cpp/absl/types/optional_ref_test.cc
@@ -362,7 +362,7 @@ TEST(OptionalRefTest, AsOptional) {
TEST(OptionalRefTest, Constexpr) {
static constexpr int foo = 123;
constexpr optional_ref<const int> ref(foo);
- static_assert(ref.has_value() && *ref == foo && ref.value() == foo, "");
+ static_assert(ref.has_value() && *ref == foo && ref.value() == foo);
}
} // namespace
diff --git a/deps/v8/third_party/abseil-cpp/absl/types/span.h b/deps/v8/third_party/abseil-cpp/absl/types/span.h
index c33e29411c9..41aba0aea5b 100644
--- a/deps/v8/third_party/abseil-cpp/absl/types/span.h
+++ b/deps/v8/third_party/abseil-cpp/absl/types/span.h
@@ -39,8 +39,7 @@
// * bounds-checked access to `absl::Span` is accomplished with `at()`
// however `std::span` now supports the same as of the draft C++26 standard
// * `absl::Span` has compiler-provided move and copy constructors and
-// assignment. This is due to them being specified as `constexpr`, but that
-// implies const in C++11.
+// assignment.
// * `absl::Span` has no `bytes()`, `size_bytes()`, `as_bytes()`, or
// `as_writable_bytes()` methods
// * `absl::Span` has no static extent template parameter, nor constructors
@@ -85,9 +84,6 @@ ABSL_NAMESPACE_END
// If std::ranges is available, mark Span as satisfying the `view` and
// `borrowed_range` concepts, just like std::span.
-#if !defined(__has_include)
-#define __has_include(header) 0
-#endif
#if __has_include(<version>)
#include <version> // NOLINT(misc-include-cleaner)
#endif
@@ -220,7 +216,7 @@ class ABSL_ATTRIBUTE_VIEW Span {
using absl_internal_is_view = std::true_type;
// NOLINTNEXTLINE
- static const size_type npos = ~(size_type(0));
+ static constexpr size_type npos = static_cast<size_type>(-1);
constexpr Span() noexcept : Span(nullptr, 0) {}
constexpr Span(pointer array ABSL_ATTRIBUTE_LIFETIME_BOUND,
@@ -510,9 +506,6 @@ class ABSL_ATTRIBUTE_VIEW Span {
size_type len_;
};
-template <typename T>
-const typename Span<T>::size_type Span<T>::npos;
-
// Span relationals
// Equality is compared element-by-element, while ordering is lexicographical.
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 051e673dc74..5a8b82e61a0 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
@@ -27,7 +27,6 @@
#include "absl/base/attributes.h"
#include "absl/base/config.h"
#include "absl/base/internal/exception_testing.h"
-#include "absl/base/internal/hardening.h"
#include "absl/base/options.h"
#include "absl/container/fixed_array.h"
#include "absl/container/inlined_vector.h"
@@ -251,7 +250,6 @@ TEST(IntSpan, ElementAccess) {
EXPECT_EQ(s.back(), s[9]);
#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
EXPECT_DEATH_IF_SUPPORTED(s[-1], "");
EXPECT_DEATH_IF_SUPPORTED(s[10], "");
#endif
@@ -293,7 +291,6 @@ TEST(IntSpan, RemovePrefixAndSuffix) {
EXPECT_EQ(v, MakeRamp(20, 1));
#if !defined(NDEBUG) || ABSL_OPTION_HARDENED
- absl::base_internal::ScopedSetAbslHardeningForTesting hardener(true);
absl::Span<int> prefix_death(v);
EXPECT_DEATH_IF_SUPPORTED(prefix_death.remove_prefix(21), "");
absl::Span<int> suffix_death(v);
diff --git a/deps/v8/third_party/abseil-cpp/absl/utility/BUILD.gn b/deps/v8/third_party/abseil-cpp/absl/utility/BUILD.gn
index ef2d98bebc1..2b082de381d 100644
--- a/deps/v8/third_party/abseil-cpp/absl/utility/BUILD.gn
+++ b/deps/v8/third_party/abseil-cpp/absl/utility/BUILD.gn
@@ -1,13 +1,14 @@
# Copyright 2018 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
+#
+# Generated file. DO NOT EDIT.
import("//third_party/abseil-cpp/absl.gni")
absl_source_set("utility") {
public = [ "utility.h" ]
deps = [
- "//third_party/abseil-cpp/absl/base:base_internal",
"//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/convert_bazel_to_gn.py b/deps/v8/third_party/abseil-cpp/convert_bazel_to_gn.py
new file mode 100755
index 00000000000..fdbb611b95a
--- /dev/null
+++ b/deps/v8/third_party/abseil-cpp/convert_bazel_to_gn.py
@@ -0,0 +1,525 @@
+#!/usr/bin/env python3
+"""Script to generate BUILD.gn files from Abseil's BUILD.bazel at roll time."""
+
+import ast
+import datetime
+import logging
+import os
+import re
+import subprocess
+import sys
+
+# List of targets that do not have matching gn target generated.
+_SKIP_TARGETS = {
+ 'container:btree_test':
+ 'TODO(mbonadei): Fix issue with EXPECT_DEATH and uncomment.',
+ 'container:container_memory_test':
+ 'Disabled because container_memory_test requires -frtti',
+ 'container:raw_hash_set_test':
+ 'raw_hash_set_test uses typeid(), i.e., relies on RTTI.',
+ 'debugging:demangle_test': 'Disabled because this test relies on RTTI',
+ 'flags:commandlineflag_test':
+ 'Conflicts at link_time with "parse_test" because defines the same flags.',
+ 'flags:reflection_test':
+ 'Conflicts at link time with "flag_test" because defines the same flags.',
+ 'log:check_test': 'Overlaps with absl_check_test',
+ 'log:log_basic_test': 'Overlaps with absl_log_basic_test',
+ 'profiling:sample_recorder_test':
+ 'TODO: Re-enable once the issue with gmock activating generic gtest printers hitting issues with -Wmicrosoft-cast.',
+ 'random/internal:nanobenchmark': 'Only used for benchmarking',
+ 'synchronization:blocking_counter_test':
+ 'Conflicts at link time with "tracing_strong_test" because also defines strong functions for AbslInternalTraceWait and alike',
+ 'synchronization:mutex_method_pointer_test': 'Doesn\'t compile.',
+ 'synchronization:notification_test':
+ 'Conflicts at link time with "tracing_strong_test" because also defines strong functions for AbslInternalTraceWait and alike',
+ 'types:any_span_test':
+ 'any_span_test is not ported because relies on RTTI',
+}
+
+# Targets that are public in absl in general, but are not exposed to chromium targets
+_PRIVATE_TARGETS = {
+ # Flags rely on static initializers and thus are not exposed in chromium
+ 'flags:config',
+ 'flags:commandlineflag',
+ 'flags:flag',
+ 'flags:marshalling',
+ 'flags:parse',
+ 'flags:reflection',
+ 'flags:usage',
+ 'log:flags',
+ # Targets below expose macros that conflicts with similar chromium macros,
+ # there are targets with alternative absl macro prefixed with ABSL_.
+ 'log:log',
+ 'log:check',
+ 'log:vlog_is_on',
+ # absl::any, same as std::any doesn't work with chromium component builds.
+ 'types:any',
+ # currently public, but shouldn't be, there are TODOs to make them private
+ 'base:malloc_internal',
+ 'cleanup:cleanup_internal',
+ 'container:compressed_tuple',
+ 'container:raw_hash_set',
+ 'strings:internal',
+ # public in cctz, private for abseil users.
+ 'time/internal/cctz:civil_time',
+ 'time/internal/cctz:time_zone',
+}
+
+# Dependencies that preferably shouldn't be public in chromium, but are.
+_PUBLIC_TARGETS = {
+ 'base:dynamic_annotations',
+ 'base:raw_logging_internal',
+ 'container:layout',
+}
+
+# Extra output added just before the target.
+_ADD_PREFIX = {
+ 'base:c_header_test':
+ 'if (absl_build_tests) { import("//testing/test.gni") ',
+ 'flags:config':
+ '''# Since absl/flags are only used by some test binaries (e.g. in WebRTC),
+# there is no need to strip flags from mobile platforms binaries.
+# This does not affect Chromium.
+config("absl_flags_config") {
+ defines = [ "ABSL_FLAGS_STRIP_NAMES=0" ]
+ }
+ ''',
+ 'log:check':
+ '''# This target is banned both for 1st party and 3rd party code, use absl_check
+# in third_party code instead.
+# This header introduces CHECK macros that collides with chromium's macros.
+# Instead libraries should use ABSL_CHECK that provides the same functionality.''',
+ 'log:log':
+ '''# This target is banned both for 1st party and 3rd party code. Use absl_log
+# in third_party code instead.
+# This header introduces LOG macros that collides with chromium's macros.
+# Instead libraries should use ABSL_LOG that provides the same functionality.''',
+ 'log:vlog_is_on':
+ '''# This target is banned both for 1st party and 3rd party code, use ABSL_
+# prefixed macros and absl_vlog_is_on in third_party code instead.'''
+}
+
+# Extra build rules added at the end. The reason they are needed vary per target.
+_ADD_CONTENT = {
+ 'base:c_header_test':
+ '}', # Closes extra '{' opened by prefix.
+ 'cleanup:cleanup_internal':
+ 'visibility = [ "//third_party/abseil-cpp/absl/*" ]',
+ 'container:hashtablez_sampler_test':
+ 'if (is_win) { sources = [] }',
+ 'container:test_allocator':
+ 'deps = [ "//third_party/abseil-cpp/absl/base:config", "//third_party/googletest:gtest" ]',
+ 'flags:config':
+ 'public_configs = [ ":absl_flags_config" ]',
+ 'flags:parse_test':
+ 'if (is_ios) { sources = [] }',
+ 'log:absl_check_test':
+ 'if (is_ios) { sources = [] }',
+ 'log:log_sink_test':
+ 'if (is_ios) { sources = [] }',
+ 'log:scoped_mock_log_test':
+ 'if (is_ios) { sources = [] }',
+ 'log/internal:log_sink_set':
+ 'if (is_android) { libs = [ "log" ] }',
+ 'log/internal:stderr_log_sink_test':
+ 'if (is_apple || is_android) { sources = [] }',
+ 'random:uniform_real_distribution_test':
+ 'if (is_ios) { sources = [] }',
+ 'random/internal:seed_material':
+ 'if (is_win) { libs = [ "bcrypt.lib" ]}',
+ 'strings:strings':
+ '''public_deps = [
+ # string_view.h was once part of :strings, so string_view.h is
+ # re-exported for backwards compatibility.
+ # New code should directly depend on :string_view.
+ # TODO(crbug.com/40276308): Remove once all targets are migrated to
+ # :string_view.
+ ":string_view" ]''',
+ 'strings:str_format_convert_test':
+ 'if (is_fuchsia) { sources = [] }',
+ # Instead of parsing 'select', add platform-specific rules manually while there are few of those.
+ 'time/internal/cctz:time_zone':
+ '''
+if (is_win) { sources += [ "src/time_zone_name_win.cc" ]
+ public += [ "src/time_zone_name_win.h" ] }
+defines = []
+if (is_apple) {
+ frameworks = [ "Foundation.framework" ]
+ # Work-around for https://github.com/llvm/llvm-project/issues/117630
+ defines += [ "_XOPEN_SOURCE=700" ]
+}
+if (is_fuchsia) {
+ deps += [
+ "//third_party/fuchsia-sdk/sdk/fidl/fuchsia.intl:fuchsia.intl_hlcpp",
+ "//third_party/fuchsia-sdk/sdk/pkg/async",
+ "//third_party/fuchsia-sdk/sdk/pkg/async-loop-cpp",
+ "//third_party/fuchsia-sdk/sdk/pkg/sys_cpp",
+ "//third_party/fuchsia-sdk/sdk/pkg/zx",
+ ]
+}''',
+ 'time/internal/cctz:time_zone_name_win_test':
+ 'if (is_win) { sources = [ "src/time_zone_name_win_test.cc" ] }',
+}
+
+
+def _ast_get_value(node, local_vars):
+ if isinstance(node, ast.Constant):
+ return node.value
+ elif isinstance(node, ast.List):
+ return [_ast_get_value(elt, local_vars) for elt in node.elts]
+ elif isinstance(node, ast.Name):
+ if node.id in local_vars:
+ return local_vars[node.id]
+ return node.id
+ elif isinstance(node, ast.BinOp) and isinstance(node.op, ast.Add):
+ left = _ast_get_value(node.left, local_vars) or []
+ right = _ast_get_value(node.right, local_vars) or []
+ return left + right
+ return None
+
+
+class _Converter:
+
+ def __init__(self, path, old_gn_content=None):
+ self.bazel_targets = []
+ self.test_targets = []
+ self.public_targets = []
+ self.packages = {}
+ self.year = str(datetime.datetime.now().year)
+ self.path = path
+ m = re.search(r'.*/absl/(.*)', path)
+ self.rel_path = m.group(1) if m else ''
+ if old_gn_content:
+ m = re.search(r'# Copyright (\d{4})', old_gn_content)
+ if m:
+ self.year = m.group(1)
+
+ def _translate_dep(self, dep):
+ if dep.startswith('@do_not_use'):
+ return None
+ if dep == '//absl/' + self.rel_path:
+ return ':' + self.rel_path.split('/')[-1]
+ if dep.startswith(':'):
+ return dep
+ if dep.startswith('//absl/' + self.rel_path + ':'):
+ return dep[7 + len(self.rel_path):]
+ if dep.startswith('//absl'):
+ return '//third_party/abseil-cpp/' + dep[2:]
+ if dep.startswith('@googletest'):
+ return None
+ return dep
+
+ def _translate_visibility(self, vis_list):
+ result = []
+ for vis in vis_list:
+ if vis == '//visibility:public':
+ return []
+ if vis == '//visibility:private':
+ result.append(':*')
+ if vis == '//absl:friends':
+ continue
+ if vis.startswith('//absl'):
+ parts = vis.split(':')
+ pkg = parts[0]
+ rule = parts[1] if len(parts) > 1 else ''
+ gn_pkg = '' if pkg[7:] == self.rel_path else (
+ '//third_party/abseil-cpp/' + pkg[2:])
+ if rule == '__pkg__':
+ result.append(gn_pkg + ':*')
+ elif rule == '__subpackages__':
+ result.append(gn_pkg + '/*')
+ else:
+ result.append(gn_pkg + ':' + rule)
+ if vis.startswith(':') and vis[1:] in self.packages:
+ result += self.packages[vis[1:]]
+ # In bazel targets are implicitly visible to the same BUILD file
+ # in gn such visibility should be explicit.
+ if ':*' not in result and '//third_party/abseil-cpp/absl/*' not in result:
+ result.append(':*')
+ return result
+
+ def _translate_package(self, package):
+ if package.endswith('/...'):
+ return '//third_party/abseil-cpp' + package[1:-4] + "/*"
+ else:
+ path = package[7:]
+ gn_path = '' if path == self.rel_path else '//third_party/abseil-cpp/absl/' + path
+ return gn_path + ':*'
+
+ # Targets that include string_view.h should depend on string_view target.
+ # For backward compatibility it is possible to depend just on 'strings', but it is
+ # better to depend on string_view directly.
+ def _need_to_add_string_view(self, bt):
+ string_target = ':strings' if self.rel_path == 'strings' else '//absl/strings'
+ if string_target not in bt.get('deps', []):
+ # If target doesn't depend on 'strings', it either doesn't use string_view,
+ # or already directly depends on string_view. Skip reading source files.
+ return False
+
+ for s in bt.get('srcs', []) + bt.get('hdrs', []):
+ with open(os.path.join(self.path, s), 'r', encoding='utf-8') as f:
+ if re.search(r'#include "absl/strings/string_view.h"',
+ f.read()):
+ return True
+ return False
+
+ def parse_bazel(self, content):
+ tree = ast.parse(content)
+ local_vars = {
+ 'ABSL_DEFAULT_LINKOPTS': [],
+ 'ABSL_DEFAULT_COPTS': [],
+ 'ABSL_TEST_COPTS': []
+ }
+ default_vis = []
+ for node in tree.body:
+ if isinstance(node, ast.Assign):
+ for target in node.targets:
+ if isinstance(target, ast.Name):
+ local_vars[target.id] = _ast_get_value(
+ node.value, local_vars)
+ if isinstance(node, ast.Expr) and isinstance(node.value, ast.Call):
+ call = node.value
+ if isinstance(call.func, ast.Name):
+ func_name = call.func.id
+ if func_name == 'package':
+ for kw in call.keywords:
+ if kw.arg == 'default_visibility':
+ default_vis = _ast_get_value(
+ kw.value, local_vars)
+ elif func_name == 'package_group':
+ name = None
+ packages = []
+ for kw in call.keywords:
+ if kw.arg == 'name':
+ name = _ast_get_value(kw.value, local_vars)
+ elif kw.arg == 'packages':
+ for p in _ast_get_value(kw.value, local_vars):
+ packages.append(self._translate_package(p))
+ if name:
+ self.packages[name] = packages
+ elif func_name in ('cc_library', 'cc_test'):
+ t = {'is_test': func_name == 'cc_test'}
+ for kw in call.keywords:
+ t[kw.arg] = _ast_get_value(kw.value, local_vars)
+ if 'visibility' not in t and default_vis:
+ t['visibility'] = default_vis
+ self.bazel_targets.append(t)
+
+ def generate(self):
+ out = []
+ out.append(f'# Copyright {self.year} The Chromium Authors')
+ out.append(
+ '# Use of this source code is governed by a BSD-style license that'
+ ' can be')
+ out.append('# found in the LICENSE file.')
+ out.append('#')
+ out.append('# Generated file. DO NOT EDIT.')
+ out.append('')
+ out.append('import("//third_party/abseil-cpp/absl.gni")')
+ out.append('')
+
+ for bt in self.bazel_targets:
+ name = bt.get('name')
+ if not name:
+ continue
+
+ is_test = bt.get('is_test')
+ rule = 'absl_test' if is_test else 'absl_source_set'
+ bazel_deps = bt.get('deps', [])
+ target_name = f"{self.rel_path}:{name}"
+
+ skip = _SKIP_TARGETS.get(target_name)
+ if skip:
+ out.append(f'# {skip}')
+ out.append(f'# {rule}("{name}")')
+ out.append(f'')
+ continue
+
+ if '@google_benchmark//:benchmark_main' in bazel_deps:
+ # Porting benchmarks targets is not implemented.
+ continue
+
+ if '//absl/base:exception_safety_testing' in bazel_deps:
+ out.append(
+ f'# skipped because chromium doesn\'t use c++ exceptions')
+ out.append(f'# {rule}("{name}")')
+ out.append(f'')
+ continue
+
+ if is_test and target_name != 'base:c_header_test' and '@googletest//:gtest_main' not in bazel_deps:
+ out.append(
+ f'# {name} is excluded because defines its own main function'
+ )
+ out.append(f'# {rule}("{name}")')
+ out.append(f'')
+ continue
+
+ # Start writing the output.
+ out.append(_ADD_PREFIX.get(target_name, ''))
+ if target_name == 'base:c_header_test':
+ # This test is ported despite having own main function.
+ out.append('test("absl_c_header_test") {')
+ else:
+ out.append(f'{rule}("{name}") {{')
+
+ if bt.get('testonly'):
+ out.append('testonly = true')
+
+ srcs = bt.get('srcs', [])
+ if srcs:
+ out.append('sources = [')
+ for s in sorted(srcs):
+ out.append(f'"{s}",')
+ out.append(']')
+
+ hdrs = bt.get('hdrs', []) + bt.get('textual_hdrs', [])
+ if hdrs:
+ out.append('public = [')
+ for h in sorted(hdrs):
+ # One exception where header is excluded
+ if target_name == 'strings:strings' and h == 'string_view.h':
+ continue
+ out.append(f'"{h}",')
+ out.append(']')
+
+ vis = [] if is_test else self._translate_visibility(
+ bt.get('visibility', []))
+ if target_name in _PUBLIC_TARGETS:
+ if not vis:
+ # Turn generally public target into public to abseil only.
+ vis.append("//third_party/abseil-cpp/absl/*")
+ vis.append('//third_party/abseil-cpp:absl_component_deps')
+ # empty visibility is handled by the rule template, in particular for non-tests
+ # it imply public visibility, but in component builds it is still restricted.
+ if vis:
+ out.append('visibility = [')
+ for v in sorted(vis):
+ out.append(f'"{v}",')
+ out.append(']')
+
+ gn_deps = []
+ for d in bazel_deps:
+ td = self._translate_dep(d)
+ if td:
+ gn_deps.append(td)
+ elif not is_test and d == '@googletest//:gtest':
+ gn_deps.append("//third_party/googletest:gmock")
+ gn_deps.append("//third_party/googletest:gtest")
+ if self._need_to_add_string_view(bt):
+ gn_deps.append(
+ self._translate_dep('//absl/strings:string_view'))
+ if gn_deps:
+ out.append('deps = [')
+ for d in sorted(gn_deps):
+ out.append(f'"{d}",')
+ out.append(']')
+
+ out.append(_ADD_CONTENT.get(target_name, ''))
+ out.append('}')
+ out.append('')
+
+ if target_name == 'base:c_header_test':
+ pass
+ elif is_test:
+ self.test_targets.append(target_name)
+ elif not (bt.get('testonly') or target_name in _PRIVATE_TARGETS
+ or vis):
+ self.public_targets.append(target_name)
+
+ return '\n'.join(out)
+
+
+def convert_one(path):
+ bazel_path = os.path.join(path, 'BUILD.bazel')
+ gn_path = os.path.join(path, 'BUILD.gn')
+ logging.info(f'Converting {bazel_path}')
+ old_gn = None
+ if os.path.exists(gn_path):
+ with open(gn_path, 'r', encoding='utf-8') as f:
+ old_gn = f.read()
+
+ with open(bazel_path, 'r', encoding='utf-8') as f:
+ bazel_content = f.read()
+
+ converter = _Converter(path, old_gn)
+ converter.parse_bazel(bazel_content)
+
+ if not converter.bazel_targets:
+ logging.info(f'Skipping {bazel_path} (no cc_library/cc_test targets)')
+ return [], []
+
+ new_gn = converter.generate()
+
+ with open(gn_path, 'w', encoding='utf-8', newline='') as f:
+ subprocess.run(['gn', 'format', '--stdin'],
+ check=True,
+ input=new_gn,
+ stdout=f,
+ stderr=subprocess.DEVNULL,
+ text=True)
+
+ return converter.test_targets, converter.public_targets
+
+
+def convert_all(root_dir):
+ all_test_targets = []
+ all_public_targets = []
+ for dirpath, dirnames, filenames in os.walk(os.path.join(root_dir,
+ 'absl')):
+ if 'BUILD.bazel' in filenames:
+ t, p = convert_one(dirpath)
+ all_test_targets.extend(t)
+ all_public_targets.extend(p)
+
+ # Update root BUILD.gn
+ root_gn_path = os.path.join(root_dir, 'BUILD.gn')
+ if not os.path.exists(root_gn_path):
+ logging.error(f"Failed to find {root_gn_path}")
+ return
+
+ logging.info(f"Updating root targets in {root_gn_path}")
+ with open(root_gn_path, 'r') as f:
+ content = f.read()
+
+ # Update absl_component_deps
+ pattern_comp = re.compile(
+ r'(group\("absl_component_deps"\)\s*\{\s*public_deps\s*=\s*)\[([\s\S]*?)\]'
+ )
+ libs_lines = [
+ f'"//third_party/abseil-cpp/absl/{label}"'
+ for label in sorted(all_public_targets)
+ ]
+ new_libs_str = "[\n" + ",\n".join(libs_lines) + "\n]"
+ content = pattern_comp.sub(r'\1' + new_libs_str, content, count=1)
+
+ # Update absl_tests
+ pattern_test = re.compile(
+ r'(test\("absl_tests"\)\s*\{[\s\S]*?deps\s*=\s*)\[([\s\S]*?)\]')
+ deps_lines = [f'"absl/{label}"' for label in sorted(all_test_targets)]
+ deps_lines.append('"//third_party/googletest:gtest_main"')
+ new_deps_str = "[" + ",\n".join(deps_lines) + "]"
+ content = pattern_test.sub(r'\1' + new_deps_str, content, count=1)
+
+ with open(root_gn_path, 'w', encoding='utf-8', newline='') as f:
+ subprocess.run(['gn', 'format', '--stdin'],
+ check=True,
+ input=content,
+ stdout=f,
+ stderr=subprocess.DEVNULL,
+ text=True)
+
+
+if __name__ == '__main__':
+ logging.getLogger().setLevel(logging.INFO)
+
+ if len(sys.argv) == 2 and os.path.isdir(sys.argv[1]):
+ convert_one(sys.argv[1])
+ elif len(sys.argv) < 2:
+ if not os.getcwd().endswith('src') or not os.path.exists(
+ 'chrome/browser'):
+ logging.error('Run this script from a chromium/src/ directory.')
+ exit(1)
+ convert_all(os.path.join(os.getcwd(), 'third_party', 'abseil-cpp'))
+ else:
+ logging.info('Usage: convert_bazel_to_gn.py [<dir>]')
+ exit(1)
diff --git a/deps/v8/third_party/abseil-cpp/generate_def_files.py b/deps/v8/third_party/abseil-cpp/generate_def_files.py
index c80356f8414..2e269dab8d0 100755
--- a/deps/v8/third_party/abseil-cpp/generate_def_files.py
+++ b/deps/v8/third_party/abseil-cpp/generate_def_files.py
@@ -41,112 +41,129 @@ ABSL_SYM_RE = r'0* [BT] (?P<symbol>[?]+[^?].*absl.*|_?Absl.*)'
def _DebugOrRelease(is_debug):
- return 'dbg' if is_debug else 'rel'
+ return 'dbg' if is_debug else 'rel'
def _GenerateDefFileBuild(cpu, is_debug, use_cxx23, extra_gn_args, suffix, out_dir, cwd):
- if extra_gn_args:
- assert suffix != None, 'suffix is needed when extra_gn_args is used'
-
- flavor = _DebugOrRelease(is_debug)
- gn_args = [
- 'ffmpeg_branding = "Chrome"',
- 'is_component_build = true',
- 'is_debug = {}'.format(str(is_debug).lower()),
- 'proprietary_codecs = true',
- 'use_cxx23={}'.format(str(use_cxx23).lower()),
- 'symbol_level = 0',
- 'target_cpu = "{}"'.format(cpu),
- 'target_os = "win"',
- 'use_remoteexec = true',
- ]
- gn_args.extend(extra_gn_args)
-
- gn = 'gn'
- autoninja = 'autoninja'
- llvm_nm = ['third_party/llvm-build/Release+Asserts/bin/llvm-nm']
- if sys.platform == 'win32':
- gn = 'gn.bat'
- autoninja = 'autoninja.bat'
- llvm_nm += '.exe'
-
- logging.info('[%s - %s] Creating tmp out dir in %s', cpu, flavor, out_dir)
- subprocess.check_call([gn, 'gen', out_dir, '--args=' + ' '.join(gn_args)],
- cwd=cwd)
- logging.info('[%s - %s] gn gen completed', cpu, flavor)
- subprocess.check_call(
- [autoninja, '-C', out_dir, 'third_party/abseil-cpp:absl_component_deps'],
- cwd=os.getcwd())
- logging.info('[%s - %s] autoninja completed', cpu, flavor)
-
- obj_files = []
- for root, _dirnames, filenames in os.walk(
- os.path.join(out_dir, 'obj', 'third_party', 'abseil-cpp')):
- matched_files = fnmatch.filter(filenames, '*.obj')
- obj_files.extend((os.path.join(root, f) for f in matched_files))
-
- logging.info('[%s - %s] Found %d object files.', cpu, flavor, len(obj_files))
-
- absl_symbols = set()
- for f in obj_files:
- stdout = subprocess.check_output(llvm_nm + [f], cwd=os.getcwd())
- for line in stdout.splitlines():
- line = line.decode('utf-8')
- match = re.match(ABSL_SYM_RE, line)
- if match:
- symbol = match.group('symbol')
- assert symbol.count(' ') == 0, ('Regex matched too much, probably got '
- 'undecorated name as well')
- # Avoid to export deleting dtors since they trigger
- # "lld-link: error: export of deleting dtor" linker errors, see
- # crbug.com/1201277.
- if symbol.startswith('??_G'):
- continue
- # Strip any leading underscore for C names (as in __cdecl). It's only
- # there on x86, but the x86 toolchain falls over when you include it!
- if cpu == 'x86' and symbol.startswith('_'):
- symbol = symbol[1:]
- absl_symbols.add(symbol)
-
- logging.info('[%s - %s] Found %d absl symbols.', cpu, flavor, len(absl_symbols))
-
- if extra_gn_args:
- def_file = os.path.join('third_party', 'abseil-cpp',
- 'symbols_{}_{}_{}'.format(cpu, flavor, suffix))
- else:
- def_file = os.path.join('third_party', 'abseil-cpp',
- 'symbols_{}_{}'.format(cpu, flavor))
- if use_cxx23:
- def_file += "_cxx23"
- def_file += ".def"
-
- with open(def_file, 'w', newline='') as f:
- f.write('EXPORTS\n')
- for s in sorted(absl_symbols):
- f.write(' {}\n'.format(s))
-
- logging.info('[%s - %s] .def file successfully generated.', cpu, flavor)
-
-
-def _GenerateDefFile(cpu, is_debug, use_cxx23, extra_gn_args=[], suffix=None):
- """Generates a .def file for the absl component build on the specified CPU."""
- cwd = os.getcwd()
- with tempfile.TemporaryDirectory(dir=os.path.join(cwd, 'out')) as out_dir:
- _GenerateDefFileBuild(cpu, is_debug, use_cxx23, extra_gn_args, suffix, out_dir, cwd)
-
- # Hack, it looks like there is a race in the directory cleanup.
- time.sleep(10)
+ if extra_gn_args:
+ assert suffix != None, 'suffix is needed when extra_gn_args is used'
+
+ flavor = _DebugOrRelease(is_debug)
+ gn_args = [
+ 'ffmpeg_branding = "Chrome"',
+ 'is_component_build = true',
+ 'is_debug = {}'.format(str(is_debug).lower()),
+ 'proprietary_codecs = true',
+ 'use_cxx23={}'.format(str(use_cxx23).lower()),
+ 'symbol_level = 0',
+ 'target_cpu = "{}"'.format(cpu),
+ 'target_os = "win"',
+ 'use_remoteexec = true',
+ ]
+ gn_args.extend(extra_gn_args)
+
+ gn = 'gn'
+ autoninja = 'autoninja'
+ llvm_nm = ['third_party/llvm-build/Release+Asserts/bin/llvm-nm']
+ if sys.platform == 'win32':
+ gn = 'gn.bat'
+ autoninja = 'autoninja.bat'
+ llvm_nm += '.exe'
+
+ logging.info('[%s - %s] Creating tmp out dir in %s', cpu, flavor, out_dir)
+ subprocess.check_call([gn, 'gen', out_dir, '--args=' + ' '.join(gn_args)],
+ cwd=cwd)
+ logging.info('[%s - %s] gn gen completed', cpu, flavor)
+ subprocess.check_call([
+ autoninja, '-C', out_dir, 'third_party/abseil-cpp:absl_component_deps'
+ ],
+ cwd=os.getcwd())
+ logging.info('[%s - %s] autoninja completed', cpu, flavor)
+
+ obj_files = []
+ for root, _dirnames, filenames in os.walk(
+ os.path.join(out_dir, 'obj', 'third_party', 'abseil-cpp')):
+ matched_files = fnmatch.filter(filenames, '*.obj')
+ obj_files.extend((os.path.join(root, f) for f in matched_files))
+
+ logging.info('[%s - %s] Found %d object files.', cpu, flavor,
+ len(obj_files))
+
+ absl_symbols = set()
+ for f in obj_files:
+ stdout = subprocess.check_output(llvm_nm + [f], cwd=os.getcwd())
+ for line in stdout.splitlines():
+ line = line.decode('utf-8')
+ match = re.match(ABSL_SYM_RE, line)
+ if match:
+ symbol = match.group('symbol')
+ assert symbol.count(' ') == 0, (
+ 'Regex matched too much, probably got '
+ 'undecorated name as well')
+ # Avoid to export deleting dtors since they trigger
+ # "lld-link: error: export of deleting dtor" linker errors, see
+ # crbug.com/1201277.
+ if symbol.startswith('??_G'):
+ continue
+ # Strip any leading underscore for C names (as in __cdecl). It's only
+ # there on x86, but the x86 toolchain falls over when you include it!
+ if cpu == 'x86' and symbol.startswith('_'):
+ symbol = symbol[1:]
+ absl_symbols.add(symbol)
+
+ logging.info('[%s - %s] Found %d absl symbols.', cpu, flavor,
+ len(absl_symbols))
+
+ if extra_gn_args:
+ def_file = os.path.join('third_party', 'abseil-cpp',
+ 'symbols_{}_{}_{}'.format(cpu, flavor, suffix))
+ else:
+ def_file = os.path.join('third_party', 'abseil-cpp',
+ 'symbols_{}_{}'.format(cpu, flavor))
+ if use_cxx23:
+ def_file += "_cxx23"
+ def_file += ".def"
+
+ with open(def_file, 'w', newline='') as f:
+ f.write('EXPORTS\n')
+ for s in sorted(absl_symbols):
+ f.write(' {}\n'.format(s))
+
+ logging.info('[%s - %s] .def file successfully generated.', cpu, flavor)
+
+
+def _GenerateDefFile(chromium_dir,
+ cpu,
+ is_debug,
+ use_cxx23,
+ extra_gn_args=[],
+ suffix=None):
+ """Generates a .def file for the absl component build on the specified CPU."""
+ with tempfile.TemporaryDirectory(
+ dir=os.path.join(chromium_dir, 'out')) as out_dir:
+ _GenerateDefFileBuild(cpu, is_debug, use_cxx23, extra_gn_args, suffix,
+ out_dir, chromium_dir)
+
+ # Hack, it looks like there is a race in the directory cleanup.
+ time.sleep(10)
+
+
+def generate_all(chromium_dir):
+ for use_cxx23 in (True, False):
+ _GenerateDefFile(chromium_dir, 'x64', False, use_cxx23,
+ ['is_asan = true'], 'asan')
+ for arch in ('x86', 'x64', 'arm64'):
+ for is_debug in (True, False):
+ _GenerateDefFile(chromium_dir, arch, is_debug, use_cxx23)
if __name__ == '__main__':
- logging.getLogger().setLevel(logging.INFO)
+ logging.getLogger().setLevel(logging.INFO)
+ chromium_dir = os.getcwd()
- if not os.getcwd().endswith('src') or not os.path.exists('chrome/browser'):
- logging.error('Run this script from a chromium/src/ directory.')
- exit(1)
+ if not chromium_dir.endswith('src') or not os.path.exists(
+ 'chrome/browser'):
+ logging.error('Run this script from a chromium/src/ directory.')
+ exit(1)
- for use_cxx23 in (True, False):
- _GenerateDefFile('x64', False, use_cxx23, ['is_asan = true'], 'asan')
- for arch in ('x86', 'x64', 'arm64'):
- for is_debug in (True, False):
- _GenerateDefFile(arch, is_debug, use_cxx23)
+ generate_all(chromium_dir)
diff --git a/deps/v8/third_party/abseil-cpp/roll_abseil.py b/deps/v8/third_party/abseil-cpp/roll_abseil.py
index 7243c919823..15c1ed0ded2 100755
--- a/deps/v8/third_party/abseil-cpp/roll_abseil.py
+++ b/deps/v8/third_party/abseil-cpp/roll_abseil.py
@@ -1,9 +1,10 @@
#!/usr/bin/env python3
-"""Script to do the first step of Abseil roll into chromium.
-"""
+"""Script to roll Abseil into chromium."""
import argparse
+import convert_bazel_to_gn
+import generate_def_files
import logging
import os
import re
@@ -14,76 +15,86 @@ from datetime import datetime
ABSL_URI = 'https://github.com/abseil/abseil-cpp.git'
def _PullAbseil(abseil_dir, revision):
- logging.info('Updating abseil...')
- args = ['git', 'clone', ABSL_URI]
- if revision:
- args.extend(['--revision', revision])
- subprocess.check_call(args, cwd=abseil_dir)
+ logging.info('Updating abseil...')
+ args = ['git', 'clone', ABSL_URI]
+ if revision:
+ args.extend(['--revision', revision])
+ subprocess.check_call(args, cwd=abseil_dir)
def _SyncChromium(chromium_dir):
- logging.info('Updating chromium...')
- subprocess.check_call(['git', 'pull', '--rebase'], cwd=chromium_dir)
- subprocess.check_call(['gclient', 'sync'], cwd=chromium_dir)
+ logging.info('Updating chromium...')
+ subprocess.check_call(['git', 'pull', '--rebase'], cwd=chromium_dir)
+ subprocess.check_call(['gclient', 'sync'], cwd=chromium_dir)
def _UpdateChromiumReadme(readme_filename, abseil_dir):
- logging.info('Updating ' + readme_filename)
+ logging.info('Updating ' + readme_filename)
- stdout = subprocess.check_output(['git', 'log', '-n1', '--pretty=short'],
- cwd=abseil_dir)
- new_revision = re.search('commit\\s(.{40})', str(stdout)).group(1)
+ stdout = subprocess.check_output(['git', 'log', '-n1', '--pretty=short'],
+ cwd=abseil_dir)
+ new_revision = re.search('commit\\s(.{40})', str(stdout)).group(1)
- with open(readme_filename, 'r+') as f:
- content = f.read()
- prefix = 'Revision: '
- pos = content.find(prefix)
- assert(pos > 0)
- pos = pos + len(prefix)
- old_revision = content[pos:pos+40]
- f.seek(pos)
- f.write(new_revision)
+ with open(readme_filename, 'r+') as f:
+ content = f.read()
+ prefix = 'Revision: '
+ pos = content.find(prefix)
+ assert (pos > 0)
+ pos = pos + len(prefix)
+ old_revision = content[pos:pos + 40]
+ f.seek(pos)
+ f.write(new_revision)
- logging.info('Abseil old revision is ' + old_revision)
- logging.info('Abseil new revision is ' + new_revision)
- return old_revision[0:10] + '..' + new_revision[0:10]
+ logging.info('Abseil old revision is ' + old_revision)
+ logging.info('Abseil new revision is ' + new_revision)
+ return old_revision[0:10] + '..' + new_revision[0:10]
def _UpdateAbseilInChromium(abseil_dir, chromium_dir):
- logging.info('Syncing abseil in chromium/src/third_party...')
- exclude = [
- '*BUILD.gn',
- 'DIR_METADATA',
- 'README.chromium',
- 'OWNERS',
- '.clang-format-ignore',
- '.git',
- '.gitignore',
- '*.gni',
- '*clang-format',
- 'patches/*',
- 'patches',
- 'absl_hardening_test.cc',
- 'roll_abseil.py',
- 'generate_def_files.py',
- '*.def',
- ]
- params = ['rsync', '-aP', abseil_dir, os.path.join(chromium_dir, 'third_party'), '--delete']
- for e in exclude:
- params.append('--exclude={}'.format(e))
- subprocess.check_call(params, cwd=chromium_dir)
+ logging.info('Syncing abseil in chromium/src/third_party...')
+ exclude = [
+ '*BUILD.gn',
+ 'DIR_METADATA',
+ 'README.chromium',
+ 'OWNERS',
+ '.clang-format-ignore',
+ '.git',
+ '.gitignore',
+ '.style.yapf',
+ '*.gni',
+ '*clang-format',
+ 'patches/*',
+ 'patches',
+ 'absl_hardening_test.cc',
+ 'roll_abseil.py',
+ 'generate_def_files.py',
+ 'convert_bazel_to_gn.py',
+ '*.def',
+ ]
+ params = [
+ 'rsync', '-aP', abseil_dir,
+ os.path.join(chromium_dir, 'third_party'), '--delete'
+ ]
+ for e in exclude:
+ params.append('--exclude={}'.format(e))
+ subprocess.check_call(params, cwd=chromium_dir)
def _PatchAbseil(abseil_in_chromium_dir):
- logging.info('Patching abseil...')
- for patch in os.listdir(os.path.join(abseil_in_chromium_dir, 'patches')):
- subprocess.check_call(['patch', '--strip', '1', '-i', os.path.join(abseil_in_chromium_dir, 'patches', patch)])
+ logging.info('Patching abseil...')
+ for patch in os.listdir(os.path.join(abseil_in_chromium_dir, 'patches')):
+ subprocess.check_call([
+ 'patch', '--strip', '1', '-i',
+ os.path.join(abseil_in_chromium_dir, 'patches', patch)
+ ])
- os.remove(os.path.join(abseil_in_chromium_dir, 'absl', 'base', 'internal', 'dynamic_annotations.h'))
+ os.remove(
+ os.path.join(abseil_in_chromium_dir, 'absl', 'base', 'internal',
+ 'dynamic_annotations.h'))
def _Commit(chromium_dir, hash_diff, should_upload):
- logging.info('Commit...')
- desc="""Roll abseil_revision {0}
+ logging.info('Commit...')
+ desc = """Roll abseil_revision {0}
Change Log:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+log/{0}
@@ -91,62 +102,80 @@ Full diff:
https://chromium.googlesource.com/external/github.com/abseil/abseil-cpp/+/{0}
Bug: None""".format(hash_diff)
- subprocess.check_call(['git', 'add', 'third_party/abseil-cpp'], cwd=chromium_dir)
- proc = subprocess.run(['git', 'diff', '--staged', '--quiet', 'third_party/abseil-cpp'], cwd=chromium_dir)
- if proc.returncode == 0:
- logging.info('Abseil is up-to-date, nothing to commit!')
- return
-
- subprocess.check_call(['git', 'commit', '-m', desc], cwd=chromium_dir)
-
- if should_upload:
- logging.info('Upload...')
- subprocess.check_call(['git', 'cl', 'upload', '-m', desc, '--bypass-hooks'], cwd=chromium_dir)
-
- logging.info("Next step is manual: Fix BUILD.gn files to match BUILD.bazel changes.")
- logging.info("After that run generate_def_files.py. ")
-
-
-def _Roll(should_branch, should_pull, should_upload, revision):
- chromium_dir = os.getcwd()
- abseil_in_chromium_dir = os.path.join(chromium_dir, 'third_party', 'abseil-cpp')
- if should_branch:
- branch_name = datetime.today().strftime('rolling-absl-%Y%m%d')
- logging.info('Creating branch ' + branch_name + ' for the roll...')
- subprocess.check_call(['git', 'new-branch', branch_name], cwd=chromium_dir)
-
- if should_pull:
- _SyncChromium(chromium_dir)
-
- with tempfile.TemporaryDirectory() as abseil_root:
- _PullAbseil(abseil_root, revision)
- abseil_dir = os.path.join(abseil_root, 'abseil-cpp')
- _UpdateAbseilInChromium(abseil_dir, chromium_dir)
- hash_diff = _UpdateChromiumReadme(os.path.join(abseil_in_chromium_dir, 'README.chromium'),
- abseil_dir)
-
- _PatchAbseil(abseil_in_chromium_dir)
- _Commit(chromium_dir, hash_diff, should_upload)
+ subprocess.check_call(['git', 'add', 'third_party/abseil-cpp'],
+ cwd=chromium_dir)
+ proc = subprocess.run(
+ ['git', 'diff', '--staged', '--quiet', 'third_party/abseil-cpp'],
+ cwd=chromium_dir)
+ if proc.returncode == 0:
+ logging.info('Abseil is up-to-date, nothing to commit!')
+ return
+
+ subprocess.check_call(['git', 'commit', '-m', desc], cwd=chromium_dir)
+
+ if should_upload:
+ logging.info('Upload...')
+ subprocess.check_call([
+ 'git', 'cl', 'upload', '--commit-description=' + desc,
+ '--bypass-hooks'
+ ],
+ cwd=chromium_dir)
+
+
+def _Roll(should_branch, should_pull, should_generate_def, should_upload,
+ revision):
+ chromium_dir = os.getcwd()
+ abseil_in_chromium_dir = os.path.join(chromium_dir, 'third_party',
+ 'abseil-cpp')
+ if should_branch:
+ branch_name = datetime.today().strftime('rolling-absl-%Y%m%d')
+ logging.info('Creating branch ' + branch_name + ' for the roll...')
+ subprocess.check_call(['git', 'new-branch', branch_name],
+ cwd=chromium_dir)
+
+ if should_pull:
+ _SyncChromium(chromium_dir)
+
+ with tempfile.TemporaryDirectory() as abseil_root:
+ _PullAbseil(abseil_root, revision)
+ abseil_dir = os.path.join(abseil_root, 'abseil-cpp')
+ _UpdateAbseilInChromium(abseil_dir, chromium_dir)
+ hash_diff = _UpdateChromiumReadme(
+ os.path.join(abseil_in_chromium_dir, 'README.chromium'),
+ abseil_dir)
+
+ _PatchAbseil(abseil_in_chromium_dir)
+ convert_bazel_to_gn.convert_all(abseil_in_chromium_dir)
+ if should_generate_def:
+ generate_def_files.generate_all(chromium_dir)
+
+ _Commit(chromium_dir, hash_diff, should_upload)
if __name__ == '__main__':
- logging.getLogger().setLevel(logging.INFO)
-
- parser = argparse.ArgumentParser()
- parser.add_argument('--no-branch', action='store_true',
- help='Skip creating a new branch, use the current one.')
- parser.add_argument('--no-pull', action='store_true',
- help='Skip pulling the latest Chromium revision.')
- parser.add_argument('--no-upload', action='store_true',
- help='Skip uploading the change.')
- parser.add_argument('--revision', default=None,
- help='Revision to roll to. The default is the latest.')
- args = parser.parse_args()
-
- if os.getcwd().endswith('src') and os.path.exists('chrome/browser'):
- _Roll(not args.no_branch, not args.no_pull, not args.no_upload,
- args.revision)
- else:
- logging.error('Run this script from a chromium/src/ directory.')
-
-
+ logging.getLogger().setLevel(logging.INFO)
+
+ parser = argparse.ArgumentParser()
+ parser.add_argument(
+ '--no-branch',
+ action='store_true',
+ help='Skip creating a new branch, use the current one.')
+ parser.add_argument('--no-pull',
+ action='store_true',
+ help='Skip pulling the latest Chromium revision.')
+ parser.add_argument('--no-def',
+ action='store_true',
+ help='Skip regenerating def files.')
+ parser.add_argument('--no-upload',
+ action='store_true',
+ help='Skip uploading the change.')
+ parser.add_argument('--revision',
+ default=None,
+ help='Revision to roll to. The default is the latest.')
+ args = parser.parse_args()
+
+ if os.getcwd().endswith('src') and os.path.exists('chrome/browser'):
+ _Roll(not args.no_branch, not args.no_pull, not args.no_def,
+ not args.no_upload, args.revision)
+ else:
+ logging.error('Run this script from a chromium/src/ directory.')
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 ca14668effd..8cdec919a4f 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_arm64_dbg.def
@@ -36,31 +36,6 @@ EXPORTS
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAPEAVCommandLineFlag@absl@@AEA_N@__Cr@std@@QEAA@AEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@_K$07$02@23@@__Cr@std@@QEAA@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@_K$07$02@45@@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEBQEAVCommandLineFlag@absl@@@__Cr@std@@QEAA@AEBQEAVCommandLineFlag@absl@@@Z
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0AEAPEAPEAVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEAVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAPEBVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEBVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEBVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@_N$0A@@?$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@@QEAA@AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$QEA_N@Z
@@ -119,6 +94,7 @@ EXPORTS
??$?0I@FormatArgImpl@str_format_internal@absl@@QEAA@AEBI@Z
??$?0M@FormatArgImpl@str_format_internal@absl@@QEAA@AEBM@Z
??$?0N@FormatArgImpl@str_format_internal@absl@@QEAA@AEBN@Z
+ ??$?0P6AXPEAX@Z$0A@@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV01234@$0A@@?$pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV12345@@__Cr@std@@QEAA@$$QEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$?0PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU0123@$0A@@?$pair@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU1234@@__Cr@std@@QEAA@$$QEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
@@ -138,10 +114,26 @@ EXPORTS
??$?0PEBD@FormatArgImpl@str_format_internal@absl@@QEAA@AEBQEBD@Z
??$?0PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU0123@$0A@@?$pair@PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@@__Cr@std@@QEAA@$$QEAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$?0PEBVFormatArgImpl@str_format_internal@absl@@$0A@@?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@QEAA@PEBVFormatArgImpl@str_format_internal@1@0AEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$?0U?$__check_pair_construction@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@_K$07$02@23@@__Cr@std@@$0A@@?$pair@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@_K$07$02@23@@__Cr@std@@QEAA@AEBUFindInfo@container_internal@absl@@AEBV?$NonIterableBitMask@_K$07$02@45@@Z
??$?0U?$array@D$0DKJI@@__Cr@std@@XU012@H@?$Span@D@absl@@QEAA@AEAU?$array@D$0DKJI@@__Cr@std@@@Z
+ ??$?0U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0UHex@absl@@X@AlphaNum@absl@@QEAA@AEBUHex@1@$$QEAVStringifySink@strings_internal@1@@Z
??$?0UStringEq@container_internal@absl@@@?$Storage@UStringEq@container_internal@absl@@$01U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAUStringEq@23@@Z
??$?0UStringHash@container_internal@absl@@@?$Storage@UStringHash@container_internal@absl@@$00U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAUStringHash@23@@Z
@@ -192,12 +184,20 @@ EXPORTS
??$?0V?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@XV01@H@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@AEBV?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@1@@Z
??$?0V?$Span@D@absl@@XV01@$0A@@?$Span@$$CBD@absl@@QEAA@AEBV?$Span@D@1@@Z
??$?0V?$Span@I@absl@@XV01@$0A@@?$Span@$$CBI@absl@@QEAA@AEBV?$Span@I@1@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
+ ??$?0V?$__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@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
??$?0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V012@$0A@@?$pair@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V123@@__Cr@std@@QEAA@$$QEAV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@AEA_N$0A@@?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAV?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@AEA_N@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N$0A@@?$pair@V?$__hash_const_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAU?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@@@12@AEA_N@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__hash_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$allocator@D@__Cr@std@@@?$Storage@V?$allocator@D@__Cr@std@@$02U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@D@56@@Z
??$?0V?$allocator@D@__Cr@std@@@AlphaNum@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@?$Storage@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@U?$StorageTag@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@_K@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@PEAUCordRep@cord_internal@absl@@@56@@Z
@@ -335,11 +335,11 @@ EXPORTS
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_backward_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?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@__Cr@std@@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@@12@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@QEBA_NAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@FindElement@?$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@@QEBA?AVconst_iterator@123@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@67@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@67@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@Z
??$?RVDuration@absl@@V01@@?$__less@XX@__Cr@std@@QEBA_NAEBVDuration@absl@@0@Z
??$?RVMixingHashState@hash_internal@absl@@@CombineRaw@hash_internal@absl@@QEBA?AVMixingHashState@12@V312@_K@Z
@@ -410,7 +410,7 @@ EXPORTS
??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AssertHashEqConsistent@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$AssertOnFind@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Assign@V?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@inlined_vector_internal@absl@@@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@12@_K@Z
??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPEAUPayload@status_internal@1@AEAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@01@_K@Z
@@ -461,12 +461,12 @@ EXPORTS
??$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
??$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@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@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
??$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@V?$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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
??$DecomposePair@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@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@01@$$QEAUFindElement@301@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePairImpl@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@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
- ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@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
+ ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@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
??$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
@@ -615,7 +615,7 @@ EXPORTS
??$InvokeFlush@VBufferRawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVBufferRawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeFlush@VFILERawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVFILERawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeGet@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?$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@@@FlagImplPeer@flags_internal@absl@@SA?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@@@12@@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$InvokeParseFlag@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAHPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@M@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAMPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@N@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEANPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
@@ -662,24 +662,39 @@ EXPORTS
??$MakeCheckOpValueString@_K@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_K@Z
??$MakeCheckOpValueString@_N@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_N@Z
??$MakeConstSpan@$SQEAX@absl@@YA?AV?$Span@QEAX@0@PEBQEAX_K@Z
- ??$MakeError@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorFromStringView@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$MakeSpan@$S$$CBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@AEBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@0@@Z
??$MakeSpan@$S$$CBVSourceLocation@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@PEBVSourceLocation@0@_K@Z
??$MakeSpan@$SD@absl@@YA?AV?$Span@D@0@PEAD_K@Z
@@ -855,7 +870,7 @@ EXPORTS
??$TrailingZeros@_K@container_internal@absl@@YAI_K@Z
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
??$Unparse@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@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV?$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@@34@@Z
??$UnparseFlag@H@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBH@Z
@@ -866,11 +881,16 @@ EXPORTS
??$__add_alignment_assumption@PEAPEAVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVCordzHandle@cord_internal@absl@@PEAPEAV345@@Z
??$__add_alignment_assumption@PEAPEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVLogSink@absl@@PEAPEAV34@@Z
??$__add_alignment_assumption@PEAPEBVCommandLineFlag@absl@@$0A@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCommandLineFlag@absl@@PEAPEBV34@@Z
+ ??$__add_alignment_assumption@PEAPEBVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCordzHandle@cord_internal@absl@@PEAPEBV345@@Z
??$__add_alignment_assumption@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransition@cctz@time_internal@absl@@$0A@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransition@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransitionType@cctz@time_internal@absl@@$0A@@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransitionType@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAUUnrecognizedFlag@absl@@PEAU34@@Z
+ ??$__add_alignment_assumption@PEAUViableSubstitution@strings_internal@absl@@$0A@@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUViableSubstitution@strings_internal@absl@@PEAU345@@Z
??$__add_alignment_assumption@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@CAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@PEAV312@@Z
+ ??$__add_alignment_assumption@PEBQEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEBQEAVLogSink@absl@@PEBQEAV34@@Z
+ ??$__add_alignment_assumption@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEBU3456@@Z
+ ??$__add_alignment_assumption@PEBUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEBUUnrecognizedFlag@absl@@PEBU34@@Z
??$__advance@PEBUTransition@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
@@ -967,13 +987,13 @@ 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
??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
??$__construct_at_end@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node_hash@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@@AEAA?AV?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@12@_KAEBQEBUCordRep@cord_internal@absl@@@Z
@@ -1136,7 +1156,7 @@ EXPORTS
??$__in_bounds@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@@@__Cr@std@@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@@@23@$0A@@__unique_ptr_array_bounds_stateless@__Cr@std@@QEBA_NPEAPEAU?$__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@@@12@_K@Z
??$__insert_assign_n_unchecked@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@$0A@@?$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@_JPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@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
- ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$__invoke@AEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAU__identity@__Cr@std@@AEAPEAVLogSink@absl@@@__Cr@std@@YAAEAPEAVLogSink@absl@@AEAU__identity@01@AEAPEAV23@@Z
@@ -1347,8 +1367,8 @@ EXPORTS
??$advance@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@@_J_J$0A@@__Cr@std@@YAXAEAV?$__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@@01@_J@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
@@ -1357,12 +1377,16 @@ EXPORTS
??$apply@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$assign@PEBVSourceLocation@absl@@$0A@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QEAAXPEBVSourceLocation@1@0@Z
??$assign@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@$0A@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
+ ??$begin@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$begin@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$begin@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$bit_cast@PEAXVFastTypeIdType@absl@@@__Cr@std@@YAPEAXAEBVFastTypeIdType@absl@@@Z
??$bit_cast@U?$FlagValueAndInitBit@_N@flags_internal@absl@@_J@__Cr@std@@YA?AU?$FlagValueAndInitBit@_N@flags_internal@absl@@AEB_J@Z
??$bit_cast@VFastTypeIdType@absl@@PEAX@__Cr@std@@YA?AVFastTypeIdType@absl@@AEBQEAX@Z
+ ??$c_begin@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_begin@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
+ ??$c_copy@V?$Span@$$CBI@absl@@PEAI@absl@@YAPEAIAEBV?$Span@$$CBI@0@$$QEAPEAI@Z
+ ??$c_end@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_end@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
??$call_once@A6AXXZ$$V@absl@@YAXAEAVonce_flag@0@A6AXXZ@Z
??$call_once@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@absl@@YAXAEAVonce_flag@0@$$QEAP8FlagImpl@flags_internal@0@EAAXXZ$$QEAPEAV230@@Z
@@ -1509,8 +1533,8 @@ EXPORTS
??$emplace@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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
@@ -1536,6 +1560,7 @@ EXPORTS
??$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
??$emplace_front@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
+ ??$end@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$end@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$end@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$find@V?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@PEAVLogSink@absl@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@01@V201@0AEBQEAVLogSink@absl@@@Z
@@ -1608,7 +1633,7 @@ EXPORTS
??$hash_with_seed@V?$tuple@AEB_K@__Cr@std@@$0A@@MixingHashState@hash_internal@absl@@SA_KAEBV?$tuple@AEB_K@__Cr@std@@_K@Z
??$insert@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$insert@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@@$0A@@?$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@@QEAA?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@Z
- ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$invoke@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@__Cr@std@@YAX$$QEAP8FlagImpl@flags_internal@absl@@EAAXXZ$$QEAPEAV234@@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@AEAPEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@PEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@$$QEAPEAPEAV34@@Z
@@ -1690,6 +1715,9 @@ EXPORTS
??$safe_strtoi_base@K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAKH@Z
??$safe_strtoi_base@_J@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_JH@Z
??$safe_strtoi_base@_K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_KH@Z
+ ??$size@U<unnamed-type-locks>@SynchLocksHeld@absl@@$0CI@@__Cr@std@@YA_KAEAY0CI@$$CBU<unnamed-type-locks>@SynchLocksHeld@absl@@@Z
+ ??$size@UGraphId@synchronization_internal@absl@@$09@__Cr@std@@YA_KAEAY09$$CBUGraphId@synchronization_internal@absl@@@Z
+ ??$size@USpinLockWaitTransition@base_internal@absl@@$02@__Cr@std@@YA_KAEAY02$$CBUSpinLockWaitTransition@base_internal@absl@@@Z
??$swap@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$swap@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@YAXAEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$swap@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@YAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
@@ -1737,8 +1765,8 @@ EXPORTS
??0?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@$0JPOAA@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
- ??0?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
- ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??0?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
+ ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@AEAA@W4InvalidCapacity@012@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@Uuninitialized_tag_t@12@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@_K@Z
@@ -1757,7 +1785,6 @@ EXPORTS
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@inlined_vector_internal@absl@@QEAA@AEBQEBVSourceLocation@2@@Z
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@V?$move_iterator@PEAVSourceLocation@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAVSourceLocation@absl@@@__Cr@std@@@Z
??0?$NonIterableBitMask@_K$07$02@container_internal@absl@@QEAA@_K@Z
- ??0?$PerTableSeedImpl@E@container_internal@absl@@AEAA@_K@Z
??0?$ProbedItemImpl@I$0CA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0EA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0HK@@container_internal@absl@@QEAA@E_K0@Z
@@ -1851,8 +1878,8 @@ EXPORTS
??0?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -1863,32 +1890,32 @@ EXPORTS
??0?$__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@@QEAA@_K0AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@XZ
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@XZ
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__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@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@@AEAA@PEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@12@@Z
@@ -1899,13 +1926,27 @@ EXPORTS
??0?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@QEAA@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@@@12@_N@Z
??0?$__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@@__Cr@std@@QEAA@XZ
??0?$__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@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@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@@QEAA@XZ
??0?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEAVCommandLineFlag@absl@@@Z
??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEAVCordzHandle@cord_internal@absl@@@Z
??0?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@AEAA@PEAPEAVLogSink@absl@@@Z
??0?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEBVCommandLineFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ??0?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@AEAA@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransition@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransitionType@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@AEAA@PEAUUnrecognizedFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@AEAA@PEAUViableSubstitution@strings_internal@absl@@@Z
??0?$__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@@AEAA@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@@12@AEBV567@@Z@@Z
??0?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@AEAA@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@@Z
??0?$__wrap_iter@PEBQEAVLogSink@absl@@@__Cr@std@@AEAA@PEBQEAVLogSink@absl@@@Z
@@ -2078,7 +2119,6 @@ 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@AEBV012@@Z
??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
@@ -2119,6 +2159,7 @@ EXPORTS
??0ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA@PEAV123@@Z
??0Payload@status_internal@absl@@QEAA@$$QEAU012@@Z
??0Payload@status_internal@absl@@QEAA@AEBU012@@Z
+ ??0PerTableSeed@container_internal@absl@@AEAA@_K@Z
??0PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@_KVcrc32c_t@3@@Z
@@ -2128,6 +2169,7 @@ EXPORTS
??0ReaderMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0RefcountAndFlags@cord_internal@absl@@QEAA@XZ
??0RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??0ReleasableMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0Rep@CordBuffer@absl@@QEAA@PEAUCordRepFlat@cord_internal@2@@Z
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
@@ -2192,8 +2234,8 @@ EXPORTS
??0ZoneInfoSource@cctz@time_internal@absl@@QEAA@XZ
??0_ConstructTransaction@?$__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@@QEAA@PEAV123@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV123@AEAU__deque_block_range@123@@Z
??0_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
??0_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
@@ -2272,8 +2314,8 @@ EXPORTS
??1?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -2285,17 +2327,17 @@ EXPORTS
??1?$__policy_func@$$A6A_NAEBVCommandLineFlag@absl@@@Z@__function@__Cr@std@@QEAA@XZ
??1?$__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@@QEAA@XZ
??1?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__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@XZ
@@ -2390,6 +2432,7 @@ EXPORTS
??1PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??1ReaderMutexLock@absl@@QEAA@XZ
??1RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??1ReleasableMutexLock@absl@@QEAA@XZ
??1Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??1Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
??1Rep@StatusBuilder@absl@@QEAA@XZ
@@ -2416,8 +2459,8 @@ EXPORTS
??1ZoneInfoSource@cctz@time_internal@absl@@UEAA@XZ
??1_ConstructTransaction@?$__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@@QEAA@XZ
??1_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
@@ -2443,7 +2486,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4FlagsUsageConfig@absl@@QEAAAEAU01@AEBU01@@Z
??4HiRep@Duration@absl@@QEAAAEAV012@_J@Z
- ??4InlineData@cord_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4InlineRep@Cord@absl@@QEAAAEAV012@$$QEAV012@@Z
??4Payload@status_internal@absl@@QEAAAEAU012@$$QEAU012@@Z
??4Rep@CrcCordState@crc_internal@absl@@QEAAAEAU0123@AEBU0123@@Z
@@ -2552,6 +2594,17 @@ EXPORTS
??A?$Span@D@absl@@QEBAAEAD_K@Z
??A?$Span@I@absl@@QEBAAEAI_K@Z
??A?$__farray@P6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@__Cr@std@@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@456@@Z$03@__Cr@std@@QEBAAEBQ6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@12@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@612@@Z_K@Z
+ ??A?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEAVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEAVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@QEBAAEAPEAVLogSink@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEBVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEBVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@QEBAAEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransition@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransitionType@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@QEBAAEAUUnrecognizedFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@QEBAAEAUViableSubstitution@strings_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEBAAEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@_J@Z
??A?$array@Uraw_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@$0BA@@__Cr@std@@QEAAAEAUraw_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@@12@AEBV567@@Z@_K@Z
??A?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
??A?$map@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@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?$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@@QEAAAEAV?$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@@12@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
@@ -2598,6 +2651,7 @@ EXPORTS
??C?$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@@QEBAPEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
??C?$__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@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__hash_map_const_iterator@V?$__hash_const_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@@@__Cr@std@@QEBAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
+ ??C?$__hash_map_iterator@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@@@__Cr@std@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAPEAPEAVCommandLineFlag@absl@@XZ
@@ -2791,7 +2845,7 @@ EXPORTS
??R?$HashImpl@H@hash_internal@absl@@QEBA_KAEBH@Z
??R?$HashImpl@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@Z
??R?$HashImpl@V?$tuple@AEB_K@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEB_K@__Cr@std@@@Z
- ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEBA_K_K@Z
+ ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEBA_K_K@Z
??R?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??R?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??R?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@@Z
@@ -3218,6 +3272,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DisableRescheduling@SchedulingGuard@base_internal@absl@@SA_NXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@AEBAP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@ZXZ
@@ -3714,6 +3769,7 @@ EXPORTS
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
?IsHeld@SpinLock@base_internal@absl@@QEBA_NXZ
?IsImmortal@RefcountAndFlags@cord_internal@absl@@QEBA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInfiniteDuration@time_internal@absl@@YA_NVDuration@2@@Z
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInlined@Status@absl@@CA_N_K@Z
@@ -3878,7 +3934,7 @@ EXPORTS
?NextCapacity@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@SA_K_K@Z
?NextCapacity@container_internal@absl@@YA_K_K@Z
?NextGeneration@container_internal@absl@@YAEE@Z
- ?NextHashTableSeed@container_internal@absl@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextRandom@ExponentialBiased@profiling_internal@absl@@SA_K_K@Z
?NextTransition@Impl@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@2345@@Z
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -4100,7 +4156,6 @@ EXPORTS
?SentinelEmptyGeneration@container_internal@absl@@YAEXZ
?Set@?$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@@AEAAXAEBV?$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@@@Z
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAllocation@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@23@@Z
@@ -4348,6 +4403,7 @@ EXPORTS
?ToInt64Nanoseconds@absl@@YA_JVDuration@1@@Z
?ToInt64Seconds@absl@@YA_JVDuration@1@@Z
?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
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
@@ -4502,6 +4558,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithSourceLocation@Status@absl@@QEHAA$$QEAV12@VSourceLocation@2@@Z
@@ -4522,8 +4579,41 @@ EXPORTS
?__addr@?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
?__alloc@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$__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@@@__Cr@std@@QEAAAEAV?$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@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@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?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__alloc@?$__vector_layout@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@@QEBAAEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@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@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
@@ -4535,13 +4625,21 @@ EXPORTS
?__annotate_contiguous_container@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$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@@AEBAXPEBX0@Z
+ ?__annotate_delete@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@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@@AEBAXXZ
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
@@ -4560,19 +4658,19 @@ EXPORTS
?__annotate_increase@?$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@@AEBAX_K@Z
?__annotate_increase_back@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_increase_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@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@@AEBAX_K@Z
?__annotate_new@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_new@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$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@@AEBAX_K@Z
?__annotate_poison_block@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_shrink@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_shrink@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
@@ -4591,8 +4689,8 @@ EXPORTS
?__as_base@?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__variant_detail@__Cr@std@@IEGAA@XZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -4607,17 +4705,56 @@ EXPORTS
?__base_destruct_at_end@?$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@@AEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
+ ?__begin_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__capacity@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@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@@QEBA_KXZ
?__capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__complete@?$__exception_guard_noexceptions@V<lambda_1>@?0??__add_back_capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z@@__Cr@std@@QEAAXXZ
?__complete@?$__exception_guard_noexceptions@V?$_AllocatorDestroyRangeReverse@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@PEAUUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?__compose@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@PEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAU5678@@Z
- ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
- ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@U?$integral_constant@_N$0A@@23@@Z
+ ?__data@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__data@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUViableSubstitution@strings_internal@absl@@XZ
+ ?__data@?$__vector_layout@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@@QEBAPEBV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__deallocate_node@?$__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@@AEAAXPEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@23@@Z
?__deallocate_node@?$__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@@AEAAXPEAU?$__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@23@@Z
?__deallocate_node_list@?$__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@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@@Z
@@ -4630,28 +4767,28 @@ EXPORTS
?__destruct_at_end@?$__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@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAPEAVLogSink@absl@@@Z
?__destruct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@@Z
?__destruct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
@@ -4662,40 +4799,53 @@ EXPORTS
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEAAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__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
?__front_cap@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__get@?$__optional_storage_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEGAAAEAVStream@status_internal@absl@@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__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@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_value@?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@QEAAAEAPEBUCordRep@cord_internal@absl@@XZ
@@ -4713,11 +4863,14 @@ EXPORTS
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@PEAPEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBQEAVLogSink@absl@@@23@PEBQEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@PEAPEBVCommandLineFlag@absl@@@Z
+ ?__make_iter@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@PEAUUnrecognizedFlag@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@PEBUUnrecognizedFlag@absl@@@Z
+ ?__make_iter@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@PEAUViableSubstitution@strings_internal@absl@@@Z
?__make_iter@?$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@@AEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@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
@@ -4742,6 +4895,32 @@ EXPORTS
?__recommend_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SA_K_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@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@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
+ ?__relocate@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@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@@QEAAXAEAV?$__split_buffer@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@V__split_buffer_size_layout@23@@23@@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@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
?__rewrap@?$__unwrap_iter_impl@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$00@__Cr@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV45678@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@$00@__Cr@std@@SAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU4567@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAVLogSink@absl@@$00@__Cr@std@@SAPEAPEAVLogSink@absl@@PEAPEAV45@0@Z
@@ -4758,105 +4937,104 @@ EXPORTS
?__root_ptr@?$__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@@QEBAPEAPEAV?$__tree_node_base@PEAX@23@XZ
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@23@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@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@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__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@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__size@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@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@@QEBA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAUUnrecognizedFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@00@Z
- ?__swap_layouts@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
+ ?__swap@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__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
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
?__swap_without_allocator@?$__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@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__throw_length_error@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -4955,10 +5133,17 @@ EXPORTS
?back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@XZ
?back@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
+ ?back@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?back@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@XZ
+ ?back@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCordzHandle@cord_internal@absl@@XZ
?back@?$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@@XZ
?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?back@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?back@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@XZ
?back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@XZ
+ ?back@?$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@@@23@XZ
?back@CordRepBtree@cord_internal@absl@@QEBA_KXZ
?base@?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?base@?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
@@ -4981,17 +5166,17 @@ EXPORTS
?begin@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?begin@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$array@Uraw_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@$0BA@@__Cr@std@@QEAA?AV?$__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@XZ
@@ -5031,17 +5216,17 @@ EXPORTS
?capacity@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$HashtableCapacityImpl@$00@23@XZ
?capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__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@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$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@@QEBA_KXZ
?capacity@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?capacity@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -5070,17 +5255,17 @@ EXPORTS
?clear@?$__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@@QEAAXXZ
?clear@?$__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@@QEAAXXZ
?clear@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__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
+ ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXXZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?clear@?$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@@QEAAXXZ
?clear@?$unordered_map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@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@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@@QEAAXXZ
@@ -5248,6 +5433,11 @@ EXPORTS
?empty@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$map@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@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?$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@@QEBA_NXZ
?empty@?$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@@QEBA_NXZ
+ ?empty@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
@@ -5273,17 +5463,17 @@ EXPORTS
?end@?$__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?AV?$__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@@@23@XZ
?end@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?end@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@23@XZ
@@ -5297,11 +5487,14 @@ EXPORTS
?end@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@23@XZ
?end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@XZ
?end@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@XZ
+ ?end@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$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@@@23@XZ
?end@?$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@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@XZ
+ ?end@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@XZ
?end@?$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@@QEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?end@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ
?end@CordRepBtree@cord_internal@absl@@QEBA_KXZ
@@ -5589,8 +5782,6 @@ EXPORTS
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@PEBU?$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@@@__Cr@std@@SAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@AEBU423@@Z
- ?poison@InlineData@cord_internal@absl@@QEAAXXZ
- ?poison_this@InlineData@cord_internal@absl@@QEAAXXZ
?pop_back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAXXZ
?pop_back@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
@@ -5691,11 +5882,9 @@ EXPORTS
?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?second@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
- ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?seed@?$PerTableSeedImpl@E@container_internal@absl@@QEBA_KXZ
- ?seed@CommonFields@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEAAPEAU1234@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEBAPEBU1234@XZ
+ ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@CommonFields@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@PerTableSeed@container_internal@absl@@QEBA_KXZ
?set@?$MaybeInitializedPtr@W4ctrl_t@container_internal@absl@@@container_internal@absl@@QEAAXPEAW4ctrl_t@23@@Z
?set_arg@BoundConversion@str_format_internal@absl@@QEAAXPEBVFormatArgImpl@23@@Z
?set_begin@CordRepBtree@cord_internal@absl@@AEAAX_K@Z
@@ -5854,7 +6043,6 @@ EXPORTS
?unlock@Mutex@absl@@QEAAXXZ
?unlock@SpinLock@base_internal@absl@@QEAAXXZ
?unlock_shared@Mutex@absl@@QEAAXXZ
- ?unpoison@InlineData@cord_internal@absl@@QEAAXXZ
?utc_time_zone@cctz@time_internal@absl@@YA?AVtime_zone@123@XZ
?value@ConvertibleToStringView@strings_internal@absl@@QEBA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?value@InputValue@UnboundConversion@str_format_internal@absl@@QEBAHXZ
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 e405204c578..23eb95d92cc 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
@@ -36,31 +36,6 @@ EXPORTS
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAPEAVCommandLineFlag@absl@@AEA_N@__Cr@std@@QEAA@AEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@_K$07$02@23@@__Cr@std@@QEAA@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@_K$07$02@45@@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEBQEAVCommandLineFlag@absl@@@__Cr@std@@QEAA@AEBQEAVCommandLineFlag@absl@@@Z
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0AEAPEAPEAVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEAVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAPEBVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEBVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEBVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@_N$0A@@?$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@@QEAA@AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$QEA_N@Z
@@ -119,6 +94,7 @@ EXPORTS
??$?0I@FormatArgImpl@str_format_internal@absl@@QEAA@AEBI@Z
??$?0M@FormatArgImpl@str_format_internal@absl@@QEAA@AEBM@Z
??$?0N@FormatArgImpl@str_format_internal@absl@@QEAA@AEBN@Z
+ ??$?0P6AXPEAX@Z$0A@@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV01234@$0A@@?$pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV12345@@__Cr@std@@QEAA@$$QEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$?0PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU0123@$0A@@?$pair@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU1234@@__Cr@std@@QEAA@$$QEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
@@ -138,9 +114,25 @@ EXPORTS
??$?0PEBD@FormatArgImpl@str_format_internal@absl@@QEAA@AEBQEBD@Z
??$?0PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU0123@$0A@@?$pair@PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@@__Cr@std@@QEAA@$$QEAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$?0PEBVFormatArgImpl@str_format_internal@absl@@$0A@@?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@QEAA@PEBVFormatArgImpl@str_format_internal@1@0AEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$?0U?$array@D$0DKJI@@__Cr@std@@XU012@H@?$Span@D@absl@@QEAA@AEAU?$array@D$0DKJI@@__Cr@std@@@Z
+ ??$?0U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0UFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@_K$07$02@12@$0A@@?$pair@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@_K$07$02@23@@__Cr@std@@QEAA@$$QEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@_K$07$02@45@@Z
??$?0UHex@absl@@X@AlphaNum@absl@@QEAA@AEBUHex@1@$$QEAVStringifySink@strings_internal@1@@Z
??$?0UStringEq@container_internal@absl@@@?$Storage@UStringEq@container_internal@absl@@$01U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAUStringEq@23@@Z
@@ -192,12 +184,20 @@ EXPORTS
??$?0V?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@XV01@H@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@AEBV?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@1@@Z
??$?0V?$Span@D@absl@@XV01@$0A@@?$Span@$$CBD@absl@@QEAA@AEBV?$Span@D@1@@Z
??$?0V?$Span@I@absl@@XV01@$0A@@?$Span@$$CBI@absl@@QEAA@AEBV?$Span@I@1@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
+ ??$?0V?$__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@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
??$?0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V012@$0A@@?$pair@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V123@@__Cr@std@@QEAA@$$QEAV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@AEA_N$0A@@?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAV?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@AEA_N@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N$0A@@?$pair@V?$__hash_const_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAU?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@@@12@AEA_N@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__hash_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$allocator@D@__Cr@std@@@?$Storage@V?$allocator@D@__Cr@std@@$02U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@D@56@@Z
??$?0V?$allocator@D@__Cr@std@@@AlphaNum@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@?$Storage@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@U?$StorageTag@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@_K@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@PEAUCordRep@cord_internal@absl@@@56@@Z
@@ -335,11 +335,11 @@ EXPORTS
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_backward_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?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@__Cr@std@@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@@12@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@QEBA_NAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@FindElement@?$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@@QEBA?AVconst_iterator@123@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@67@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@67@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@Z
??$?RVDuration@absl@@V01@@?$__less@XX@__Cr@std@@QEBA_NAEBVDuration@absl@@0@Z
??$?RVMixingHashState@hash_internal@absl@@@CombineRaw@hash_internal@absl@@QEBA?AVMixingHashState@12@V312@_K@Z
@@ -410,7 +410,7 @@ EXPORTS
??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AssertHashEqConsistent@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$AssertOnFind@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Assign@V?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@inlined_vector_internal@absl@@@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@12@_K@Z
??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPEAUPayload@status_internal@1@AEAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@01@_K@Z
@@ -461,12 +461,12 @@ EXPORTS
??$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
??$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@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@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
??$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@V?$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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
??$DecomposePair@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@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@01@$$QEAUFindElement@301@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePairImpl@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@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
- ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@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
+ ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@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
??$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
@@ -615,7 +615,7 @@ EXPORTS
??$InvokeFlush@VBufferRawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVBufferRawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeFlush@VFILERawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVFILERawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeGet@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?$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@@@FlagImplPeer@flags_internal@absl@@SA?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@@@12@@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$InvokeParseFlag@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAHPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@M@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAMPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@N@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEANPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
@@ -662,24 +662,39 @@ EXPORTS
??$MakeCheckOpValueString@_K@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_K@Z
??$MakeCheckOpValueString@_N@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_N@Z
??$MakeConstSpan@$SQEAX@absl@@YA?AV?$Span@QEAX@0@PEBQEAX_K@Z
- ??$MakeError@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorFromStringView@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$MakeSpan@$S$$CBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@AEBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@0@@Z
??$MakeSpan@$S$$CBVSourceLocation@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@PEBVSourceLocation@0@_K@Z
??$MakeSpan@$SD@absl@@YA?AV?$Span@D@0@PEAD_K@Z
@@ -848,7 +863,7 @@ EXPORTS
??$TrailingZeros@_K@container_internal@absl@@YAI_K@Z
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
??$Unparse@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@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV?$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@@34@@Z
??$UnparseFlag@H@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBH@Z
@@ -859,11 +874,16 @@ EXPORTS
??$__add_alignment_assumption@PEAPEAVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVCordzHandle@cord_internal@absl@@PEAPEAV345@@Z
??$__add_alignment_assumption@PEAPEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVLogSink@absl@@PEAPEAV34@@Z
??$__add_alignment_assumption@PEAPEBVCommandLineFlag@absl@@$0A@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCommandLineFlag@absl@@PEAPEBV34@@Z
+ ??$__add_alignment_assumption@PEAPEBVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCordzHandle@cord_internal@absl@@PEAPEBV345@@Z
??$__add_alignment_assumption@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransition@cctz@time_internal@absl@@$0A@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransition@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransitionType@cctz@time_internal@absl@@$0A@@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransitionType@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAUUnrecognizedFlag@absl@@PEAU34@@Z
+ ??$__add_alignment_assumption@PEAUViableSubstitution@strings_internal@absl@@$0A@@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUViableSubstitution@strings_internal@absl@@PEAU345@@Z
??$__add_alignment_assumption@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@CAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@PEAV312@@Z
+ ??$__add_alignment_assumption@PEBQEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEBQEAVLogSink@absl@@PEBQEAV34@@Z
+ ??$__add_alignment_assumption@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEBU3456@@Z
+ ??$__add_alignment_assumption@PEBUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEBUUnrecognizedFlag@absl@@PEBU34@@Z
??$__advance@PEBUTransition@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
@@ -960,13 +980,13 @@ 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
??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
??$__construct_at_end@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node_hash@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@@AEAA?AV?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@12@_KAEBQEBUCordRep@cord_internal@absl@@@Z
@@ -1129,7 +1149,7 @@ EXPORTS
??$__in_bounds@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@@@__Cr@std@@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@@@23@$0A@@__unique_ptr_array_bounds_stateless@__Cr@std@@QEBA_NPEAPEAU?$__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@@@12@_K@Z
??$__insert_assign_n_unchecked@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@$0A@@?$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@_JPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@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
- ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$__invoke@AEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAU__identity@__Cr@std@@AEAPEAVLogSink@absl@@@__Cr@std@@YAAEAPEAVLogSink@absl@@AEAU__identity@01@AEAPEAV23@@Z
@@ -1353,8 +1373,8 @@ EXPORTS
??$allocate_at_least@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@@?$allocator_traits@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@SA?AU?$allocation_result@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@_K@12@AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@_K@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
@@ -1363,12 +1383,16 @@ EXPORTS
??$apply@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$assign@PEBVSourceLocation@absl@@$0A@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QEAAXPEBVSourceLocation@1@0@Z
??$assign@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@$0A@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
+ ??$begin@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$begin@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$begin@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$bit_cast@PEAXVFastTypeIdType@absl@@@__Cr@std@@YAPEAXAEBVFastTypeIdType@absl@@@Z
??$bit_cast@U?$FlagValueAndInitBit@_N@flags_internal@absl@@_J@__Cr@std@@YA?AU?$FlagValueAndInitBit@_N@flags_internal@absl@@AEB_J@Z
??$bit_cast@VFastTypeIdType@absl@@PEAX@__Cr@std@@YA?AVFastTypeIdType@absl@@AEBQEAX@Z
+ ??$c_begin@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_begin@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
+ ??$c_copy@V?$Span@$$CBI@absl@@PEAI@absl@@YAPEAIAEBV?$Span@$$CBI@0@$$QEAPEAI@Z
+ ??$c_end@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_end@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
??$call_once@A6AXXZ$$V@absl@@YAXAEAVonce_flag@0@A6AXXZ@Z
??$call_once@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@absl@@YAXAEAVonce_flag@0@$$QEAP8FlagImpl@flags_internal@0@EAAXXZ$$QEAPEAV230@@Z
@@ -1515,8 +1539,8 @@ EXPORTS
??$emplace@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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
@@ -1542,6 +1566,7 @@ EXPORTS
??$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
??$emplace_front@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
+ ??$end@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$end@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$end@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$find@V?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@PEAVLogSink@absl@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@01@V201@0AEBQEAVLogSink@absl@@@Z
@@ -1614,7 +1639,7 @@ EXPORTS
??$hash_with_seed@V?$tuple@AEB_K@__Cr@std@@$0A@@MixingHashState@hash_internal@absl@@SA_KAEBV?$tuple@AEB_K@__Cr@std@@_K@Z
??$insert@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$insert@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@@$0A@@?$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@@QEAA?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@Z
- ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$invoke@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@__Cr@std@@YAX$$QEAP8FlagImpl@flags_internal@absl@@EAAXXZ$$QEAPEAV234@@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@AEAPEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@PEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@$$QEAPEAPEAV34@@Z
@@ -1703,6 +1728,9 @@ EXPORTS
??$safe_strtoi_base@K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAKH@Z
??$safe_strtoi_base@_J@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_JH@Z
??$safe_strtoi_base@_K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_KH@Z
+ ??$size@U<unnamed-type-locks>@SynchLocksHeld@absl@@$0CI@@__Cr@std@@YA_KAEAY0CI@$$CBU<unnamed-type-locks>@SynchLocksHeld@absl@@@Z
+ ??$size@UGraphId@synchronization_internal@absl@@$09@__Cr@std@@YA_KAEAY09$$CBUGraphId@synchronization_internal@absl@@@Z
+ ??$size@USpinLockWaitTransition@base_internal@absl@@$02@__Cr@std@@YA_KAEAY02$$CBUSpinLockWaitTransition@base_internal@absl@@@Z
??$swap@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$swap@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@YAXAEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$swap@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@YAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
@@ -1750,8 +1778,8 @@ EXPORTS
??0?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@$0JPOAA@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
- ??0?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
- ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??0?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
+ ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@AEAA@W4InvalidCapacity@012@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@Uuninitialized_tag_t@12@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@_K@Z
@@ -1770,7 +1798,6 @@ EXPORTS
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@inlined_vector_internal@absl@@QEAA@AEBQEBVSourceLocation@2@@Z
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@V?$move_iterator@PEAVSourceLocation@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAVSourceLocation@absl@@@__Cr@std@@@Z
??0?$NonIterableBitMask@_K$07$02@container_internal@absl@@QEAA@_K@Z
- ??0?$PerTableSeedImpl@E@container_internal@absl@@AEAA@_K@Z
??0?$ProbedItemImpl@I$0CA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0EA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0HK@@container_internal@absl@@QEAA@E_K0@Z
@@ -1864,8 +1891,8 @@ EXPORTS
??0?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -1876,32 +1903,32 @@ EXPORTS
??0?$__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@@QEAA@_K0AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@XZ
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@XZ
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__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@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@@AEAA@PEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@12@@Z
@@ -1912,13 +1939,27 @@ EXPORTS
??0?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@QEAA@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@@@12@_N@Z
??0?$__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@@__Cr@std@@QEAA@XZ
??0?$__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@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@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@@QEAA@XZ
??0?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEAVCommandLineFlag@absl@@@Z
??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEAVCordzHandle@cord_internal@absl@@@Z
??0?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@AEAA@PEAPEAVLogSink@absl@@@Z
??0?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEBVCommandLineFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ??0?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@AEAA@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransition@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransitionType@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@AEAA@PEAUUnrecognizedFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@AEAA@PEAUViableSubstitution@strings_internal@absl@@@Z
??0?$__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@@AEAA@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@@12@AEBV567@@Z@@Z
??0?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@AEAA@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@@Z
??0?$__wrap_iter@PEBQEAVLogSink@absl@@@__Cr@std@@AEAA@PEBQEAVLogSink@absl@@@Z
@@ -2091,7 +2132,6 @@ 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@AEBV012@@Z
??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
@@ -2132,6 +2172,7 @@ EXPORTS
??0ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA@PEAV123@@Z
??0Payload@status_internal@absl@@QEAA@$$QEAU012@@Z
??0Payload@status_internal@absl@@QEAA@AEBU012@@Z
+ ??0PerTableSeed@container_internal@absl@@AEAA@_K@Z
??0PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@_KVcrc32c_t@3@@Z
@@ -2141,6 +2182,7 @@ EXPORTS
??0ReaderMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0RefcountAndFlags@cord_internal@absl@@QEAA@XZ
??0RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??0ReleasableMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0Rep@CordBuffer@absl@@QEAA@PEAUCordRepFlat@cord_internal@2@@Z
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
@@ -2205,8 +2247,8 @@ EXPORTS
??0ZoneInfoSource@cctz@time_internal@absl@@QEAA@XZ
??0_ConstructTransaction@?$__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@@QEAA@PEAV123@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV123@AEAU__deque_block_range@123@@Z
??0_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
??0_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
@@ -2285,8 +2327,8 @@ EXPORTS
??1?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -2298,17 +2340,17 @@ EXPORTS
??1?$__policy_func@$$A6A_NAEBVCommandLineFlag@absl@@@Z@__function@__Cr@std@@QEAA@XZ
??1?$__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@@QEAA@XZ
??1?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__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@XZ
@@ -2403,6 +2445,7 @@ EXPORTS
??1PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??1ReaderMutexLock@absl@@QEAA@XZ
??1RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??1ReleasableMutexLock@absl@@QEAA@XZ
??1Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??1Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
??1Rep@StatusBuilder@absl@@QEAA@XZ
@@ -2429,8 +2472,8 @@ EXPORTS
??1ZoneInfoSource@cctz@time_internal@absl@@UEAA@XZ
??1_ConstructTransaction@?$__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@@QEAA@XZ
??1_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
@@ -2456,7 +2499,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4FlagsUsageConfig@absl@@QEAAAEAU01@AEBU01@@Z
??4HiRep@Duration@absl@@QEAAAEAV012@_J@Z
- ??4InlineData@cord_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4InlineRep@Cord@absl@@QEAAAEAV012@$$QEAV012@@Z
??4Payload@status_internal@absl@@QEAAAEAU012@$$QEAU012@@Z
??4Rep@CrcCordState@crc_internal@absl@@QEAAAEAU0123@AEBU0123@@Z
@@ -2565,6 +2607,17 @@ EXPORTS
??A?$Span@D@absl@@QEBAAEAD_K@Z
??A?$Span@I@absl@@QEBAAEAI_K@Z
??A?$__farray@P6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@__Cr@std@@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@456@@Z$03@__Cr@std@@QEBAAEBQ6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@12@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@612@@Z_K@Z
+ ??A?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEAVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEAVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@QEBAAEAPEAVLogSink@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEBVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEBVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@QEBAAEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransition@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransitionType@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@QEBAAEAUUnrecognizedFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@QEBAAEAUViableSubstitution@strings_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEBAAEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@_J@Z
??A?$array@Uraw_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@$0BA@@__Cr@std@@QEAAAEAUraw_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@@12@AEBV567@@Z@_K@Z
??A?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
??A?$map@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@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?$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@@QEAAAEAV?$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@@12@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
@@ -2611,6 +2664,7 @@ EXPORTS
??C?$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@@QEBAPEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
??C?$__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@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__hash_map_const_iterator@V?$__hash_const_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@@@__Cr@std@@QEBAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
+ ??C?$__hash_map_iterator@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@@@__Cr@std@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAPEAPEAVCommandLineFlag@absl@@XZ
@@ -2804,7 +2858,7 @@ EXPORTS
??R?$HashImpl@H@hash_internal@absl@@QEBA_KAEBH@Z
??R?$HashImpl@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@Z
??R?$HashImpl@V?$tuple@AEB_K@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEB_K@__Cr@std@@@Z
- ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEBA_K_K@Z
+ ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEBA_K_K@Z
??R?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??R?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??R?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@@Z
@@ -3231,6 +3285,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DisableRescheduling@SchedulingGuard@base_internal@absl@@SA_NXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@AEBAP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@ZXZ
@@ -3726,6 +3781,7 @@ EXPORTS
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
?IsHeld@SpinLock@base_internal@absl@@QEBA_NXZ
?IsImmortal@RefcountAndFlags@cord_internal@absl@@QEBA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInfiniteDuration@time_internal@absl@@YA_NVDuration@2@@Z
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInlined@Status@absl@@CA_N_K@Z
@@ -3890,7 +3946,7 @@ EXPORTS
?NextCapacity@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@SA_K_K@Z
?NextCapacity@container_internal@absl@@YA_K_K@Z
?NextGeneration@container_internal@absl@@YAEE@Z
- ?NextHashTableSeed@container_internal@absl@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextRandom@ExponentialBiased@profiling_internal@absl@@SA_K_K@Z
?NextTransition@Impl@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@2345@@Z
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -4112,7 +4168,6 @@ EXPORTS
?SentinelEmptyGeneration@container_internal@absl@@YAEXZ
?Set@?$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@@AEAAXAEBV?$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@@@Z
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAllocation@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@23@@Z
@@ -4360,6 +4415,7 @@ EXPORTS
?ToInt64Nanoseconds@absl@@YA_JVDuration@1@@Z
?ToInt64Seconds@absl@@YA_JVDuration@1@@Z
?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
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
@@ -4514,6 +4570,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithSourceLocation@Status@absl@@QEHAA$$QEAV12@VSourceLocation@2@@Z
@@ -4534,8 +4591,41 @@ EXPORTS
?__addr@?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
?__alloc@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$__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@@@__Cr@std@@QEAAAEAV?$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@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@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?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__alloc@?$__vector_layout@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@@QEBAAEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@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@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
@@ -4547,13 +4637,21 @@ EXPORTS
?__annotate_contiguous_container@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$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@@AEBAXPEBX0@Z
+ ?__annotate_delete@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@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@@AEBAXXZ
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
@@ -4572,19 +4670,19 @@ EXPORTS
?__annotate_increase@?$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@@AEBAX_K@Z
?__annotate_increase_back@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_increase_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@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@@AEBAX_K@Z
?__annotate_new@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_new@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$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@@AEBAX_K@Z
?__annotate_poison_block@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_shrink@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_shrink@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
@@ -4603,8 +4701,8 @@ EXPORTS
?__as_base@?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__variant_detail@__Cr@std@@IEGAA@XZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -4619,17 +4717,56 @@ EXPORTS
?__base_destruct_at_end@?$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@@AEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
+ ?__begin_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__capacity@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@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@@QEBA_KXZ
?__capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__complete@?$__exception_guard_noexceptions@V<lambda_1>@?0??__add_back_capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z@@__Cr@std@@QEAAXXZ
?__complete@?$__exception_guard_noexceptions@V?$_AllocatorDestroyRangeReverse@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@PEAUUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?__compose@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@PEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAU5678@@Z
- ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
- ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@U?$integral_constant@_N$0A@@23@@Z
+ ?__data@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__data@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUViableSubstitution@strings_internal@absl@@XZ
+ ?__data@?$__vector_layout@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@@QEBAPEBV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__deallocate_node@?$__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@@AEAAXPEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@23@@Z
?__deallocate_node@?$__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@@AEAAXPEAU?$__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@23@@Z
?__deallocate_node_list@?$__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@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@@Z
@@ -4642,28 +4779,28 @@ EXPORTS
?__destruct_at_end@?$__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@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAPEAVLogSink@absl@@@Z
?__destruct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@@Z
?__destruct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
@@ -4674,40 +4811,53 @@ EXPORTS
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEAAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__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
?__front_cap@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__get@?$__optional_storage_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEGAAAEAVStream@status_internal@absl@@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__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@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_value@?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@QEAAAEAPEBUCordRep@cord_internal@absl@@XZ
@@ -4725,11 +4875,14 @@ EXPORTS
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@PEAPEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBQEAVLogSink@absl@@@23@PEBQEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@PEAPEBVCommandLineFlag@absl@@@Z
+ ?__make_iter@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@PEAUUnrecognizedFlag@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@PEBUUnrecognizedFlag@absl@@@Z
+ ?__make_iter@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@PEAUViableSubstitution@strings_internal@absl@@@Z
?__make_iter@?$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@@AEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@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
@@ -4754,6 +4907,32 @@ EXPORTS
?__recommend_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SA_K_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@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@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
+ ?__relocate@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@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@@QEAAXAEAV?$__split_buffer@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@V__split_buffer_size_layout@23@@23@@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@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
?__rewrap@?$__unwrap_iter_impl@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$00@__Cr@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV45678@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@$00@__Cr@std@@SAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU4567@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAVLogSink@absl@@$00@__Cr@std@@SAPEAPEAVLogSink@absl@@PEAPEAV45@0@Z
@@ -4770,105 +4949,104 @@ EXPORTS
?__root_ptr@?$__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@@QEBAPEAPEAV?$__tree_node_base@PEAX@23@XZ
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@23@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@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@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__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@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__size@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@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@@QEBA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAUUnrecognizedFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@00@Z
- ?__swap_layouts@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
+ ?__swap@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__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
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
?__swap_without_allocator@?$__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@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__throw_length_error@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -4980,10 +5158,17 @@ EXPORTS
?back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@XZ
?back@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
+ ?back@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?back@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@XZ
+ ?back@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCordzHandle@cord_internal@absl@@XZ
?back@?$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@@XZ
?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?back@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?back@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@XZ
?back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@XZ
+ ?back@?$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@@@23@XZ
?back@CordRepBtree@cord_internal@absl@@QEBA_KXZ
?base@?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?base@?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
@@ -5006,17 +5191,17 @@ EXPORTS
?begin@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?begin@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$array@Uraw_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@$0BA@@__Cr@std@@QEAA?AV?$__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@XZ
@@ -5056,17 +5241,17 @@ EXPORTS
?capacity@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$HashtableCapacityImpl@$00@23@XZ
?capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__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@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$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@@QEBA_KXZ
?capacity@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?capacity@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -5095,17 +5280,17 @@ EXPORTS
?clear@?$__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@@QEAAXXZ
?clear@?$__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@@QEAAXXZ
?clear@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__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
+ ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXXZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?clear@?$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@@QEAAXXZ
?clear@?$unordered_map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@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@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@@QEAAXXZ
@@ -5273,6 +5458,11 @@ EXPORTS
?empty@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$map@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@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?$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@@QEBA_NXZ
?empty@?$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@@QEBA_NXZ
+ ?empty@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
@@ -5298,17 +5488,17 @@ EXPORTS
?end@?$__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?AV?$__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@@@23@XZ
?end@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?end@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@23@XZ
@@ -5322,11 +5512,14 @@ EXPORTS
?end@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@23@XZ
?end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@XZ
?end@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@XZ
+ ?end@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$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@@@23@XZ
?end@?$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@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@XZ
+ ?end@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@XZ
?end@?$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@@QEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?end@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ
?end@CordRepBtree@cord_internal@absl@@QEBA_KXZ
@@ -5614,8 +5807,6 @@ EXPORTS
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@PEBU?$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@@@__Cr@std@@SAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@AEBU423@@Z
- ?poison@InlineData@cord_internal@absl@@QEAAXXZ
- ?poison_this@InlineData@cord_internal@absl@@QEAAXXZ
?pop_back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAXXZ
?pop_back@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
@@ -5716,11 +5907,9 @@ EXPORTS
?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?second@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
- ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?seed@?$PerTableSeedImpl@E@container_internal@absl@@QEBA_KXZ
- ?seed@CommonFields@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEAAPEAU1234@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEBAPEBU1234@XZ
+ ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@CommonFields@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@PerTableSeed@container_internal@absl@@QEBA_KXZ
?set@?$MaybeInitializedPtr@W4ctrl_t@container_internal@absl@@@container_internal@absl@@QEAAXPEAW4ctrl_t@23@@Z
?set_arg@BoundConversion@str_format_internal@absl@@QEAAXPEBVFormatArgImpl@23@@Z
?set_begin@CordRepBtree@cord_internal@absl@@AEAAX_K@Z
@@ -5879,7 +6068,6 @@ EXPORTS
?unlock@Mutex@absl@@QEAAXXZ
?unlock@SpinLock@base_internal@absl@@QEAAXXZ
?unlock_shared@Mutex@absl@@QEAAXXZ
- ?unpoison@InlineData@cord_internal@absl@@QEAAXXZ
?utc_time_zone@cctz@time_internal@absl@@YA?AVtime_zone@123@XZ
?value@ConvertibleToStringView@strings_internal@absl@@QEBA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?value@InputValue@UnboundConversion@str_format_internal@absl@@QEBAHXZ
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 408a5f352e3..50ecaf35082 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_arm64_rel.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_arm64_rel.def
@@ -1,6 +1,7 @@
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
@@ -111,7 +112,7 @@ EXPORTS
??$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
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$MakeCheckOpString@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@DD@log_internal@absl@@YAPEBDDDPEBD@Z
@@ -125,23 +126,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPEBD_J0PEBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPEBD_K0PEBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPEBD_N0PEBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$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
@@ -159,6 +175,7 @@ EXPORTS
??$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
??$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
@@ -170,7 +187,7 @@ EXPORTS
??$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
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@?$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@@12@_K@Z
@@ -188,10 +205,11 @@ EXPORTS
??$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
??$emplace@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QEAAAEAVStream@status_internal@absl@@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@AEBU34@@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
@@ -446,6 +464,7 @@ 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
@@ -588,6 +607,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?Dtor@Mutex@absl@@AEAAXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@Z
@@ -863,6 +883,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_NPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_N_K0PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NAEBVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NAEBVStatus@1@@Z
@@ -953,7 +974,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
@@ -1100,7 +1121,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?SendToLog@LogMessage@log_internal@absl@@AEAAXXZ
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPEBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QEAAXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QEGAAAEAV12@W4StatusCode@2@@Z
@@ -1341,6 +1361,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QEAAAEAV123@I@Z
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 03f5f3ee1c3..6573f37ce73 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,6 +1,7 @@
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
@@ -111,7 +112,7 @@ EXPORTS
??$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
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$MakeCheckOpString@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@DD@log_internal@absl@@YAPEBDDDPEBD@Z
@@ -125,23 +126,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPEBD_J0PEBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPEBD_K0PEBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPEBD_N0PEBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$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
@@ -159,6 +175,7 @@ EXPORTS
??$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
??$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
@@ -169,7 +186,7 @@ EXPORTS
??$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
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@?$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@@12@_K@Z
@@ -187,10 +204,11 @@ EXPORTS
??$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
??$emplace@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QEAAAEAVStream@status_internal@absl@@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@AEBU34@@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
@@ -446,6 +464,7 @@ 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
@@ -588,6 +607,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?Dtor@Mutex@absl@@AEAAXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@Z
@@ -863,6 +883,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_NPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_N_K0PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NAEBVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NAEBVStatus@1@@Z
@@ -953,7 +974,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
@@ -1100,7 +1121,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?SendToLog@LogMessage@log_internal@absl@@AEAAXXZ
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPEBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QEAAXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QEGAAAEAV12@W4StatusCode@2@@Z
@@ -1341,6 +1361,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QEAAAEAV123@I@Z
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 7f1836c618c..a56306b4e41 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_dbg.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_dbg.def
@@ -36,31 +36,6 @@ EXPORTS
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAPEAVCommandLineFlag@absl@@AEA_N@__Cr@std@@QEAA@AEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QEAA@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEBQEAVCommandLineFlag@absl@@@__Cr@std@@QEAA@AEBQEAVCommandLineFlag@absl@@@Z
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0AEAPEAPEAVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEAVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAPEBVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEBVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEBVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@_N$0A@@?$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@@QEAA@AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$QEA_N@Z
@@ -119,6 +94,7 @@ EXPORTS
??$?0I@FormatArgImpl@str_format_internal@absl@@QEAA@AEBI@Z
??$?0M@FormatArgImpl@str_format_internal@absl@@QEAA@AEBM@Z
??$?0N@FormatArgImpl@str_format_internal@absl@@QEAA@AEBN@Z
+ ??$?0P6AXPEAX@Z$0A@@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV01234@$0A@@?$pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV12345@@__Cr@std@@QEAA@$$QEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$?0PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU0123@$0A@@?$pair@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU1234@@__Cr@std@@QEAA@$$QEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
@@ -138,10 +114,26 @@ EXPORTS
??$?0PEBD@FormatArgImpl@str_format_internal@absl@@QEAA@AEBQEBD@Z
??$?0PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU0123@$0A@@?$pair@PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@@__Cr@std@@QEAA@$$QEAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$?0PEBVFormatArgImpl@str_format_internal@absl@@$0A@@?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@QEAA@PEBVFormatArgImpl@str_format_internal@1@0AEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$?0U?$__check_pair_construction@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@$0A@@?$pair@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QEAA@AEBUFindInfo@container_internal@absl@@AEBV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0U?$array@D$0DKJI@@__Cr@std@@XU012@H@?$Span@D@absl@@QEAA@AEAU?$array@D$0DKJI@@__Cr@std@@@Z
+ ??$?0U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0UHex@absl@@X@AlphaNum@absl@@QEAA@AEBUHex@1@$$QEAVStringifySink@strings_internal@1@@Z
??$?0UStringEq@container_internal@absl@@@?$Storage@UStringEq@container_internal@absl@@$01U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAUStringEq@23@@Z
??$?0UStringHash@container_internal@absl@@@?$Storage@UStringHash@container_internal@absl@@$00U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAUStringHash@23@@Z
@@ -192,12 +184,20 @@ EXPORTS
??$?0V?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@XV01@H@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@AEBV?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@1@@Z
??$?0V?$Span@D@absl@@XV01@$0A@@?$Span@$$CBD@absl@@QEAA@AEBV?$Span@D@1@@Z
??$?0V?$Span@I@absl@@XV01@$0A@@?$Span@$$CBI@absl@@QEAA@AEBV?$Span@I@1@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
+ ??$?0V?$__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@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
??$?0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V012@$0A@@?$pair@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V123@@__Cr@std@@QEAA@$$QEAV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@AEA_N$0A@@?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAV?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@AEA_N@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N$0A@@?$pair@V?$__hash_const_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAU?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@@@12@AEA_N@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__hash_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$allocator@D@__Cr@std@@@?$Storage@V?$allocator@D@__Cr@std@@$02U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@D@56@@Z
??$?0V?$allocator@D@__Cr@std@@@AlphaNum@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@?$Storage@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@U?$StorageTag@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@_K@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@PEAUCordRep@cord_internal@absl@@@56@@Z
@@ -335,11 +335,11 @@ EXPORTS
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_backward_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?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@__Cr@std@@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@@12@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@QEBA_NAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@FindElement@?$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@@QEBA?AVconst_iterator@123@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@67@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@67@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@Z
??$?RVDuration@absl@@V01@@?$__less@XX@__Cr@std@@QEBA_NAEBVDuration@absl@@0@Z
??$?RVMixingHashState@hash_internal@absl@@@CombineRaw@hash_internal@absl@@QEBA?AVMixingHashState@12@V312@_K@Z
@@ -410,7 +410,7 @@ EXPORTS
??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AssertHashEqConsistent@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$AssertOnFind@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Assign@V?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@inlined_vector_internal@absl@@@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@12@_K@Z
??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPEAUPayload@status_internal@1@AEAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@01@_K@Z
@@ -461,12 +461,12 @@ EXPORTS
??$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
??$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@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@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
??$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@V?$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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
??$DecomposePair@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@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@01@$$QEAUFindElement@301@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePairImpl@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@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
- ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@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
+ ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@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
??$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
@@ -615,7 +615,7 @@ EXPORTS
??$InvokeFlush@VBufferRawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVBufferRawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeFlush@VFILERawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVFILERawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeGet@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?$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@@@FlagImplPeer@flags_internal@absl@@SA?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@@@12@@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$InvokeParseFlag@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAHPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@M@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAMPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@N@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEANPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
@@ -662,24 +662,39 @@ EXPORTS
??$MakeCheckOpValueString@_K@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_K@Z
??$MakeCheckOpValueString@_N@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_N@Z
??$MakeConstSpan@$SQEAX@absl@@YA?AV?$Span@QEAX@0@PEBQEAX_K@Z
- ??$MakeError@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorFromStringView@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$MakeSpan@$S$$CBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@AEBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@0@@Z
??$MakeSpan@$S$$CBVSourceLocation@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@PEBVSourceLocation@0@_K@Z
??$MakeSpan@$SD@absl@@YA?AV?$Span@D@0@PEAD_K@Z
@@ -855,7 +870,7 @@ EXPORTS
??$TrailingZeros@_K@container_internal@absl@@YAI_K@Z
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
??$Unparse@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@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV?$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@@34@@Z
??$UnparseFlag@H@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBH@Z
@@ -866,11 +881,16 @@ EXPORTS
??$__add_alignment_assumption@PEAPEAVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVCordzHandle@cord_internal@absl@@PEAPEAV345@@Z
??$__add_alignment_assumption@PEAPEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVLogSink@absl@@PEAPEAV34@@Z
??$__add_alignment_assumption@PEAPEBVCommandLineFlag@absl@@$0A@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCommandLineFlag@absl@@PEAPEBV34@@Z
+ ??$__add_alignment_assumption@PEAPEBVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCordzHandle@cord_internal@absl@@PEAPEBV345@@Z
??$__add_alignment_assumption@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransition@cctz@time_internal@absl@@$0A@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransition@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransitionType@cctz@time_internal@absl@@$0A@@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransitionType@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAUUnrecognizedFlag@absl@@PEAU34@@Z
+ ??$__add_alignment_assumption@PEAUViableSubstitution@strings_internal@absl@@$0A@@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUViableSubstitution@strings_internal@absl@@PEAU345@@Z
??$__add_alignment_assumption@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@CAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@PEAV312@@Z
+ ??$__add_alignment_assumption@PEBQEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEBQEAVLogSink@absl@@PEBQEAV34@@Z
+ ??$__add_alignment_assumption@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEBU3456@@Z
+ ??$__add_alignment_assumption@PEBUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEBUUnrecognizedFlag@absl@@PEBU34@@Z
??$__advance@PEBUTransition@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
@@ -967,13 +987,13 @@ 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
??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
??$__construct_at_end@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node_hash@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@@AEAA?AV?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@12@_KAEBQEBUCordRep@cord_internal@absl@@@Z
@@ -1136,7 +1156,7 @@ EXPORTS
??$__in_bounds@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@@@__Cr@std@@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@@@23@$0A@@__unique_ptr_array_bounds_stateless@__Cr@std@@QEBA_NPEAPEAU?$__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@@@12@_K@Z
??$__insert_assign_n_unchecked@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@$0A@@?$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@_JPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@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
- ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$__invoke@AEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAU__identity@__Cr@std@@AEAPEAVLogSink@absl@@@__Cr@std@@YAAEAPEAVLogSink@absl@@AEAU__identity@01@AEAPEAV23@@Z
@@ -1347,8 +1367,8 @@ EXPORTS
??$advance@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@@_J_J$0A@@__Cr@std@@YAXAEAV?$__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@@01@_J@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
@@ -1357,12 +1377,16 @@ EXPORTS
??$apply@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$assign@PEBVSourceLocation@absl@@$0A@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QEAAXPEBVSourceLocation@1@0@Z
??$assign@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@$0A@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
+ ??$begin@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$begin@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$begin@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$bit_cast@PEAXVFastTypeIdType@absl@@@__Cr@std@@YAPEAXAEBVFastTypeIdType@absl@@@Z
??$bit_cast@U?$FlagValueAndInitBit@_N@flags_internal@absl@@_J@__Cr@std@@YA?AU?$FlagValueAndInitBit@_N@flags_internal@absl@@AEB_J@Z
??$bit_cast@VFastTypeIdType@absl@@PEAX@__Cr@std@@YA?AVFastTypeIdType@absl@@AEBQEAX@Z
+ ??$c_begin@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_begin@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
+ ??$c_copy@V?$Span@$$CBI@absl@@PEAI@absl@@YAPEAIAEBV?$Span@$$CBI@0@$$QEAPEAI@Z
+ ??$c_end@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_end@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
??$call_once@A6AXXZ$$V@absl@@YAXAEAVonce_flag@0@A6AXXZ@Z
??$call_once@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@absl@@YAXAEAVonce_flag@0@$$QEAP8FlagImpl@flags_internal@0@EAAXXZ$$QEAPEAV230@@Z
@@ -1509,8 +1533,8 @@ EXPORTS
??$emplace@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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
@@ -1536,6 +1560,7 @@ EXPORTS
??$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
??$emplace_front@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
+ ??$end@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$end@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$end@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$find@V?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@PEAVLogSink@absl@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@01@V201@0AEBQEAVLogSink@absl@@@Z
@@ -1608,7 +1633,7 @@ EXPORTS
??$hash_with_seed@V?$tuple@AEB_K@__Cr@std@@$0A@@MixingHashState@hash_internal@absl@@SA_KAEBV?$tuple@AEB_K@__Cr@std@@_K@Z
??$insert@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$insert@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@@$0A@@?$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@@QEAA?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@Z
- ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$invoke@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@__Cr@std@@YAX$$QEAP8FlagImpl@flags_internal@absl@@EAAXXZ$$QEAPEAV234@@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@AEAPEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@PEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@$$QEAPEAPEAV34@@Z
@@ -1690,6 +1715,9 @@ EXPORTS
??$safe_strtoi_base@K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAKH@Z
??$safe_strtoi_base@_J@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_JH@Z
??$safe_strtoi_base@_K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_KH@Z
+ ??$size@U<unnamed-type-locks>@SynchLocksHeld@absl@@$0CI@@__Cr@std@@YA_KAEAY0CI@$$CBU<unnamed-type-locks>@SynchLocksHeld@absl@@@Z
+ ??$size@UGraphId@synchronization_internal@absl@@$09@__Cr@std@@YA_KAEAY09$$CBUGraphId@synchronization_internal@absl@@@Z
+ ??$size@USpinLockWaitTransition@base_internal@absl@@$02@__Cr@std@@YA_KAEAY02$$CBUSpinLockWaitTransition@base_internal@absl@@@Z
??$swap@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$swap@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@YAXAEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$swap@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@YAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
@@ -1737,8 +1765,8 @@ EXPORTS
??0?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@$0JPOAA@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
- ??0?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
- ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??0?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
+ ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@AEAA@W4InvalidCapacity@012@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@Uuninitialized_tag_t@12@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@_K@Z
@@ -1758,7 +1786,6 @@ EXPORTS
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@V?$move_iterator@PEAVSourceLocation@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAVSourceLocation@absl@@@__Cr@std@@@Z
??0?$NonIterableBitMask@I$0BA@$0A@@container_internal@absl@@QEAA@I@Z
??0?$NonIterableBitMask@_K$07$02@container_internal@absl@@QEAA@_K@Z
- ??0?$PerTableSeedImpl@E@container_internal@absl@@AEAA@_K@Z
??0?$ProbedItemImpl@I$0CA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0EA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0HK@@container_internal@absl@@QEAA@E_K0@Z
@@ -1852,8 +1879,8 @@ EXPORTS
??0?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -1864,32 +1891,32 @@ EXPORTS
??0?$__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@@QEAA@_K0AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@XZ
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@XZ
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__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@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@@AEAA@PEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@12@@Z
@@ -1900,13 +1927,27 @@ EXPORTS
??0?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@QEAA@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@@@12@_N@Z
??0?$__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@@__Cr@std@@QEAA@XZ
??0?$__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@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@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@@QEAA@XZ
??0?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEAVCommandLineFlag@absl@@@Z
??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEAVCordzHandle@cord_internal@absl@@@Z
??0?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@AEAA@PEAPEAVLogSink@absl@@@Z
??0?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEBVCommandLineFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ??0?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@AEAA@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransition@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransitionType@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@AEAA@PEAUUnrecognizedFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@AEAA@PEAUViableSubstitution@strings_internal@absl@@@Z
??0?$__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@@AEAA@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@@12@AEBV567@@Z@@Z
??0?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@AEAA@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@@Z
??0?$__wrap_iter@PEBQEAVLogSink@absl@@@__Cr@std@@AEAA@PEBQEAVLogSink@absl@@@Z
@@ -2079,7 +2120,6 @@ 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@AEBV012@@Z
??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
@@ -2120,6 +2160,7 @@ EXPORTS
??0ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA@PEAV123@@Z
??0Payload@status_internal@absl@@QEAA@$$QEAU012@@Z
??0Payload@status_internal@absl@@QEAA@AEBU012@@Z
+ ??0PerTableSeed@container_internal@absl@@AEAA@_K@Z
??0PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@_KVcrc32c_t@3@@Z
@@ -2129,6 +2170,7 @@ EXPORTS
??0ReaderMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0RefcountAndFlags@cord_internal@absl@@QEAA@XZ
??0RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??0ReleasableMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0Rep@CordBuffer@absl@@QEAA@PEAUCordRepFlat@cord_internal@2@@Z
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
@@ -2193,8 +2235,8 @@ EXPORTS
??0ZoneInfoSource@cctz@time_internal@absl@@QEAA@XZ
??0_ConstructTransaction@?$__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@@QEAA@PEAV123@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV123@AEAU__deque_block_range@123@@Z
??0_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
??0_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
@@ -2273,8 +2315,8 @@ EXPORTS
??1?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -2286,17 +2328,17 @@ EXPORTS
??1?$__policy_func@$$A6A_NAEBVCommandLineFlag@absl@@@Z@__function@__Cr@std@@QEAA@XZ
??1?$__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@@QEAA@XZ
??1?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__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@XZ
@@ -2391,6 +2433,7 @@ EXPORTS
??1PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??1ReaderMutexLock@absl@@QEAA@XZ
??1RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??1ReleasableMutexLock@absl@@QEAA@XZ
??1Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??1Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
??1Rep@StatusBuilder@absl@@QEAA@XZ
@@ -2417,8 +2460,8 @@ EXPORTS
??1ZoneInfoSource@cctz@time_internal@absl@@UEAA@XZ
??1_ConstructTransaction@?$__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@@QEAA@XZ
??1_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
@@ -2444,7 +2487,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4FlagsUsageConfig@absl@@QEAAAEAU01@AEBU01@@Z
??4HiRep@Duration@absl@@QEAAAEAV012@_J@Z
- ??4InlineData@cord_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4InlineRep@Cord@absl@@QEAAAEAV012@$$QEAV012@@Z
??4Payload@status_internal@absl@@QEAAAEAU012@$$QEAU012@@Z
??4Rep@CrcCordState@crc_internal@absl@@QEAAAEAU0123@AEBU0123@@Z
@@ -2553,6 +2595,17 @@ EXPORTS
??A?$Span@D@absl@@QEBAAEAD_K@Z
??A?$Span@I@absl@@QEBAAEAI_K@Z
??A?$__farray@P6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@__Cr@std@@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@456@@Z$03@__Cr@std@@QEBAAEBQ6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@12@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@612@@Z_K@Z
+ ??A?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEAVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEAVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@QEBAAEAPEAVLogSink@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEBVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEBVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@QEBAAEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransition@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransitionType@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@QEBAAEAUUnrecognizedFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@QEBAAEAUViableSubstitution@strings_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEBAAEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@_J@Z
??A?$array@Uraw_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@$0BA@@__Cr@std@@QEAAAEAUraw_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@@12@AEBV567@@Z@_K@Z
??A?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
??A?$map@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@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?$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@@QEAAAEAV?$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@@12@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
@@ -2599,6 +2652,7 @@ EXPORTS
??C?$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@@QEBAPEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
??C?$__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@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__hash_map_const_iterator@V?$__hash_const_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@@@__Cr@std@@QEBAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
+ ??C?$__hash_map_iterator@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@@@__Cr@std@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAPEAPEAVCommandLineFlag@absl@@XZ
@@ -2792,7 +2846,7 @@ EXPORTS
??R?$HashImpl@H@hash_internal@absl@@QEBA_KAEBH@Z
??R?$HashImpl@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@Z
??R?$HashImpl@V?$tuple@AEB_K@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEB_K@__Cr@std@@@Z
- ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEBA_K_K@Z
+ ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEBA_K_K@Z
??R?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??R?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??R?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@@Z
@@ -3219,6 +3273,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DisableRescheduling@SchedulingGuard@base_internal@absl@@SA_NXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@AEBAP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@ZXZ
@@ -3715,6 +3770,7 @@ EXPORTS
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
?IsHeld@SpinLock@base_internal@absl@@QEBA_NXZ
?IsImmortal@RefcountAndFlags@cord_internal@absl@@QEBA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInfiniteDuration@time_internal@absl@@YA_NVDuration@2@@Z
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInlined@Status@absl@@CA_N_K@Z
@@ -3882,7 +3938,7 @@ EXPORTS
?NextCapacity@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@SA_K_K@Z
?NextCapacity@container_internal@absl@@YA_K_K@Z
?NextGeneration@container_internal@absl@@YAEE@Z
- ?NextHashTableSeed@container_internal@absl@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextRandom@ExponentialBiased@profiling_internal@absl@@SA_K_K@Z
?NextTransition@Impl@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@2345@@Z
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -4104,7 +4160,6 @@ EXPORTS
?SentinelEmptyGeneration@container_internal@absl@@YAEXZ
?Set@?$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@@AEAAXAEBV?$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@@@Z
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAllocation@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@23@@Z
@@ -4352,6 +4407,7 @@ EXPORTS
?ToInt64Nanoseconds@absl@@YA_JVDuration@1@@Z
?ToInt64Seconds@absl@@YA_JVDuration@1@@Z
?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
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
@@ -4506,6 +4562,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithSourceLocation@Status@absl@@QEHAA$$QEAV12@VSourceLocation@2@@Z
@@ -4526,8 +4583,41 @@ EXPORTS
?__addr@?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
?__alloc@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$__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@@@__Cr@std@@QEAAAEAV?$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@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@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?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__alloc@?$__vector_layout@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@@QEBAAEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@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@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
@@ -4539,13 +4629,21 @@ EXPORTS
?__annotate_contiguous_container@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$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@@AEBAXPEBX0@Z
+ ?__annotate_delete@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@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@@AEBAXXZ
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
@@ -4564,19 +4662,19 @@ EXPORTS
?__annotate_increase@?$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@@AEBAX_K@Z
?__annotate_increase_back@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_increase_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@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@@AEBAX_K@Z
?__annotate_new@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_new@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$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@@AEBAX_K@Z
?__annotate_poison_block@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_shrink@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_shrink@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
@@ -4595,8 +4693,8 @@ EXPORTS
?__as_base@?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__variant_detail@__Cr@std@@IEGAA@XZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -4611,17 +4709,56 @@ EXPORTS
?__base_destruct_at_end@?$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@@AEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
+ ?__begin_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__capacity@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@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@@QEBA_KXZ
?__capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__complete@?$__exception_guard_noexceptions@V<lambda_1>@?0??__add_back_capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z@@__Cr@std@@QEAAXXZ
?__complete@?$__exception_guard_noexceptions@V?$_AllocatorDestroyRangeReverse@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@PEAUUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?__compose@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@PEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAU5678@@Z
- ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
- ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@U?$integral_constant@_N$0A@@23@@Z
+ ?__data@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__data@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUViableSubstitution@strings_internal@absl@@XZ
+ ?__data@?$__vector_layout@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@@QEBAPEBV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__deallocate_node@?$__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@@AEAAXPEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@23@@Z
?__deallocate_node@?$__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@@AEAAXPEAU?$__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@23@@Z
?__deallocate_node_list@?$__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@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@@Z
@@ -4634,28 +4771,28 @@ EXPORTS
?__destruct_at_end@?$__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@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAPEAVLogSink@absl@@@Z
?__destruct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@@Z
?__destruct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
@@ -4666,40 +4803,53 @@ EXPORTS
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEAAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__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
?__front_cap@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__get@?$__optional_storage_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEGAAAEAVStream@status_internal@absl@@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__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@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_value@?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@QEAAAEAPEBUCordRep@cord_internal@absl@@XZ
@@ -4717,11 +4867,14 @@ EXPORTS
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@PEAPEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBQEAVLogSink@absl@@@23@PEBQEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@PEAPEBVCommandLineFlag@absl@@@Z
+ ?__make_iter@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@PEAUUnrecognizedFlag@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@PEBUUnrecognizedFlag@absl@@@Z
+ ?__make_iter@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@PEAUViableSubstitution@strings_internal@absl@@@Z
?__make_iter@?$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@@AEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@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
@@ -4746,6 +4899,32 @@ EXPORTS
?__recommend_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SA_K_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@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@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
+ ?__relocate@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@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@@QEAAXAEAV?$__split_buffer@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@V__split_buffer_size_layout@23@@23@@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@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
?__rewrap@?$__unwrap_iter_impl@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$00@__Cr@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV45678@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@$00@__Cr@std@@SAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU4567@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAVLogSink@absl@@$00@__Cr@std@@SAPEAPEAVLogSink@absl@@PEAPEAV45@0@Z
@@ -4762,105 +4941,104 @@ EXPORTS
?__root_ptr@?$__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@@QEBAPEAPEAV?$__tree_node_base@PEAX@23@XZ
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@23@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@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@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__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@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__size@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@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@@QEBA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAUUnrecognizedFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@00@Z
- ?__swap_layouts@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
+ ?__swap@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__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
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
?__swap_without_allocator@?$__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@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__throw_length_error@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -4960,10 +5138,17 @@ EXPORTS
?back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@XZ
?back@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
+ ?back@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?back@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@XZ
+ ?back@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCordzHandle@cord_internal@absl@@XZ
?back@?$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@@XZ
?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?back@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?back@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@XZ
?back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@XZ
+ ?back@?$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@@@23@XZ
?back@CordRepBtree@cord_internal@absl@@QEBA_KXZ
?base@?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?base@?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
@@ -4986,17 +5171,17 @@ EXPORTS
?begin@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?begin@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$array@Uraw_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@$0BA@@__Cr@std@@QEAA?AV?$__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@XZ
@@ -5036,17 +5221,17 @@ EXPORTS
?capacity@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$HashtableCapacityImpl@$00@23@XZ
?capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__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@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$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@@QEBA_KXZ
?capacity@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?capacity@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -5075,17 +5260,17 @@ EXPORTS
?clear@?$__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@@QEAAXXZ
?clear@?$__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@@QEAAXXZ
?clear@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__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
+ ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXXZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?clear@?$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@@QEAAXXZ
?clear@?$unordered_map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@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@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@@QEAAXXZ
@@ -5253,6 +5438,11 @@ EXPORTS
?empty@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$map@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@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?$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@@QEBA_NXZ
?empty@?$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@@QEBA_NXZ
+ ?empty@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
@@ -5278,17 +5468,17 @@ EXPORTS
?end@?$__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?AV?$__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@@@23@XZ
?end@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?end@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@23@XZ
@@ -5302,11 +5492,14 @@ EXPORTS
?end@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@23@XZ
?end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@XZ
?end@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@XZ
+ ?end@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$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@@@23@XZ
?end@?$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@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@XZ
+ ?end@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@XZ
?end@?$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@@QEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?end@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ
?end@CordRepBtree@cord_internal@absl@@QEBA_KXZ
@@ -5594,8 +5787,6 @@ EXPORTS
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@PEBU?$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@@@__Cr@std@@SAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@AEBU423@@Z
- ?poison@InlineData@cord_internal@absl@@QEAAXXZ
- ?poison_this@InlineData@cord_internal@absl@@QEAAXXZ
?pop_back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAXXZ
?pop_back@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
@@ -5696,11 +5887,9 @@ EXPORTS
?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?second@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
- ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?seed@?$PerTableSeedImpl@E@container_internal@absl@@QEBA_KXZ
- ?seed@CommonFields@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEAAPEAU1234@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEBAPEBU1234@XZ
+ ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@CommonFields@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@PerTableSeed@container_internal@absl@@QEBA_KXZ
?set@?$MaybeInitializedPtr@W4ctrl_t@container_internal@absl@@@container_internal@absl@@QEAAXPEAW4ctrl_t@23@@Z
?set_arg@BoundConversion@str_format_internal@absl@@QEAAXPEBVFormatArgImpl@23@@Z
?set_begin@CordRepBtree@cord_internal@absl@@AEAAX_K@Z
@@ -5859,7 +6048,6 @@ EXPORTS
?unlock@Mutex@absl@@QEAAXXZ
?unlock@SpinLock@base_internal@absl@@QEAAXXZ
?unlock_shared@Mutex@absl@@QEAAXXZ
- ?unpoison@InlineData@cord_internal@absl@@QEAAXXZ
?utc_time_zone@cctz@time_internal@absl@@YA?AVtime_zone@123@XZ
?value@ConvertibleToStringView@strings_internal@absl@@QEBA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?value@InputValue@UnboundConversion@str_format_internal@absl@@QEBAHXZ
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 417e80144ae..203bba8c770 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
@@ -36,31 +36,6 @@ EXPORTS
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAPEAVCommandLineFlag@absl@@AEA_N@__Cr@std@@QEAA@AEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QEAA@AEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AEBQEAVCommandLineFlag@absl@@@__Cr@std@@QEAA@AEBQEAVCommandLineFlag@absl@@@Z
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$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@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
- ??$?0$00X@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0AEAPEAPEAVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEAVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEAVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAPEBVCommandLineFlag@absl@@AEA_N$0A@@?$pair@PEAPEBVCommandLineFlag@absl@@_N@__Cr@std@@QEAA@AEAPEAPEBVCommandLineFlag@absl@@AEA_N@Z
??$?0AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@_N$0A@@?$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@@QEAA@AEAPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@$$QEA_N@Z
@@ -119,6 +94,7 @@ EXPORTS
??$?0I@FormatArgImpl@str_format_internal@absl@@QEAA@AEBI@Z
??$?0M@FormatArgImpl@str_format_internal@absl@@QEAA@AEBM@Z
??$?0N@FormatArgImpl@str_format_internal@absl@@QEAA@AEBN@Z
+ ??$?0P6AXPEAX@Z$0A@@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPEAX@Z@__Cr@std@@QEAA@PEAUThreadIdentity@base_internal@absl@@AEBQ6AXPEAX@Z@Z
??$?0PEAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QEAA@PEAI0@Z
??$?0PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV01234@$0A@@?$pair@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV12345@@__Cr@std@@QEAA@$$QEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$?0PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU0123@$0A@@?$pair@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU1234@@__Cr@std@@QEAA@$$QEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
@@ -138,9 +114,25 @@ EXPORTS
??$?0PEBD@FormatArgImpl@str_format_internal@absl@@QEAA@AEBQEBD@Z
??$?0PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU0123@$0A@@?$pair@PEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@@__Cr@std@@QEAA@$$QEAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$?0PEBVFormatArgImpl@str_format_internal@absl@@$0A@@?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@QEAA@PEBVFormatArgImpl@str_format_internal@1@0AEBV?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@?$FunctionRef@$$A6A_K_K@Z@absl@@IEAA@Uin_place_t@__Cr@std@@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@X@?$FunctionRef@$$A6A_K_K@Z@absl@@QEAA@$$QEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$?0U?$array@D$0DKJI@@__Cr@std@@XU012@H@?$Span@D@absl@@QEAA@AEAU?$array@D$0DKJI@@__Cr@std@@@Z
+ ??$?0U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEBVImpl@time_zone@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAULogMessageData@LogMessage@log_internal@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAURep@StatusBuilder@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??$?0U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVFlagState@flags_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVTimeZoneLibC@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAVZoneInfoSource@cctz@time_internal@absl@@@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@$$T@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QEAA@PEAX$$QEAUDynValueDeleter@flags_internal@absl@@@Z
??$?0UFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@I$0BA@$0A@@12@$0A@@?$pair@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QEAA@$$QEAUFindInfo@container_internal@absl@@AEAV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0UHex@absl@@X@AlphaNum@absl@@QEAA@AEBUHex@1@$$QEAVStringifySink@strings_internal@1@@Z
??$?0UStringEq@container_internal@absl@@@?$Storage@UStringEq@container_internal@absl@@$01U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAUStringEq@23@@Z
@@ -192,12 +184,20 @@ EXPORTS
??$?0V?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@XV01@H@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QEAA@AEBV?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@1@@Z
??$?0V?$Span@D@absl@@XV01@$0A@@?$Span@$$CBD@absl@@QEAA@AEBV?$Span@D@1@@Z
??$?0V?$Span@I@absl@@XV01@$0A@@?$Span@$$CBI@absl@@QEAA@AEBV?$Span@I@1@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAA@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QEAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
+ ??$?0V?$__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@@@__Cr@std@@$0A@@?$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@@QEAA@XZ
??$?0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V012@$0A@@?$pair@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@V123@@__Cr@std@@QEAA@$$QEAV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@AEA_N$0A@@?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAV?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@AEA_N@Z
??$?0V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N$0A@@?$pair@V?$__hash_const_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QEAA@$$QEAU?$pair@V?$__hash_iterator@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@_N@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@@@12@AEA_N@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@12@$$QEAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__hash_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__hash_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__hash_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
??$?0V?$__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@@AEA_N$0A@@?$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@__Cr@std@@QEAA@$$QEAV?$__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@12@AEA_N@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@__Cr@std@@QEAA@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@12@$$QEAV?$__tree_node_destructor@V?$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@@@__Cr@std@@@12@@Z
??$?0V?$allocator@D@__Cr@std@@@?$Storage@V?$allocator@D@__Cr@std@@$02U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@D@56@@Z
??$?0V?$allocator@D@__Cr@std@@@AlphaNum@absl@@QEAA@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?0V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@?$Storage@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@U?$StorageTag@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@_K@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QEAA@Uin_place_t@__Cr@std@@$$QEAV?$allocator@PEAUCordRep@cord_internal@absl@@@56@@Z
@@ -335,11 +335,11 @@ EXPORTS
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_backward_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QEBA?AU?$__in_out_result@PEAUTransitionType@cctz@time_internal@absl@@PEAU1234@@12@PEAUTransitionType@cctz@time_internal@absl@@00@Z
??$?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@__Cr@std@@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@@12@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@12@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@12@@EmplaceDecomposable@?$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@@QEBA?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@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBUpiecewise_construct_t@56@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@QEBA_NAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEBA_KAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@45@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@45@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@12@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@AEBQEAVCommandLineFlag@absl@@@12@@FindElement@?$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@@QEBA?AVconst_iterator@123@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBUpiecewise_construct_t@67@$$QEAV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@67@$$QEAV?$tuple@AEBQEAVCommandLineFlag@absl@@@67@@Z
??$?RVDuration@absl@@V01@@?$__less@XX@__Cr@std@@QEBA_NAEBVDuration@absl@@0@Z
??$?RVMixingHashState@hash_internal@absl@@@CombineRaw@hash_internal@absl@@QEBA?AVMixingHashState@12@V312@_K@Z
@@ -410,7 +410,7 @@ EXPORTS
??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPEADPEBD_K@Z
??$AssertHashEqConsistent@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@functional_internal@absl@@YAXAEBU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$AssertOnFind@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@@IEAAXAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Assign@V?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@inlined_vector_internal@absl@@@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXV?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PEBVSourceLocation@absl@@@12@_K@Z
??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPEAUPayload@status_internal@1@AEAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PEAUPayload@status_internal@absl@@@23@@01@_K@Z
@@ -461,12 +461,12 @@ EXPORTS
??$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
??$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@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@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
??$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@V?$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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@Z
??$DecomposePair@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@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@01@$$QEAUFindElement@301@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePairImpl@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@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
- ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@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
+ ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@AEBQEAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@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
??$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
@@ -615,7 +615,7 @@ EXPORTS
??$InvokeFlush@VBufferRawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVBufferRawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeFlush@VFILERawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPEAVFILERawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeGet@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?$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@@@FlagImplPeer@flags_internal@absl@@SA?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@@@12@@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$InvokeParseFlag@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAHPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@M@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAMPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@N@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEANPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
@@ -662,24 +662,39 @@ EXPORTS
??$MakeCheckOpValueString@_K@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_K@Z
??$MakeCheckOpValueString@_N@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEB_N@Z
??$MakeConstSpan@$SQEAX@absl@@YA?AV?$Span@QEAX@0@PEBQEAX_K@Z
- ??$MakeError@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorFromStringView@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$MakeSpan@$S$$CBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@AEBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@0@@Z
??$MakeSpan@$S$$CBVSourceLocation@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@PEBVSourceLocation@0@_K@Z
??$MakeSpan@$SD@absl@@YA?AV?$Span@D@0@PEAD_K@Z
@@ -848,7 +863,7 @@ EXPORTS
??$TrailingZeros@_K@container_internal@absl@@YAI_K@Z
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnhidePtr@X@base_internal@absl@@YAPEAX_K@Z
??$Unparse@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@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV?$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@@34@@Z
??$UnparseFlag@H@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBH@Z
@@ -859,11 +874,16 @@ EXPORTS
??$__add_alignment_assumption@PEAPEAVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVCordzHandle@cord_internal@absl@@PEAPEAV345@@Z
??$__add_alignment_assumption@PEAPEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEAVLogSink@absl@@PEAPEAV34@@Z
??$__add_alignment_assumption@PEAPEBVCommandLineFlag@absl@@$0A@@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCommandLineFlag@absl@@PEAPEBV34@@Z
+ ??$__add_alignment_assumption@PEAPEBVCordzHandle@cord_internal@absl@@$0A@@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAPEBVCordzHandle@cord_internal@absl@@PEAPEBV345@@Z
??$__add_alignment_assumption@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransition@cctz@time_internal@absl@@$0A@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransition@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUTransitionType@cctz@time_internal@absl@@$0A@@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUTransitionType@cctz@time_internal@absl@@PEAU3456@@Z
??$__add_alignment_assumption@PEAUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEAUUnrecognizedFlag@absl@@PEAU34@@Z
+ ??$__add_alignment_assumption@PEAUViableSubstitution@strings_internal@absl@@$0A@@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEAUViableSubstitution@strings_internal@absl@@PEAU345@@Z
??$__add_alignment_assumption@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@CAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@PEAV312@@Z
+ ??$__add_alignment_assumption@PEBQEAVLogSink@absl@@$0A@@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPEBQEAVLogSink@absl@@PEBQEAV34@@Z
+ ??$__add_alignment_assumption@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@PEBU3456@@Z
+ ??$__add_alignment_assumption@PEBUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPEBUUnrecognizedFlag@absl@@PEBU34@@Z
??$__advance@PEBUTransition@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEBUTransition@cctz@time_internal@absl@@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAEAV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@_JUrandom_access_iterator_tag@01@@Z
@@ -960,13 +980,13 @@ 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
??$__construct_at_end@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
??$__construct_at_end@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end_with_size@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@@@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXV?$__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@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@?$__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@@QEAAXV?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@_K@Z
??$__construct_at_end_with_size@V?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransition@cctz@time_internal@absl@@@12@_K@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXV?$move_iterator@PEAUTransitionType@cctz@time_internal@absl@@@12@_K@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@V?$__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@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@__Cr@std@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node@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@@AEAA?AV?$unique_ptr@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@@V?$__tree_node_destructor@V?$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@@@__Cr@std@@@23@@12@AEBUpiecewise_construct_t@12@$$QEAV?$tuple@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QEAV?$tuple@$$V@12@@Z
??$__construct_node_hash@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@@AEAA?AV?$unique_ptr@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@@12@_KAEBQEBUCordRep@cord_internal@absl@@@Z
@@ -1129,7 +1149,7 @@ EXPORTS
??$__in_bounds@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@@@__Cr@std@@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@@@23@$0A@@__unique_ptr_array_bounds_stateless@__Cr@std@@QEBA_NPEAPEAU?$__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@@@12@_K@Z
??$__insert_assign_n_unchecked@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@$0A@@?$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@_JPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@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
- ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$__invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$__invoke@AEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByCivilTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU2345@AEBU2345@@__Cr@std@@YA_NAEAUByUnixTime@Transition@cctz@time_internal@absl@@AEBU3456@1@Z
??$__invoke@AEAU__identity@__Cr@std@@AEAPEAVLogSink@absl@@@__Cr@std@@YAAEAPEAVLogSink@absl@@AEAU__identity@01@AEAPEAV23@@Z
@@ -1353,8 +1373,8 @@ EXPORTS
??$allocate_at_least@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@@?$allocator_traits@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@SA?AU?$allocation_result@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@_K@12@AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@_K@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_N$$QEAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_K$$QEAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$apply@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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
@@ -1363,12 +1383,16 @@ EXPORTS
??$apply@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@@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@AEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$assign@PEBVSourceLocation@absl@@$0A@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QEAAXPEBVSourceLocation@1@0@Z
??$assign@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@$0A@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@12@0@Z
+ ??$begin@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$begin@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$begin@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$bit_cast@PEAXVFastTypeIdType@absl@@@__Cr@std@@YAPEAXAEBVFastTypeIdType@absl@@@Z
??$bit_cast@U?$FlagValueAndInitBit@_N@flags_internal@absl@@_J@__Cr@std@@YA?AU?$FlagValueAndInitBit@_N@flags_internal@absl@@AEB_J@Z
??$bit_cast@VFastTypeIdType@absl@@PEAX@__Cr@std@@YA?AVFastTypeIdType@absl@@AEBQEAX@Z
+ ??$c_begin@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_begin@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
+ ??$c_copy@V?$Span@$$CBI@absl@@PEAI@absl@@YAPEAIAEBV?$Span@$$CBI@0@$$QEAPEAI@Z
+ ??$c_end@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPEBIAEBV?$Span@$$CBI@1@@Z
??$c_end@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AEAV?$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@@34@@Z
??$call_once@A6AXXZ$$V@absl@@YAXAEAVonce_flag@0@A6AXXZ@Z
??$call_once@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@absl@@YAXAEAVonce_flag@0@$$QEAP8FlagImpl@flags_internal@0@EAAXXZ$$QEAPEAV230@@Z
@@ -1515,8 +1539,8 @@ EXPORTS
??$emplace@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
??$emplace_at@AEBUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QEAPEAVCommandLineFlag@absl@@@23@@?$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@@IEAAXPEAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@12@AEBUpiecewise_construct_t@__Cr@std@@$$QEAV?$tuple@$$QEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QEAV?$tuple@$$QEAPEAVCommandLineFlag@absl@@@56@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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
@@ -1542,6 +1566,7 @@ EXPORTS
??$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
??$emplace_front@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
+ ??$end@V?$Span@$$CBI@absl@@@__Cr@std@@YAPEBIAEBV?$Span@$$CBI@absl@@@Z
??$end@V?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@01@AEAV?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$end@V?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@01@AEAV?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$find@V?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@PEAVLogSink@absl@@@__Cr@std@@YA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@01@V201@0AEBQEAVLogSink@absl@@@Z
@@ -1614,7 +1639,7 @@ EXPORTS
??$hash_with_seed@V?$tuple@AEB_K@__Cr@std@@$0A@@MixingHashState@hash_internal@absl@@SA_KAEBV?$tuple@AEB_K@__Cr@std@@_K@Z
??$insert@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QEAA?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@@$$QEAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAVCommandLineFlag@absl@@@45@@Z
??$insert@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@@$0A@@?$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@@QEAA?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@Z
- ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QEA_K@Z
+ ??$invoke@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K@__Cr@std@@YA_KAEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QEA_K@Z
??$invoke@P8FlagImpl@flags_internal@absl@@EAAXXZPEAV123@@__Cr@std@@YAX$$QEAP8FlagImpl@flags_internal@absl@@EAAXXZ$$QEAPEAV234@@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@AEAPEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
??$iter_swap@AEAPEAPEAVCommandLineFlag@absl@@PEAPEAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAEAPEAPEAVCommandLineFlag@absl@@$$QEAPEAPEAV34@@Z
@@ -1703,6 +1728,9 @@ EXPORTS
??$safe_strtoi_base@K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAKH@Z
??$safe_strtoi_base@_J@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_JH@Z
??$safe_strtoi_base@_K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEA_KH@Z
+ ??$size@U<unnamed-type-locks>@SynchLocksHeld@absl@@$0CI@@__Cr@std@@YA_KAEAY0CI@$$CBU<unnamed-type-locks>@SynchLocksHeld@absl@@@Z
+ ??$size@UGraphId@synchronization_internal@absl@@$09@__Cr@std@@YA_KAEAY09$$CBUGraphId@synchronization_internal@absl@@@Z
+ ??$size@USpinLockWaitTransition@base_internal@absl@@$02@__Cr@std@@YA_KAEAY02$$CBUSpinLockWaitTransition@base_internal@absl@@@Z
??$swap@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@YAXAEAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$swap@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@YAXAEAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$swap@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@YAXAEAPEAPEAVCommandLineFlag@absl@@0@Z
@@ -1750,8 +1778,8 @@ EXPORTS
??0?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@$0JPOAA@@str_format_internal@absl@@QEAA@PEBD@Z
??0?$FormatSpecTemplate@$0JPPPL@@str_format_internal@absl@@QEAA@PEBD@Z
- ??0?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
- ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??0?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@_K@Z
+ ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEAA@AEBUStringHash@12@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@AEAA@W4InvalidCapacity@012@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@Uuninitialized_tag_t@12@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QEAA@_K@Z
@@ -1771,7 +1799,6 @@ EXPORTS
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@V?$move_iterator@PEAVSourceLocation@absl@@@23@@inlined_vector_internal@absl@@QEAA@AEBV?$move_iterator@PEAVSourceLocation@absl@@@__Cr@std@@@Z
??0?$NonIterableBitMask@I$0BA@$0A@@container_internal@absl@@QEAA@I@Z
??0?$NonIterableBitMask@_K$07$02@container_internal@absl@@QEAA@_K@Z
- ??0?$PerTableSeedImpl@E@container_internal@absl@@AEAA@_K@Z
??0?$ProbedItemImpl@I$0CA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0EA@@container_internal@absl@@QEAA@E_K0@Z
??0?$ProbedItemImpl@_K$0HK@@container_internal@absl@@QEAA@E_K0@Z
@@ -1865,8 +1892,8 @@ EXPORTS
??0?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??0?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??0?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??0?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -1877,32 +1904,32 @@ EXPORTS
??0?$__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@@QEAA@_K0AEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
??0?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@_K0AEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@_K0AEAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@_K0AEAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@_K0AEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@XZ
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAA@XZ
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__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@@QEAA@AEBV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAA@AEBV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAA@AEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@AEBV?$__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@@12@@Z
??0?$__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@@AEAA@PEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@12@@Z
@@ -1913,13 +1940,27 @@ EXPORTS
??0?$__tree_node_destructor@V?$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@@@__Cr@std@@@__Cr@std@@QEAA@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@@@12@_N@Z
??0?$__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@@__Cr@std@@QEAA@XZ
??0?$__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@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
+ ??0?$__vector_layout@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@@QEAA@XZ
??0?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEAVCommandLineFlag@absl@@@Z
??0?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEAVCordzHandle@cord_internal@absl@@@Z
??0?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@AEAA@PEAPEAVLogSink@absl@@@Z
??0?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@AEAA@PEAPEBVCommandLineFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@AEAA@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ??0?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@AEAA@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransition@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@AEAA@PEAUTransitionType@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@AEAA@PEAUUnrecognizedFlag@absl@@@Z
+ ??0?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@AEAA@PEAUViableSubstitution@strings_internal@absl@@@Z
??0?$__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@@AEAA@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@@12@AEBV567@@Z@@Z
??0?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@AEAA@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@@Z
??0?$__wrap_iter@PEBQEAVLogSink@absl@@@__Cr@std@@AEAA@PEBQEAVLogSink@absl@@@Z
@@ -2092,7 +2133,6 @@ 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@AEBV012@@Z
??0InlineData@cord_internal@absl@@QEAA@W4DefaultInitType@012@@Z
??0InlineData@cord_internal@absl@@QEAA@XZ
??0InlineRep@Cord@absl@@QEAA@$$QEAV012@@Z
@@ -2133,6 +2173,7 @@ EXPORTS
??0ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QEAA@PEAV123@@Z
??0Payload@status_internal@absl@@QEAA@$$QEAU012@@Z
??0Payload@status_internal@absl@@QEAA@AEBU012@@Z
+ ??0PerTableSeed@container_internal@absl@@AEAA@_K@Z
??0PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QEAA@_KVcrc32c_t@3@@Z
@@ -2142,6 +2183,7 @@ EXPORTS
??0ReaderMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0RefcountAndFlags@cord_internal@absl@@QEAA@XZ
??0RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??0ReleasableMutexLock@absl@@QEAA@AEAVMutex@1@@Z
??0Rep@CordBuffer@absl@@QEAA@PEAUCordRepFlat@cord_internal@2@@Z
??0Rep@CordBuffer@absl@@QEAA@XZ
??0Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
@@ -2206,8 +2248,8 @@ EXPORTS
??0ZoneInfoSource@cctz@time_internal@absl@@QEAA@XZ
??0_ConstructTransaction@?$__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@@QEAA@PEAV123@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransition@cctz@time_internal@absl@@_K@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@PEAV123@PEAUTransitionType@cctz@time_internal@absl@@_K@Z
??0_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@PEAV123@AEAU__deque_block_range@123@@Z
??0_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
??0_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@AEAV123@_K@Z
@@ -2286,8 +2328,8 @@ EXPORTS
??1?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QEAA@XZ
- ??1?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QEAA@XZ
+ ??1?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEAA@XZ
??1?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QEAA@XZ
@@ -2299,17 +2341,17 @@ EXPORTS
??1?$__policy_func@$$A6A_NAEBVCommandLineFlag@absl@@@Z@__function@__Cr@std@@QEAA@XZ
??1?$__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@@QEAA@XZ
??1?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAA@XZ
- ??1?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAA@XZ
+ ??1?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1?$__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@XZ
@@ -2404,6 +2446,7 @@ EXPORTS
??1PosixTimeZone@cctz@time_internal@absl@@QEAA@XZ
??1ReaderMutexLock@absl@@QEAA@XZ
??1RefcountedRep@CrcCordState@crc_internal@absl@@QEAA@XZ
+ ??1ReleasableMutexLock@absl@@QEAA@XZ
??1Rep@CrcCordState@crc_internal@absl@@QEAA@XZ
??1Rep@GraphCycles@synchronization_internal@absl@@QEAA@XZ
??1Rep@StatusBuilder@absl@@QEAA@XZ
@@ -2430,8 +2473,8 @@ EXPORTS
??1ZoneInfoSource@cctz@time_internal@absl@@UEAA@XZ
??1_ConstructTransaction@?$__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@@QEAA@XZ
??1_ConstructTransaction@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
??1_ConstructTransaction@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA@XZ
@@ -2457,7 +2500,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4FlagsUsageConfig@absl@@QEAAAEAU01@AEBU01@@Z
??4HiRep@Duration@absl@@QEAAAEAV012@_J@Z
- ??4InlineData@cord_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4InlineRep@Cord@absl@@QEAAAEAV012@$$QEAV012@@Z
??4Payload@status_internal@absl@@QEAAAEAU012@$$QEAU012@@Z
??4Rep@CrcCordState@crc_internal@absl@@QEAAAEAU0123@AEBU0123@@Z
@@ -2566,6 +2608,17 @@ EXPORTS
??A?$Span@D@absl@@QEBAAEAD_K@Z
??A?$Span@I@absl@@QEBAAEAI_K@Z
??A?$__farray@P6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@__Cr@std@@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@456@@Z$03@__Cr@std@@QEBAAEBQ6A_K$$QEAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YA_KUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@12@AEAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@612@@Z_K@Z
+ ??A?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEAVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEAVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEAVLogSink@absl@@@__Cr@std@@QEBAAEAPEAVLogSink@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@__Cr@std@@QEBAAEAPEBVCommandLineFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@__Cr@std@@QEBAAEAPEBVCordzHandle@cord_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@QEBAAEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransition@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@QEBAAEAUTransitionType@cctz@time_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@__Cr@std@@QEBAAEAUUnrecognizedFlag@absl@@_J@Z
+ ??A?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@__Cr@std@@QEBAAEAUViableSubstitution@strings_internal@absl@@_J@Z
+ ??A?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEBAAEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@_J@Z
??A?$array@Uraw_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@$0BA@@__Cr@std@@QEAAAEAUraw_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@@12@AEBV567@@Z@_K@Z
??A?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
??A?$map@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@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?$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@@QEAAAEAV?$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@@12@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
@@ -2612,6 +2665,7 @@ EXPORTS
??C?$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@@QEBAPEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
??C?$__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@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__hash_map_const_iterator@V?$__hash_const_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@@@__Cr@std@@QEBAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
+ ??C?$__hash_map_iterator@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@@@__Cr@std@@QEBAPEAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__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@@QEBAPEAU?$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@@12@XZ
??C?$__wrap_iter@PEAPEAVCommandLineFlag@absl@@@__Cr@std@@QEBAPEAPEAVCommandLineFlag@absl@@XZ
@@ -2805,7 +2859,7 @@ EXPORTS
??R?$HashImpl@H@hash_internal@absl@@QEBA_KAEBH@Z
??R?$HashImpl@V?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBH@__Cr@std@@@Z
??R?$HashImpl@V?$tuple@AEB_K@__Cr@std@@@hash_internal@absl@@QEBA_KAEBV?$tuple@AEB_K@__Cr@std@@@Z
- ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QEBA_K_K@Z
+ ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QEBA_K_K@Z
??R?$__allocator_destructor@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
??R?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??R?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@12@@Z
@@ -3232,6 +3286,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DisableRescheduling@SchedulingGuard@base_internal@absl@@SA_NXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@AEBAP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@ZXZ
@@ -3727,6 +3782,7 @@ EXPORTS
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
?IsHeld@SpinLock@base_internal@absl@@QEBA_NXZ
?IsImmortal@RefcountAndFlags@cord_internal@absl@@QEBA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInfiniteDuration@time_internal@absl@@YA_NVDuration@2@@Z
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInlined@Status@absl@@CA_N_K@Z
@@ -3894,7 +3950,7 @@ EXPORTS
?NextCapacity@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@SA_K_K@Z
?NextCapacity@container_internal@absl@@YA_K_K@Z
?NextGeneration@container_internal@absl@@YAEE@Z
- ?NextHashTableSeed@container_internal@absl@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextRandom@ExponentialBiased@profiling_internal@absl@@SA_K_K@Z
?NextTransition@Impl@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@2345@@Z
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
@@ -4116,7 +4172,6 @@ EXPORTS
?SentinelEmptyGeneration@container_internal@absl@@YAEXZ
?Set@?$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@@AEAAXAEBV?$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@@@Z
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAllocation@?$Storage@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@PEAVLogSink@absl@@$0BA@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QEAAXU?$Allocation@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@23@@Z
@@ -4364,6 +4419,7 @@ EXPORTS
?ToInt64Nanoseconds@absl@@YA_JVDuration@1@@Z
?ToInt64Seconds@absl@@YA_JVDuration@1@@Z
?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
?ToSinkAlso@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QEAAAEAV123@PEAVLogSink@3@@Z
@@ -4518,6 +4574,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithSourceLocation@Status@absl@@QEHAA$$QEAV12@VSourceLocation@2@@Z
@@ -4538,8 +4595,41 @@ EXPORTS
?__addr@?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
?__alloc@?$__bucket_list_deallocator@V?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$__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@@@__Cr@std@@QEAAAEAV?$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@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@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?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__alloc@?$__vector_layout@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@@QEBAAEBV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAV?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@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@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
@@ -4551,13 +4641,21 @@ EXPORTS
?__annotate_contiguous_container@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_contiguous_container@?$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@@AEBAXPEBX0@Z
+ ?__annotate_delete@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
+ ?__annotate_delete@?$__vector_layout@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@@AEBAXXZ
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
- ?__annotate_delete@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
?__annotate_delete@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAXXZ
@@ -4576,19 +4674,19 @@ EXPORTS
?__annotate_increase@?$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@@AEBAX_K@Z
?__annotate_increase_back@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_increase_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
+ ?__annotate_new@?$__vector_layout@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@@AEBAX_K@Z
?__annotate_new@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_new@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
- ?__annotate_new@?$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@@AEBAX_K@Z
?__annotate_poison_block@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAXPEBX0@Z
?__annotate_shrink@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
?__annotate_shrink@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEBAX_K@Z
@@ -4607,8 +4705,8 @@ EXPORTS
?__as_base@?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__variant_detail@__Cr@std@@IEGAA@XZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__back_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__back_spare_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -4623,17 +4721,56 @@ EXPORTS
?__base_destruct_at_end@?$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@@AEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBUPrefixCrc@CrcCordState@crc_internal@absl@@PEBQEAU4567@@Z
+ ?__begin_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__capacity@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__capacity@?$__vector_layout@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@@QEBA_KXZ
?__capacity@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__complete@?$__exception_guard_noexceptions@V<lambda_1>@?0??__add_back_capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z@@__Cr@std@@QEAAXXZ
?__complete@?$__exception_guard_noexceptions@V?$_AllocatorDestroyRangeReverse@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@PEAUUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?__compose@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@PEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAU5678@@Z
- ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
- ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
+ ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAX_K@Z
?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAX_K@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEBV123@U?$integral_constant@_N$0A@@23@@Z
+ ?__data@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBQEBVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransition@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__data@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUViableSubstitution@strings_internal@absl@@XZ
+ ?__data@?$__vector_layout@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@@QEBAPEBV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__deallocate_node@?$__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@@AEAAXPEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@23@@Z
?__deallocate_node@?$__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@@AEAAXPEAU?$__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@23@@Z
?__deallocate_node_list@?$__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@@AEAAXPEAU?$__hash_node_base@PEAU?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@@23@@Z
@@ -4646,28 +4783,28 @@ EXPORTS
?__destruct_at_end@?$__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@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
?__destruct_at_end@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAPEAVLogSink@absl@@@Z
?__destruct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransition@cctz@time_internal@absl@@@Z
?__destruct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
@@ -4678,40 +4815,53 @@ EXPORTS
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEAAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
?__end_node@?$__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@@QEBAPEAV?$__tree_end_node@PEAV?$__tree_node_base@PEAX@__Cr@std@@@23@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBAPEBUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@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@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__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
?__front_cap@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?__front_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__front_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?__get@?$__optional_storage_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QEGAAAEAVStream@status_internal@absl@@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEAVLogSink@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__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@@QEAAAEAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAAEAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAAEAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_np@?$__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@@AEBAPEAV?$__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@XZ
?__get_value@?$__hash_node@PEBUCordRep@cord_internal@absl@@PEAX@__Cr@std@@QEAAAEAPEBUCordRep@cord_internal@absl@@XZ
@@ -4729,11 +4879,14 @@ EXPORTS
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@PEAPEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBQEAVLogSink@absl@@@23@PEBQEAVLogSink@absl@@@Z
?__make_iter@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@PEAPEBVCommandLineFlag@absl@@@Z
+ ?__make_iter@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@PEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransition@cctz@time_internal@absl@@@23@PEAUTransition@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUTransitionType@cctz@time_internal@absl@@@23@PEAUTransitionType@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@PEAUUnrecognizedFlag@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@PEBUUnrecognizedFlag@absl@@@Z
+ ?__make_iter@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@PEAUViableSubstitution@strings_internal@absl@@@Z
?__make_iter@?$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@@AEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@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
@@ -4758,6 +4911,32 @@ EXPORTS
?__recommend_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SA_K_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
?__rehash_unique@?$__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@@QEAAX_K@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@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@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
+ ?__relocate@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@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@@QEAAXAEAV?$__split_buffer@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@V__split_buffer_size_layout@23@@23@@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@PEAU4567@AEAPEAU4567@AEA_K2@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
?__rewrap@?$__unwrap_iter_impl@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@$00@__Cr@std@@SAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEAPEBV45678@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@$00@__Cr@std@@SAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@PEAPEAU4567@0@Z
?__rewrap@?$__unwrap_iter_impl@PEAPEAVLogSink@absl@@$00@__Cr@std@@SAPEAPEAVLogSink@absl@@PEAPEAV45@0@Z
@@ -4774,105 +4953,104 @@ EXPORTS
?__root_ptr@?$__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@@QEBAPEAPEAV?$__tree_node_base@PEAX@23@XZ
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEAU1234@AEAU1234@PEAPEAU1234@_J$0A@@23@@Z
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@__Cr@std@@SAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@23@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@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@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__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@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAX_K@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAX_K@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@_K@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@_K@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEAVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXPEAPEAVLogSink@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXPEAPEBVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransition@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXPEAUTransitionType@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__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@@QEAAXPEAUUnrecognizedFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXPEAUViableSubstitution@strings_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__size@?$__vector_layout@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
+ ?__size@?$__vector_layout@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@@QEBA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEA_KXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEB_KXZ
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAUUnrecognizedFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@00@Z
- ?__swap_layouts@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransition@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAPEAUTransitionType@cctz@time_internal@absl@@AEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PEAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$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@@AEAAXAEAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
+ ?__swap@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEAVLogSink@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCommandLineFlag@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAPEBVCordzHandle@cord_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransition@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUTransitionType@cctz@time_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__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
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAXAEAPEAUViableSubstitution@strings_internal@absl@@AEA_K1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAXAEAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AEA_K1@Z
?__swap_without_allocator@?$__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@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAXAEAV123@@Z
?__throw_length_error@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -4985,10 +5163,17 @@ EXPORTS
?back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAAEAPEAUCordRep@cord_internal@2@XZ
?back@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAAEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBAAEBUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
+ ?back@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?back@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEAVLogSink@absl@@XZ
+ ?back@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAPEBVCordzHandle@cord_internal@absl@@XZ
?back@?$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@@XZ
?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransition@cctz@time_internal@absl@@XZ
?back@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?back@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@XZ
?back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUViableSubstitution@strings_internal@absl@@XZ
+ ?back@?$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@@@23@XZ
?back@CordRepBtree@cord_internal@absl@@QEBA_KXZ
?base@?$move_iterator@PEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?base@?$move_iterator@PEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@QEGBAAEBQEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
@@ -5011,17 +5196,17 @@ EXPORTS
?begin@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBAPEBQEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?begin@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$__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?AV?$__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@23@XZ
?begin@?$array@Uraw_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@$0BA@@__Cr@std@@QEAA?AV?$__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@XZ
@@ -5061,17 +5246,17 @@ EXPORTS
?capacity@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$HashtableCapacityImpl@$00@23@XZ
?capacity@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__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@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEBA_KXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEBA_KXZ
?capacity@?$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@@QEBA_KXZ
?capacity@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
?capacity@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_KXZ
@@ -5100,17 +5285,17 @@ EXPORTS
?clear@?$__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@@QEAAXXZ
?clear@?$__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@@QEAAXXZ
?clear@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QEAAXXZ
- ?clear@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ?clear@?$__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
+ ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QEAAXXZ
+ ?clear@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QEAAXXZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?clear@?$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@@QEAAXXZ
?clear@?$unordered_map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@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@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@@QEAAXXZ
@@ -5278,6 +5463,11 @@ EXPORTS
?empty@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$map@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@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?$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@@QEBA_NXZ
?empty@?$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@@QEBA_NXZ
+ ?empty@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
+ ?empty@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
?empty@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA_NXZ
@@ -5303,17 +5493,17 @@ EXPORTS
?end@?$__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?AV?$__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@@@23@XZ
?end@?$__split_buffer_pointer_layout@V?$__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@@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEAPEBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAPEBVImpl@time_zone@cctz@time_internal@absl@@XZ
?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QEAAPEAUUnrecognizedFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEAVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEAVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@23@@__Cr@std@@QEAAPEAPEAVLogSink@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@23@@__Cr@std@@QEAAPEAPEBVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QEAAPEAPEBVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QEAAPEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransition@cctz@time_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QEAAPEAUTransitionType@cctz@time_internal@absl@@XZ
+ ?end@?$__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@@QEAAPEAUUnrecognizedFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QEAAPEAUViableSubstitution@strings_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QEAAPEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$__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?AV?$__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@23@XZ
?end@?$deque@PEBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PEBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__deque_iterator@PEBVImpl@time_zone@cctz@time_internal@absl@@PEAPEBV12345@AEAPEBV12345@PEAPEAPEBV12345@_J$0A@@23@XZ
@@ -5327,11 +5517,14 @@ EXPORTS
?end@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVCordzHandle@cord_internal@absl@@@23@XZ
?end@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEAVLogSink@absl@@@23@XZ
?end@?$vector@PEBVCommandLineFlag@absl@@V?$allocator@PEBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCommandLineFlag@absl@@@23@XZ
+ ?end@?$vector@PEBVCordzHandle@cord_internal@absl@@V?$allocator@PEBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAPEBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$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@@@23@XZ
?end@?$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@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUUnrecognizedFlag@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEBA?AV?$__wrap_iter@PEBUUnrecognizedFlag@absl@@@23@XZ
+ ?end@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAA?AV?$__wrap_iter@PEAUViableSubstitution@strings_internal@absl@@@23@XZ
?end@?$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@@QEAA?AV?$__wrap_iter@PEAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?end@ChunkRange@Cord@absl@@QEBA?AVChunkIterator@23@XZ
?end@CordRepBtree@cord_internal@absl@@QEBA_KXZ
@@ -5619,8 +5812,6 @@ EXPORTS
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@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@__Cr@std@@@__Cr@std@@SAPEAV?$__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@AEAV423@@Z
?pointer_to@?$pointer_traits@PEBU?$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@@@__Cr@std@@SAPEBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PEBVImpl@time_zone@cctz@time_internal@absl@@@23@AEBU423@@Z
- ?poison@InlineData@cord_internal@absl@@QEAAXXZ
- ?poison_this@InlineData@cord_internal@absl@@QEAAXXZ
?pop_back@?$InlinedVector@PEAUCordRep@cord_internal@absl@@$01V?$allocator@PEAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QEAAXXZ
?pop_back@?$__split_buffer@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PEAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
@@ -5721,11 +5912,9 @@ EXPORTS
?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
?second@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QEBAHXZ
- ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?seed@?$PerTableSeedImpl@E@container_internal@absl@@QEBA_KXZ
- ?seed@CommonFields@container_internal@absl@@QEBA?AV?$PerTableSeedImpl@E@23@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEAAPEAU1234@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QEBAPEBU1234@XZ
+ ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@CommonFields@container_internal@absl@@QEBA?AVPerTableSeed@23@XZ
+ ?seed@PerTableSeed@container_internal@absl@@QEBA_KXZ
?set@?$MaybeInitializedPtr@W4ctrl_t@container_internal@absl@@@container_internal@absl@@QEAAXPEAW4ctrl_t@23@@Z
?set_arg@BoundConversion@str_format_internal@absl@@QEAAXPEBVFormatArgImpl@23@@Z
?set_begin@CordRepBtree@cord_internal@absl@@AEAAX_K@Z
@@ -5884,7 +6073,6 @@ EXPORTS
?unlock@Mutex@absl@@QEAAXXZ
?unlock@SpinLock@base_internal@absl@@QEAAXXZ
?unlock_shared@Mutex@absl@@QEAAXXZ
- ?unpoison@InlineData@cord_internal@absl@@QEAAXXZ
?utc_time_zone@cctz@time_internal@absl@@YA?AVtime_zone@123@XZ
?value@ConvertibleToStringView@strings_internal@absl@@QEBA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?value@InputValue@UnboundConversion@str_format_internal@absl@@QEBAHXZ
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 96743d150e4..0430b16f860 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x64_rel.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x64_rel.def
@@ -1,6 +1,7 @@
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
@@ -105,14 +106,13 @@ EXPORTS
??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$GenRuntimeTypeId@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@@YAPEBVtype_info@@XZ
- ??$GenericCompare@HV?$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@@_K@Z
??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
??$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
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$MakeCheckOpString@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@DD@log_internal@absl@@YAPEBDDDPEBD@Z
@@ -126,23 +126,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPEBD_J0PEBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPEBD_K0PEBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPEBD_N0PEBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$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
@@ -160,6 +175,7 @@ EXPORTS
??$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
??$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
@@ -171,7 +187,7 @@ EXPORTS
??$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
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@?$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@@12@_K@Z
@@ -179,7 +195,6 @@ 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
@@ -189,10 +204,11 @@ EXPORTS
??$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
??$emplace@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QEAAAEAVStream@status_internal@absl@@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@AEBU34@@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
@@ -364,6 +380,7 @@ 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
@@ -539,6 +556,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
@@ -587,6 +605,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?Dtor@Mutex@absl@@AEAAXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@Z
@@ -862,6 +881,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_NPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_N_K0PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NAEBVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NAEBVStatus@1@@Z
@@ -952,7 +972,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
@@ -1099,7 +1119,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?SendToLog@LogMessage@log_internal@absl@@AEAAXXZ
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPEBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QEAAXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QEGAAAEAV12@W4StatusCode@2@@Z
@@ -1340,6 +1359,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QEAAAEAV123@I@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 3acb20d6df5..b3744ff7aa6 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
@@ -2,7 +2,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
??$?0$$V$0A@@?$NoDestructor@VFlagRegistry@flags_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
@@ -106,15 +105,13 @@ EXPORTS
??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$GenRuntimeTypeId@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@@YAPEBVtype_info@@XZ
- ??$GenericCompare@HV?$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@@_K@Z
??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
- ??$GenericCompare@_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YA_NAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
??$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
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$MakeCheckOpString@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@DD@log_internal@absl@@YAPEBDDDPEBD@Z
@@ -128,23 +125,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPEBD_J0PEBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPEBD_K0PEBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPEBD_N0PEBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$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
@@ -156,7 +168,7 @@ EXPORTS
??$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
??$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@VCord@absl@@@absl@@YAHAEBVCord@0@0@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
@@ -169,7 +181,7 @@ EXPORTS
??$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
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@?$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@@12@_K@Z
@@ -194,18 +206,17 @@ EXPORTS
??$__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@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
- ??$__invoke@AEAV<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@AEAVCommandLineFlag@5@@__Cr@std@@YAXAEAV<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@AEAVCommandLineFlag@6@@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@UPayload@status_internal@absl@@U123@PEAU123@@__Cr@std@@YAPEAUPayload@status_internal@absl@@PEAU234@$$QEAU234@@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
??$emplace@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QEAAAEAVStream@status_internal@absl@@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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@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
@@ -242,10 +253,10 @@ 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@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
+ ??0Cord@absl@@QEAA@AEBV01@@Z
??0CordzHandle@cord_internal@absl@@IEAA@_N@Z
??0CordzInfo@cord_internal@absl@@AEAA@PEAUCordRep@12@PEBV012@W4MethodIdentifier@CordzUpdateTracker@12@_J@Z
??0CrcCordState@crc_internal@absl@@QEAA@$$QEAV012@@Z
@@ -257,7 +268,6 @@ EXPORTS
??0HashtablezInfo@container_internal@absl@@QEAA@XZ
??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
- ??0InlineRep@Cord@absl@@QEAA@AEBV012@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VTime@2@@Z
??0LeakCheckDisabler@absl@@QEAA@XZ
@@ -329,8 +339,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@$$QEAV012@@Z
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4FlagsUsageConfig@absl@@QEAAAEAU01@AEBU01@@Z
- ??4InlineData@cord_internal@absl@@QEAAAEAV012@AEBV012@@Z
- ??4InlineRep@Cord@absl@@QEAAAEAV012@$$QEAV012@@Z
??6LogMessage@log_internal@absl@@QEAAAEAV012@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??6LogMessage@log_internal@absl@@QEAAAEAV012@AEBV?$basic_string@_WU?$char_traits@_W@__Cr@std@@V?$allocator@_W@23@@__Cr@std@@@Z
??6LogMessage@log_internal@absl@@QEAAAEAV012@P6AAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAV345@@Z@Z
@@ -364,7 +372,6 @@ 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
- ??8cord_internal@absl@@YA_NAEBVInlineData@01@0@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
@@ -380,6 +387,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?$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
@@ -554,13 +562,12 @@ 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
- ?CopyInlineToString@InlineData@cord_internal@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
?CopyPrefix@CordRepBtree@cord_internal@absl@@AEAA?AUCopyResult@123@_K_N@Z
?CopySuffix@CordRepBtree@cord_internal@absl@@AEAA?AUCopyResult@123@_K@Z
- ?CopyToArrayImpl@Cord@absl@@AEBAXPEAD@Z
?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z
?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z
?Crc32c@CRC@crc_internal@absl@@SAPEAV123@XZ
@@ -604,6 +611,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?Dtor@Mutex@absl@@AEAAXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@Z
@@ -880,6 +888,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_NPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_N_K0PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NAEBVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NAEBVStatus@1@@Z
@@ -927,7 +936,6 @@ EXPORTS
?MakeCheckOpValueString@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@D@Z
?MakeCheckOpValueString@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@E@Z
?MakeCheckOpValueString@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEBX@Z
- ?MakeFlatWithExtraCapacity@InlineRep@Cord@absl@@QEAAPEAUCordRepFlat@cord_internal@3@_K@Z
?MakeInitValue@FlagImpl@flags_internal@absl@@AEBA?AV?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@XZ
?MakeNonOkStatusWithOkCode@Status@absl@@CA?AV12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?MakeRelativeTimespec@KernelTimeout@synchronization_internal@absl@@QEBA?AUtimespec@@XZ
@@ -971,7 +979,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
@@ -1103,7 +1111,6 @@ EXPORTS
?ReportUsageError@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_N@Z
?ReserveTableToFitNewSize@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@_K@Z
?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__Cr@std@@@chrono@__Cr@std@@@Z
- ?ResetToEmpty@InlineRep@Cord@absl@@AEAAXXZ
?ResizeAllocatedTableWithSeedChange@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@_K@Z
?Restore@FlagState@flags_internal@absl@@EEHAAXXZ
?RestoreState@FlagImpl@flags_internal@absl@@AEAA_NAEBVFlagState@23@@Z
@@ -1119,7 +1126,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?SendToLog@LogMessage@log_internal@absl@@AEAAXXZ
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPEBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QEAAXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QEGAAAEAV12@W4StatusCode@2@@Z
@@ -1147,7 +1153,6 @@ EXPORTS
?SetMessage@StatusPrivateAccessorForStatusBuilder@status_internal@absl@@SA?AVStatus@3@AEBV43@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetMinLogLevel@absl@@YAXW4LogSeverityAtLeast@1@@Z
?SetMutexDeadlockDetectionMode@absl@@YAXW4OnDeadlockCycle@1@@Z
- ?SetPayload@Status@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VCord@2@@Z
?SetPayload@StatusRep@status_internal@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VCord@3@@Z
?SetProgramInvocationName@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetProgramUsageMessage@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -1159,7 +1164,6 @@ EXPORTS
?SetTimeZone@log_internal@absl@@YAXVTimeZone@2@@Z
?SetToZero@?$BigUnsigned@$03@strings_internal@absl@@QEAAXXZ
?SetToZero@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXXZ
- ?SetTreeOrEmpty@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@AEBVCordzUpdateScope@53@@Z
?SetVModuleListHeadForTestOnly@log_internal@absl@@YAPEAVVLogSite@12@PEAV312@@Z
?ShiftLeft@?$BigUnsigned@$03@strings_internal@absl@@QEAAXH@Z
?ShiftLeft@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z
@@ -1362,6 +1366,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QEAAAEAV123@I@Z
@@ -1379,7 +1384,8 @@ EXPORTS
?__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
?__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
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@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
?__throw_length_error@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -1423,11 +1429,9 @@ EXPORTS
?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
- ?poison@InlineData@cord_internal@absl@@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
- ?remove_prefix@InlineRep@Cord@absl@@QEAAX_K@Z
?reserve@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAX_K@Z
?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAX_K@Z
?reserve@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAX_K@Z
@@ -1454,10 +1458,8 @@ EXPORTS
?shrink_to_fit@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?size@?$BigUnsigned@$03@strings_internal@absl@@QEBAHXZ
?size@?$BigUnsigned@$0FE@@strings_internal@absl@@QEBAHXZ
- ?size@Cord@absl@@QEBA_KXZ
?status@BadStatusOrAccess@absl@@QEBAAEBVStatus@2@XZ
?stream@OstreamView@LogMessage@log_internal@absl@@QEAAAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
- ?tag@Rep@InlineData@cord_internal@absl@@QEBACXZ
?transfer_unprobed_elements_to_next_capacity_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@@CAXAEAVCommonFields@23@PEBW4ctrl_t@23@PEAX2P6AX2E_K3@Z@Z
?try_lock@Mutex@absl@@QEAA_NXZ
?try_lock_shared@Mutex@absl@@QEAA_NXZ
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 bc011d31c68..62ca7bbcfeb 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
@@ -2,7 +2,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
??$?0$$V$0A@@?$NoDestructor@VFlagRegistry@flags_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
@@ -106,15 +105,13 @@ EXPORTS
??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$GenRuntimeTypeId@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@@YAPEBVtype_info@@XZ
- ??$GenericCompare@HV?$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@@_K@Z
??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
- ??$GenericCompare@_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@absl@@YA_NAEBVCord@0@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
??$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
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$MakeCheckOpString@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@DD@log_internal@absl@@YAPEBDDDPEBD@Z
@@ -128,23 +125,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPEBD_J0PEBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPEBD_K0PEBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPEBD_N0PEBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$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
@@ -156,7 +168,7 @@ EXPORTS
??$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
??$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@VCord@absl@@@absl@@YAHAEBVCord@0@0@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
@@ -167,7 +179,7 @@ EXPORTS
??$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
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@?$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@@12@_K@Z
@@ -192,18 +204,17 @@ EXPORTS
??$__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@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
- ??$__invoke@AEAV<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@AEAVCommandLineFlag@5@@__Cr@std@@YAXAEAV<lambda_1>@?0??SaveFromRegistry@FlagSaverImpl@flags_internal@absl@@QEAAXXZ@AEAVCommandLineFlag@6@@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@UPayload@status_internal@absl@@U123@PEAU123@@__Cr@std@@YAPEAUPayload@status_internal@absl@@PEAU234@$$QEAU234@@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
??$emplace@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QEAAAEAVStream@status_internal@absl@@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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@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
@@ -247,10 +258,10 @@ 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@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
+ ??0Cord@absl@@QEAA@AEBV01@@Z
??0CordzHandle@cord_internal@absl@@IEAA@_N@Z
??0CordzInfo@cord_internal@absl@@AEAA@PEAUCordRep@12@PEBV012@W4MethodIdentifier@CordzUpdateTracker@12@_J@Z
??0CrcCordState@crc_internal@absl@@QEAA@$$QEAV012@@Z
@@ -262,7 +273,6 @@ EXPORTS
??0HashtablezInfo@container_internal@absl@@QEAA@XZ
??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
- ??0InlineRep@Cord@absl@@QEAA@AEBV012@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VDuration@2@@Z
??0KernelTimeout@synchronization_internal@absl@@QEAA@VTime@2@@Z
??0LeakCheckDisabler@absl@@QEAA@XZ
@@ -334,8 +344,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@$$QEAV012@@Z
??4CrcCordState@crc_internal@absl@@QEAAAEAV012@AEBV012@@Z
??4FlagsUsageConfig@absl@@QEAAAEAU01@AEBU01@@Z
- ??4InlineData@cord_internal@absl@@QEAAAEAV012@AEBV012@@Z
- ??4InlineRep@Cord@absl@@QEAAAEAV012@$$QEAV012@@Z
??6LogMessage@log_internal@absl@@QEAAAEAV012@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??6LogMessage@log_internal@absl@@QEAAAEAV012@AEBV?$basic_string@_WU?$char_traits@_W@__Cr@std@@V?$allocator@_W@23@@__Cr@std@@@Z
??6LogMessage@log_internal@absl@@QEAAAEAV012@P6AAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEAV345@@Z@Z
@@ -369,7 +377,6 @@ 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
- ??8cord_internal@absl@@YA_NAEBVInlineData@01@0@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
@@ -385,6 +392,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?$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
@@ -559,13 +567,12 @@ 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
- ?CopyInlineToString@InlineData@cord_internal@absl@@QEBAXPEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
?CopyPrefix@CordRepBtree@cord_internal@absl@@AEAA?AUCopyResult@123@_K_N@Z
?CopySuffix@CordRepBtree@cord_internal@absl@@AEAA?AUCopyResult@123@_K@Z
- ?CopyToArrayImpl@Cord@absl@@AEBAXPEAD@Z
?CopyToArraySlowPath@Cord@absl@@AEBAXPEAD@Z
?Crash@Helper@internal_statusor@absl@@SAXAEBVStatus@3@@Z
?Crc32c@CRC@crc_internal@absl@@SAPEAV123@XZ
@@ -609,6 +616,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?Dtor@Mutex@absl@@AEAAXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@Z
@@ -885,6 +893,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_NPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_N_K0PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NAEBVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NAEBVStatus@1@@Z
@@ -932,7 +941,6 @@ EXPORTS
?MakeCheckOpValueString@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@D@Z
?MakeCheckOpValueString@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@E@Z
?MakeCheckOpValueString@log_internal@absl@@YAXAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEBX@Z
- ?MakeFlatWithExtraCapacity@InlineRep@Cord@absl@@QEAAPEAUCordRepFlat@cord_internal@3@_K@Z
?MakeInitValue@FlagImpl@flags_internal@absl@@AEBA?AV?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@XZ
?MakeNonOkStatusWithOkCode@Status@absl@@CA?AV12@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?MakeRelativeTimespec@KernelTimeout@synchronization_internal@absl@@QEBA?AUtimespec@@XZ
@@ -976,7 +984,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
@@ -1108,7 +1116,6 @@ EXPORTS
?ReportUsageError@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_N@Z
?ReserveTableToFitNewSize@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@_K@Z
?ResetToBuiltinUTC@TimeZoneInfo@cctz@time_internal@absl@@AEAA_NAEBV?$duration@_JV?$ratio@$00$00@__Cr@std@@@chrono@__Cr@std@@@Z
- ?ResetToEmpty@InlineRep@Cord@absl@@AEAAXXZ
?ResizeAllocatedTableWithSeedChange@container_internal@absl@@YAXAEAVCommonFields@12@AEBUPolicyFunctions@12@_K@Z
?Restore@FlagState@flags_internal@absl@@EEHAAXXZ
?RestoreState@FlagImpl@flags_internal@absl@@AEAA_NAEBVFlagState@23@@Z
@@ -1124,7 +1131,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?SendToLog@LogMessage@log_internal@absl@@AEAAXXZ
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPEBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QEAAXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QEGAAAEAV12@W4StatusCode@2@@Z
@@ -1152,7 +1158,6 @@ EXPORTS
?SetMessage@StatusPrivateAccessorForStatusBuilder@status_internal@absl@@SA?AVStatus@3@AEBV43@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetMinLogLevel@absl@@YAXW4LogSeverityAtLeast@1@@Z
?SetMutexDeadlockDetectionMode@absl@@YAXW4OnDeadlockCycle@1@@Z
- ?SetPayload@Status@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VCord@2@@Z
?SetPayload@StatusRep@status_internal@absl@@QEAAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VCord@3@@Z
?SetProgramInvocationName@flags_internal@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?SetProgramUsageMessage@absl@@YAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
@@ -1164,7 +1169,6 @@ EXPORTS
?SetTimeZone@log_internal@absl@@YAXVTimeZone@2@@Z
?SetToZero@?$BigUnsigned@$03@strings_internal@absl@@QEAAXXZ
?SetToZero@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXXZ
- ?SetTreeOrEmpty@InlineRep@Cord@absl@@QEAAXPEAUCordRep@cord_internal@3@AEBVCordzUpdateScope@53@@Z
?SetVModuleListHeadForTestOnly@log_internal@absl@@YAPEAVVLogSite@12@PEAV312@@Z
?ShiftLeft@?$BigUnsigned@$03@strings_internal@absl@@QEAAXH@Z
?ShiftLeft@?$BigUnsigned@$0FE@@strings_internal@absl@@QEAAXH@Z
@@ -1367,6 +1371,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QEAAAEAV123@I@Z
@@ -1384,7 +1389,8 @@ EXPORTS
?__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
?__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
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AEAAXAEAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@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
?__throw_length_error@?$vector@PEAVCordzHandle@cord_internal@absl@@V?$allocator@PEAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PEAVLogSink@absl@@V?$allocator@PEAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -1428,11 +1434,9 @@ EXPORTS
?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
- ?poison@InlineData@cord_internal@absl@@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
- ?remove_prefix@InlineRep@Cord@absl@@QEAAX_K@Z
?reserve@?$vector@PEAVCommandLineFlag@absl@@V?$allocator@PEAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAX_K@Z
?reserve@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAX_K@Z
?reserve@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAX_K@Z
@@ -1459,10 +1463,8 @@ EXPORTS
?shrink_to_fit@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QEAAXXZ
?size@?$BigUnsigned@$03@strings_internal@absl@@QEBAHXZ
?size@?$BigUnsigned@$0FE@@strings_internal@absl@@QEBAHXZ
- ?size@Cord@absl@@QEBA_KXZ
?status@BadStatusOrAccess@absl@@QEBAAEBVStatus@2@XZ
?stream@OstreamView@LogMessage@log_internal@absl@@QEAAAEAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
- ?tag@Rep@InlineData@cord_internal@absl@@QEBACXZ
?transfer_unprobed_elements_to_next_capacity_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@@CAXAEAVCommonFields@23@PEBW4ctrl_t@23@PEAX2P6AX2E_K3@Z@Z
?try_lock@Mutex@absl@@QEAA_NXZ
?try_lock_shared@Mutex@absl@@QEAA_NXZ
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 b4a8135b94a..37d6f8a1d89 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,6 +1,7 @@
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
@@ -105,14 +106,13 @@ EXPORTS
??$Flush@VBufferRawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Flush@VFILERawSink@str_format_internal@absl@@@FormatRawSinkImpl@str_format_internal@absl@@CAXPEAXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$GenRuntimeTypeId@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@@YAPEBVtype_info@@XZ
- ??$GenericCompare@HV?$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@@_K@Z
??$GenericCompare@HVCord@absl@@@absl@@YAHAEBVCord@0@0_K@Z
??$GenericCompare@_NVCord@absl@@@absl@@YA_NAEBVCord@0@0_K@Z
??$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
??$GrowSooTableToNextCapacityAndPrepareInsert@$0A@$0A@@container_internal@absl@@YAPEAXAEAVCommonFields@01@AEBUPolicyFunctions@01@V?$FunctionRef@$$A6A_K_K@Z@1@_N@Z
- ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
+ ??$InvokeObject@AEAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@_K_K@functional_internal@absl@@YA_KTVoidPtr@01@_K@Z
??$MakeCheckOpString@AEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@AEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AEBV123@@log_internal@absl@@YAPEBDAEBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PEBD@Z
??$MakeCheckOpString@DD@log_internal@absl@@YAPEBDDDPEBD@Z
@@ -126,23 +126,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPEBD_J0PEBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPEBD_K0PEBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPEBD_N0PEBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPEAV012@PEAV012@0@Z
??$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
@@ -160,6 +175,7 @@ EXPORTS
??$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
??$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
@@ -170,7 +186,7 @@ EXPORTS
??$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
??$TransferNRelocatable@$0BI@@container_internal@absl@@YAXPEAX00_K@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YA_K_K00PEAW4ctrl_t@01@0@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YA_KPEBXPEAX_K@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YA_KPEBXPEAX_K@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PEBU1234@AEBU1234@PEBQEBU1234@_J$0A@@__Cr@std@@@?$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@@12@_K@Z
@@ -178,7 +194,6 @@ 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
@@ -188,10 +203,11 @@ EXPORTS
??$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
??$emplace@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QEAAAEAVStream@status_internal@absl@@AEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QEAAXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QEAAXXZ
+ ??$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@AEBUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QEAAAEAUUnrecognizedFlag@absl@@AEBU34@@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
@@ -364,6 +380,7 @@ 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
@@ -539,6 +556,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
@@ -587,6 +605,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPEBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPEBX@Z
?Dtor@Mutex@absl@@AEAAXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@AEBVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@AEBVCord@3@@Z
@@ -862,6 +881,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_NPEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QEBA_N_K0PEAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NAEBVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NAEBVStatus@1@@Z
@@ -952,7 +972,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QEBA_NVTime@2@PEAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UEBA_NAEBV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PEAUcivil_transition@time_zone@234@@Z
@@ -1099,7 +1119,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QEAA?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@_K@Z
?SendToLog@LogMessage@log_internal@absl@@AEAAXXZ
?Set@MaskedPointer@flags_internal@absl@@QEAAXP6APEAXW4FlagOp@23@PEBXPEAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPEBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QEAAXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QEGAAAEAV12@W4StatusCode@2@@Z
@@ -1340,6 +1359,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PEAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YA_K_WPEADAEAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CA_K_KV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QEAAAEAV123@AEBVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QEAAAEAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QEAAAEAV123@I@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 10f1a476e38..5dc09c0c875 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x86_dbg.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x86_dbg.def
@@ -36,31 +36,6 @@ EXPORTS
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AAPAVCommandLineFlag@absl@@AA_N@__Cr@std@@QAE@AAPAVCommandLineFlag@absl@@AA_N@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AAUFindInfo@container_internal@absl@@AAV?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QAE@AAUFindInfo@container_internal@absl@@AAV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@ABQAVCommandLineFlag@absl@@@__Cr@std@@QAE@ABQAVCommandLineFlag@absl@@@Z
- ??$?0$00X@?$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@@QAE@XZ
- ??$?0$00X@?$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@@QAE@XZ
- ??$?0$00X@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PBVImpl@time_zone@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__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@@V?$__hash_node_destructor@V?$allocator@U?$__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@@@23@@__Cr@std@@QAE@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@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__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@@@12@@Z
- ??$?0$00X@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAULogMessageData@LogMessage@log_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@PAURep@StatusBuilder@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
- ??$?0$00X@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPAX@Z@__Cr@std@@QAE@PAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
- ??$?0$00X@?$unique_ptr@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFlagState@flags_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneInfo@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneLibC@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVZoneInfoSource@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@PAX$$QAUDynValueDeleter@flags_internal@absl@@@Z
??$?0AAI@?$Storage@I$0A@U?$StorageTag@IV?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$0A@@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@AAI@Z
??$?0AAIABV?$allocator@D@__Cr@std@@$00@?$CompressedTuple@IV?$allocator@D@__Cr@std@@@container_internal@absl@@QAE@AAIABV?$allocator@D@__Cr@std@@@Z
??$?0AAIABV?$allocator@D@__Cr@std@@@?$CompressedTupleImpl@V?$CompressedTuple@IV?$allocator@D@__Cr@std@@@container_internal@absl@@U?$integer_sequence@I$0A@$00@__Cr@std@@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@AAIABV?$allocator@D@56@@Z
@@ -119,6 +94,7 @@ EXPORTS
??$?0I@FormatArgImpl@str_format_internal@absl@@QAE@ABI@Z
??$?0M@FormatArgImpl@str_format_internal@absl@@QAE@ABM@Z
??$?0N@FormatArgImpl@str_format_internal@absl@@QAE@ABN@Z
+ ??$?0P6AXPAX@Z$0A@@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPAX@Z@__Cr@std@@QAE@PAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z
??$?0PAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QAE@PAI0@Z
??$?0PAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV01234@$0A@@?$pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV12345@@__Cr@std@@QAE@$$QAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$?0PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PAPAU0123@$0A@@?$pair@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PAPAU1234@@__Cr@std@@QAE@$$QAPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
@@ -138,10 +114,26 @@ EXPORTS
??$?0PBD@FormatArgImpl@str_format_internal@absl@@QAE@ABQBD@Z
??$?0PBUPrefixCrc@CrcCordState@crc_internal@absl@@PBU0123@$0A@@?$pair@PBUPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@@__Cr@std@@QAE@$$QAPBUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$?0PBVFormatArgImpl@str_format_internal@absl@@$0A@@?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@QAE@PBVFormatArgImpl@str_format_internal@1@0ABV?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@?$FunctionRef@$$A6AII@Z@absl@@IAE@Uin_place_t@__Cr@std@@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@X@?$FunctionRef@$$A6AII@Z@absl@@QAE@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@?$FunctionRef@$$A6AII@Z@absl@@IAE@Uin_place_t@__Cr@std@@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@X@?$FunctionRef@$$A6AII@Z@absl@@QAE@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$?0U?$__check_pair_construction@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@$0A@@?$pair@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QAE@ABUFindInfo@container_internal@absl@@ABV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0U?$array@D$0DKJI@@__Cr@std@@XU012@H@?$Span@D@absl@@QAE@AAU?$array@D$0DKJI@@__Cr@std@@@Z
+ ??$?0U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PBVImpl@time_zone@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAULogMessageData@LogMessage@log_internal@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@PAURep@StatusBuilder@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??$?0U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFlagState@flags_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
+ ??$?0U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneLibC@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVZoneInfoSource@cctz@time_internal@absl@@@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@$$T@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@PAX$$QAUDynValueDeleter@flags_internal@absl@@@Z
??$?0UHex@absl@@X@AlphaNum@absl@@QAE@ABUHex@1@$$QAVStringifySink@strings_internal@1@@Z
??$?0UStringEq@container_internal@absl@@@?$Storage@UStringEq@container_internal@absl@@$01U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAUStringEq@23@@Z
??$?0UStringHash@container_internal@absl@@@?$Storage@UStringHash@container_internal@absl@@$00U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAUStringHash@23@@Z
@@ -192,12 +184,20 @@ EXPORTS
??$?0V?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@XV01@H@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QAE@ABV?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@1@@Z
??$?0V?$Span@D@absl@@XV01@$0A@@?$Span@$$CBD@absl@@QAE@ABV?$Span@D@1@@Z
??$?0V?$Span@I@absl@@XV01@$0A@@?$Span@$$CBI@absl@@QAE@ABV?$Span@I@1@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@QAE@XZ
+ ??$?0V?$__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@@@__Cr@std@@$0A@@?$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@@QAE@XZ
??$?0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V012@$0A@@?$pair@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V123@@__Cr@std@@QAE@$$QAV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@0@Z
??$?0V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@AA_N$0A@@?$pair@V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QAE@$$QAV?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@12@AA_N@Z
??$?0V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N$0A@@?$pair@V?$__hash_const_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QAE@$$QAU?$pair@V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N@12@@Z
??$?0V?$__hash_iterator@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@@AA_N$0A@@?$pair@V?$__hash_iterator@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@@_N@__Cr@std@@QAE@$$QAV?$__hash_iterator@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@@@12@AA_N@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__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@@$0A@@?$unique_ptr@U?$__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@@V?$__hash_node_destructor@V?$allocator@U?$__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@@@23@@__Cr@std@@QAE@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@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__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@@@12@@Z
??$?0V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@AA_N$0A@@?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@_N@__Cr@std@@QAE@$$QAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@12@AA_N@Z
??$?0V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@AA_N$0A@@?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@_N@__Cr@std@@QAE@$$QAV?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@12@AA_N@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
??$?0V?$allocator@D@__Cr@std@@@?$Storage@V?$allocator@D@__Cr@std@@$02U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAV?$allocator@D@56@@Z
??$?0V?$allocator@D@__Cr@std@@@AlphaNum@absl@@QAE@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?0V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@?$Storage@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@U?$StorageTag@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@I@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAV?$allocator@PAUCordRep@cord_internal@absl@@@56@@Z
@@ -335,11 +335,11 @@ EXPORTS
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_backward_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QBE?AU?$__in_out_result@PAUTransitionType@cctz@time_internal@absl@@PAU1234@@12@PAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QBE?AU?$__in_out_result@PAUTransitionType@cctz@time_internal@absl@@PAU1234@@12@PAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@12@$0A@@__copy_impl@__Cr@std@@QBE?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@23@@12@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@12@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@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
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@$$QBV?$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@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@QBE_NABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@45@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@45@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@45@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@45@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@45@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@45@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@FindElement@?$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?AVconst_iterator@123@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@67@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@67@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@67@@Z
??$?RVDuration@absl@@V01@@?$__less@XX@__Cr@std@@QBE_NABVDuration@absl@@0@Z
??$?RVMixingHashState@hash_internal@absl@@@CombineRaw@hash_internal@absl@@QBE?AVMixingHashState@12@V312@_K@Z
@@ -410,7 +410,7 @@ EXPORTS
??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPADPBDI@Z
??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPADPBDI@Z
??$AssertHashEqConsistent@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@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@IAEXABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@functional_internal@absl@@YAXABU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@functional_internal@absl@@YAXABU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$AssertOnFind@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@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@IAEXABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Assign@V?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PBVSourceLocation@absl@@@inlined_vector_internal@absl@@@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXV?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PBVSourceLocation@absl@@@12@I@Z
??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPAUPayload@status_internal@1@AAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@01@I@Z
@@ -461,12 +461,12 @@ EXPORTS
??$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
??$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@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@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
??$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@V?$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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@Z
??$DecomposePair@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@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@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@01@$$QAUFindElement@301@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePairImpl@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@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
- ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00@12@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
+ ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@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
??$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
@@ -614,7 +614,7 @@ EXPORTS
??$InvokeFlush@VBufferRawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPAVBufferRawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeFlush@VFILERawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPAVFILERawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeGet@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?$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@@@FlagImplPeer@flags_internal@absl@@SA?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@@@12@@Z
- ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
+ ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
??$InvokeParseFlag@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAHPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@M@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAMPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@N@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PANPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
@@ -661,24 +661,39 @@ EXPORTS
??$MakeCheckOpValueString@_K@log_internal@absl@@YAXAAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AB_K@Z
??$MakeCheckOpValueString@_N@log_internal@absl@@YAXAAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AB_N@Z
??$MakeConstSpan@$SQAX@absl@@YA?AV?$Span@QAX@0@PBQAXI@Z
- ??$MakeError@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorFromStringView@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$MakeSpan@$S$$CBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@ABV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@0@@Z
??$MakeSpan@$S$$CBVSourceLocation@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@PBVSourceLocation@0@I@Z
??$MakeSpan@$SD@absl@@YA?AV?$Span@D@0@PADI@Z
@@ -854,7 +869,7 @@ EXPORTS
??$TrailingZeros@_K@container_internal@absl@@YAI_K@Z
??$TransferNRelocatable@$0M@@container_internal@absl@@YAXPAX00I@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YAIIIIPAW4ctrl_t@01@I@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YAIPBXPAXI@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YAIPBXPAXI@Z
??$UnhidePtr@X@base_internal@absl@@YAPAXI@Z
??$Unparse@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@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABV?$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@@34@@Z
??$UnparseFlag@H@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABH@Z
@@ -865,11 +880,16 @@ EXPORTS
??$__add_alignment_assumption@PAPAVCordzHandle@cord_internal@absl@@$0A@@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAPAVCordzHandle@cord_internal@absl@@PAPAV345@@Z
??$__add_alignment_assumption@PAPAVLogSink@absl@@$0A@@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPAPAVLogSink@absl@@PAPAV34@@Z
??$__add_alignment_assumption@PAPBVCommandLineFlag@absl@@$0A@@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAPAPBVCommandLineFlag@absl@@PAPBV34@@Z
+ ??$__add_alignment_assumption@PAPBVCordzHandle@cord_internal@absl@@$0A@@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAPBVCordzHandle@cord_internal@absl@@PAPBV345@@Z
??$__add_alignment_assumption@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PAU3456@@Z
??$__add_alignment_assumption@PAUTransition@cctz@time_internal@absl@@$0A@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUTransition@cctz@time_internal@absl@@PAU3456@@Z
??$__add_alignment_assumption@PAUTransitionType@cctz@time_internal@absl@@$0A@@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUTransitionType@cctz@time_internal@absl@@PAU3456@@Z
??$__add_alignment_assumption@PAUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPAUUnrecognizedFlag@absl@@PAU34@@Z
+ ??$__add_alignment_assumption@PAUViableSubstitution@strings_internal@absl@@$0A@@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUViableSubstitution@strings_internal@absl@@PAU345@@Z
??$__add_alignment_assumption@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@CAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@PAV312@@Z
+ ??$__add_alignment_assumption@PBQAVLogSink@absl@@$0A@@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPBQAVLogSink@absl@@PBQAV34@@Z
+ ??$__add_alignment_assumption@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@PBU3456@@Z
+ ??$__add_alignment_assumption@PBUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPBUUnrecognizedFlag@absl@@PBU34@@Z
??$__advance@PBUTransition@cctz@time_internal@absl@@@__Cr@std@@YAXAAPBUTransition@cctz@time_internal@absl@@HUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAAV?$__wrap_iter@PAPAVCommandLineFlag@absl@@@01@HUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PAPBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAAV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@01@HUrandom_access_iterator_tag@01@@Z
@@ -966,13 +986,13 @@ EXPORTS
??$__construct_at_end@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@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@@AAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@0I@Z
??$__construct_at_end@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__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@@QAEXV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
??$__construct_at_end@V?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end_with_size@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@I@Z
+ ??$__construct_at_end@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end_with_size@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@I@Z
??$__construct_at_end_with_size@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@?$__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@@QAEXV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@12@I@Z
??$__construct_at_end_with_size@V?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@I@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@I@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@I@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@I@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@I@Z
??$__construct_node@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QAV?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@AAE?AV?$unique_ptr@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
??$__construct_node@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@ABV?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@AAE?AV?$unique_ptr@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
??$__construct_node_hash@ABQBUCordRep@cord_internal@absl@@@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AAE?AV?$unique_ptr@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@@12@IABQBUCordRep@cord_internal@absl@@@Z
@@ -1135,7 +1155,7 @@ EXPORTS
??$__in_bounds@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@@@__Cr@std@@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@@@23@$0A@@__unique_ptr_array_bounds_stateless@__Cr@std@@QBE_NPAPAU?$__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@@@12@I@Z
??$__insert_assign_n_unchecked@U_ClassicAlgPolicy@__Cr@std@@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@23@$0A@@?$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@@AAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@HPAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$__insert_with_size@U_ClassicAlgPolicy@__Cr@std@@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@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@@AAE?AV?$__wrap_iter@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@1H@Z
- ??$__invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QAI@Z
+ ??$__invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QAI@Z
??$__invoke@AAUByCivilTime@Transition@cctz@time_internal@absl@@ABU2345@ABU2345@@__Cr@std@@YA_NAAUByCivilTime@Transition@cctz@time_internal@absl@@ABU3456@1@Z
??$__invoke@AAUByUnixTime@Transition@cctz@time_internal@absl@@ABU2345@ABU2345@@__Cr@std@@YA_NAAUByUnixTime@Transition@cctz@time_internal@absl@@ABU3456@1@Z
??$__invoke@AAU__identity@__Cr@std@@AAPAVLogSink@absl@@@__Cr@std@@YAAAPAVLogSink@absl@@AAU__identity@01@AAPAV23@@Z
@@ -1346,8 +1366,8 @@ EXPORTS
??$advance@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@HH$0A@@__Cr@std@@YAXAAV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@01@H@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$apply@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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
@@ -1356,12 +1376,16 @@ EXPORTS
??$apply@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@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$assign@PBVSourceLocation@absl@@$0A@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QAEXPBVSourceLocation@1@0@Z
??$assign@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@$0A@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@0@Z
+ ??$begin@V?$Span@$$CBI@absl@@@__Cr@std@@YAPBIABV?$Span@$$CBI@absl@@@Z
??$begin@V?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPAVCommandLineFlag@absl@@@01@AAV?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$begin@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@01@AAV?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$bit_cast@PAXVFastTypeIdType@absl@@@__Cr@std@@YAPAXABVFastTypeIdType@absl@@@Z
??$bit_cast@U?$FlagValueAndInitBit@_N@flags_internal@absl@@_J@__Cr@std@@YA?AU?$FlagValueAndInitBit@_N@flags_internal@absl@@AB_J@Z
??$bit_cast@VFastTypeIdType@absl@@PAX@__Cr@std@@YA?AVFastTypeIdType@absl@@ABQAX@Z
+ ??$c_begin@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPBIABV?$Span@$$CBI@1@@Z
??$c_begin@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AAV?$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@@34@@Z
+ ??$c_copy@V?$Span@$$CBI@absl@@PAI@absl@@YAPAIABV?$Span@$$CBI@0@$$QAPAI@Z
+ ??$c_end@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPBIABV?$Span@$$CBI@1@@Z
??$c_end@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AAV?$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@@34@@Z
??$call_once@A6AXXZ$$V@absl@@YAXAAVonce_flag@0@A6AXXZ@Z
??$call_once@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@absl@@YAXAAVonce_flag@0@$$QAP8FlagImpl@flags_internal@0@AEXXZ$$QAPAV230@@Z
@@ -1508,8 +1532,8 @@ EXPORTS
??$emplace@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QAE?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@@$$QAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$emplace_at@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@?$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@@IAEXPAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@12@ABUpiecewise_construct_t@__Cr@std@@$$QAV?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
??$emplace_at@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@?$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@@IAEXPAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@12@ABUpiecewise_construct_t@__Cr@std@@$$QAV?$tuple@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ??$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@@QAEXXZ
??$emplace_back@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_back@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_back@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABV123@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUViableSubstitution@strings_internal@absl@@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@ABV612@AAI@Z
@@ -1535,6 +1559,7 @@ EXPORTS
??$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
??$emplace_front@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
+ ??$end@V?$Span@$$CBI@absl@@@__Cr@std@@YAPBIABV?$Span@$$CBI@absl@@@Z
??$end@V?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPAVCommandLineFlag@absl@@@01@AAV?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$end@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@01@AAV?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$find@V?$__wrap_iter@PAPAVLogSink@absl@@@__Cr@std@@PAVLogSink@absl@@@__Cr@std@@YA?AV?$__wrap_iter@PAPAVLogSink@absl@@@01@V201@0ABQAVLogSink@absl@@@Z
@@ -1607,7 +1632,7 @@ EXPORTS
??$hash_with_seed@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@$0A@@MixingHashState@hash_internal@absl@@SAIABV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@I@Z
??$insert@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QAE?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@@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$insert@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@$0A@@?$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@@QAE?AV?$__wrap_iter@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@1@Z
- ??$invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QAI@Z
+ ??$invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QAI@Z
??$invoke@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@__Cr@std@@YAX$$QAP8FlagImpl@flags_internal@absl@@AEXXZ$$QAPAV234@@Z
??$iter_swap@AAPAPAVCommandLineFlag@absl@@AAPAPAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAAPAPAVCommandLineFlag@absl@@0@Z
??$iter_swap@AAPAPAVCommandLineFlag@absl@@PAPAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAAPAPAVCommandLineFlag@absl@@$$QAPAPAV34@@Z
@@ -1689,6 +1714,9 @@ EXPORTS
??$safe_strtoi_base@K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAKH@Z
??$safe_strtoi_base@_J@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PA_JH@Z
??$safe_strtoi_base@_K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PA_KH@Z
+ ??$size@U<unnamed-type-locks>@SynchLocksHeld@absl@@$0CI@@__Cr@std@@YAIAAY0CI@$$CBU<unnamed-type-locks>@SynchLocksHeld@absl@@@Z
+ ??$size@UGraphId@synchronization_internal@absl@@$09@__Cr@std@@YAIAAY09$$CBUGraphId@synchronization_internal@absl@@@Z
+ ??$size@USpinLockWaitTransition@base_internal@absl@@$02@__Cr@std@@YAIAAY02$$CBUSpinLockWaitTransition@base_internal@absl@@@Z
??$swap@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@YAXAAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$swap@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@YAXAAPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$swap@PAPAVCommandLineFlag@absl@@@__Cr@std@@YAXAAPAPAVCommandLineFlag@absl@@0@Z
@@ -1736,8 +1764,8 @@ EXPORTS
??0?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@absl@@QAE@PBD@Z
??0?$FormatSpecTemplate@$0JPPPL@$0JPOAA@@str_format_internal@absl@@QAE@PBD@Z
??0?$FormatSpecTemplate@$0JPPPL@@str_format_internal@absl@@QAE@PBD@Z
- ??0?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QAE@ABUStringHash@12@I@Z
- ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QAE@ABUStringHash@12@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??0?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QAE@ABUStringHash@12@I@Z
+ ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QAE@ABUStringHash@12@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@AAE@W4InvalidCapacity@012@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QAE@I@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QAE@Uuninitialized_tag_t@12@@Z
@@ -1757,7 +1785,6 @@ EXPORTS
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@V?$move_iterator@PAVSourceLocation@absl@@@23@@inlined_vector_internal@absl@@QAE@ABV?$move_iterator@PAVSourceLocation@absl@@@__Cr@std@@@Z
??0?$NonIterableBitMask@I$0BA@$0A@@container_internal@absl@@QAE@I@Z
??0?$NonIterableBitMask@_K$07$02@container_internal@absl@@QAE@_K@Z
- ??0?$PerTableSeedImpl@E@container_internal@absl@@AAE@_K@Z
??0?$ProbedItemImpl@I$0CA@@container_internal@absl@@QAE@EII@Z
??0?$ProbedItemImpl@_K$0EA@@container_internal@absl@@QAE@EII@Z
??0?$ProbedItemImpl@_K$0HK@@container_internal@absl@@QAE@EII@Z
@@ -1851,8 +1878,8 @@ EXPORTS
??0?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
- ??0?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QAE@XZ
- ??0?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QAE@XZ
+ ??0?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QAE@XZ
+ ??0?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QAE@XZ
??0?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
@@ -1863,32 +1890,32 @@ EXPORTS
??0?$__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@@QAE@XZ
??0?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??0?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAE@IIAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAE@IIAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@XZ
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAE@XZ
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__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@@QAE@ABV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@@12@@Z
??0?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@12@@Z
??0?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@AAE@PAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@12@@Z
@@ -1899,13 +1926,27 @@ EXPORTS
??0?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@AAV?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@12@_N@Z
??0?$__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@@__Cr@std@@QAE@XZ
??0?$__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@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@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@@QAE@XZ
??0?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@AAE@PAPAVCommandLineFlag@absl@@@Z
??0?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@__Cr@std@@AAE@PAPAVCordzHandle@cord_internal@absl@@@Z
??0?$__wrap_iter@PAPAVLogSink@absl@@@__Cr@std@@AAE@PAPAVLogSink@absl@@@Z
??0?$__wrap_iter@PAPBVCommandLineFlag@absl@@@__Cr@std@@AAE@PAPBVCommandLineFlag@absl@@@Z
+ ??0?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@__Cr@std@@AAE@PAPBVCordzHandle@cord_internal@absl@@@Z
+ ??0?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@AAE@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
??0?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@AAE@PAUTransition@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@AAE@PAUTransitionType@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PAUUnrecognizedFlag@absl@@@__Cr@std@@AAE@PAUUnrecognizedFlag@absl@@@Z
+ ??0?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@__Cr@std@@AAE@PAUViableSubstitution@strings_internal@absl@@@Z
??0?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@AAE@PAUraw_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@@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@@12@ABV567@@Z@@Z
??0?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@AAE@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@@Z
??0?$__wrap_iter@PBQAVLogSink@absl@@@__Cr@std@@AAE@PBQAVLogSink@absl@@@Z
@@ -2077,7 +2118,6 @@ 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@ABV012@@Z
??0InlineData@cord_internal@absl@@QAE@W4DefaultInitType@012@@Z
??0InlineData@cord_internal@absl@@QAE@XZ
??0InlineRep@Cord@absl@@QAE@$$QAV012@@Z
@@ -2118,6 +2158,7 @@ EXPORTS
??0ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE@PAV123@@Z
??0Payload@status_internal@absl@@QAE@$$QAU012@@Z
??0Payload@status_internal@absl@@QAE@ABU012@@Z
+ ??0PerTableSeed@container_internal@absl@@AAE@_K@Z
??0PosixTimeZone@cctz@time_internal@absl@@QAE@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QAE@IVcrc32c_t@3@@Z
??0PrefixCrc@CrcCordState@crc_internal@absl@@QAE@XZ
@@ -2127,6 +2168,7 @@ EXPORTS
??0ReaderMutexLock@absl@@QAE@AAVMutex@1@@Z
??0RefcountAndFlags@cord_internal@absl@@QAE@XZ
??0RefcountedRep@CrcCordState@crc_internal@absl@@QAE@XZ
+ ??0ReleasableMutexLock@absl@@QAE@AAVMutex@1@@Z
??0Rep@CordBuffer@absl@@QAE@PAUCordRepFlat@cord_internal@2@@Z
??0Rep@CordBuffer@absl@@QAE@XZ
??0Rep@CrcCordState@crc_internal@absl@@QAE@XZ
@@ -2191,8 +2233,8 @@ EXPORTS
??0ZoneInfoSource@cctz@time_internal@absl@@QAE@XZ
??0_ConstructTransaction@?$__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@@QAE@PAV123@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@I@Z
??0_ConstructTransaction@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@PAV123@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@I@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@PAV123@PAUTransition@cctz@time_internal@absl@@I@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@PAV123@PAUTransitionType@cctz@time_internal@absl@@I@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@PAV123@PAUTransition@cctz@time_internal@absl@@I@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@PAV123@PAUTransitionType@cctz@time_internal@absl@@I@Z
??0_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAV123@AAU__deque_block_range@123@@Z
??0_ConstructTransaction@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@AAV123@I@Z
??0_ConstructTransaction@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@AAV123@I@Z
@@ -2271,8 +2313,8 @@ EXPORTS
??1?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
- ??1?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QAE@XZ
- ??1?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QAE@XZ
+ ??1?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QAE@XZ
+ ??1?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QAE@XZ
??1?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
@@ -2284,17 +2326,17 @@ EXPORTS
??1?$__policy_func@$$A6A_NABVCommandLineFlag@absl@@@Z@__function@__Cr@std@@QAE@XZ
??1?$__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@@QAE@XZ
??1?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAE@XZ
??1?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE@XZ
@@ -2389,6 +2431,7 @@ EXPORTS
??1PosixTimeZone@cctz@time_internal@absl@@QAE@XZ
??1ReaderMutexLock@absl@@QAE@XZ
??1RefcountedRep@CrcCordState@crc_internal@absl@@QAE@XZ
+ ??1ReleasableMutexLock@absl@@QAE@XZ
??1Rep@CrcCordState@crc_internal@absl@@QAE@XZ
??1Rep@GraphCycles@synchronization_internal@absl@@QAE@XZ
??1Rep@StatusBuilder@absl@@QAE@XZ
@@ -2415,8 +2458,8 @@ EXPORTS
??1ZoneInfoSource@cctz@time_internal@absl@@UAE@XZ
??1_ConstructTransaction@?$__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@@QAE@XZ
??1_ConstructTransaction@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
??1_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1_ConstructTransaction@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1_ConstructTransaction@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
@@ -2442,7 +2485,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QAEAAV012@ABV012@@Z
??4FlagsUsageConfig@absl@@QAEAAU01@ABU01@@Z
??4HiRep@Duration@absl@@QAEAAV012@_J@Z
- ??4InlineData@cord_internal@absl@@QAEAAV012@ABV012@@Z
??4InlineRep@Cord@absl@@QAEAAV012@$$QAV012@@Z
??4Payload@status_internal@absl@@QAEAAU012@$$QAU012@@Z
??4Rep@CrcCordState@crc_internal@absl@@QAEAAU0123@ABU0123@@Z
@@ -2551,6 +2593,17 @@ EXPORTS
??A?$Span@D@absl@@QBEAADI@Z
??A?$Span@I@absl@@QBEAAII@Z
??A?$__farray@P6AI$$QAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YAIUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@__Cr@std@@AAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@456@@Z$03@__Cr@std@@QBEABQ6AI$$QAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YAIUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@12@AAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@612@@ZI@Z
+ ??A?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@QBEAAPAVCommandLineFlag@absl@@H@Z
+ ??A?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@__Cr@std@@QBEAAPAVCordzHandle@cord_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAPAVLogSink@absl@@@__Cr@std@@QBEAAPAVLogSink@absl@@H@Z
+ ??A?$__wrap_iter@PAPBVCommandLineFlag@absl@@@__Cr@std@@QBEAAPBVCommandLineFlag@absl@@H@Z
+ ??A?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@__Cr@std@@QBEAAPBVCordzHandle@cord_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@QBEAAUConversionItem@ParsedFormatBase@str_format_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@QBEAAUTransition@cctz@time_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@QBEAAUTransitionType@cctz@time_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUUnrecognizedFlag@absl@@@__Cr@std@@QBEAAUUnrecognizedFlag@absl@@H@Z
+ ??A?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@__Cr@std@@QBEAAUViableSubstitution@strings_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QBEAAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@H@Z
??A?$array@Uraw_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@@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@@ABV345@@Z@$0BA@@__Cr@std@@QAEAAUraw_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@@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@@12@ABV567@@Z@I@Z
??A?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABUPrefixCrc@CrcCordState@crc_internal@absl@@I@Z
??A?$map@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@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?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@12@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
@@ -2597,6 +2650,7 @@ EXPORTS
??C?$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@@QBEPBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
??C?$__hash_iterator@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@@QBEPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__hash_map_const_iterator@V?$__hash_const_iterator@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@@QBEPBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
+ ??C?$__hash_map_iterator@V?$__hash_iterator@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@@QBEPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@QBEPAU?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@12@XZ
??C?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@QBEPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@12@XZ
??C?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@QBEPAPAVCommandLineFlag@absl@@XZ
@@ -2790,7 +2844,7 @@ EXPORTS
??R?$HashImpl@H@hash_internal@absl@@QBEIABH@Z
??R?$HashImpl@V?$tuple@ABI@__Cr@std@@@hash_internal@absl@@QBEIABV?$tuple@ABI@__Cr@std@@@Z
??R?$HashImpl@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@@hash_internal@absl@@QBEIABV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@@Z
- ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QBEII@Z
+ ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QBEII@Z
??R?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
??R?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??R?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAEXPAPAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@12@@Z
@@ -3217,6 +3271,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DisableRescheduling@SchedulingGuard@base_internal@absl@@SA_NXZ
?DoIgnoreLeak@absl@@YAXPBX@Z
?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@ABVCord@absl@@@Z@base_internal@absl@@ABEP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@ABVCord@3@@ZXZ
@@ -3713,6 +3768,7 @@ EXPORTS
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
?IsHeld@SpinLock@base_internal@absl@@QBE_NXZ
?IsImmortal@RefcountAndFlags@cord_internal@absl@@QBE_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInfiniteDuration@time_internal@absl@@YA_NVDuration@2@@Z
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInlined@Status@absl@@CA_NI@Z
@@ -3879,7 +3935,7 @@ EXPORTS
?NextCapacity@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@SAII@Z
?NextCapacity@container_internal@absl@@YAII@Z
?NextGeneration@container_internal@absl@@YAEE@Z
- ?NextHashTableSeed@container_internal@absl@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextRandom@ExponentialBiased@profiling_internal@absl@@SA_K_K@Z
?NextTransition@Impl@time_zone@cctz@time_internal@absl@@QBE_NABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PAUcivil_transition@2345@@Z
?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z
@@ -4101,7 +4157,6 @@ EXPORTS
?SentinelEmptyGeneration@container_internal@absl@@YAEXZ
?Set@?$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@@AAEXABV?$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@@@Z
?Set@MaskedPointer@flags_internal@absl@@QAEXP6APAXW4FlagOp@23@PBXPAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAllocation@?$Storage@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@PAVLogSink@absl@@$0BA@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@23@@Z
@@ -4349,6 +4404,7 @@ EXPORTS
?ToInt64Nanoseconds@absl@@YA_JVDuration@1@@Z
?ToInt64Seconds@absl@@YA_JVDuration@1@@Z
?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
?ToSinkAlso@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
@@ -4503,6 +4559,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YAI_WPADAAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CAIIV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QAEAAV123@ABVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QAEAAV123@XZ
?WithSourceLocation@Status@absl@@QHAE$$QAV12@VSourceLocation@2@@Z
@@ -4523,8 +4580,41 @@ EXPORTS
?__addr@?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
?__alloc@?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$__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@@@__Cr@std@@QAEAAV?$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@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@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?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__alloc@?$__vector_layout@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@@QBEABV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
+ ?__annotate_contiguous_container@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@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@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
@@ -4536,13 +4626,21 @@ EXPORTS
?__annotate_contiguous_container@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$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@@ABEXPBX0@Z
+ ?__annotate_delete@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@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@@ABEXXZ
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
- ?__annotate_delete@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
- ?__annotate_delete@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
- ?__annotate_delete@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
@@ -4561,19 +4659,19 @@ EXPORTS
?__annotate_increase@?$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@@ABEXI@Z
?__annotate_increase_back@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
?__annotate_increase_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@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@@ABEXI@Z
?__annotate_new@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
?__annotate_new@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$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@@ABEXI@Z
?__annotate_poison_block@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_shrink@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
?__annotate_shrink@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
@@ -4592,8 +4690,8 @@ EXPORTS
?__as_base@?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__variant_detail@__Cr@std@@IGAE@XZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__back_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__back_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__back_spare@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__back_spare_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
@@ -4608,17 +4706,56 @@ EXPORTS
?__base_destruct_at_end@?$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@@AAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PBQAU4567@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPBUPrefixCrc@CrcCordState@crc_internal@absl@@PBQAU4567@@Z
+ ?__begin_ptr@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@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@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__capacity@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@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@@QBEIXZ
?__capacity@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__complete@?$__exception_guard_noexceptions@V<lambda_1>@?0??__add_back_capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXI@Z@@__Cr@std@@QAEXXZ
?__complete@?$__exception_guard_noexceptions@V?$_AllocatorDestroyRangeReverse@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@PAUUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXXZ
?__compose@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@__Cr@std@@@__Cr@std@@SA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@23@PBQAUPrefixCrc@CrcCordState@crc_internal@absl@@PAU5678@@Z
- ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXI@Z
- ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXI@Z
+ ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXI@Z
+ ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXI@Z
?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXI@Z
?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXI@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXABV123@@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXABV123@U?$integral_constant@_N$0A@@23@@Z
+ ?__data@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBQBVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBQBVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransition@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBUUnrecognizedFlag@absl@@XZ
+ ?__data@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUViableSubstitution@strings_internal@absl@@XZ
+ ?__data@?$__vector_layout@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@@QBEPBV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__deallocate_node@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AAEXPAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@23@@Z
?__deallocate_node@?$__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@@AAEXPAU?$__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@23@@Z
?__deallocate_node_list@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AAEXPAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@23@@Z
@@ -4631,28 +4768,28 @@ EXPORTS
?__destruct_at_end@?$__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@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
?__destruct_at_end@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAEXPAPAVLogSink@absl@@@Z
?__destruct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXPAUTransition@cctz@time_internal@absl@@@Z
?__destruct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXPAUTransitionType@cctz@time_internal@absl@@@Z
@@ -4663,40 +4800,53 @@ EXPORTS
?__end_node@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QBEPAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@23@XZ
?__end_node@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@23@XZ
?__end_node@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QBEPAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@23@XZ
+ ?__end_ptr@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@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@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__erase_to_end@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@23@@Z
?__front_cap@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__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@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__front_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__front_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__front_spare@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__front_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__get@?$__optional_storage_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QGAEAAVStream@status_internal@absl@@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVLogSink@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVLogSink@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__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@@QAEAAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__get_np@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@ABEPAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@XZ
?__get_np@?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@ABEPAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@XZ
?__get_value@?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@QAEAAPBUCordRep@cord_internal@absl@@XZ
@@ -4714,11 +4864,14 @@ EXPORTS
?__make_iter@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAPAVLogSink@absl@@@23@PAPAVLogSink@absl@@@Z
?__make_iter@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABE?AV?$__wrap_iter@PBQAVLogSink@absl@@@23@PBQAVLogSink@absl@@@Z
?__make_iter@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@23@PAPBVCommandLineFlag@absl@@@Z
+ ?__make_iter@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@23@PAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABE?AV?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@23@PAUTransition@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@23@PAUTransitionType@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUUnrecognizedFlag@absl@@@23@PAUUnrecognizedFlag@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABE?AV?$__wrap_iter@PBUUnrecognizedFlag@absl@@@23@PBUUnrecognizedFlag@absl@@@Z
+ ?__make_iter@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@23@PAUViableSubstitution@strings_internal@absl@@@Z
?__make_iter@?$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@@AAE?AV?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__maybe_remove_back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAE_N_N@Z
?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXPAUTransition@cctz@time_internal@absl@@00@Z
@@ -4743,6 +4896,32 @@ EXPORTS
?__recommend_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SAII@Z
?__rehash_unique@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@QAEXI@Z
?__rehash_unique@?$__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@@QAEXI@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPAVCommandLineFlag@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPAVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXAAPAPAVLogSink@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPBVCommandLineFlag@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPBVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXAAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransition@cctz@time_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransitionType@cctz@time_internal@absl@@AAI1@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@@QAEXAAPAUUnrecognizedFlag@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXAAPAUViableSubstitution@strings_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXAAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AAI1@Z
+ ?__relocate@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@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@@QAEXAAV?$__split_buffer@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@V__split_buffer_size_layout@23@@23@@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@PAU4567@AAPAU4567@AAI2@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@PAU4567@AAPAU4567@AAI2@Z
+ ?__relocate_with_pivot@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@AAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PAU4567@@Z
+ ?__relocate_with_pivot@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@AAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PAU4567@@Z
?__rewrap@?$__unwrap_iter_impl@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@$00@__Cr@std@@SAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV45678@0@Z
?__rewrap@?$__unwrap_iter_impl@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@$00@__Cr@std@@SAPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PAPAU4567@0@Z
?__rewrap@?$__unwrap_iter_impl@PAPAVLogSink@absl@@$00@__Cr@std@@SAPAPAVLogSink@absl@@PAPAV45@0@Z
@@ -4759,105 +4938,104 @@ EXPORTS
?__root_ptr@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QBEPAPAV?$__tree_node_base@PAX@23@XZ
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPBQAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@23@@Z
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPBQAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@23@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@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@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__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@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXI@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__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@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__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@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@I@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@I@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__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@@QAEXPAUUnrecognizedFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__size@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@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@@QBEIXZ
?__size@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAIXZ
?__size@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABIXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAIXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABIXZ
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPAVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPAVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXAAPAPAVLogSink@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPBVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPBVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXAAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransition@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransitionType@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXAAPAUUnrecognizedFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXAAPAUViableSubstitution@strings_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXAAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@00@Z
- ?__swap_layouts@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$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@@AAEXAAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEPAUTransition@cctz@time_internal@absl@@AAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEPAUTransitionType@cctz@time_internal@absl@@AAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$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@@AAEXAAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
+ ?__swap@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV123@@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPAVCommandLineFlag@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPAVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXAAPAPAVLogSink@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPBVCommandLineFlag@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPBVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXAAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransition@cctz@time_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransitionType@cctz@time_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__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@@QAEXAAPAUUnrecognizedFlag@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXAAPAUViableSubstitution@strings_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXAAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AAI1@Z
?__swap_without_allocator@?$__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@@QAEXAAV123@@Z
?__swap_without_allocator@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXAAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
?__throw_length_error@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -4957,10 +5135,17 @@ EXPORTS
?back@?$InlinedVector@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QAEAAPAUCordRep@cord_internal@2@XZ
?back@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEAAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
+ ?back@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAPAVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAPAVCordzHandle@cord_internal@absl@@XZ
+ ?back@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEAAPAVLogSink@absl@@XZ
+ ?back@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAPBVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAPBVCordzHandle@cord_internal@absl@@XZ
?back@?$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@@XZ
?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUTransition@cctz@time_internal@absl@@XZ
?back@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUTransitionType@cctz@time_internal@absl@@XZ
+ ?back@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAUUnrecognizedFlag@absl@@XZ
?back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUViableSubstitution@strings_internal@absl@@XZ
+ ?back@?$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@XZ
?back@CordRepBtree@cord_internal@absl@@QBEIXZ
?base@?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@QGBEABQAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?base@?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@QGBEABQAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
@@ -4983,17 +5168,17 @@ EXPORTS
?begin@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEPBQAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?begin@?$__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@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?begin@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@23@XZ
?begin@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@23@XZ
?begin@?$array@Uraw_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@@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@@ABV345@@Z@$0BA@@__Cr@std@@QAE?AV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@23@XZ
@@ -5033,17 +5218,17 @@ EXPORTS
?capacity@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AV?$HashtableCapacityImpl@$00@23@XZ
?capacity@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__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@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QBEIXZ
?capacity@?$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@@QBEIXZ
?capacity@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?capacity@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
@@ -5072,17 +5257,17 @@ EXPORTS
?clear@?$__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@@QAEXXZ
?clear@?$__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@@QAEXXZ
?clear@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXXZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXXZ
?clear@?$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@@QAEXXZ
?clear@?$unordered_map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@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@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@@QAEXXZ
@@ -5250,6 +5435,11 @@ EXPORTS
?empty@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$map@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@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?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QBE_NXZ
?empty@?$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_NXZ
+ ?empty@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
@@ -5275,17 +5465,17 @@ EXPORTS
?end@?$__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@@QAE?AV?$__hash_iterator@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@@@23@XZ
?end@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?end@?$__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@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?end@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@23@XZ
?end@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@23@XZ
?end@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__deque_iterator@PBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@AAPBV12345@PAPAPBV12345@H$0A@@23@XZ
@@ -5299,11 +5489,14 @@ EXPORTS
?end@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@23@XZ
?end@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPAVLogSink@absl@@@23@XZ
?end@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@23@XZ
+ ?end@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBE?AV?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@23@XZ
?end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUUnrecognizedFlag@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBE?AV?$__wrap_iter@PBUUnrecognizedFlag@absl@@@23@XZ
+ ?end@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@23@XZ
?end@?$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@@QAE?AV?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?end@ChunkRange@Cord@absl@@QBE?AVChunkIterator@23@XZ
?end@CordRepBtree@cord_internal@absl@@QBEIXZ
@@ -5591,8 +5784,6 @@ EXPORTS
?pointer_to@?$pointer_traits@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@SAPAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@AAV423@@Z
?pointer_to@?$pointer_traits@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@SAPAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@AAV423@@Z
?pointer_to@?$pointer_traits@PBU?$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@@@__Cr@std@@SAPBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@ABU423@@Z
- ?poison@InlineData@cord_internal@absl@@QAEXXZ
- ?poison_this@InlineData@cord_internal@absl@@QAEXXZ
?pop_back@?$InlinedVector@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QAEXXZ
?pop_back@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXXZ
@@ -5693,11 +5884,9 @@ EXPORTS
?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
?second@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
- ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AV?$PerTableSeedImpl@E@23@XZ
- ?seed@?$PerTableSeedImpl@E@container_internal@absl@@QBEIXZ
- ?seed@CommonFields@container_internal@absl@@QBE?AV?$PerTableSeedImpl@E@23@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QAEPAU1234@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QBEPBU1234@XZ
+ ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AVPerTableSeed@23@XZ
+ ?seed@CommonFields@container_internal@absl@@QBE?AVPerTableSeed@23@XZ
+ ?seed@PerTableSeed@container_internal@absl@@QBEIXZ
?set@?$MaybeInitializedPtr@W4ctrl_t@container_internal@absl@@@container_internal@absl@@QAEXPAW4ctrl_t@23@@Z
?set_arg@BoundConversion@str_format_internal@absl@@QAEXPBVFormatArgImpl@23@@Z
?set_begin@CordRepBtree@cord_internal@absl@@AAEXI@Z
@@ -5856,7 +6045,6 @@ EXPORTS
?unlock@Mutex@absl@@QAEXXZ
?unlock@SpinLock@base_internal@absl@@QAEXXZ
?unlock_shared@Mutex@absl@@QAEXXZ
- ?unpoison@InlineData@cord_internal@absl@@QAEXXZ
?utc_time_zone@cctz@time_internal@absl@@YA?AVtime_zone@123@XZ
?value@ConvertibleToStringView@strings_internal@absl@@QBE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?value@InputValue@UnboundConversion@str_format_internal@absl@@QBEHXZ
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 c00a9d8c26f..6f1a9600edc 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
@@ -36,31 +36,6 @@ EXPORTS
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AAPAVCommandLineFlag@absl@@AA_N@__Cr@std@@QAE@AAPAVCommandLineFlag@absl@@AA_N@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@AAUFindInfo@container_internal@absl@@AAV?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QAE@AAUFindInfo@container_internal@absl@@AAV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0$$Y_And@__Cr@std@@$0A@@?$tuple@ABQAVCommandLineFlag@absl@@@__Cr@std@@QAE@ABQAVCommandLineFlag@absl@@@Z
- ??$?0$00X@?$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@@QAE@XZ
- ??$?0$00X@?$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@@QAE@XZ
- ??$?0$00X@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PBVImpl@time_zone@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@U?$__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@@V?$__hash_node_destructor@V?$allocator@U?$__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@@@23@@__Cr@std@@QAE@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@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__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@@@12@@Z
- ??$?0$00X@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAULogMessageData@LogMessage@log_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@PAURep@StatusBuilder@absl@@@Z
- ??$?0$00X@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
- ??$?0$00X@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPAX@Z@__Cr@std@@QAE@PAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
- ??$?0$00X@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
- ??$?0$00X@?$unique_ptr@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
- ??$?0$00X@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFlagState@flags_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneInfo@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneLibC@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVZoneInfoSource@cctz@time_internal@absl@@@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@$$T@Z
- ??$?0$00X@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@PAX$$QAUDynValueDeleter@flags_internal@absl@@@Z
??$?0AAI@?$Storage@I$0A@U?$StorageTag@IV?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$0A@@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@AAI@Z
??$?0AAIABV?$allocator@D@__Cr@std@@$00@?$CompressedTuple@IV?$allocator@D@__Cr@std@@@container_internal@absl@@QAE@AAIABV?$allocator@D@__Cr@std@@@Z
??$?0AAIABV?$allocator@D@__Cr@std@@@?$CompressedTupleImpl@V?$CompressedTuple@IV?$allocator@D@__Cr@std@@@container_internal@absl@@U?$integer_sequence@I$0A@$00@__Cr@std@@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@AAIABV?$allocator@D@56@@Z
@@ -119,6 +94,7 @@ EXPORTS
??$?0I@FormatArgImpl@str_format_internal@absl@@QAE@ABI@Z
??$?0M@FormatArgImpl@str_format_internal@absl@@QAE@ABM@Z
??$?0N@FormatArgImpl@str_format_internal@absl@@QAE@ABN@Z
+ ??$?0P6AXPAX@Z$0A@@?$unique_ptr@UThreadIdentity@base_internal@absl@@P6AXPAX@Z@__Cr@std@@QAE@PAUThreadIdentity@base_internal@absl@@ABQ6AXPAX@Z@Z
??$?0PAI@?$SaltedSeedSeq@Vseed_seq@__Cr@std@@@random_internal@absl@@QAE@PAI0@Z
??$?0PAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV01234@$0A@@?$pair@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV12345@@__Cr@std@@QAE@$$QAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$?0PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PAPAU0123@$0A@@?$pair@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PAPAU1234@@__Cr@std@@QAE@$$QAPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
@@ -138,9 +114,25 @@ EXPORTS
??$?0PBD@FormatArgImpl@str_format_internal@absl@@QAE@ABQBD@Z
??$?0PBUPrefixCrc@CrcCordState@crc_internal@absl@@PBU0123@$0A@@?$pair@PBUPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@@__Cr@std@@QAE@$$QAPBUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$?0PBVFormatArgImpl@str_format_internal@absl@@$0A@@?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@QAE@PBVFormatArgImpl@str_format_internal@1@0ABV?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@?$FunctionRef@$$A6AII@Z@absl@@IAE@Uin_place_t@__Cr@std@@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
- ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@X@?$FunctionRef@$$A6AII@Z@absl@@QAE@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@?$FunctionRef@$$A6AII@Z@absl@@IAE@Uin_place_t@__Cr@std@@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
+ ??$?0U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@X@?$FunctionRef@$$A6AII@Z@absl@@QAE@$$QAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$?0U?$array@D$0DKJI@@__Cr@std@@XU012@H@?$Span@D@absl@@QAE@AAU?$array@D$0DKJI@@__Cr@std@@@Z
+ ??$?0U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@$$CBVImpl@time_zone@cctz@time_internal@absl@@U?$default_delete@$$CBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PBVImpl@time_zone@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@ULogMessageData@LogMessage@log_internal@absl@@U?$default_delete@ULogMessageData@LogMessage@log_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAULogMessageData@LogMessage@log_internal@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@PAURep@StatusBuilder@absl@@@Z
+ ??$?0U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@$0A@@?$unique_ptr@URep@StatusBuilder@absl@@U?$default_delete@URep@StatusBuilder@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@PAV?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@Z
+ ??$?0U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@$0A@@?$unique_ptr@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@U?$default_delete@V?$InlinedVector@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??$?0U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFallbackCrcMemcpyEngine@crc_internal@absl@@U?$default_delete@VFallbackCrcMemcpyEngine@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFallbackCrcMemcpyEngine@crc_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagState@flags_internal@absl@@U?$default_delete@VFlagState@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVFlagState@flags_internal@absl@@@Z
+ ??$?0U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
+ ??$?0U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneInfo@cctz@time_internal@absl@@U?$default_delete@VTimeZoneInfo@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneInfo@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VTimeZoneLibC@cctz@time_internal@absl@@U?$default_delete@VTimeZoneLibC@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVTimeZoneLibC@cctz@time_internal@absl@@@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@$$T@Z
+ ??$?0U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$unique_ptr@VZoneInfoSource@cctz@time_internal@absl@@U?$default_delete@VZoneInfoSource@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAVZoneInfoSource@cctz@time_internal@absl@@@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@$$T@Z
+ ??$?0UDynValueDeleter@flags_internal@absl@@$0A@@?$unique_ptr@XUDynValueDeleter@flags_internal@absl@@@__Cr@std@@QAE@PAX$$QAUDynValueDeleter@flags_internal@absl@@@Z
??$?0UFindInfo@container_internal@absl@@AAV?$NonIterableBitMask@I$0BA@$0A@@12@$0A@@?$pair@UFindInfo@container_internal@absl@@V?$NonIterableBitMask@I$0BA@$0A@@23@@__Cr@std@@QAE@$$QAUFindInfo@container_internal@absl@@AAV?$NonIterableBitMask@I$0BA@$0A@@45@@Z
??$?0UHex@absl@@X@AlphaNum@absl@@QAE@ABUHex@1@$$QAVStringifySink@strings_internal@1@@Z
??$?0UStringEq@container_internal@absl@@@?$Storage@UStringEq@container_internal@absl@@$01U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@23@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAUStringEq@23@@Z
@@ -192,12 +184,20 @@ EXPORTS
??$?0V?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@absl@@XV01@H@?$Span@$$CBVFormatArgImpl@str_format_internal@absl@@@absl@@QAE@ABV?$InlinedVector@VFormatArgImpl@str_format_internal@absl@@$03V?$allocator@VFormatArgImpl@str_format_internal@absl@@@__Cr@std@@@1@@Z
??$?0V?$Span@D@absl@@XV01@$0A@@?$Span@$$CBD@absl@@QAE@ABV?$Span@D@1@@Z
??$?0V?$Span@I@absl@@XV01@$0A@@?$Span@$$CBI@absl@@QAE@ABV?$Span@I@1@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAPBVImpl@time_zone@cctz@time_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@PAUPrefixCrc@CrcCordState@crc_internal@absl@@$$QAV?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@12@@Z
+ ??$?0V?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@QAE@XZ
+ ??$?0V?$__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@@@__Cr@std@@$0A@@?$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@@QAE@XZ
??$?0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V012@$0A@@?$pair@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V123@@__Cr@std@@QAE@$$QAV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@0@Z
??$?0V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@AA_N$0A@@?$pair@V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QAE@$$QAV?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@12@AA_N@Z
??$?0V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N$0A@@?$pair@V?$__hash_const_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N@__Cr@std@@QAE@$$QAU?$pair@V?$__hash_iterator@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@_N@12@@Z
??$?0V?$__hash_iterator@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@@AA_N$0A@@?$pair@V?$__hash_iterator@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@@_N@__Cr@std@@QAE@$$QAV?$__hash_iterator@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@@@12@AA_N@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__hash_node_destructor@V?$allocator@U?$__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@@$0A@@?$unique_ptr@U?$__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@@V?$__hash_node_destructor@V?$allocator@U?$__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@@@23@@__Cr@std@@QAE@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@12@$$QAV?$__hash_node_destructor@V?$allocator@U?$__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@@@12@@Z
??$?0V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@AA_N$0A@@?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@_N@__Cr@std@@QAE@$$QAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@12@AA_N@Z
??$?0V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@AA_N$0A@@?$pair@V?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@_N@__Cr@std@@QAE@$$QAV?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@12@AA_N@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
+ ??$?0V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@$0A@@?$unique_ptr@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@12@$$QAV?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@12@@Z
??$?0V?$allocator@D@__Cr@std@@@?$Storage@V?$allocator@D@__Cr@std@@$02U?$StorageTag@VCommonFields@container_internal@absl@@UStringHash@23@UStringEq@23@V?$allocator@D@__Cr@std@@@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAV?$allocator@D@56@@Z
??$?0V?$allocator@D@__Cr@std@@@AlphaNum@absl@@QAE@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@Z
??$?0V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@?$Storage@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@$0A@U?$StorageTag@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@I@internal_compressed_tuple@container_internal@absl@@$00@internal_compressed_tuple@container_internal@absl@@QAE@Uin_place_t@__Cr@std@@$$QAV?$allocator@PAUCordRep@cord_internal@absl@@@56@@Z
@@ -335,11 +335,11 @@ EXPORTS
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_backward_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QBE?AU?$__in_out_result@PAUTransitionType@cctz@time_internal@absl@@PAU1234@@12@PAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RUTransitionType@cctz@time_internal@absl@@U0123@$0A@@?$__move_impl@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@QBE?AU?$__in_out_result@PAUTransitionType@cctz@time_internal@absl@@PAU1234@@12@PAUTransitionType@cctz@time_internal@absl@@00@Z
??$?RV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@12@$0A@@__copy_impl@__Cr@std@@QBE?AU?$__in_out_result@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@23@@12@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@0V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@12@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$$V@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@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
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@$$QBV?$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@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@QBE_NABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@45@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@45@@Z
- ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@45@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@45@@Z
+ ??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QBEIABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@45@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@45@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@45@@Z
??$?RV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@12@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$tuple@ABQAVCommandLineFlag@absl@@@12@@FindElement@?$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?AVconst_iterator@123@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABUpiecewise_construct_t@67@$$QAV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@67@$$QAV?$tuple@ABQAVCommandLineFlag@absl@@@67@@Z
??$?RVDuration@absl@@V01@@?$__less@XX@__Cr@std@@QBE_NABVDuration@absl@@0@Z
??$?RVMixingHashState@hash_internal@absl@@@CombineRaw@hash_internal@absl@@QBE?AVMixingHashState@12@V312@_K@Z
@@ -410,7 +410,7 @@ EXPORTS
??$AsciiStrCaseFoldImpl@$0A@$00@ascii_internal@absl@@YAXPADPBDI@Z
??$AsciiStrCaseFoldImpl@$0A@$0A@@ascii_internal@absl@@YAXPADPBDI@Z
??$AssertHashEqConsistent@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@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@IAEXABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
- ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@@functional_internal@absl@@YAXABU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@1@@Z
+ ??$AssertNonNull@U?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@@functional_internal@absl@@YAXABU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@1@@Z
??$AssertOnFind@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@@PAVCommandLineFlag@absl@@@container_internal@absl@@$$V@container_internal@absl@@IAEXABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$Assign@V?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PBVSourceLocation@absl@@@inlined_vector_internal@absl@@@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXV?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@PBVSourceLocation@absl@@@12@I@Z
??$AssignElements@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@inlined_vector_internal@absl@@@inlined_vector_internal@absl@@YAXPAUPayload@status_internal@1@AAV?$IteratorValueAdapter@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@V?$move_iterator@PAUPayload@status_internal@absl@@@23@@01@I@Z
@@ -461,12 +461,12 @@ EXPORTS
??$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
??$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@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@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
??$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@V?$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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@Z
??$DecomposePair@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@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@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@01@$$QAUFindElement@301@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$DecomposePairImpl@U?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@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
- ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00@12@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
+ ??$DecomposePairImpl@U?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@V?$tuple@ABQAVCommandLineFlag@absl@@@56@@memory_internal@container_internal@absl@@YAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@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
??$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
@@ -614,7 +614,7 @@ EXPORTS
??$InvokeFlush@VBufferRawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPAVBufferRawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeFlush@VFILERawSink@str_format_internal@absl@@@str_format_internal@absl@@YAXPAVFILERawSink@01@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??$InvokeGet@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?$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@@@FlagImplPeer@flags_internal@absl@@SA?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@@@12@@Z
- ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
+ ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
??$InvokeParseFlag@H@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAHPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@M@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAMPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
??$InvokeParseFlag@N@flags_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PANPAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
@@ -661,24 +661,39 @@ EXPORTS
??$MakeCheckOpValueString@_K@log_internal@absl@@YAXAAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AB_K@Z
??$MakeCheckOpValueString@_N@log_internal@absl@@YAXAAV?$basic_ostream@DU?$char_traits@D@__Cr@std@@@__Cr@std@@AB_N@Z
??$MakeConstSpan@$SQAX@absl@@YA?AV?$Span@QAX@0@PBQAXI@Z
- ??$MakeError@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorFromStringView@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$MakeSpan@$S$$CBV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@ABV?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@0@@Z
??$MakeSpan@$S$$CBVSourceLocation@absl@@@absl@@YA?AV?$Span@$$CBVSourceLocation@absl@@@0@PBVSourceLocation@0@I@Z
??$MakeSpan@$SD@absl@@YA?AV?$Span@D@0@PADI@Z
@@ -847,7 +862,7 @@ EXPORTS
??$TrailingZeros@_K@container_internal@absl@@YAI_K@Z
??$TransferNRelocatable@$0M@@container_internal@absl@@YAXPAX00I@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YAIIIIPAW4ctrl_t@01@I@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YAIPBXPAXI@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YAIPBXPAXI@Z
??$UnhidePtr@X@base_internal@absl@@YAPAXI@Z
??$Unparse@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@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABV?$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@@34@@Z
??$UnparseFlag@H@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABH@Z
@@ -858,11 +873,16 @@ EXPORTS
??$__add_alignment_assumption@PAPAVCordzHandle@cord_internal@absl@@$0A@@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAPAVCordzHandle@cord_internal@absl@@PAPAV345@@Z
??$__add_alignment_assumption@PAPAVLogSink@absl@@$0A@@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPAPAVLogSink@absl@@PAPAV34@@Z
??$__add_alignment_assumption@PAPBVCommandLineFlag@absl@@$0A@@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAPAPBVCommandLineFlag@absl@@PAPBV34@@Z
+ ??$__add_alignment_assumption@PAPBVCordzHandle@cord_internal@absl@@$0A@@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAPBVCordzHandle@cord_internal@absl@@PAPBV345@@Z
??$__add_alignment_assumption@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@PAU3456@@Z
??$__add_alignment_assumption@PAUTransition@cctz@time_internal@absl@@$0A@@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUTransition@cctz@time_internal@absl@@PAU3456@@Z
??$__add_alignment_assumption@PAUTransitionType@cctz@time_internal@absl@@$0A@@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUTransitionType@cctz@time_internal@absl@@PAU3456@@Z
??$__add_alignment_assumption@PAUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPAUUnrecognizedFlag@absl@@PAU34@@Z
+ ??$__add_alignment_assumption@PAUViableSubstitution@strings_internal@absl@@$0A@@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@CAPAUViableSubstitution@strings_internal@absl@@PAU345@@Z
??$__add_alignment_assumption@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@$0A@@?$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@@CAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@PAV312@@Z
+ ??$__add_alignment_assumption@PBQAVLogSink@absl@@$0A@@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAPBQAVLogSink@absl@@PBQAV34@@Z
+ ??$__add_alignment_assumption@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@$0A@@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@CAPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@PBU3456@@Z
+ ??$__add_alignment_assumption@PBUUnrecognizedFlag@absl@@$0A@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@CAPBUUnrecognizedFlag@absl@@PBU34@@Z
??$__advance@PBUTransition@cctz@time_internal@absl@@@__Cr@std@@YAXAAPBUTransition@cctz@time_internal@absl@@HUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAAV?$__wrap_iter@PAPAVCommandLineFlag@absl@@@01@HUrandom_access_iterator_tag@01@@Z
??$__advance@V?$__wrap_iter@PAPBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@YAXAAV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@01@HUrandom_access_iterator_tag@01@@Z
@@ -959,13 +979,13 @@ EXPORTS
??$__construct_at_end@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@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@@AAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@0I@Z
??$__construct_at_end@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__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@@QAEXV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@12@0@Z
??$__construct_at_end@V?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@0@Z
- ??$__construct_at_end_with_size@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@I@Z
+ ??$__construct_at_end@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@$0A@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@0@Z
+ ??$__construct_at_end_with_size@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@I@Z
??$__construct_at_end_with_size@V?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@?$__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@@QAEXV?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@12@I@Z
??$__construct_at_end_with_size@V?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@I@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@I@Z
- ??$__construct_at_end_with_size@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@I@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransition@cctz@time_internal@absl@@@12@I@Z
+ ??$__construct_at_end_with_size@V?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXV?$move_iterator@PAUTransitionType@cctz@time_internal@absl@@@12@I@Z
??$__construct_node@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QAV?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@AAE?AV?$unique_ptr@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
??$__construct_node@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@ABV?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@AAE?AV?$unique_ptr@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@V?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@23@@12@ABUpiecewise_construct_t@12@$$QAV?$tuple@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@12@$$QAV?$tuple@$$V@12@@Z
??$__construct_node_hash@ABQBUCordRep@cord_internal@absl@@@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AAE?AV?$unique_ptr@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@V?$__hash_node_destructor@V?$allocator@U?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@@12@IABQBUCordRep@cord_internal@absl@@@Z
@@ -1128,7 +1148,7 @@ EXPORTS
??$__in_bounds@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@@@__Cr@std@@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@@@23@$0A@@__unique_ptr_array_bounds_stateless@__Cr@std@@QBE_NPAPAU?$__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@@@12@I@Z
??$__insert_assign_n_unchecked@U_ClassicAlgPolicy@__Cr@std@@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@23@$0A@@?$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@@AAEXV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@HPAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@@Z
??$__insert_with_size@U_ClassicAlgPolicy@__Cr@std@@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@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@@AAE?AV?$__wrap_iter@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@1H@Z
- ??$__invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QAI@Z
+ ??$__invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QAI@Z
??$__invoke@AAUByCivilTime@Transition@cctz@time_internal@absl@@ABU2345@ABU2345@@__Cr@std@@YA_NAAUByCivilTime@Transition@cctz@time_internal@absl@@ABU3456@1@Z
??$__invoke@AAUByUnixTime@Transition@cctz@time_internal@absl@@ABU2345@ABU2345@@__Cr@std@@YA_NAAUByUnixTime@Transition@cctz@time_internal@absl@@ABU3456@1@Z
??$__invoke@AAU__identity@__Cr@std@@AAPAVLogSink@absl@@@__Cr@std@@YAAAPAVLogSink@absl@@AAU__identity@01@AAPAV23@@Z
@@ -1352,8 +1372,8 @@ EXPORTS
??$allocate_at_least@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@@?$allocator_traits@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@SA?AU?$allocation_result@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@I@12@AAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@I@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA_N$$QAU?$EqualElement@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@UStringEq@container_internal@absl@@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
- ??$apply@U?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
+ ??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@23@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SAI$$QAU?$HashElement@UStringHash@container_internal@absl@@$00$0A@@12@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$apply@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@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$apply@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@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$apply@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@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@SA?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@$$QAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
@@ -1362,12 +1382,16 @@ EXPORTS
??$apply@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@@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@34@@?$hash_policy_traits@U?$FlatHashMapPolicy@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@container_internal@absl@@X@container_internal@absl@@SA?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@AAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@@Z
??$assign@PBVSourceLocation@absl@@$0A@@?$InlinedVector@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@absl@@QAEXPBVSourceLocation@1@0@Z
??$assign@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@$0A@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@0@Z
+ ??$begin@V?$Span@$$CBI@absl@@@__Cr@std@@YAPBIABV?$Span@$$CBI@absl@@@Z
??$begin@V?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPAVCommandLineFlag@absl@@@01@AAV?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$begin@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@01@AAV?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$bit_cast@PAXVFastTypeIdType@absl@@@__Cr@std@@YAPAXABVFastTypeIdType@absl@@@Z
??$bit_cast@U?$FlagValueAndInitBit@_N@flags_internal@absl@@_J@__Cr@std@@YA?AU?$FlagValueAndInitBit@_N@flags_internal@absl@@AB_J@Z
??$bit_cast@VFastTypeIdType@absl@@PAX@__Cr@std@@YA?AVFastTypeIdType@absl@@ABQAX@Z
+ ??$c_begin@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPBIABV?$Span@$$CBI@1@@Z
??$c_begin@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AAV?$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@@34@@Z
+ ??$c_copy@V?$Span@$$CBI@absl@@PAI@absl@@YAPAIABV?$Span@$$CBI@0@$$QAPAI@Z
+ ??$c_end@$$CBV?$Span@$$CBI@absl@@@container_algorithm_internal@absl@@YAPBIABV?$Span@$$CBI@1@@Z
??$c_end@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@@@container_algorithm_internal@absl@@YA?AV?$__wrap_iter@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@AAV?$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@@34@@Z
??$call_once@A6AXXZ$$V@absl@@YAXAAVonce_flag@0@A6AXXZ@Z
??$call_once@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@absl@@YAXAAVonce_flag@0@$$QAP8FlagImpl@flags_internal@0@AEXXZ$$QAPAV230@@Z
@@ -1514,8 +1538,8 @@ EXPORTS
??$emplace@U?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QAE?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@@$$QAU?$pair@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$emplace_at@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@?$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@@IAEXPAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@12@ABUpiecewise_construct_t@__Cr@std@@$$QAV?$tuple@$$QAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
??$emplace_at@ABUpiecewise_construct_t@__Cr@std@@V?$tuple@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@23@V?$tuple@$$QAPAVCommandLineFlag@absl@@@23@@?$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@@IAEXPAT?$map_slot_type@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@12@ABUpiecewise_construct_t@__Cr@std@@$$QAV?$tuple@$$QBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@56@$$QAV?$tuple@$$QAPAVCommandLineFlag@absl@@@56@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ??$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@@QAEXXZ
??$emplace_back@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_back@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_back@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABV123@AAI@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUViableSubstitution@strings_internal@absl@@AAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@12@ABV612@AAI@Z
@@ -1541,6 +1565,7 @@ EXPORTS
??$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
??$emplace_front@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
+ ??$end@V?$Span@$$CBI@absl@@@__Cr@std@@YAPBIABV?$Span@$$CBI@absl@@@Z
??$end@V?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPAVCommandLineFlag@absl@@@01@AAV?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$end@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@YA?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@01@AAV?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@01@@Z
??$find@V?$__wrap_iter@PAPAVLogSink@absl@@@__Cr@std@@PAVLogSink@absl@@@__Cr@std@@YA?AV?$__wrap_iter@PAPAVLogSink@absl@@@01@V201@0ABQAVLogSink@absl@@@Z
@@ -1613,7 +1638,7 @@ EXPORTS
??$hash_with_seed@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@$0A@@MixingHashState@hash_internal@absl@@SAIABV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@I@Z
??$insert@U?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@__Cr@std@@$0A@@?$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@@QAE?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@@$$QAU?$pair@$$CBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAVCommandLineFlag@absl@@@45@@Z
??$insert@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@$0A@@?$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@@QAE?AV?$__wrap_iter@PAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@12@V?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@12@1@Z
- ??$invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@$$QAI@Z
+ ??$invoke@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@I@__Cr@std@@YAIAAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@$$QAI@Z
??$invoke@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@__Cr@std@@YAX$$QAP8FlagImpl@flags_internal@absl@@AEXXZ$$QAPAV234@@Z
??$iter_swap@AAPAPAVCommandLineFlag@absl@@AAPAPAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAAPAPAVCommandLineFlag@absl@@0@Z
??$iter_swap@AAPAPAVCommandLineFlag@absl@@PAPAV12@@?$_IterOps@U_ClassicAlgPolicy@__Cr@std@@@__Cr@std@@SAXAAPAPAVCommandLineFlag@absl@@$$QAPAPAV34@@Z
@@ -1702,6 +1727,9 @@ EXPORTS
??$safe_strtoi_base@K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAKH@Z
??$safe_strtoi_base@_J@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PA_JH@Z
??$safe_strtoi_base@_K@numbers_internal@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PA_KH@Z
+ ??$size@U<unnamed-type-locks>@SynchLocksHeld@absl@@$0CI@@__Cr@std@@YAIAAY0CI@$$CBU<unnamed-type-locks>@SynchLocksHeld@absl@@@Z
+ ??$size@UGraphId@synchronization_internal@absl@@$09@__Cr@std@@YAIAAY09$$CBUGraphId@synchronization_internal@absl@@@Z
+ ??$size@USpinLockWaitTransition@base_internal@absl@@$02@__Cr@std@@YAIAAY02$$CBUSpinLockWaitTransition@base_internal@absl@@@Z
??$swap@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@YAXAAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@0@Z
??$swap@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@YAXAAPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
??$swap@PAPAVCommandLineFlag@absl@@@__Cr@std@@YAXAAPAPAVCommandLineFlag@absl@@0@Z
@@ -1749,8 +1777,8 @@ EXPORTS
??0?$FormatSpecTemplate@$0BPPPL@$0JPPPL@$0JPPPL@$0JPPPL@@str_format_internal@absl@@QAE@PBD@Z
??0?$FormatSpecTemplate@$0JPPPL@$0JPOAA@@str_format_internal@absl@@QAE@PBD@Z
??0?$FormatSpecTemplate@$0JPPPL@@str_format_internal@absl@@QAE@PBD@Z
- ??0?$HashElement@UStringHash@container_internal@absl@@$00@container_internal@absl@@QAE@ABUStringHash@12@I@Z
- ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QAE@ABUStringHash@12@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
+ ??0?$HashElement@UStringHash@container_internal@absl@@$00$0A@@container_internal@absl@@QAE@ABUStringHash@12@I@Z
+ ??0?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QAE@ABUStringHash@12@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@AAE@W4InvalidCapacity@012@@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QAE@I@Z
??0?$HashtableCapacityImpl@$00@container_internal@absl@@QAE@Uuninitialized_tag_t@12@@Z
@@ -1770,7 +1798,6 @@ EXPORTS
??0?$IteratorValueAdapter@V?$allocator@VSourceLocation@absl@@@__Cr@std@@V?$move_iterator@PAVSourceLocation@absl@@@23@@inlined_vector_internal@absl@@QAE@ABV?$move_iterator@PAVSourceLocation@absl@@@__Cr@std@@@Z
??0?$NonIterableBitMask@I$0BA@$0A@@container_internal@absl@@QAE@I@Z
??0?$NonIterableBitMask@_K$07$02@container_internal@absl@@QAE@_K@Z
- ??0?$PerTableSeedImpl@E@container_internal@absl@@AAE@_K@Z
??0?$ProbedItemImpl@I$0CA@@container_internal@absl@@QAE@EII@Z
??0?$ProbedItemImpl@_K$0EA@@container_internal@absl@@QAE@EII@Z
??0?$ProbedItemImpl@_K$0HK@@container_internal@absl@@QAE@EII@Z
@@ -1864,8 +1891,8 @@ EXPORTS
??0?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
- ??0?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QAE@XZ
- ??0?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QAE@XZ
+ ??0?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QAE@XZ
+ ??0?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QAE@XZ
??0?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??0?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
@@ -1876,32 +1903,32 @@ EXPORTS
??0?$__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@@QAE@XZ
??0?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??0?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAE@IIAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@IIAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@IIAAV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@IIAAV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAE@IIAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@XZ
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@12@@Z
??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAE@XZ
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVLogSink@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
- ??0?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PAVLogSink@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCommandLineFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@PBVCordzHandle@cord_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransition@cctz@time_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UTransitionType@cctz@time_internal@absl@@@12@@Z
+ ??0?$__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@@QAE@ABV?$allocator@UUnrecognizedFlag@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAE@ABV?$allocator@UViableSubstitution@strings_internal@absl@@@12@@Z
+ ??0?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@12@@Z
??0?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@@12@@Z
??0?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAE@ABV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@23@U?$less@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@23@@12@@Z
??0?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@AAE@PAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@12@@Z
@@ -1912,13 +1939,27 @@ EXPORTS
??0?$__tree_node_destructor@V?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@QAE@AAV?$allocator@V?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@12@_N@Z
??0?$__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@@__Cr@std@@QAE@XZ
??0?$__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@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
+ ??0?$__vector_layout@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@@QAE@XZ
??0?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@AAE@PAPAVCommandLineFlag@absl@@@Z
??0?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@__Cr@std@@AAE@PAPAVCordzHandle@cord_internal@absl@@@Z
??0?$__wrap_iter@PAPAVLogSink@absl@@@__Cr@std@@AAE@PAPAVLogSink@absl@@@Z
??0?$__wrap_iter@PAPBVCommandLineFlag@absl@@@__Cr@std@@AAE@PAPBVCommandLineFlag@absl@@@Z
+ ??0?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@__Cr@std@@AAE@PAPBVCordzHandle@cord_internal@absl@@@Z
+ ??0?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@AAE@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
??0?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@AAE@PAUTransition@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@AAE@PAUTransitionType@cctz@time_internal@absl@@@Z
??0?$__wrap_iter@PAUUnrecognizedFlag@absl@@@__Cr@std@@AAE@PAUUnrecognizedFlag@absl@@@Z
+ ??0?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@__Cr@std@@AAE@PAUViableSubstitution@strings_internal@absl@@@Z
??0?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@__Cr@std@@AAE@PAUraw_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@@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@@12@ABV567@@Z@@Z
??0?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@AAE@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@@Z
??0?$__wrap_iter@PBQAVLogSink@absl@@@__Cr@std@@AAE@PBQAVLogSink@absl@@@Z
@@ -2090,7 +2131,6 @@ 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@ABV012@@Z
??0InlineData@cord_internal@absl@@QAE@W4DefaultInitType@012@@Z
??0InlineData@cord_internal@absl@@QAE@XZ
??0InlineRep@Cord@absl@@QAE@$$QAV012@@Z
@@ -2131,6 +2171,7 @@ EXPORTS
??0ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE@PAV123@@Z
??0Payload@status_internal@absl@@QAE@$$QAU012@@Z
??0Payload@status_internal@absl@@QAE@ABU012@@Z
+ ??0PerTableSeed@container_internal@absl@@AAE@_K@Z
??0PosixTimeZone@cctz@time_internal@absl@@QAE@XZ
??0PrefixCrc@CrcCordState@crc_internal@absl@@QAE@IVcrc32c_t@3@@Z
??0PrefixCrc@CrcCordState@crc_internal@absl@@QAE@XZ
@@ -2140,6 +2181,7 @@ EXPORTS
??0ReaderMutexLock@absl@@QAE@AAVMutex@1@@Z
??0RefcountAndFlags@cord_internal@absl@@QAE@XZ
??0RefcountedRep@CrcCordState@crc_internal@absl@@QAE@XZ
+ ??0ReleasableMutexLock@absl@@QAE@AAVMutex@1@@Z
??0Rep@CordBuffer@absl@@QAE@PAUCordRepFlat@cord_internal@2@@Z
??0Rep@CordBuffer@absl@@QAE@XZ
??0Rep@CrcCordState@crc_internal@absl@@QAE@XZ
@@ -2204,8 +2246,8 @@ EXPORTS
??0ZoneInfoSource@cctz@time_internal@absl@@QAE@XZ
??0_ConstructTransaction@?$__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@@QAE@PAV123@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@I@Z
??0_ConstructTransaction@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@PAV123@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@I@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@PAV123@PAUTransition@cctz@time_internal@absl@@I@Z
- ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@PAV123@PAUTransitionType@cctz@time_internal@absl@@I@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@PAV123@PAUTransition@cctz@time_internal@absl@@I@Z
+ ??0_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@PAV123@PAUTransitionType@cctz@time_internal@absl@@I@Z
??0_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@PAV123@AAU__deque_block_range@123@@Z
??0_ConstructTransaction@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@AAV123@I@Z
??0_ConstructTransaction@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@AAV123@I@Z
@@ -2284,8 +2326,8 @@ EXPORTS
??1?$__optional_copy_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_destruct_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_destruct_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
- ??1?$__optional_iterator_base@VCord@absl@@X@__Cr@std@@QAE@XZ
- ??1?$__optional_iterator_base@VStream@status_internal@absl@@X@__Cr@std@@QAE@XZ
+ ??1?$__optional_iterator_base@VCord@absl@@@__Cr@std@@QAE@XZ
+ ??1?$__optional_iterator_base@VStream@status_internal@absl@@@__Cr@std@@QAE@XZ
??1?$__optional_move_assign_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_move_assign_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QAE@XZ
??1?$__optional_move_base@VCord@absl@@$0A@@__Cr@std@@QAE@XZ
@@ -2297,17 +2339,17 @@ EXPORTS
??1?$__policy_func@$$A6A_NABVCommandLineFlag@absl@@@Z@__function@__Cr@std@@QAE@XZ
??1?$__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@@QAE@XZ
??1?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAE@XZ
- ??1?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAE@XZ
+ ??1?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAE@XZ
??1?$__temp_value@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE@XZ
@@ -2402,6 +2444,7 @@ EXPORTS
??1PosixTimeZone@cctz@time_internal@absl@@QAE@XZ
??1ReaderMutexLock@absl@@QAE@XZ
??1RefcountedRep@CrcCordState@crc_internal@absl@@QAE@XZ
+ ??1ReleasableMutexLock@absl@@QAE@XZ
??1Rep@CrcCordState@crc_internal@absl@@QAE@XZ
??1Rep@GraphCycles@synchronization_internal@absl@@QAE@XZ
??1Rep@StatusBuilder@absl@@QAE@XZ
@@ -2428,8 +2471,8 @@ EXPORTS
??1ZoneInfoSource@cctz@time_internal@absl@@UAE@XZ
??1_ConstructTransaction@?$__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@@QAE@XZ
??1_ConstructTransaction@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
- ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAE@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
+ ??1_ConstructTransaction@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAE@XZ
??1_ConstructTransaction@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1_ConstructTransaction@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
??1_ConstructTransaction@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE@XZ
@@ -2455,7 +2498,6 @@ EXPORTS
??4CrcCordState@crc_internal@absl@@QAEAAV012@ABV012@@Z
??4FlagsUsageConfig@absl@@QAEAAU01@ABU01@@Z
??4HiRep@Duration@absl@@QAEAAV012@_J@Z
- ??4InlineData@cord_internal@absl@@QAEAAV012@ABV012@@Z
??4InlineRep@Cord@absl@@QAEAAV012@$$QAV012@@Z
??4Payload@status_internal@absl@@QAEAAU012@$$QAU012@@Z
??4Rep@CrcCordState@crc_internal@absl@@QAEAAU0123@ABU0123@@Z
@@ -2564,6 +2606,17 @@ EXPORTS
??A?$Span@D@absl@@QBEAADI@Z
??A?$Span@I@absl@@QBEAAII@Z
??A?$__farray@P6AI$$QAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YAIUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@__Cr@std@@AAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@456@@Z$03@__Cr@std@@QBEABQ6AI$$QAU?$__value_visitor@UBufferSizeVisitor@?1??BufferSizeForStructuredProtoField@log_internal@absl@@YAIUStructuredProtoField@34@@Z@@__variant@__visitation@__variant_detail@12@AAV?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@612@@ZI@Z
+ ??A?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@QBEAAPAVCommandLineFlag@absl@@H@Z
+ ??A?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@__Cr@std@@QBEAAPAVCordzHandle@cord_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAPAVLogSink@absl@@@__Cr@std@@QBEAAPAVLogSink@absl@@H@Z
+ ??A?$__wrap_iter@PAPBVCommandLineFlag@absl@@@__Cr@std@@QBEAAPBVCommandLineFlag@absl@@H@Z
+ ??A?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@__Cr@std@@QBEAAPBVCordzHandle@cord_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@QBEAAUConversionItem@ParsedFormatBase@str_format_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@__Cr@std@@QBEAAUTransition@cctz@time_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@__Cr@std@@QBEAAUTransitionType@cctz@time_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAUUnrecognizedFlag@absl@@@__Cr@std@@QBEAAUUnrecognizedFlag@absl@@H@Z
+ ??A?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@__Cr@std@@QBEAAUViableSubstitution@strings_internal@absl@@H@Z
+ ??A?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QBEAAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@12@H@Z
??A?$array@Uraw_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@@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@@ABV345@@Z@$0BA@@__Cr@std@@QAEAAUraw_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@@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@@12@ABV567@@Z@I@Z
??A?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABUPrefixCrc@CrcCordState@crc_internal@absl@@I@Z
??A?$map@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@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?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@12@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
@@ -2610,6 +2663,7 @@ EXPORTS
??C?$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@@QBEPBV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
??C?$__hash_iterator@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@@QBEPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__hash_map_const_iterator@V?$__hash_const_iterator@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@@QBEPBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
+ ??C?$__hash_map_iterator@V?$__hash_iterator@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@@QBEPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@12@XZ
??C?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@QBEPAU?$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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@12@XZ
??C?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@QBEPAU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@12@XZ
??C?$__wrap_iter@PAPAVCommandLineFlag@absl@@@__Cr@std@@QBEPAPAVCommandLineFlag@absl@@XZ
@@ -2803,7 +2857,7 @@ EXPORTS
??R?$HashImpl@H@hash_internal@absl@@QBEIABH@Z
??R?$HashImpl@V?$tuple@ABI@__Cr@std@@@hash_internal@absl@@QBEIABV?$tuple@ABI@__Cr@std@@@Z
??R?$HashImpl@V?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@@hash_internal@absl@@QBEIABV?$tuple@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABH@__Cr@std@@@Z
- ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@QBEII@Z
+ ??R?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@QBEII@Z
??R?$__allocator_destructor@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
??R?$__allocator_destructor@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
??R?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAEXPAPAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@12@@Z
@@ -3230,6 +3284,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DisableRescheduling@SchedulingGuard@base_internal@absl@@SA_NXZ
?DoIgnoreLeak@absl@@YAXPBX@Z
?DoLoad@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@ABVCord@absl@@@Z@base_internal@absl@@ABEP6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@ABVCord@3@@ZXZ
@@ -3725,6 +3780,7 @@ EXPORTS
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
?IsHeld@SpinLock@base_internal@absl@@QBE_NXZ
?IsImmortal@RefcountAndFlags@cord_internal@absl@@QBE_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInfiniteDuration@time_internal@absl@@YA_NVDuration@2@@Z
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInlined@Status@absl@@CA_NI@Z
@@ -3891,7 +3947,7 @@ EXPORTS
?NextCapacity@?$Storage@VSourceLocation@absl@@$00V?$allocator@VSourceLocation@absl@@@__Cr@std@@@inlined_vector_internal@absl@@SAII@Z
?NextCapacity@container_internal@absl@@YAII@Z
?NextGeneration@container_internal@absl@@YAEE@Z
- ?NextHashTableSeed@container_internal@absl@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextRandom@ExponentialBiased@profiling_internal@absl@@SA_K_K@Z
?NextTransition@Impl@time_zone@cctz@time_internal@absl@@QBE_NABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PAUcivil_transition@2345@@Z
?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z
@@ -4113,7 +4169,6 @@ EXPORTS
?SentinelEmptyGeneration@container_internal@absl@@YAEXZ
?Set@?$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@@AAEXABV?$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@@@Z
?Set@MaskedPointer@flags_internal@absl@@QAEXP6APAXW4FlagOp@23@PBXPAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAllocation@?$Storage@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@PAVLogSink@absl@@$0BA@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@23@@Z
?SetAllocation@?$Storage@UPayload@status_internal@absl@@$00V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@inlined_vector_internal@absl@@QAEXU?$Allocation@V?$allocator@UPayload@status_internal@absl@@@__Cr@std@@@23@@Z
@@ -4361,6 +4416,7 @@ EXPORTS
?ToInt64Nanoseconds@absl@@YA_JVDuration@1@@Z
?ToInt64Seconds@absl@@YA_JVDuration@1@@Z
?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
?ToSinkAlso@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
?ToSinkOnly@LogMessage@log_internal@absl@@QAEAAV123@PAVLogSink@3@@Z
@@ -4515,6 +4571,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YAI_WPADAAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CAIIV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QAEAAV123@ABVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QAEAAV123@XZ
?WithSourceLocation@Status@absl@@QHAE$$QAV12@VSourceLocation@2@@Z
@@ -4535,8 +4592,41 @@ EXPORTS
?__addr@?$__temp_value@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
?__alloc@?$__bucket_list_deallocator@V?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$__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@@@__Cr@std@@QAEAAV?$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@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PAVLogSink@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__alloc@?$__vector_layout@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?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__alloc@?$__vector_layout@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@@QBEABV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__alloc@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAV?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
+ ?__annotate_contiguous_container@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
+ ?__annotate_contiguous_container@?$__vector_layout@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@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
@@ -4548,13 +4638,21 @@ EXPORTS
?__annotate_contiguous_container@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_contiguous_container@?$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@@ABEXPBX0@Z
+ ?__annotate_delete@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
+ ?__annotate_delete@?$__vector_layout@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@@ABEXXZ
?__annotate_delete@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
- ?__annotate_delete@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
- ?__annotate_delete@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
- ?__annotate_delete@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
?__annotate_delete@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXXZ
@@ -4573,19 +4671,19 @@ EXPORTS
?__annotate_increase@?$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@@ABEXI@Z
?__annotate_increase_back@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
?__annotate_increase_back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
+ ?__annotate_new@?$__vector_layout@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@@ABEXI@Z
?__annotate_new@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
?__annotate_new@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
- ?__annotate_new@?$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@@ABEXI@Z
?__annotate_poison_block@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXPBX0@Z
?__annotate_shrink@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
?__annotate_shrink@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@ABEXI@Z
@@ -4604,8 +4702,8 @@ EXPORTS
?__as_base@?$__base@$0A@V?$variant@_K_JIH_N@__Cr@std@@V?$variant@_K_JN@23@V?$Span@$$CBD@absl@@V?$variant@IHM@23@@__variant_detail@__Cr@std@@IGAE@XZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__back_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__back_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__back_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__back_spare@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__back_spare_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
@@ -4620,17 +4718,56 @@ EXPORTS
?__base_destruct_at_end@?$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@@AAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PBQAU4567@@Z
?__begin@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPBUPrefixCrc@CrcCordState@crc_internal@absl@@PBQAU4567@@Z
+ ?__begin_ptr@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVLogSink@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransition@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBUUnrecognizedFlag@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?__begin_ptr@?$__vector_layout@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@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__capacity@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__capacity@?$__vector_layout@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@@QBEIXZ
?__capacity@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__complete@?$__exception_guard_noexceptions@V<lambda_1>@?0??__add_back_capacity@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXI@Z@@__Cr@std@@QAEXXZ
?__complete@?$__exception_guard_noexceptions@V?$_AllocatorDestroyRangeReverse@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@PAUUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXXZ
?__compose@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@__Cr@std@@@__Cr@std@@SA?AV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@23@PBQAUPrefixCrc@CrcCordState@crc_internal@absl@@PAU5678@@Z
- ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXI@Z
- ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXI@Z
+ ?__construct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXI@Z
+ ?__construct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXI@Z
?__construct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXI@Z
?__construct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXI@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXABV123@@Z
?__copy_assign_alloc@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXABV123@U?$integral_constant@_N$0A@@23@@Z
+ ?__data@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEPBQAVLogSink@absl@@XZ
+ ?__data@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBQBVCommandLineFlag@absl@@XZ
+ ?__data@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBQBVCordzHandle@cord_internal@absl@@XZ
+ ?__data@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransition@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUTransitionType@cctz@time_internal@absl@@XZ
+ ?__data@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBUUnrecognizedFlag@absl@@XZ
+ ?__data@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUViableSubstitution@strings_internal@absl@@XZ
+ ?__data@?$__vector_layout@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@@QBEPBV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__deallocate_node@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AAEXPAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@23@@Z
?__deallocate_node@?$__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@@AAEXPAU?$__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@23@@Z
?__deallocate_node_list@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@AAEXPAU?$__hash_node_base@PAU?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@@23@@Z
@@ -4643,28 +4780,28 @@ EXPORTS
?__destruct_at_end@?$__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@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
?__destruct_at_end@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
- ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
- ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPAVLogSink@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__destruct_at_end@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@U?$integral_constant@_N$0A@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__destruct_at_end@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@U?$integral_constant@_N$0A@@23@@Z
?__destruct_at_end@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAEXPAPAVLogSink@absl@@@Z
?__destruct_at_end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXPAUTransition@cctz@time_internal@absl@@@Z
?__destruct_at_end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXPAUTransitionType@cctz@time_internal@absl@@@Z
@@ -4675,40 +4812,53 @@ EXPORTS
?__end_node@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QBEPAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@23@XZ
?__end_node@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@23@XZ
?__end_node@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QBEPAV?$__tree_end_node@PAV?$__tree_node_base@PAX@__Cr@std@@@23@XZ
+ ?__end_ptr@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEPBUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEPBUUnrecognizedFlag@absl@@XZ
+ ?__end_ptr@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?__end_ptr@?$__vector_layout@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@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__erase_to_end@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@23@@Z
?__front_cap@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
- ?__front_cap@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?__front_cap@?$__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@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?__front_cap@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?__front_spare@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__front_spare@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?__front_spare@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?__front_spare@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__front_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?__get@?$__optional_storage_base@VStream@status_internal@absl@@$0A@@__Cr@std@@QGAEAAVStream@status_internal@absl@@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@XZ
?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVLogSink@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
- ?__get_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PAVLogSink@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCommandLineFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@PBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransition@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UTransitionType@cctz@time_internal@absl@@@23@XZ
+ ?__get_allocator@?$__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@@QAEAAV?$allocator@UUnrecognizedFlag@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEAAV?$allocator@UViableSubstitution@strings_internal@absl@@@23@XZ
+ ?__get_allocator@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEAAV?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?__get_np@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@__Cr@std@@ABEPAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@XZ
?__get_np@?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@__Cr@std@@ABEPAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@XZ
?__get_value@?$__hash_node@PBUCordRep@cord_internal@absl@@PAX@__Cr@std@@QAEAAPBUCordRep@cord_internal@absl@@XZ
@@ -4726,11 +4876,14 @@ EXPORTS
?__make_iter@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAPAVLogSink@absl@@@23@PAPAVLogSink@absl@@@Z
?__make_iter@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@ABE?AV?$__wrap_iter@PBQAVLogSink@absl@@@23@PBQAVLogSink@absl@@@Z
?__make_iter@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@23@PAPBVCommandLineFlag@absl@@@Z
+ ?__make_iter@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@23@PAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@ABE?AV?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
?__make_iter@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@23@PAUTransition@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@23@PAUTransitionType@cctz@time_internal@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUUnrecognizedFlag@absl@@@23@PAUUnrecognizedFlag@absl@@@Z
?__make_iter@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@ABE?AV?$__wrap_iter@PBUUnrecognizedFlag@absl@@@23@PBUUnrecognizedFlag@absl@@@Z
+ ?__make_iter@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AAE?AV?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@23@PAUViableSubstitution@strings_internal@absl@@@Z
?__make_iter@?$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@@AAE?AV?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__maybe_remove_back_spare@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAE_N_N@Z
?__move_range@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXPAUTransition@cctz@time_internal@absl@@00@Z
@@ -4755,6 +4908,32 @@ EXPORTS
?__recommend_blocks@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@SAII@Z
?__rehash_unique@?$__hash_table@PBUCordRep@cord_internal@absl@@U?$hash@PBUCordRep@cord_internal@absl@@@__Cr@std@@U?$equal_to@PBUCordRep@cord_internal@absl@@@56@V?$allocator@PBUCordRep@cord_internal@absl@@@56@@__Cr@std@@QAEXI@Z
?__rehash_unique@?$__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@@QAEXI@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPAVCommandLineFlag@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPAVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXAAPAPAVLogSink@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPBVCommandLineFlag@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPBVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXAAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransition@cctz@time_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransitionType@cctz@time_internal@absl@@AAI1@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@@QAEXAAPAUUnrecognizedFlag@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXAAPAUViableSubstitution@strings_internal@absl@@AAI1@Z
+ ?__relocate@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXAAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AAI1@Z
+ ?__relocate@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@@Z
+ ?__relocate@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@23@@Z
+ ?__relocate@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@23@@Z
+ ?__relocate@?$__vector_layout@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@@QAEXAAV?$__split_buffer@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@V__split_buffer_size_layout@23@@23@@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@PAU4567@AAPAU4567@AAI2@Z
+ ?__relocate_with_pivot@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@PAU4567@AAPAU4567@AAI2@Z
+ ?__relocate_with_pivot@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@AAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PAU4567@@Z
+ ?__relocate_with_pivot@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@AAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@23@PAU4567@@Z
?__rewrap@?$__unwrap_iter_impl@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@$00@__Cr@std@@SAPAPAPBVImpl@time_zone@cctz@time_internal@absl@@PAPAPBV45678@0@Z
?__rewrap@?$__unwrap_iter_impl@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@$00@__Cr@std@@SAPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@PAPAU4567@0@Z
?__rewrap@?$__unwrap_iter_impl@PAPAVLogSink@absl@@$00@__Cr@std@@SAPAPAVLogSink@absl@@PAPAV45@0@Z
@@ -4771,105 +4950,104 @@ EXPORTS
?__root_ptr@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QBEPAPAV?$__tree_node_base@PAX@23@XZ
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPBQAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PAU1234@AAU1234@PAPAU1234@H$0A@@23@@Z
?__segment@?$__segmented_iterator_traits@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@@__Cr@std@@SAPBQAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@23@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_bound_using_pointer@?$__vector_layout@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@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXI@Z
- ?__set_capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__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@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXI@Z
+ ?__set_capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXI@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_data@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_data@?$__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@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_data@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@@Z
?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
- ?__set_sentinel@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@@Z
+ ?__set_sentinel@?$__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@@QAEXPAUUnrecognizedFlag@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@@Z
+ ?__set_sentinel@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAPAPBVImpl@time_zone@cctz@time_internal@absl@@I@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@0@Z
?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@I@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXPAUUnrecognizedFlag@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@0@Z
- ?__set_valid_range@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPAVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPAVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXPAPAVLogSink@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXPAPBVCommandLineFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXPAPBVCordzHandle@cord_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransition@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXPAUTransitionType@cctz@time_internal@absl@@0@Z
+ ?__set_valid_range@?$__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@@QAEXPAUUnrecognizedFlag@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXPAUViableSubstitution@strings_internal@absl@@0@Z
+ ?__set_valid_range@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@0@Z
+ ?__size@?$__vector_layout@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
+ ?__size@?$__vector_layout@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@@QBEIXZ
?__size@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAIXZ
?__size@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABIXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAIXZ
?__size@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABIXZ
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPAVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPAVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXAAPAPAVLogSink@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPBVCommandLineFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPBVCordzHandle@cord_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXAAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransition@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransitionType@cctz@time_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEXAAPAUUnrecognizedFlag@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXAAPAUViableSubstitution@strings_internal@absl@@00@Z
- ?__swap_layouts@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXAAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@00@Z
- ?__swap_layouts@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_layouts@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_layouts@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_layouts@?$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@@AAEXAAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEPAUTransition@cctz@time_internal@absl@@AAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEPAUTransitionType@cctz@time_internal@absl@@AAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@PAU4567@@Z
- ?__swap_out_circular_buffer@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@23@@Z
- ?__swap_out_circular_buffer@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXAAV?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@23@@Z
- ?__swap_out_circular_buffer@?$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@@AAEXAAV?$__split_buffer@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@V__split_buffer_pointer_layout@23@@23@@Z
+ ?__swap@?$__vector_layout@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEXAAV123@@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPAVCommandLineFlag@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPAVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEXAAPAPAVLogSink@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEXAAPAPBVCommandLineFlag@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEXAAPAPBVCordzHandle@cord_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEXAAPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransition@cctz@time_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAPAUTransitionType@cctz@time_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__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@@QAEXAAPAUUnrecognizedFlag@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEXAAPAUViableSubstitution@strings_internal@absl@@AAI1@Z
+ ?__swap_layouts@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEXAAPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@AAI1@Z
?__swap_without_allocator@?$__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@@QAEXAAV123@@Z
?__swap_without_allocator@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXAAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
- ?__swap_without_allocator@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
+ ?__swap_without_allocator@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEXAAV123@@Z
?__throw_length_error@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
?__throw_length_error@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@CAXXZ
@@ -4982,10 +5160,17 @@ EXPORTS
?back@?$InlinedVector@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QAEAAPAUCordRep@cord_internal@2@XZ
?back@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEAAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?back@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBEABUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
+ ?back@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAPAVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAPAVCordzHandle@cord_internal@absl@@XZ
+ ?back@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAEAAPAVLogSink@absl@@XZ
+ ?back@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAPBVCommandLineFlag@absl@@XZ
+ ?back@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAPBVCordzHandle@cord_internal@absl@@XZ
?back@?$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@@XZ
?back@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUTransition@cctz@time_internal@absl@@XZ
?back@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUTransitionType@cctz@time_internal@absl@@XZ
+ ?back@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAUUnrecognizedFlag@absl@@XZ
?back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEAAUViableSubstitution@strings_internal@absl@@XZ
+ ?back@?$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@XZ
?back@CordRepBtree@cord_internal@absl@@QBEIXZ
?base@?$move_iterator@PAPAPBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@QGBEABQAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?base@?$move_iterator@PAPAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@QGBEABQAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
@@ -5008,17 +5193,17 @@ EXPORTS
?begin@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEPBQAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
- ?begin@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?begin@?$__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@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?begin@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?begin@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@23@XZ
?begin@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@23@XZ
?begin@?$array@Uraw_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@@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@@ABV345@@Z@$0BA@@__Cr@std@@QAE?AV?$__wrap_iter@PAUraw_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@@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@@ABV345@@Z@@23@XZ
@@ -5058,17 +5243,17 @@ EXPORTS
?capacity@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AV?$HashtableCapacityImpl@$00@23@XZ
?capacity@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QBEIXZ
- ?capacity@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__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@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QBEIXZ
+ ?capacity@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QBEIXZ
?capacity@?$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@@QBEIXZ
?capacity@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
?capacity@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBEIXZ
@@ -5097,17 +5282,17 @@ EXPORTS
?clear@?$__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@@QAEXXZ
?clear@?$__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@@QAEXXZ
?clear@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@QAEXXZ
- ?clear@?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@QAEXXZ
+ ?clear@?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@QAEXXZ
?clear@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXXZ
?clear@?$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@@QAEXXZ
?clear@?$unordered_map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@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@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@@QAEXXZ
@@ -5275,6 +5460,11 @@ EXPORTS
?empty@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$map@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@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?$map@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QBE_NXZ
?empty@?$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_NXZ
+ ?empty@?$vector@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
+ ?empty@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
?empty@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QBE_NXZ
@@ -5300,17 +5490,17 @@ EXPORTS
?end@?$__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@@QAE?AV?$__hash_iterator@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@@@23@XZ
?end@?$__split_buffer_pointer_layout@V?$__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@@PAPBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PAPBVImpl@time_zone@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAPAPBVImpl@time_zone@cctz@time_internal@absl@@XZ
?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@23@@__Cr@std@@QAEPAPAUPrefixCrc@CrcCordState@crc_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@V__split_buffer_pointer_layout@45@@__Cr@std@@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@23@@__Cr@std@@QAEPAUUnrecognizedFlag@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
- ?end@?$__split_buffer_pointer_layout@V?$__split_buffer@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@V__split_buffer_pointer_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVCommandLineFlag@absl@@V?$allocator@PAVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPAVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPAVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@23@@__Cr@std@@QAEPAPAVLogSink@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@V__split_buffer_size_layout@45@@__Cr@std@@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@23@@__Cr@std@@QAEPAPBVCommandLineFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@23@@__Cr@std@@QAEPAPBVCordzHandle@cord_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@@__Cr@std@@QAEPAUConversionItem@ParsedFormatBase@str_format_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransition@cctz@time_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@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@@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@23@@__Cr@std@@QAEPAUTransitionType@cctz@time_internal@absl@@XZ
+ ?end@?$__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@@QAEPAUUnrecognizedFlag@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@56@@__Cr@std@@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@23@@__Cr@std@@QAEPAUViableSubstitution@strings_internal@absl@@XZ
+ ?end@?$__split_buffer_size_layout@V?$__split_buffer@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@V__split_buffer_size_layout@23@@__Cr@std@@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@V?$allocator@V?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@@__Cr@std@@QAEPAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@23@XZ
?end@?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@H@23@XZ
?end@?$__tree@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@__Cr@std@@QAE?AV?$__tree_iterator@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@H@23@XZ
?end@?$deque@PBVImpl@time_zone@cctz@time_internal@absl@@V?$allocator@PBVImpl@time_zone@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__deque_iterator@PBVImpl@time_zone@cctz@time_internal@absl@@PAPBV12345@AAPBV12345@PAPAPBV12345@H$0A@@23@XZ
@@ -5324,11 +5514,14 @@ EXPORTS
?end@?$vector@PAVCordzHandle@cord_internal@absl@@V?$allocator@PAVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPAVCordzHandle@cord_internal@absl@@@23@XZ
?end@?$vector@PAVLogSink@absl@@V?$allocator@PAVLogSink@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPAVLogSink@absl@@@23@XZ
?end@?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPBVCommandLineFlag@absl@@@23@XZ
+ ?end@?$vector@PBVCordzHandle@cord_internal@absl@@V?$allocator@PBVCordzHandle@cord_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAPBVCordzHandle@cord_internal@absl@@@23@XZ
+ ?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UConversionItem@ParsedFormatBase@str_format_internal@absl@@V?$allocator@UConversionItem@ParsedFormatBase@str_format_internal@absl@@@__Cr@std@@@__Cr@std@@QBE?AV?$__wrap_iter@PBUConversionItem@ParsedFormatBase@str_format_internal@absl@@@23@XZ
?end@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@23@XZ
?end@?$vector@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUUnrecognizedFlag@absl@@@23@XZ
?end@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QBE?AV?$__wrap_iter@PBUUnrecognizedFlag@absl@@@23@XZ
+ ?end@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUViableSubstitution@strings_internal@absl@@@23@XZ
?end@?$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@@QAE?AV?$__wrap_iter@PAV?$unique_ptr@VFlagStateInterface@flags_internal@absl@@U?$default_delete@VFlagStateInterface@flags_internal@absl@@@__Cr@std@@@__Cr@std@@@23@XZ
?end@ChunkRange@Cord@absl@@QBE?AVChunkIterator@23@XZ
?end@CordRepBtree@cord_internal@absl@@QBEIXZ
@@ -5616,8 +5809,6 @@ EXPORTS
?pointer_to@?$pointer_traits@PAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@SAPAV?$__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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@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@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@@23@@23@@__Cr@std@@PAX@23@AAV423@@Z
?pointer_to@?$pointer_traits@PAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@__Cr@std@@@__Cr@std@@SAPAV?$__tree_node@U?$__value_type@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$vector@PBVCommandLineFlag@absl@@V?$allocator@PBVCommandLineFlag@absl@@@__Cr@std@@@23@@__Cr@std@@PAX@23@AAV423@@Z
?pointer_to@?$pointer_traits@PBU?$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@@@__Cr@std@@SAPBU?$pair@$$CBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@PBVImpl@time_zone@cctz@time_internal@absl@@@23@ABU423@@Z
- ?poison@InlineData@cord_internal@absl@@QAEXXZ
- ?poison_this@InlineData@cord_internal@absl@@QAEXXZ
?pop_back@?$InlinedVector@PAUCordRep@cord_internal@absl@@$01V?$allocator@PAUCordRep@cord_internal@absl@@@__Cr@std@@@absl@@QAEXXZ
?pop_back@?$__split_buffer@PAUPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@PAUPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
?pop_back@?$vector@UViableSubstitution@strings_internal@absl@@V?$allocator@UViableSubstitution@strings_internal@absl@@@__Cr@std@@@__Cr@std@@QAEXXZ
@@ -5718,11 +5909,9 @@ EXPORTS
?scale_add@impl@detail@cctz@time_internal@absl@@YA_J_J00@Z
?second@?$civil_time@Usecond_tag@detail@cctz@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
?second@?$civil_time@Usecond_tag@time_internal@absl@@@detail@cctz@time_internal@absl@@QBEHXZ
- ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AV?$PerTableSeedImpl@E@23@XZ
- ?seed@?$PerTableSeedImpl@E@container_internal@absl@@QBEIXZ
- ?seed@CommonFields@container_internal@absl@@QBE?AV?$PerTableSeedImpl@E@23@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QAEPAU1234@XZ
- ?self@Rep@InlineData@cord_internal@absl@@QBEPBU1234@XZ
+ ?seed@?$HashtableInlineDataImpl@$00@container_internal@absl@@QBE?AVPerTableSeed@23@XZ
+ ?seed@CommonFields@container_internal@absl@@QBE?AVPerTableSeed@23@XZ
+ ?seed@PerTableSeed@container_internal@absl@@QBEIXZ
?set@?$MaybeInitializedPtr@W4ctrl_t@container_internal@absl@@@container_internal@absl@@QAEXPAW4ctrl_t@23@@Z
?set_arg@BoundConversion@str_format_internal@absl@@QAEXPBVFormatArgImpl@23@@Z
?set_begin@CordRepBtree@cord_internal@absl@@AAEXI@Z
@@ -5881,7 +6070,6 @@ EXPORTS
?unlock@Mutex@absl@@QAEXXZ
?unlock@SpinLock@base_internal@absl@@QAEXXZ
?unlock_shared@Mutex@absl@@QAEXXZ
- ?unpoison@InlineData@cord_internal@absl@@QAEXXZ
?utc_time_zone@cctz@time_internal@absl@@YA?AVtime_zone@123@XZ
?value@ConvertibleToStringView@strings_internal@absl@@QBE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@XZ
?value@InputValue@UnboundConversion@str_format_internal@absl@@QBEHXZ
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 d1df82749a7..c1075858c50 100644
--- a/deps/v8/third_party/abseil-cpp/symbols_x86_rel.def
+++ b/deps/v8/third_party/abseil-cpp/symbols_x86_rel.def
@@ -1,6 +1,7 @@
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
@@ -44,6 +45,7 @@ EXPORTS
??$CallOnceImpl@A6AXXZ$$V@base_internal@absl@@YAXPAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@A6AXXZ@Z
??$CallOnceImpl@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@base_internal@absl@@YAXPAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@$$QAP8FlagImpl@flags_internal@1@AEXXZ$$QAPAV671@@Z
??$CastAndCallFunction@$$CBU?$atomic@_N@__Cr@std@@@Condition@absl@@CA_NPBV01@@Z
+ ??$CheckedAdd@$SI@substitute_internal@absl@@YAIII@Z
??$Clear@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUPolicyFunctions@01@P6AXPAX2@Z2@Z
??$Clear@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUPolicyFunctions@01@P6AXPAX2@Z2@Z
??$ConsumeConversion@$00@str_format_internal@absl@@YAPBDPBDQBDPAUUnboundConversion@01@PAH@Z
@@ -110,7 +112,7 @@ EXPORTS
??$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
- ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
+ ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
??$JoinAlgorithm@V?$__wrap_iter@PBV?$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@PBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@34@0V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@UNoFormatter@01@@Z
??$MakeCheckOpString@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABV123@@log_internal@absl@@YAPBDABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PBD@Z
??$MakeCheckOpString@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABV123@@log_internal@absl@@YAPBDABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PBD@Z
@@ -125,23 +127,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPBD_J0PBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPBD_K0PBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPBD_N0PBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@0@Z
??$Merge@$0A@@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@0@Z
??$NewLeaf@$00@CordRepBtree@cord_internal@absl@@CAPAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
@@ -159,6 +176,7 @@ EXPORTS
??$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
??$Register@AB_JAAIAAIAAIAAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AB_JAAI11AAG@Z
??$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
@@ -172,7 +190,7 @@ EXPORTS
??$StringResizeAndOverwriteFallback@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V<lambda_1>@?0???$JoinAlgorithm@V?$__wrap_iter@PBV?$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@PBV?$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@@YAXAAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@IV<lambda_1>@?0???$JoinAlgorithm@V?$__wrap_iter@PBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@X@01@YA?AV234@V?$__wrap_iter@PBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@34@1V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@UNoFormatter@01@@Z@@Z
??$TransferNRelocatable@$0M@@container_internal@absl@@YAXPAX00I@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YAIIIIPAW4ctrl_t@01@I@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YAIPBXPAXI@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YAIPBXPAXI@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@I@Z
@@ -192,10 +210,11 @@ EXPORTS
??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransition@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@@QAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransitionType@cctz@time_internal@absl@@@12@@Z
??$emplace@AAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QAEAAVStream@status_internal@absl@@AAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ??$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@@QAEXXZ
??$emplace_back@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_back@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_back@ABUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAUUnrecognizedFlag@absl@@ABU34@@Z
??$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
@@ -445,6 +464,7 @@ EXPORTS
?Append@Cord@absl@@QAEXABV12@@Z
?Append@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?Append@FormatSinkImpl@str_format_internal@absl@@QAEXID@Z
+ ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QAEXID@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QAEXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@strings_internal@absl@@QAEXID@Z
@@ -587,6 +607,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPBX@Z
?Dtor@Mutex@absl@@AAEXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@ABVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@ABVCord@3@@Z
@@ -862,6 +883,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QBE_NIIPAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QBE_NPAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NABVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NABVStatus@1@@Z
@@ -952,7 +974,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PAUcivil_transition@time_zone@234@@Z
@@ -1101,7 +1123,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?SendToLog@LogMessage@log_internal@absl@@AAEXXZ
?Set@MaskedPointer@flags_internal@absl@@QAEXP6APAXW4FlagOp@23@PBXPAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QAEXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QGAEAAV12@W4StatusCode@2@@Z
@@ -1343,6 +1364,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YAI_WPADAAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CAIIV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QAEAAV123@ABVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QAEAAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QAEAAV123@I@Z
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 4ebbead0120..39999d36bfe 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,6 +1,7 @@
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
@@ -44,6 +45,7 @@ EXPORTS
??$CallOnceImpl@A6AXXZ$$V@base_internal@absl@@YAXPAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@A6AXXZ@Z
??$CallOnceImpl@P8FlagImpl@flags_internal@absl@@AEXXZPAV123@@base_internal@absl@@YAXPAU?$atomic@I@__Cr@std@@W4SchedulingMode@01@$$QAP8FlagImpl@flags_internal@1@AEXXZ$$QAPAV671@@Z
??$CastAndCallFunction@$$CBU?$atomic@_N@__Cr@std@@@Condition@absl@@CA_NPBV01@@Z
+ ??$CheckedAdd@$SI@substitute_internal@absl@@YAIII@Z
??$Clear@$00@container_internal@absl@@YAXAAVCommonFields@01@ABUPolicyFunctions@01@P6AXPAX2@Z2@Z
??$Clear@$0A@@container_internal@absl@@YAXAAVCommonFields@01@ABUPolicyFunctions@01@P6AXPAX2@Z2@Z
??$ConsumeConversion@$00@str_format_internal@absl@@YAPBDPBDQBDPAUUnboundConversion@01@PAH@Z
@@ -110,7 +112,7 @@ EXPORTS
??$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
- ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
+ ??$InvokeObject@AAU?$HashKey@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@II@functional_internal@absl@@YAITVoidPtr@01@I@Z
??$JoinAlgorithm@V?$__wrap_iter@PBV?$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@PBV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@34@0V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@UNoFormatter@01@@Z
??$MakeCheckOpString@ABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@ABV123@@log_internal@absl@@YAPBDABV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@0PBD@Z
??$MakeCheckOpString@ABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@ABV123@@log_internal@absl@@YAPBDABV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@0PBD@Z
@@ -125,23 +127,38 @@ EXPORTS
??$MakeCheckOpString@_J_J@log_internal@absl@@YAPBD_J0PBD@Z
??$MakeCheckOpString@_K_K@log_internal@absl@@YAPBD_K0PBD@Z
??$MakeCheckOpString@_N_N@log_internal@absl@@YAPBD_N0PBD@Z
- ??$MakeErrorImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0A@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
- ??$MakeErrorImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$00@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$01@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$02@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$03@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$04@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$05@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$06@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$07@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$08@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$09@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0L@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0M@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0N@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0O@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringRvalueImpl@$0P@@status_internal@absl@@YA?AVStatus@1@$$QAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$00@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$01@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$02@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$03@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$04@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$05@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$06@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$07@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$08@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$09@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0BA@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0L@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0M@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0N@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0O@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
+ ??$MakeErrorStringViewImpl@$0P@@status_internal@absl@@YA?AVStatus@1@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@VSourceLocation@1@@Z
??$Merge@$00@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@0@Z
??$Merge@$0A@@CordRepBtree@cord_internal@absl@@CAPAV012@PAV012@0@Z
??$NewLeaf@$00@CordRepBtree@cord_internal@absl@@CAPAV012@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
@@ -159,6 +176,7 @@ EXPORTS
??$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
??$Register@AB_JAAIAAIAAIAAG@?$SampleRecorder@UHashtablezInfo@container_internal@absl@@@profiling_internal@absl@@QAEPAUHashtablezInfo@container_internal@2@AB_JAAI11AAG@Z
??$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
@@ -171,7 +189,7 @@ EXPORTS
??$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
??$TransferNRelocatable@$0M@@container_internal@absl@@YAXPAX00I@Z
??$TryFindNewIndexWithoutProbing@X@container_internal@absl@@YAIIIIPAW4ctrl_t@01@I@Z
- ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00@container_internal@absl@@YAIPBXPAXI@Z
+ ??$TypeErasedApplyToSlotFn@UStringHash@container_internal@absl@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@$00$0A@@container_internal@absl@@YAIPBXPAXI@Z
??$UnparseFloatingPointVal@M@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@M@Z
??$UnparseFloatingPointVal@N@flags_internal@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@N@Z
??$__append_with_size@V?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@__Cr@std@@@?$deque@UPrefixCrc@CrcCordState@crc_internal@absl@@V?$allocator@UPrefixCrc@CrcCordState@crc_internal@absl@@@__Cr@std@@@__Cr@std@@AAEXV?$__deque_iterator@UPrefixCrc@CrcCordState@crc_internal@absl@@PBU1234@ABU1234@PBQBU1234@H$0A@@12@I@Z
@@ -191,10 +209,11 @@ EXPORTS
??$emplace@$$V@?$vector@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@@__Cr@std@@QAE?AV?$__wrap_iter@PAUTransition@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransition@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@@QAE?AV?$__wrap_iter@PAUTransitionType@cctz@time_internal@absl@@@12@V?$__wrap_iter@PBUTransitionType@cctz@time_internal@absl@@@12@@Z
??$emplace@AAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@$0A@@?$optional@VStream@status_internal@absl@@@__Cr@std@@QAEAAVStream@status_internal@absl@@AAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@12@@Z
- ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
- ??$emplace_back@$$V@?$__split_buffer@UTransitionType@cctz@time_internal@absl@@V?$allocator@UTransitionType@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_pointer_layout@67@@__Cr@std@@QAEXXZ
+ ??$emplace_back@$$V@?$__split_buffer@UTransition@cctz@time_internal@absl@@V?$allocator@UTransition@cctz@time_internal@absl@@@__Cr@std@@V__split_buffer_size_layout@67@@__Cr@std@@QAEXXZ
+ ??$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@@QAEXXZ
??$emplace_back@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_back@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_back@ABUUnrecognizedFlag@absl@@@?$vector@UUnrecognizedFlag@absl@@V?$allocator@UUnrecognizedFlag@absl@@@__Cr@std@@@__Cr@std@@QAEAAUUnrecognizedFlag@absl@@ABU34@@Z
??$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
@@ -445,6 +464,7 @@ EXPORTS
?Append@Cord@absl@@QAEXABV12@@Z
?Append@CordRepBtree@cord_internal@absl@@SAPAV123@PAV123@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?Append@FormatSinkImpl@str_format_internal@absl@@QAEXID@Z
+ ?Append@ParsedFormatConsumer@ParsedFormatBase@str_format_internal@absl@@QAE_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QAEXID@Z
?Append@StringifySink@detect_specialization@log_internal@absl@@QAEXV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?Append@StringifySink@strings_internal@absl@@QAEXID@Z
@@ -587,6 +607,7 @@ EXPORTS
?DieBecauseNull@log_internal@absl@@YAXPBDH0@Z
?Digits10@?$BigUnsigned@$03@strings_internal@absl@@SAHXZ
?Digits10@?$BigUnsigned@$0FE@@strings_internal@absl@@SAHXZ
+ ?DisableFlagfileAndEnvParsing@absl@@YAXXZ
?DoIgnoreLeak@absl@@YAXPBX@Z
?Dtor@Mutex@absl@@AAEXXZ
?DummyFunction@?$AtomicHook@P6A?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@23@ABVCord@absl@@@Z@base_internal@absl@@CA?AV?$optional@V?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@56@ABVCord@3@@Z
@@ -862,6 +883,7 @@ EXPORTS
?IsFlat@CordRepBtree@cord_internal@absl@@QBE_NIIPAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsFlat@CordRepBtree@cord_internal@absl@@QBE_NPAV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?IsHashtablezEnabled@container_internal@absl@@YA_NXZ
+ ?IsIndirectFlagExpansionEnabled@flags_internal@absl@@YA_NXZ
?IsInitialized@log_internal@absl@@YA_NXZ
?IsInternal@absl@@YA_NABVStatus@1@@Z
?IsInvalidArgument@absl@@YA_NABVStatus@1@@Z
@@ -952,7 +974,7 @@ EXPORTS
?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@@YAGXZ
+ ?NextHashTableSeed@container_internal@absl@@YAEXZ
?NextTransition@TimeZone@absl@@QBE_NVTime@2@PAUCivilTransition@12@@Z
?NextTransition@TimeZoneInfo@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PAUcivil_transition@time_zone@234@@Z
?NextTransition@TimeZoneLibC@cctz@time_internal@absl@@UBE_NABV?$time_point@Vsystem_clock@chrono@__Cr@std@@V?$duration@_JV?$ratio@$00$00@__Cr@std@@@234@@chrono@__Cr@std@@PAUcivil_transition@time_zone@234@@Z
@@ -1101,7 +1123,6 @@ EXPORTS
?Seek@CordRepBtreeReader@cord_internal@absl@@QAE?AV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@I@Z
?SendToLog@LogMessage@log_internal@absl@@AAEXXZ
?Set@MaskedPointer@flags_internal@absl@@QAEXP6APAXW4FlagOp@23@PBXPAX2@Z1_N@Z
- ?SetAbslHardeningEnabled@base_internal@absl@@YAX_N@Z
?SetAndroidNativeTag@absl@@YAXPBD@Z
?SetCallback@FlagImpl@flags_internal@absl@@QAEXQ6AXXZ@Z
?SetCode@StatusBuilder@absl@@QGAEAAV12@W4StatusCode@2@@Z
@@ -1343,6 +1364,7 @@ EXPORTS
?WebSafeBase64Escape@absl@@YA?AV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@__Cr@std@@V?$basic_string_view@DU?$char_traits@D@__Cr@std@@@34@@Z
?WebSafeBase64Unescape@absl@@YA_NV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@PAV?$basic_string@DU?$char_traits@D@__Cr@std@@V?$allocator@D@23@@34@@Z
?WideToUtf8@strings_internal@absl@@YAI_WPADAAUShiftState@12@@Z
+ ?WithContextImpl@Status@absl@@CAIIV?$basic_string_view@DU?$char_traits@D@__Cr@std@@@__Cr@std@@@Z
?WithMetadataFrom@LogMessage@log_internal@absl@@QAEAAV123@ABVLogEntry@3@@Z
?WithPerror@LogMessage@log_internal@absl@@QAEAAV123@XZ
?WithThreadID@LogMessage@log_internal@absl@@QAEAAV123@I@Z
diff --git a/deps/v8/third_party/highway/src/hwy/contrib/sort/BUILD b/deps/v8/third_party/highway/src/hwy/contrib/sort/BUILD
new file mode 100644
index 00000000000..a146efbe3a2
--- /dev/null
+++ b/deps/v8/third_party/highway/src/hwy/contrib/sort/BUILD
@@ -0,0 +1,310 @@
+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/src/hdr/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt
index f2979866eaf..4d63860906f 100644
--- a/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/hdr/CMakeLists.txt
@@ -72,6 +72,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.fenv_macros
)
+add_proxy_header_library(
+ fnmatch_macros
+ HDRS
+ fnmatch_macros.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-macros.fnmatch_macros
+)
+
add_proxy_header_library(
inet_address_macros
HDRS
@@ -88,6 +96,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.net_if_macros
)
+add_proxy_header_library(
+ netdb_macros
+ HDRS
+ netdb_macros.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-macros.netdb_macros
+)
+
add_proxy_header_library(
netinet_in_macros
HDRS
@@ -112,6 +128,14 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.sched_macros
)
+add_proxy_header_library(
+ semaphore_macros
+ HDRS
+ semaphore_macros.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-macros.semaphore_macros
+)
+
add_proxy_header_library(
signal_macros
HDRS
@@ -253,7 +277,7 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.unistd_macros
)
-if (WIN32)
+if(WIN32)
set(windows_addtional_time_macros libc.include.llvm-libc-macros.windows.time_macros_ext)
else()
set(windows_addtional_time_macros "")
@@ -357,60 +381,12 @@ add_proxy_header_library(
libc.include.llvm-libc-macros.elf_macros
)
-add_gen_header(
+add_proxy_header_library(
elf_proxy
- YAML_FILE
- ../libc/include/elf.yaml
- GEN_HDR
+ HDRS
elf_proxy.h
- DEPENDS
- libc.include.llvm_libc_common_h
- libc.include.llvm-libc-types.Elf32_Addr
- libc.include.llvm-libc-types.Elf32_Chdr
- libc.include.llvm-libc-types.Elf32_Dyn
- libc.include.llvm-libc-types.Elf32_Ehdr
- libc.include.llvm-libc-types.Elf32_Half
- libc.include.llvm-libc-types.Elf32_Lword
- libc.include.llvm-libc-types.Elf32_Nhdr
- libc.include.llvm-libc-types.Elf32_Off
- libc.include.llvm-libc-types.Elf32_Phdr
- libc.include.llvm-libc-types.Elf32_Rel
- libc.include.llvm-libc-types.Elf32_Rela
- libc.include.llvm-libc-types.Elf32_Shdr
- libc.include.llvm-libc-types.Elf32_Sword
- libc.include.llvm-libc-types.Elf32_Sym
- libc.include.llvm-libc-types.Elf32_Verdaux
- libc.include.llvm-libc-types.Elf32_Verdef
- libc.include.llvm-libc-types.Elf32_Vernaux
- libc.include.llvm-libc-types.Elf32_Verneed
- libc.include.llvm-libc-types.Elf32_Versym
- libc.include.llvm-libc-types.Elf32_Word
- libc.include.llvm-libc-types.Elf32_Xword
- libc.include.llvm-libc-types.Elf32_auxv_t
- libc.include.llvm-libc-types.Elf64_Addr
- libc.include.llvm-libc-types.Elf64_Chdr
- libc.include.llvm-libc-types.Elf64_Dyn
- libc.include.llvm-libc-types.Elf64_Ehdr
- libc.include.llvm-libc-types.Elf64_Half
- libc.include.llvm-libc-types.Elf64_Lword
- libc.include.llvm-libc-types.Elf64_Nhdr
- libc.include.llvm-libc-types.Elf64_Off
- libc.include.llvm-libc-types.Elf64_Phdr
- libc.include.llvm-libc-types.Elf64_Rel
- libc.include.llvm-libc-types.Elf64_Rela
- libc.include.llvm-libc-types.Elf64_Shdr
- libc.include.llvm-libc-types.Elf64_Sword
- libc.include.llvm-libc-types.Elf64_Sxword
- libc.include.llvm-libc-types.Elf64_Sym
- libc.include.llvm-libc-types.Elf64_Verdaux
- libc.include.llvm-libc-types.Elf64_Verdef
- libc.include.llvm-libc-types.Elf64_Vernaux
- libc.include.llvm-libc-types.Elf64_Verneed
- libc.include.llvm-libc-types.Elf64_Versym
- libc.include.llvm-libc-types.Elf64_Word
- libc.include.llvm-libc-types.Elf64_Xword
- libc.include.llvm-libc-types.Elf64_auxv_t
- PROXY
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-proxy.elf_proxy
)
add_proxy_header_library(
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/elf_proxy.h b/deps/v8/third_party/llvm-libc/src/hdr/elf_proxy.h
new file mode 100644
index 00000000000..23e42ddff12
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/elf_proxy.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 elf.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_HDR_ELF_PROXY_H
+#define LLVM_LIBC_HDR_HDR_ELF_PROXY_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "llvm-libc-proxy/elf_proxy.h"
+
+#else // Overlay mode
+
+#include <elf.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_HDR_ELF_PROXY_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/fnmatch_macros.h b/deps/v8/third_party/llvm-libc/src/hdr/fnmatch_macros.h
new file mode 100644
index 00000000000..f9d3f35f572
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/fnmatch_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 fnmatch macros.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_FNMATCH_MACROS_H
+#define LLVM_LIBC_HDR_FNMATCH_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/fnmatch-macros.h"
+
+#else // Overlay mode
+
+#include <fnmatch.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_FNMATCH_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/netdb_macros.h b/deps/v8/third_party/llvm-libc/src/hdr/netdb_macros.h
new file mode 100644
index 00000000000..031772a53ad
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/netdb_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 netdb macros.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_NETDB_MACROS_H
+#define LLVM_LIBC_HDR_NETDB_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/netdb-macros.h"
+
+#else // Overlay mode
+
+#include <netdb.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_NETDB_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/semaphore_macros.h b/deps/v8/third_party/llvm-libc/src/hdr/semaphore_macros.h
new file mode 100644
index 00000000000..715ff920073
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/semaphore_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
+/// Definition of macros from semaphore.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_SEMAPHORE_MACROS_H
+#define LLVM_LIBC_HDR_SEMAPHORE_MACROS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-macros/semaphore-macros.h"
+
+#else // Overlay mode
+
+#include <semaphore.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_SEMAPHORE_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 0c926050221..dc15960c7a7 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
@@ -49,6 +49,22 @@ add_proxy_header_library(
libc.include.llvm-libc-types.struct_dl_phdr_info
)
+add_proxy_header_library(
+ struct_link_map
+ HDRS
+ struct_link_map.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_link_map
+)
+
+add_proxy_header_library(
+ struct_r_debug
+ HDRS
+ struct_r_debug.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_r_debug
+)
+
add_proxy_header_library(
ldiv_t
HDRS
@@ -145,6 +161,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.struct_timespec
)
+add_proxy_header_library(
+ struct_itimerspec
+ HDRS
+ struct_itimerspec.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_itimerspec
+)
+
add_proxy_header_library(
struct_tm
HDRS
@@ -153,6 +177,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.struct_tm
)
+add_proxy_header_library(
+ struct_passwd
+ HDRS
+ struct_passwd.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_passwd
+)
+
add_proxy_header_library(
rsize_t
HDRS
@@ -177,6 +209,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.struct_stat
)
+add_proxy_header_library(
+ struct_statfs
+ HDRS
+ struct_statfs.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_statfs
+)
+
add_proxy_header_library(
struct_winsize
HDRS
@@ -193,6 +233,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.ssize_t
)
+add_proxy_header_library(
+ dev_t
+ HDRS
+ dev_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.dev_t
+)
+
add_proxy_header_library(
mode_t
HDRS
@@ -256,6 +304,15 @@ add_proxy_header_library(
libc.include.time
)
+add_proxy_header_library(
+ timer_t
+ HDRS
+ timer_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.timer_t
+ libc.include.time
+)
+
add_proxy_header_library(
clockid_t
HDRS
@@ -282,6 +339,14 @@ add_proxy_header_library(
libc.include.sys_time
)
+add_proxy_header_library(
+ useconds_t
+ HDRS
+ useconds_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.useconds_t
+)
+
add_proxy_header_library(
struct_timeval
HDRS
@@ -325,6 +390,14 @@ add_proxy_header_library(
libc.include.llvm-libc-types.pthread_barrier_t
)
+add_proxy_header_library(
+ sem_t
+ HDRS
+ sem_t.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.sem_t
+)
+
add_proxy_header_library(
pthread_barrierattr_t
HDRS
@@ -360,6 +433,14 @@ add_proxy_header_library(
libc.include.signal
)
+add_proxy_header_library(
+ struct_sigevent
+ HDRS
+ struct_sigevent.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_sigevent
+)
+
add_proxy_header_library(
FILE
HDRS
@@ -583,6 +664,15 @@ add_proxy_header_library(
libc.include.net_if
)
+add_proxy_header_library(
+ struct_if_nameindex
+ HDRS
+ struct_if_nameindex.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_if_nameindex
+ libc.include.net_if
+)
+
add_proxy_header_library(
struct_sockaddr
HDRS
@@ -592,6 +682,14 @@ add_proxy_header_library(
libc.include.sys_socket
)
+add_proxy_header_library(
+ struct_addrinfo
+ HDRS
+ struct_addrinfo.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_addrinfo
+)
+
add_proxy_header_library(
struct_sockaddr_storage
HDRS
@@ -637,6 +735,15 @@ add_proxy_header_library(
libc.include.netinet_udp
)
+add_proxy_header_library(
+ struct_sysinfo
+ HDRS
+ struct_sysinfo.h
+ FULL_BUILD_DEPENDS
+ libc.include.llvm-libc-types.struct_sysinfo
+ libc.include.sys_sysinfo
+)
+
add_proxy_header_library(
struct_utsname
HDRS
@@ -686,7 +793,6 @@ add_proxy_header_library(
libc.include.wchar
)
-
add_proxy_header_library(
wctype_t
HDRS
@@ -989,7 +1095,7 @@ add_proxy_header_library(
add_proxy_header_library(
Elf32_Xword
HDRS
- Elf32_Xword.h
+ Elf32_Xword.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.Elf32_Xword
)
@@ -997,7 +1103,7 @@ add_proxy_header_library(
add_proxy_header_library(
Elf32_auxv_t
HDRS
- Elf32_auxv_t.h
+ Elf32_auxv_t.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.Elf32_auxv_t
)
@@ -1141,7 +1247,7 @@ add_proxy_header_library(
add_proxy_header_library(
Elf64_auxv_t
HDRS
- Elf64_auxv_t.h
+ Elf64_auxv_t.h
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.Elf64_auxv_t
)
@@ -1259,4 +1365,3 @@ add_proxy_header_library(
FULL_BUILD_DEPENDS
libc.include.llvm-libc-types.tcflag_t
)
-
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/dev_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/dev_t.h
new file mode 100644
index 00000000000..95dea5da04a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/dev_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 dev_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_DEV_T_H
+#define LLVM_LIBC_HDR_TYPES_DEV_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/dev_t.h"
+
+#else
+
+#include <sys/types.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_DEV_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/sem_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/sem_t.h
new file mode 100644
index 00000000000..dd5993f7188
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/sem_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 sem_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_SEM_T_H
+#define LLVM_LIBC_HDR_TYPES_SEM_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/sem_t.h"
+
+#else // Overlay mode
+
+#error "Cannot overlay sem_t"
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_SEM_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_addrinfo.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_addrinfo.h
new file mode 100644
index 00000000000..7ec1a65edbf
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_addrinfo.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 struct addrinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_ADDRINFO_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_ADDRINFO_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_addrinfo.h"
+
+#else
+
+#include <netdb.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_ADDRINFO_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_if_nameindex.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_if_nameindex.h
new file mode 100644
index 00000000000..569e33a7c53
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_if_nameindex.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 if_nameindex.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_IF_NAMEINDEX_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_IF_NAMEINDEX_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_if_nameindex.h"
+
+#else
+
+#include <net/if.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_IF_NAMEINDEX_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_itimerspec.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_itimerspec.h
new file mode 100644
index 00000000000..9507299ecb7
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_itimerspec.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 itimerspec.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERSPEC_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERSPEC_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_itimerspec.h"
+
+#else // Overlay mode
+
+#include <time.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_ITIMERSPEC_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_link_map.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_link_map.h
new file mode 100644
index 00000000000..9960913d728
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_link_map.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 link_map.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_LINK_MAP_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_LINK_MAP_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_link_map.h"
+
+#else
+
+#include <link.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_LINK_MAP_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_passwd.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_passwd.h
new file mode 100644
index 00000000000..cf82d6bca9b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_passwd.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 passwd.
+///
+//===----------------------------------------------------------------------===//
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_PASSWD_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_PASSWD_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_passwd.h"
+
+#else
+
+#include <pwd.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_PASSWD_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_r_debug.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_r_debug.h
new file mode 100644
index 00000000000..c0386bf648f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_r_debug.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 r_debug.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_R_DEBUG_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_R_DEBUG_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_r_debug.h"
+
+#else
+
+#include <link.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_R_DEBUG_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_sigevent.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_sigevent.h
new file mode 100644
index 00000000000..6ebc9e492e5
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_sigevent.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 sigevent.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_SIGEVENT_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_SIGEVENT_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_sigevent.h"
+
+#else
+
+#include <signal.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_SIGEVENT_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_statfs.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_statfs.h
new file mode 100644
index 00000000000..e19d52add80
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_statfs.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 struct statfs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_STATFS_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_STATFS_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_statfs.h"
+
+#else // Overlay mode
+
+#include <sys/statfs.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_STATFS_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/struct_sysinfo.h b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_sysinfo.h
new file mode 100644
index 00000000000..bd77ec127f1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/struct_sysinfo.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 sysinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_STRUCT_SYSINFO_H
+#define LLVM_LIBC_HDR_TYPES_STRUCT_SYSINFO_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/struct_sysinfo.h"
+
+#else // Overlay mode
+
+#include <sys/sysinfo.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_STRUCT_SYSINFO_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/timer_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/timer_t.h
new file mode 100644
index 00000000000..9e105f0f90f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/timer_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 timer_t.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_TIMER_T_H
+#define LLVM_LIBC_HDR_TYPES_TIMER_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/timer_t.h"
+
+#else // Overlay mode
+
+#include <time.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_TIMER_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/hdr/types/useconds_t.h b/deps/v8/third_party/llvm-libc/src/hdr/types/useconds_t.h
new file mode 100644
index 00000000000..c6e26bdbf81
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/hdr/types/useconds_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 the useconds_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_HDR_TYPES_USECONDS_T_H
+#define LLVM_LIBC_HDR_TYPES_USECONDS_T_H
+
+#ifdef LIBC_FULL_BUILD
+
+#include "include/llvm-libc-types/useconds_t.h"
+
+#else // Overlay mode
+
+#include <sys/types.h>
+
+#endif // LIBC_FULL_BUILD
+
+#endif // LLVM_LIBC_HDR_TYPES_USECONDS_T_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 0f161f46af4..80f6f0e34cc 100644
--- a/deps/v8/third_party/llvm-libc/src/include/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/CMakeLists.txt
@@ -17,6 +17,9 @@ add_header(
__llvm-libc-common.h
)
+# Has to be after common since elf_proxy depends on common.
+add_subdirectory(llvm-libc-proxy)
+
# TODO: Can we simplify this macro expansion?
# https://github.com/llvm/llvm-project/issues/117254
macro(add_header_macro TARGET_NAME YAML_FILE GEN_HDR DEPENDS)
@@ -47,6 +50,11 @@ add_header_macro(
.llvm-libc-types.ino_t
.llvm-libc-types.DIR
.llvm-libc-types.struct_dirent
+ .llvm-libc-types.struct_posix_dent
+ .llvm-libc-types.reclen_t
+ .llvm-libc-types.size_t
+ .llvm-libc-types.ssize_t
+ .llvm-libc-macros.dirent_macros
)
add_header_macro(
@@ -56,14 +64,22 @@ add_header_macro(
DEPENDS
.llvm-libc-macros.fcntl_macros
.llvm-libc-types.mode_t
+ .llvm-libc-types.struct_f_owner_ex
.llvm-libc-types.struct_flock
.llvm-libc-types.struct_flock64
- .llvm-libc-types.off64_t
.llvm-libc-types.pid_t
.llvm-libc-types.off_t
.llvm_libc_common_h
)
+add_header_macro(
+ sys_fcntl
+ ../libc/include/sys/fcntl.yaml
+ sys/fcntl.h
+ DEPENDS
+ .fcntl
+)
+
add_header_macro(
dlfcn
../libc/include/dlfcn.yaml
@@ -110,6 +126,15 @@ add_header_macro(
.llvm-libc-types.fexcept_t
)
+add_header_macro(
+ fnmatch
+ ../libc/include/fnmatch.yaml
+ fnmatch.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.fnmatch_macros
+)
+
add_header_macro(
stdint
../libc/include/stdint.yaml
@@ -138,6 +163,17 @@ add_header_macro(
.llvm-libc-macros.float_macros
)
+add_header_macro(
+ grp
+ ../libc/include/grp.yaml
+ grp.h
+ DEPENDS
+ .llvm-libc-types.struct_group
+ .llvm-libc-types.gid_t
+ .llvm-libc-types.size_t
+ .llvm_libc_common_h
+)
+
add_header_macro(
libgen
../libc/include/libgen.yaml
@@ -211,6 +247,23 @@ add_header_macro(
.llvm-libc-macros.sysexits_macros
)
+add_header_macro(
+ syslog
+ ../libc/include/syslog.yaml
+ syslog.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.syslog_macros
+)
+
+add_header_macro(
+ sys_syslog
+ ../libc/include/sys/syslog.yaml
+ sys/syslog.h
+ DEPENDS
+ .syslog
+)
+
add_header_macro(
alloca
../libc/include/alloca.yaml
@@ -278,16 +331,26 @@ add_header_macro(
.llvm-libc-macros.annex_k_macros
.llvm-libc-macros.null_macro
.llvm-libc-types.errno_t
+ .llvm-libc-types.locale_t
.llvm-libc-types.rsize_t
.llvm-libc-types.size_t
)
+add_header_macro(
+ memory
+ ../libc/include/memory.yaml
+ memory.h
+ DEPENDS
+ .string
+)
+
add_header_macro(
strings
../libc/include/strings.yaml
strings.h
DEPENDS
.llvm_libc_common_h
+ .llvm-libc-types.locale_t
.llvm-libc-types.size_t
)
@@ -309,6 +372,16 @@ add_header_macro(
.llvm_libc_common_h
)
+add_header_macro(
+ netdb
+ ../libc/include/netdb.yaml
+ netdb.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.netdb_macros
+ .llvm-libc-types.struct_addrinfo
+)
+
add_header_macro(
regex
../libc/include/regex.yaml
@@ -333,12 +406,18 @@ add_header_macro(
.llvm-libc-types.clock_t
.llvm-libc-types.errno_t
.llvm-libc-types.time_t
+ .llvm-libc-types.timer_t
.llvm-libc-types.struct_tm
.llvm-libc-types.struct_timespec
+ .llvm-libc-types.struct_itimerspec
.llvm-libc-types.struct_timeval
.llvm-libc-types.clockid_t
.llvm-libc-types.rsize_t
.llvm-libc-types.tm_gmtoff_t
+ .llvm-libc-types.locale_t
+ .llvm-libc-types.size_t
+ .llvm-libc-types.struct_sigevent
+ .llvm-libc-types.pid_t
)
add_header_macro(
@@ -376,14 +455,24 @@ add_header_macro(
.llvm-libc-macros.signal_macros
.llvm-libc-types.pid_t
.llvm-libc-types.sig_atomic_t
+ .llvm-libc-types.sig_t
.llvm-libc-types.sighandler_t
.llvm-libc-types.siginfo_t
.llvm-libc-types.sigset_t
.llvm-libc-types.stack_t
.llvm-libc-types.struct_sigaction
+ .llvm-libc-types.struct_sigevent
.llvm-libc-types.union_sigval
)
+add_header_macro(
+ sys_signal
+ ../libc/include/sys/signal.yaml
+ sys/signal.h
+ DEPENDS
+ .signal
+)
+
add_header_macro(
stdbit
../libc/include/stdbit.yaml
@@ -440,6 +529,7 @@ add_header_macro(
.llvm-libc-types.locale_t
.llvm-libc-types.rsize_t
.llvm-libc-types.size_t
+ .llvm-libc-types.wchar_t
.llvm_libc_common_h
)
@@ -453,14 +543,24 @@ add_header_macro(
.llvm-libc-macros.unistd_macros
.llvm-libc-types.__exec_argv_t
.llvm-libc-types.__exec_envp_t
+ .llvm-libc-types.gid_t
.llvm-libc-types.off_t
.llvm-libc-types.pid_t
.llvm-libc-types.size_t
.llvm-libc-types.ssize_t
.llvm-libc-types.uid_t
+ .llvm-libc-types.useconds_t
.llvm-libc-types.__getoptargv_t
)
+add_header_macro(
+ sys_unistd
+ ../libc/include/sys/unistd.yaml
+ sys/unistd.h
+ DEPENDS
+ .unistd
+)
+
add_header_macro(
pthread
../libc/include/pthread.yaml
@@ -490,6 +590,17 @@ add_header_macro(
.llvm_libc_common_h
)
+add_header_macro(
+ pwd
+ ../libc/include/pwd.yaml
+ pwd.h
+ DEPENDS
+ .llvm-libc-types.struct_passwd
+ .llvm-libc-types.uid_t
+ .llvm-libc-types.gid_t
+ .llvm_libc_common_h
+)
+
if(LIBC_TARGET_ARCHITECTURE STREQUAL "x86_64")
add_header_macro(
ucontext
@@ -528,6 +639,19 @@ add_header_macro(
.llvm-libc-types.struct_timespec
)
+add_header_macro(
+ semaphore
+ ../libc/include/semaphore.yaml
+ semaphore.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.semaphore_macros
+ .llvm-libc-types.clockid_t
+ .llvm-libc-types.mode_t
+ .llvm-libc-types.sem_t
+ .llvm-libc-types.struct_timespec
+)
+
add_header_macro(
spawn
../libc/include/spawn.yaml
@@ -548,6 +672,8 @@ add_header_macro(
.llvm_libc_common_h
.llvm-libc-macros.link_macros
.llvm-libc-types.struct_dl_phdr_info
+ .llvm-libc-types.struct_link_map
+ .llvm-libc-types.struct_r_debug
.llvm-libc-types.__dl_iterate_phdr_callback_t
)
@@ -556,53 +682,8 @@ add_header_macro(
../libc/include/elf.yaml
elf.h
DEPENDS
- .llvm-libc-macros.elf_macros
- .llvm-libc-macros.sys_auxv_macros
- .llvm-libc-types.Elf32_Addr
- .llvm-libc-types.Elf32_Chdr
- .llvm-libc-types.Elf32_Dyn
- .llvm-libc-types.Elf32_Ehdr
- .llvm-libc-types.Elf32_Half
- .llvm-libc-types.Elf32_Lword
- .llvm-libc-types.Elf32_Nhdr
- .llvm-libc-types.Elf32_Off
- .llvm-libc-types.Elf32_Phdr
- .llvm-libc-types.Elf32_Rel
- .llvm-libc-types.Elf32_Rela
- .llvm-libc-types.Elf32_Shdr
- .llvm-libc-types.Elf32_Sword
- .llvm-libc-types.Elf32_Sym
- .llvm-libc-types.Elf32_Verdaux
- .llvm-libc-types.Elf32_Verdef
- .llvm-libc-types.Elf32_Vernaux
- .llvm-libc-types.Elf32_Verneed
- .llvm-libc-types.Elf32_Versym
- .llvm-libc-types.Elf32_Word
- .llvm-libc-types.Elf32_Xword
- .llvm-libc-types.Elf32_auxv_t
- .llvm-libc-types.Elf64_Addr
- .llvm-libc-types.Elf64_Chdr
- .llvm-libc-types.Elf64_Dyn
- .llvm-libc-types.Elf64_Ehdr
- .llvm-libc-types.Elf64_Half
- .llvm-libc-types.Elf64_Lword
- .llvm-libc-types.Elf64_Nhdr
- .llvm-libc-types.Elf64_Off
- .llvm-libc-types.Elf64_Phdr
- .llvm-libc-types.Elf64_Rel
- .llvm-libc-types.Elf64_Rela
- .llvm-libc-types.Elf64_Shdr
- .llvm-libc-types.Elf64_Sword
- .llvm-libc-types.Elf64_Sxword
- .llvm-libc-types.Elf64_Sym
- .llvm-libc-types.Elf64_Verdaux
- .llvm-libc-types.Elf64_Verdef
- .llvm-libc-types.Elf64_Vernaux
- .llvm-libc-types.Elf64_Verneed
- .llvm-libc-types.Elf64_Versym
- .llvm-libc-types.Elf64_Word
- .llvm-libc-types.Elf64_Xword
- .llvm-libc-types.Elf64_auxv_t
+ .llvm-libc-proxy.elf_proxy
+ .llvm_libc_common_h
)
# TODO: Not all platforms will have a include/sys directory. Add the sys
@@ -628,6 +709,7 @@ add_header_macro(
.llvm-libc-types.struct_epoll_event
.llvm-libc-types.struct_epoll_data
.llvm-libc-types.sigset_t
+ .llvm-libc-types.struct_timespec
.llvm-libc-macros.sys_epoll_macros
)
@@ -662,11 +744,21 @@ add_header_macro(
DEPENDS
.llvm_libc_common_h
.llvm-libc-macros.sys_mman_macros
+ .llvm-libc-types.mode_t
.llvm-libc-types.off_t
.llvm-libc-types.size_t
.llvm-libc-types.ssize_t
)
+add_header_macro(
+ sys_mount
+ ../libc/include/sys/mount.yaml
+ sys/mount.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.sys_mount_macros
+)
+
add_header_macro(
sys_param
../libc/include/sys/param.yaml
@@ -730,6 +822,7 @@ add_header_macro(
.llvm-libc-macros.sys_resource_macros
.llvm-libc-types.rlim_t
.llvm-libc-types.struct_rlimit
+ .llvm-libc-types.struct_rusage
)
add_header_macro(
@@ -803,6 +896,7 @@ add_header_macro(
.llvm-libc-macros.sys_socket_macros
.llvm-libc-types.sa_family_t
.llvm-libc-types.socklen_t
+ .llvm-libc-types.ssize_t
.llvm-libc-types.struct_cmsghdr
.llvm-libc-types.struct_iovec
.llvm-libc-types.struct_linger
@@ -810,6 +904,18 @@ add_header_macro(
.llvm-libc-types.struct_msghdr
.llvm-libc-types.struct_sockaddr
.llvm-libc-types.struct_sockaddr_storage
+ .llvm-libc-types.struct_timespec
+ .llvm-libc-types.struct_ucred
+)
+
+add_header_macro(
+ sys_statfs
+ ../libc/include/sys/statfs.yaml
+ sys/statfs.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.sys_statfs_macros
+ .llvm-libc-types.struct_statfs
)
add_header_macro(
@@ -821,6 +927,16 @@ add_header_macro(
.llvm-libc-types.struct_statvfs
)
+add_header_macro(
+ sys_sysmacros
+ ../libc/include/sys/sysmacros.yaml
+ sys/sysmacros.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-macros.sys_sysmacros_macros
+ .llvm-libc-types.dev_t
+)
+
add_header_macro(
sys_syscall
../libc/include/sys/syscall.yaml
@@ -845,33 +961,61 @@ add_header_macro(
sys/types.h
DEPENDS
.llvm_libc_common_h
+ .llvm-libc-types.__off_t
+ .llvm-libc-types.__off64_t
+ .llvm-libc-types.__uint64_t
.llvm-libc-types.blkcnt_t
.llvm-libc-types.blksize_t
+ .llvm-libc-types.caddr_t
.llvm-libc-types.clockid_t
.llvm-libc-types.dev_t
.llvm-libc-types.gid_t
+ .llvm-libc-types.id_t
+ .llvm-libc-types.ino64_t
.llvm-libc-types.ino_t
.llvm-libc-types.key_t
.llvm-libc-types.loff_t
.llvm-libc-types.mode_t
.llvm-libc-types.nlink_t
+ .llvm-libc-types.off64_t
.llvm-libc-types.off_t
.llvm-libc-types.pid_t
.llvm-libc-types.pthread_attr_t
.llvm-libc-types.pthread_cond_t
+ .llvm-libc-types.pthread_condattr_t
.llvm-libc-types.pthread_key_t
.llvm-libc-types.pthread_mutex_t
.llvm-libc-types.pthread_mutexattr_t
.llvm-libc-types.pthread_once_t
+ .llvm-libc-types.pthread_rwlock_t
+ .llvm-libc-types.pthread_rwlockattr_t
.llvm-libc-types.pthread_t
.llvm-libc-types.size_t
.llvm-libc-types.ssize_t
.llvm-libc-types.suseconds_t
.llvm-libc-types.time_t
+ .llvm-libc-types.timer_t
.llvm-libc-types.u_char
+ .llvm-libc-types.u_int
+ .llvm-libc-types.u_int16_t
.llvm-libc-types.u_int32_t
+ .llvm-libc-types.u_int8_t
+ .llvm-libc-types.u_long
+ .llvm-libc-types.u_short
.llvm-libc-types.uid_t
.llvm-libc-types.uint
+ .llvm-libc-types.ulong
+ .llvm-libc-types.useconds_t
+ .llvm-libc-types.ushort
+)
+
+add_header_macro(
+ sys_sysinfo
+ ../libc/include/sys/sysinfo.yaml
+ sys/sysinfo.h
+ DEPENDS
+ .llvm_libc_common_h
+ .llvm-libc-types.struct_sysinfo
)
add_header_macro(
@@ -902,6 +1046,14 @@ add_header_macro(
.llvm-libc-types.struct_sockaddr_un
)
+add_header_macro(
+ sys_vfs
+ ../libc/include/sys/vfs.yaml
+ sys/vfs.h
+ DEPENDS
+ .sys_statfs
+)
+
add_header_macro(
sys_wait
../libc/include/sys/wait.yaml
@@ -923,6 +1075,7 @@ add_header_macro(
DEPENDS
.llvm_libc_common_h
.llvm-libc-macros.net_if_macros
+ .llvm-libc-types.struct_if_nameindex
.llvm-libc-types.struct_ifreq
)
@@ -1010,6 +1163,7 @@ add_header_macro(
DEPENDS
.llvm_libc_common_h
.llvm-libc-types.mbstate_t
+ .llvm-libc-types.size_t
.llvm-libc-types.char8_t
.llvm-libc-types.char16_t
.llvm-libc-types.char32_t
@@ -1028,6 +1182,8 @@ add_header_macro(
.llvm-libc-types.size_t
.llvm-libc-types.wint_t
.llvm-libc-types.wchar_t
+ .llvm-libc-types.FILE
+ .llvm-libc-types.struct_tm
)
add_header_macro(
@@ -1060,7 +1216,15 @@ add_header_macro(
.llvm-libc-types.struct_pollfd
.llvm-libc-types.nfds_t
.llvm-libc-macros.poll-macros
- )
+)
+
+add_header_macro(
+ sys_poll
+ ../libc/include/sys/poll.yaml
+ sys/poll.h
+ DEPENDS
+ .poll
+)
add_header_macro(
nl_types
@@ -1069,7 +1233,7 @@ add_header_macro(
DEPENDS
.llvm-libc-macros.nl_types_macros
.llvm-libc-types.nl_catd
- )
+)
add_header_macro(
langinfo
@@ -1080,7 +1244,7 @@ add_header_macro(
.llvm-libc-macros.langinfo_macros
.llvm-libc-types.nl_item
.llvm-libc-types.locale_t
- )
+)
# UEFI spec references "Uefi.h" so we use that name for compatibility
add_header_macro(
@@ -1112,7 +1276,7 @@ function(get_all_install_header_targets out_var)
endforeach()
list(REMOVE_DUPLICATES all_deps)
set(${out_var} ${all_deps} PARENT_SCOPE)
-endfunction(get_all_install_header_targets)
+endfunction()
get_all_install_header_targets(all_install_header_targets ${TARGET_PUBLIC_HEADERS})
add_custom_target(generate-libc-headers DEPENDS ${all_install_header_targets})
@@ -1124,13 +1288,13 @@ foreach(target IN LISTS all_install_header_targets)
get_target_property(header_file ${target} HEADER_FILE_PATH)
if(NOT header_file)
message(FATAL_ERROR "Installable header file '${target}' does not have the "
- "HEADER_FILE_PATH property set.")
+ "HEADER_FILE_PATH property set.")
endif()
file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_DIR} ${header_file})
get_filename_component(nested_dir ${relative_path} DIRECTORY)
install(FILES ${header_file}
- DESTINATION ${LIBC_INSTALL_INCLUDE_DIR}/${nested_dir}
- COMPONENT libc-headers)
+ DESTINATION ${LIBC_INSTALL_INCLUDE_DIR}/${nested_dir}
+ COMPONENT libc-headers)
# The GPU optionally provides the supported declarations externally so
# offloading languages like CUDA and OpenMP know what is supported by libc. We
# install these in the compiler's resource directory at a preset location.
@@ -1143,19 +1307,19 @@ foreach(target IN LISTS all_install_header_targets)
file(RELATIVE_PATH relative_path ${LIBC_INCLUDE_DIR} ${decls_file})
get_filename_component(nested_dir ${relative_path} DIRECTORY)
set(install_dir
- ${CMAKE_INSTALL_PREFIX}/${resource_dir}/llvm_libc_wrappers/${nested_dir})
+ ${CMAKE_INSTALL_PREFIX}/${resource_dir}/llvm_libc_wrappers/${nested_dir})
install(FILES ${decls_file}
- DESTINATION ${install_dir}
- COMPONENT libc-headers)
+ DESTINATION ${install_dir}
+ COMPONENT libc-headers)
endif()
endforeach()
if(LLVM_LIBC_FULL_BUILD)
add_custom_target(install-libc-headers
- DEPENDS libc-headers
- COMMAND "${CMAKE_COMMAND}"
- -DCMAKE_INSTALL_COMPONENT=libc-headers
- -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
+ DEPENDS libc-headers
+ COMMAND "${CMAKE_COMMAND}"
+ -DCMAKE_INSTALL_COMPONENT=libc-headers
+ -P "${CMAKE_BINARY_DIR}/cmake_install.cmake")
# Stripping is a no-op for headers
add_custom_target(install-libc-headers-stripped DEPENDS install-libc-headers)
endif()
diff --git a/deps/v8/third_party/llvm-libc/src/include/dirent.yaml b/deps/v8/third_party/llvm-libc/src/include/dirent.yaml
index 66570bca6c4..e752b564d8d 100644
--- a/deps/v8/third_party/llvm-libc/src/include/dirent.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/dirent.yaml
@@ -1,10 +1,31 @@
header: dirent.h
standards:
- posix
+macros:
+ - macro_name: DT_UNKNOWN
+ macro_header: dirent-macros.h
+ - macro_name: DT_FIFO
+ macro_header: dirent-macros.h
+ - macro_name: DT_CHR
+ macro_header: dirent-macros.h
+ - macro_name: DT_DIR
+ macro_header: dirent-macros.h
+ - macro_name: DT_BLK
+ macro_header: dirent-macros.h
+ - macro_name: DT_REG
+ macro_header: dirent-macros.h
+ - macro_name: DT_LNK
+ macro_header: dirent-macros.h
+ - macro_name: DT_SOCK
+ macro_header: dirent-macros.h
types:
- type_name: struct_dirent
+ - type_name: struct_posix_dent
- type_name: DIR
- type_name: ino_t
+ - type_name: reclen_t
+ - type_name: size_t
+ - type_name: ssize_t
functions:
- name: alphasort
standards:
diff --git a/deps/v8/third_party/llvm-libc/src/include/elf.yaml b/deps/v8/third_party/llvm-libc/src/include/elf.yaml
index 2b11dfe2a34..f86463b2f4a 100644
--- a/deps/v8/third_party/llvm-libc/src/include/elf.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/elf.yaml
@@ -1,667 +1,5 @@
header: elf.h
+public_includes:
+ - llvm-libc-proxy/elf_proxy.h
standards:
- svid
-macros:
- # ELF Header
- - macro_name: EI_NIDENT
- macro_value: 16
- - macro_name: EI_MAG0
- macro_value: 0
- - macro_name: EI_MAG1
- macro_value: 1
- - macro_name: EI_MAG2
- macro_value: 2
- - macro_name: EI_MAG3
- macro_value: 3
- - macro_name: EI_CLASS
- macro_value: 4
- - macro_name: EI_DATA
- macro_value: 5
- - macro_name: EI_VERSION
- macro_value: 6
- - macro_name: EI_OSABI
- macro_value: 7
- - macro_name: EI_ABIVERSION
- macro_value: 8
- - macro_name: EI_PAD
- macro_value: 9
- - macro_name: EI_NIDENT
- macro_value: 16
- - macro_name: ELFMAG0
- macro_value: '0x7f'
- - macro_name: ELFMAG1
- macro_value: "'E'"
- - macro_name: ELFMAG2
- macro_value: "'L'"
- - macro_name: ELFMAG3
- macro_value: "'F'"
- - macro_name: ELFMAG
- macro_value: '"\177ELF"'
- - macro_name: SELFMAG
- macro_value: 4
- - macro_name: ELFCLASSNONE
- macro_value: 0
- - macro_name: ELFCLASS32
- macro_value: 1
- - macro_name: ELFCLASS64
- macro_value: 2
- - macro_name: ELFDATANONE
- macro_value: 0
- - macro_name: ELFDATA2LSB
- macro_value: 1
- - macro_name: ELFDATA2MSB
- macro_value: 2
- - macro_name: ELFOSABI_NONE
- macro_value: 0
- - macro_name: ELFOSABI_LINUX
- macro_value: 3
- - macro_name: ET_NONE
- macro_value: 0
- - macro_name: ET_REL
- macro_value: 1
- - macro_name: ET_EXEC
- macro_value: 2
- - macro_name: ET_DYN
- macro_value: 3
- - macro_name: ET_CORE
- macro_value: 4
- - macro_name: ET_LOOS
- macro_value: '0xfe00'
- - macro_name: ET_HIOS
- macro_value: '0xfeff'
- - macro_name: ET_LOPROC
- macro_value: '0xff00'
- - macro_name: ET_HIPROC
- macro_value: '0xffff'
- - macro_name: EM_NONE
- macro_value: 0
- - macro_name: EM_386
- macro_value: 3
- - macro_name: EM_ARM
- macro_value: 40
- - macro_name: EM_X86_64
- macro_value: 62
- - macro_name: EM_AARCH64
- macro_value: 183
- - macro_name: EM_RISCV
- macro_value: 243
- - macro_name: EV_NONE
- macro_value: 0
- - macro_name: EV_CURRENT
- macro_value: 1
- # Sections
- - macro_name: SHN_UNDEF
- macro_value: 0
- - macro_name: SHN_LORESERVE
- macro_value: '0xff00'
- - macro_name: SHN_LOPROC
- macro_value: '0xff00'
- - macro_name: SHN_HIPROC
- macro_value: '0xff1f'
- - macro_name: SHN_LOOS
- macro_value: '0xff20'
- - macro_name: SHN_HIOS
- macro_value: '0xff3f'
- - macro_name: SHN_ABS
- macro_value: '0xfff1'
- - macro_name: SHN_COMMON
- macro_value: '0xfff2'
- - macro_name: SHN_XINDEX
- macro_value: '0xffff'
- - macro_name: SHN_HIRESERVE
- macro_value: '0xffff'
- - macro_name: SHT_NULL
- macro_value: 0
- - macro_name: SHT_PROGBITS
- macro_value: 1
- - macro_name: SHT_SYMTAB
- macro_value: 2
- - macro_name: SHT_STRTAB
- macro_value: 3
- - macro_name: SHT_RELA
- macro_value: 4
- - macro_name: SHT_HASH
- macro_value: 5
- - macro_name: SHT_DYNAMIC
- macro_value: 6
- - macro_name: SHT_NOTE
- macro_value: 7
- - macro_name: SHT_NOBITS
- macro_value: 8
- - macro_name: SHT_REL
- macro_value: 9
- - macro_name: SHT_SHLIB
- macro_value: 10
- - macro_name: SHT_DYNSYM
- macro_value: 11
- - macro_name: SHT_INIT_ARRAY
- macro_value: 14
- - macro_name: SHT_FINI_ARRAY
- macro_value: 15
- - macro_name: SHT_PREINIT_ARRAY
- macro_value: 16
- - macro_name: SHT_GROUP
- macro_value: 17
- - macro_name: SHT_SYMTAB_SHNDX
- macro_value: 18
- - macro_name: SHT_LOOS
- macro_value: '0x60000000'
- - macro_name: SHT_HIOS
- macro_value: '0x6fffffff'
- - macro_name: SHT_LOPROC
- macro_value: '0x70000000'
- - macro_name: SHT_HIPROC
- macro_value: '0x7fffffff'
- - macro_name: SHT_LOUSER
- macro_value: '0x80000000'
- - macro_name: SHT_HIUSER
- macro_value: '0xffffffff'
- - macro_name: SHF_WRITE
- macro_value: '0x1'
- - macro_name: SHF_ALLOC
- macro_value: '0x2'
- - macro_name: SHF_EXECINSTR
- macro_value: '0x4'
- - macro_name: SHF_MERGE
- macro_value: '0x10'
- - macro_name: SHF_STRINGS
- macro_value: '0x20'
- - macro_name: SHF_INFO_LINK
- macro_value: '0x40'
- - macro_name: SHF_LINK_ORDER
- macro_value: '0x80'
- - macro_name: SHF_OS_NONCONFORMING
- macro_value: '0x100'
- - macro_name: SHF_GROUP
- macro_value: '0x200'
- - macro_name: SHF_TLS
- macro_value: '0x400'
- - macro_name: SHF_COMPRESSED
- macro_value: '0x800'
- - macro_name: SHF_MASKOS
- macro_value: '0x0ff00000'
- - macro_name: SHF_MASKPROC
- macro_value: '0xf0000000'
- - macro_name: ELFCOMPRESS_ZLIB
- macro_value: 1
- - macro_name: ELFCOMPRESS_ZSTD
- macro_value: 2
- - macro_name: ELFCOMPRESS_LOOS
- macro_value: '0x60000000'
- - macro_name: ELFCOMPRESS_HIOS
- macro_value: '0x6fffffff'
- - macro_name: ELFCOMPRESS_LOPROC
- macro_value: '0x70000000'
- - macro_name: ELFCOMPRESS_HIPROC
- macro_value: '0x7fffffff'
- # Symbol Table
- - macro_name: STN_UNDEF
- macro_value: 0
- - macro_name: STB_LOCAL
- macro_value: 0
- - macro_name: STB_GLOBAL
- macro_value: 1
- - macro_name: STB_WEAK
- macro_value: 2
- - macro_name: STB_LOOS
- macro_value: 10
- - macro_name: STB_HIOS
- macro_value: 12
- - macro_name: STB_LOPROC
- macro_value: 13
- - macro_name: STB_HIPROC
- macro_value: 15
- - macro_name: STT_NOTYPE
- macro_value: 0
- - macro_name: STT_OBJECT
- macro_value: 1
- - macro_name: STT_FUNC
- macro_value: 2
- - macro_name: STT_SECTION
- macro_value: 3
- - macro_name: STT_FILE
- macro_value: 4
- - macro_name: STT_COMMON
- macro_value: 5
- - macro_name: STT_TLS
- macro_value: 6
- - macro_name: STT_LOOS
- macro_value: 10
- - macro_name: STT_HIOS
- macro_value: 12
- - macro_name: STT_LOPROC
- macro_value: 13
- - macro_name: STT_HIPROC
- macro_value: 15
- - macro_name: STV_DEFAULT
- macro_value: 0
- - macro_name: STV_INTERNAL
- macro_value: 1
- - macro_name: STV_HIDDEN
- macro_value: 2
- - macro_name: STV_PROTECTED
- macro_value: 3
- # Program Loading
- - macro_name: PT_NULL
- macro_value: 0
- - macro_name: PT_LOAD
- macro_value: 1
- - macro_name: PT_DYNAMIC
- macro_value: 2
- - macro_name: PT_INTERP
- macro_value: 3
- - macro_name: PT_NOTE
- macro_value: 4
- - macro_name: PT_SHLIB
- macro_value: 5
- - macro_name: PT_PHDR
- macro_value: 6
- - macro_name: PT_TLS
- macro_value: 7
- - macro_name: PT_LOOS
- macro_value: '0x60000000'
- - macro_name: PT_HIOS
- macro_value: '0x6fffffff'
- - macro_name: PT_LOPROC
- macro_value: '0x70000000'
- - macro_name: PT_HIPROC
- macro_value: '0x7fffffff'
- - macro_name: PT_GNU_EH_FRAME
- macro_value: '0x6474e550'
- standards:
- - gnu
- - macro_name: PT_GNU_STACK
- macro_value: '0x6474e551'
- standards:
- - gnu
- - macro_name: PT_GNU_RELRO
- macro_value: '0x6474e552'
- standards:
- - gnu
- - macro_name: PT_GNU_PROPERTY
- macro_value: '0x6474e553'
- - macro_name: PF_X
- macro_value: '0x1'
- - macro_name: PF_W
- macro_value: '0x2'
- - macro_name: PF_R
- macro_value: '0x4'
- - macro_name: PF_MASKOS
- macro_value: '0x0ff00000'
- - macro_name: PF_MASKPROC
- macro_value: '0xf0000000'
- # Dynamic Linking
- - macro_name: DT_NULL
- macro_value: 0
- - macro_name: DT_NEEDED
- macro_value: 1
- - macro_name: DT_PLTRELSZ
- macro_value: 2
- - macro_name: DT_PLTGOT
- macro_value: 3
- - macro_name: DT_HASH
- macro_value: 4
- - macro_name: DT_STRTAB
- macro_value: 5
- - macro_name: DT_SYMTAB
- macro_value: 6
- - macro_name: DT_RELA
- macro_value: 7
- - macro_name: DT_RELASZ
- macro_value: 8
- - macro_name: DT_RELAENT
- macro_value: 9
- - macro_name: DT_STRSZ
- macro_value: 10
- - macro_name: DT_SYMENT
- macro_value: 11
- - macro_name: DT_INIT
- macro_value: 12
- - macro_name: DT_FINI
- macro_value: 13
- - macro_name: DT_SONAME
- macro_value: 14
- - macro_name: DT_RPATH
- macro_value: 15
- - macro_name: DT_SYMBOLIC
- macro_value: 16
- - macro_name: DT_REL
- macro_value: 17
- - macro_name: DT_RELSZ
- macro_value: 18
- - macro_name: DT_RELENT
- macro_value: 19
- - macro_name: DT_PLTREL
- macro_value: 20
- - macro_name: DT_DEBUG
- macro_value: 21
- - macro_name: DT_TEXTREL
- macro_value: 22
- - macro_name: DT_JMPREL
- macro_value: 23
- - macro_name: DT_BIND_NOW
- macro_value: 24
- - macro_name: DT_INIT_ARRAY
- macro_value: 25
- - macro_name: DT_FINI_ARRAY
- macro_value: 26
- - macro_name: DT_INIT_ARRAYSZ
- macro_value: 27
- - macro_name: DT_FINI_ARRAYSZ
- macro_value: 28
- - macro_name: DT_RUNPATH
- macro_value: 29
- - macro_name: DT_FLAGS
- macro_value: 30
- - macro_name: DT_ENCODING
- macro_value: 32
- - macro_name: DT_PREINIT_ARRAY
- macro_value: 32
- - macro_name: DT_PREINIT_ARRAYSZ
- macro_value: 33
- - macro_name: DT_SYMTAB_SHNDX
- macro_value: 34
- - macro_name: DT_LOOS
- macro_value: '0x6000000D'
- - macro_name: DT_HIOS
- macro_value: '0x6ffff000'
- - macro_name: DT_LOPROC
- macro_value: '0x70000000'
- - macro_name: DT_HIPROC
- macro_value: '0x7fffffff'
- - macro_name: DT_ADDRRNGLO
- macro_value: '0x6ffffe00'
- - macro_name: DT_GNU_HASH
- macro_value: '0x6ffffef5'
- standards:
- - gnu
- - macro_name: DT_TLSDESC_PLT
- macro_value: '0x6ffffef6'
- standards:
- - gnu
- - macro_name: DT_TLSDESC_GOT
- macro_value: '0x6ffffef7'
- standards:
- - gnu
- - macro_name: DT_GNU_CONFLICT
- macro_value: '0x6ffffef8'
- standards:
- - gnu
- - macro_name: DT_GNU_LIBLIST
- macro_value: '0x6ffffef9'
- standards:
- - gnu
- - macro_name: DT_CONFIG
- macro_value: '0x6ffffefa'
- - macro_name: DT_DEPAUDIT
- macro_value: '0x6ffffefb'
- - macro_name: DT_AUDIT
- macro_value: '0x6ffffefc'
- - macro_name: DT_PLTPAD
- macro_value: '0x6ffffefd'
- - macro_name: DT_MOVETAB
- macro_value: '0x6ffffefe'
- - macro_name: DT_SYMINFO
- macro_value: '0x6ffffeff'
- - macro_name: DT_ADDRRNGHI
- macro_value: '0x6ffffeff'
- - macro_name: DT_VERSYM
- macro_value: '0x6ffffff0'
- - macro_name: DT_RELACOUNT
- macro_value: '0x6ffffff9'
- - macro_name: DT_RELCOUNT
- macro_value: '0x6ffffffa'
- - macro_name: DT_VERDEF
- macro_value: '0x6ffffffc'
- - macro_name: DT_VERDEFNUM
- macro_value: '0x6ffffffd'
- - macro_name: DT_VERNEED
- macro_value: '0x6ffffffe'
- - macro_name: DT_VERNEEDNUM
- macro_value: '0x6fffffff'
- - macro_name: DF_ORIGIN
- macro_value: '0x1'
- - macro_name: DF_SYMBOLIC
- macro_value: '0x2'
- - macro_name: DF_TEXTREL
- macro_value: '0x4'
- - macro_name: DF_BIND_NOW
- macro_value: '0x8'
- - macro_name: DF_STATIC_TLS
- macro_value: '0x10'
- # Notes used in ET_CORE.
- - macro_name: NN_PRSTATUS
- macro_value: '"CORE"'
- - macro_name: NT_PRSTATUS
- macro_value: 1
- - macro_name: NN_PRFPREG
- macro_value: '"CORE"'
- - macro_name: NT_PRFPREG
- macro_value: 2
- - macro_name: NT_FPREGSET
- macro_value: 2
- - macro_name: NN_PRPSINFO
- macro_value: '"CORE"'
- - macro_name: NT_PRPSINFO
- macro_value: 3
- - macro_name: NN_TASKSTRUCT
- macro_value: '"CORE"'
- - macro_name: NT_TASKSTRUCT
- macro_value: 4
- - macro_name: NT_PRXREG
- macro_value: 4
- - macro_name: NT_PLATFORM
- macro_value: 5
- - macro_name: NN_AUXV
- macro_value: '"CORE"'
- - macro_name: NT_AUXV
- macro_value: 6
- - macro_name: NN_SIGINFO
- macro_value: '"CORE"'
- - macro_name: NT_SIGINFO
- macro_value: '0x53494749'
- - macro_name: NN_FILE
- macro_value: '"CORE"'
- - macro_name: NT_FILE
- macro_value: '0x46494c45'
- - macro_name: NT_PRFPXREG
- macro_value: 20
- # Notes used by GNU toolchain.
- - macro_name: NT_GNU_ABI_TAG
- macro_value: 1
- standards:
- - gnu
- - macro_name: NT_GNU_HWCAP
- macro_value: 2
- standards:
- - gnu
- - macro_name: NT_GNU_BUILD_ID
- macro_value: 3
- standards:
- - gnu
- - macro_name: NT_GNU_GOLD_VERSION
- macro_value: 4
- standards:
- - gnu
- - macro_name: NT_GNU_PROPERTY_TYPE_0
- macro_value: 5
- standards:
- - gnu
- # Symbol Versioning
- - macro_name: VER_DEF_NONE
- macro_value: 0
- - macro_name: VER_DEF_CURRENT
- macro_value: 1
- - macro_name: VER_DEF_NUM
- macro_value: 2
- - macro_name: VER_FLG_BASE
- macro_value: '0x1'
- - macro_name: VER_FLG_WEAK
- macro_value: '0x2'
- - macro_name: VER_NDX_LOCAL
- macro_value: 0
- - macro_name: VER_NDX_GLOBAL
- macro_value: 1
- - macro_name: VER_NDX_LORESERVE
- macro_value: '0xff00'
- - macro_name: VER_NDX_ELIMINATE
- macro_value: '0xff01'
- # Values used in the .note.gnu.property section.
- - macro_name: GNU_PROPERTY_X86_FEATURE_1_AND
- macro_value: '0xc0000002'
- - macro_name: GNU_PROPERTY_X86_FEATURE_1_SHSTK
- macro_value: '0x00000002'
- # Architecture-specific IRELATIVE relocation types
- - macro_name: R_AARCH64_IRELATIVE
- macro_value: 1032
- - macro_name: R_ARM_IRELATIVE
- macro_value: 160
- - macro_name: R_RISCV_IRELATIVE
- macro_value: 58
- - macro_name: R_X86_64_IRELATIVE
- macro_value: 37
- - macro_name: ELF32_ST_BIND
- macro_header: elf-macros.h
- - macro_name: ELF32_ST_TYPE
- macro_header: elf-macros.h
- - macro_name: ELF32_ST_INFO
- macro_header: elf-macros.h
- - macro_name: ELF64_ST_BIND
- macro_header: elf-macros.h
- - macro_name: ELF64_ST_TYPE
- macro_header: elf-macros.h
- - macro_name: ELF64_ST_INFO
- macro_header: elf-macros.h
- - macro_name: ELF32_ST_VISIBILITY
- macro_header: elf-macros.h
- - macro_name: ELF64_ST_VISIBILITY
- macro_header: elf-macros.h
- - macro_name: ELF32_R_SYM
- macro_header: elf-macros.h
- - macro_name: ELF32_R_TYPE
- macro_header: elf-macros.h
- - macro_name: ELF32_R_INFO
- macro_header: elf-macros.h
- - macro_name: ELF64_R_SYM
- macro_header: elf-macros.h
- - macro_name: ELF64_R_TYPE
- macro_header: elf-macros.h
- - macro_name: ELF64_R_INFO
- macro_header: elf-macros.h
- - macro_name: PT_AARCH64_MEMTAG_MTE
- macro_value: '0x70000002'
- - macro_name: PN_XNUM
- macro_value: '0xffff'
- - macro_name: ELFCLASSNUM
- macro_value: 3
- - macro_name: EV_NUM
- macro_value: 2
- - macro_name: AT_NULL
- macro_header: sys-auxv-macros.h
- - macro_name: AT_IGNORE
- macro_header: sys-auxv-macros.h
- - macro_name: AT_EXECFD
- macro_header: sys-auxv-macros.h
- - macro_name: AT_PHDR
- macro_header: sys-auxv-macros.h
- - macro_name: AT_PHENT
- macro_header: sys-auxv-macros.h
- - macro_name: AT_PHNUM
- macro_header: sys-auxv-macros.h
- - macro_name: AT_PAGESZ
- macro_header: sys-auxv-macros.h
- - macro_name: AT_BASE
- macro_header: sys-auxv-macros.h
- - macro_name: AT_FLAGS
- macro_header: sys-auxv-macros.h
- - macro_name: AT_ENTRY
- macro_header: sys-auxv-macros.h
- - macro_name: AT_NOTELF
- macro_header: sys-auxv-macros.h
- - macro_name: AT_UID
- macro_header: sys-auxv-macros.h
- - macro_name: AT_EUID
- macro_header: sys-auxv-macros.h
- - macro_name: AT_GID
- macro_header: sys-auxv-macros.h
- - macro_name: AT_EGID
- macro_header: sys-auxv-macros.h
- - macro_name: AT_PLATFORM
- macro_header: sys-auxv-macros.h
- - macro_name: AT_HWCAP
- macro_header: sys-auxv-macros.h
- - macro_name: AT_CLKTCK
- macro_header: sys-auxv-macros.h
- - macro_name: AT_SECURE
- macro_header: sys-auxv-macros.h
- - macro_name: AT_BASE_PLATFORM
- macro_header: sys-auxv-macros.h
- - macro_name: AT_RANDOM
- macro_header: sys-auxv-macros.h
- - macro_name: AT_HWCAP2
- macro_header: sys-auxv-macros.h
- - macro_name: AT_RSEQ_FEATURE_SIZE
- macro_header: sys-auxv-macros.h
- - macro_name: AT_RSEQ_ALIGN
- macro_header: sys-auxv-macros.h
- - macro_name: AT_HWCAP3
- macro_header: sys-auxv-macros.h
- - macro_name: AT_HWCAP4
- macro_header: sys-auxv-macros.h
- - macro_name: AT_EXECFN
- macro_header: sys-auxv-macros.h
- - macro_name: AT_SYSINFO
- macro_header: sys-auxv-macros.h
- - macro_name: AT_SYSINFO_EHDR
- macro_header: sys-auxv-macros.h
- - macro_name: AT_MINSIGSTKSZ
- macro_header: sys-auxv-macros.h
-types:
- - type_name: Elf32_Addr
- - type_name: Elf32_Chdr
- - type_name: Elf32_Dyn
- - type_name: Elf32_Ehdr
- - type_name: Elf32_Half
- - type_name: Elf32_Lword
- - type_name: Elf32_Nhdr
- - type_name: Elf32_Off
- - type_name: Elf32_Phdr
- - type_name: Elf32_Rel
- - type_name: Elf32_Rela
- - type_name: Elf32_Shdr
- - type_name: Elf32_Sword
- - type_name: Elf32_Sym
- - type_name: Elf32_Verdaux
- - type_name: Elf32_Verdef
- - type_name: Elf32_Vernaux
- - type_name: Elf32_Verneed
- - type_name: Elf32_Versym
- - type_name: Elf32_Word
- - type_name: Elf32_Xword
- - type_name: Elf32_auxv_t
- - type_name: Elf64_Addr
- - type_name: Elf64_Chdr
- - type_name: Elf64_Dyn
- - type_name: Elf64_Ehdr
- - type_name: Elf64_Half
- - type_name: Elf64_Lword
- - type_name: Elf64_Nhdr
- - type_name: Elf64_Off
- - type_name: Elf64_Phdr
- - type_name: Elf64_Rel
- - type_name: Elf64_Rela
- - type_name: Elf64_Shdr
- - type_name: Elf64_Sword
- - type_name: Elf64_Sxword
- - type_name: Elf64_Sym
- - type_name: Elf64_Verdaux
- - type_name: Elf64_Verdef
- - type_name: Elf64_Vernaux
- - type_name: Elf64_Verneed
- - type_name: Elf64_Versym
- - type_name: Elf64_Word
- - type_name: Elf64_Xword
- - type_name: Elf64_auxv_t
-enums: []
-objects: []
-functions: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/errno.yaml b/deps/v8/third_party/llvm-libc/src/include/errno.yaml
index e29d15ba3e3..ead1fc4ef23 100644
--- a/deps/v8/third_party/llvm-libc/src/include/errno.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/errno.yaml
@@ -8,5 +8,9 @@ macros: []
types:
- type_name: errno_t
enums: []
-objects: []
+objects:
+ - object_name: program_invocation_name
+ object_type: char *
+ - object_name: program_invocation_short_name
+ object_type: char *
functions: []
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 8950f5b17cf..43226b45505 100644
--- a/deps/v8/third_party/llvm-libc/src/include/fcntl.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/fcntl.yaml
@@ -11,8 +11,12 @@ macros:
- macro_name: AT_EACCESS
macro_header: fcntl-macros.h
types:
- - type_name: off_t
- type_name: mode_t
+ - type_name: off_t
+ - type_name: pid_t
+ - type_name: struct_f_owner_ex
+ - type_name: struct_flock
+ - type_name: struct_flock64
enums: []
objects: []
functions:
diff --git a/deps/v8/third_party/llvm-libc/src/include/fnmatch.yaml b/deps/v8/third_party/llvm-libc/src/include/fnmatch.yaml
new file mode 100644
index 00000000000..4b4ff363c26
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/fnmatch.yaml
@@ -0,0 +1,28 @@
+header: fnmatch.h
+standards:
+ - posix
+macros:
+ - macro_name: FNM_NOMATCH
+ macro_header: fnmatch-macros.h
+ - macro_name: FNM_PATHNAME
+ macro_header: fnmatch-macros.h
+ - macro_name: FNM_PERIOD
+ macro_header: fnmatch-macros.h
+ - macro_name: FNM_NOESCAPE
+ macro_header: fnmatch-macros.h
+ - macro_name: FNM_CASEFOLD
+ macro_header: fnmatch-macros.h
+ - macro_name: FNM_IGNORECASE
+ macro_header: fnmatch-macros.h
+types: []
+enums: []
+objects: []
+functions:
+ - name: fnmatch
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: const char *
+ - type: int
diff --git a/deps/v8/third_party/llvm-libc/src/include/grp.yaml b/deps/v8/third_party/llvm-libc/src/include/grp.yaml
new file mode 100644
index 00000000000..015d9c46e19
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/grp.yaml
@@ -0,0 +1,10 @@
+header: grp.h
+standards:
+ - posix
+types:
+ - type_name: struct_group
+ - type_name: gid_t
+ - type_name: size_t
+enums: []
+objects: []
+functions: []
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 1c951318fb1..f14aa9abed9 100644
--- a/deps/v8/third_party/llvm-libc/src/include/limits.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/limits.yaml
@@ -86,6 +86,8 @@ macros:
macro_header: limits-macros.h
- macro_name: PTHREAD_DESTRUCTOR_ITERATIONS
macro_header: limits-macros.h
+ - macro_name: SEM_VALUE_MAX
+ macro_header: limits-macros.h
- macro_name: SSIZE_MAX
macro_header: limits-macros.h
types: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/link.yaml b/deps/v8/third_party/llvm-libc/src/include/link.yaml
index e0228ef6ed6..d8fd0bba0d4 100644
--- a/deps/v8/third_party/llvm-libc/src/include/link.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/link.yaml
@@ -12,6 +12,17 @@ types:
- type_name: struct_dl_phdr_info
standards:
- gnu
+ - type_name: struct_link_map
+ standards:
+ - svid
+ - type_name: struct_r_debug
+ standards:
+ - svid
+objects:
+ - object_name: _r_debug
+ standards:
+ - svid
+ object_type: struct r_debug
functions:
- name: dl_iterate_phdr
standards:
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 3e7bdd1bed7..e7f7d476594 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
@@ -7,7 +7,7 @@ function(add_macro_header name)
"DEPENDS" # Multi-value arguments
${ARGN}
)
- if (MACRO_HEADER_DEST_HDR)
+ if(MACRO_HEADER_DEST_HDR)
set(dest_header_arg DEST_HDR ${MACRO_HEADER_DEST_HDR})
endif()
if(TARGET libc.include.llvm-libc-macros.${LIBC_TARGET_OS}.${name})
@@ -30,7 +30,7 @@ function(add_macro_header name)
${MACRO_HEADER_DEPENDS}
)
endif()
-endfunction(add_macro_header)
+endfunction()
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
@@ -72,6 +72,12 @@ add_macro_header(
null-macro.h
)
+add_macro_header(
+ dirent_macros
+ HDR
+ dirent-macros.h
+)
+
add_macro_header(
fcntl_macros
HDR
@@ -111,6 +117,12 @@ add_macro_header(
fenv-macros.h
)
+add_macro_header(
+ fnmatch_macros
+ HDR
+ fnmatch-macros.h
+)
+
add_macro_header(
file_seek_macros
HDR
@@ -167,6 +179,7 @@ add_macro_header(
math-function-macros.h
DEPENDS
.math_macros
+ .float16_macros
)
add_macro_header(
@@ -195,6 +208,12 @@ add_macro_header(
sched-macros.h
)
+add_macro_header(
+ semaphore_macros
+ HDR
+ semaphore-macros.h
+)
+
add_macro_header(
signal_macros
HDR
@@ -235,6 +254,8 @@ add_macro_header(
sys_epoll_macros
HDR
sys-epoll-macros.h
+ DEPENDS
+ .fcntl_macros
)
add_macro_header(
@@ -261,12 +282,24 @@ add_macro_header(
sys-stat-macros.h
)
+add_macro_header(
+ sys_statfs_macros
+ HDR
+ sys-statfs-macros.h
+)
+
add_macro_header(
sys_mman_macros
HDR
sys-mman-macros.h
)
+add_macro_header(
+ sys_mount_macros
+ HDR
+ sys-mount-macros.h
+)
+
add_macro_header(
sys_personality_macros
HDR
@@ -320,6 +353,12 @@ add_macro_header(
net-if-macros.h
)
+add_macro_header(
+ netdb_macros
+ HDR
+ netdb-macros.h
+)
+
add_macro_header(
sys_time_macros
HDR
@@ -332,6 +371,12 @@ add_macro_header(
sys-wait-macros.h
)
+add_macro_header(
+ sys_sysmacros_macros
+ HDR
+ sys-sysmacros-macros.h
+)
+
add_macro_header(
termios_macros
HDR
@@ -452,7 +497,7 @@ add_macro_header(
sysexits-macros.h
)
-if (LIBC_CONF_PRINTF_MODULAR)
+if(LIBC_CONF_PRINTF_MODULAR)
add_macro_header(
_LIBC_MODULAR_FORMAT_PRINTF
HDR
@@ -463,7 +508,7 @@ else()
_LIBC_MODULAR_FORMAT_PRINTF
HDR
_LIBC_MODULAR_FORMAT_PRINTF-disable.h
- DEST_HDR
+ DEST_HDR
_LIBC_MODULAR_FORMAT_PRINTF.h
)
endif()
@@ -473,3 +518,9 @@ add_macro_header(
HDR
alloca-macros.h
)
+
+add_macro_header(
+ syslog_macros
+ HDR
+ syslog-macros.h
+)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/dirent-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/dirent-macros.h
new file mode 100644
index 00000000000..b93f9e6e74f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/dirent-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
+/// Definition of macros from dirent.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_DIRENT_MACROS_H
+#define LLVM_LIBC_MACROS_DIRENT_MACROS_H
+
+#ifdef __linux__
+#include "linux/dirent-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_DIRENT_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/float16-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/float16-macros.h
index 528c7f016f8..1416b0a658a 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/float16-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/float16-macros.h
@@ -15,14 +15,14 @@
(!defined(__GNUC__) || __GNUC__ >= 13 || \
(defined(__clang__) && __clang_major__ >= 12)) && \
!defined(__arm__) && !defined(_M_ARM) && !defined(__riscv) && \
- !defined(_WIN32)
+ !defined(_WIN32) && (!defined(__i386__) || defined(__SSE2__))
#define LIBC_TYPES_HAS_FLOAT16
// TODO: This would no longer be required if HdrGen let us guard function
// declarations with multiple macros.
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#define LIBC_TYPES_HAS_FLOAT16_AND_FLOAT128
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif
#endif // LLVM_LIBC_MACROS_FLOAT16_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/fnmatch-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/fnmatch-macros.h
new file mode 100644
index 00000000000..b0046377b0e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/fnmatch-macros.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
+/// Macros for POSIX fnmatch.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_FNMATCH_MACROS_H
+#define LLVM_LIBC_MACROS_FNMATCH_MACROS_H
+
+#define FNM_NOMATCH 1
+
+#define FNM_PATHNAME (1 << 0)
+#define FNM_NOESCAPE (1 << 1)
+#define FNM_PERIOD (1 << 2)
+#define FNM_CASEFOLD (1 << 4)
+#define FNM_IGNORECASE FNM_CASEFOLD
+
+#endif // LLVM_LIBC_MACROS_FNMATCH_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 024591eb5b4..7a6b58e2d59 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
@@ -256,6 +256,11 @@
#define _POSIX_HOST_NAME_MAX 255
#endif
+#ifndef SEM_VALUE_MAX
+/// The maximum value a semaphore may hold.
+#define SEM_VALUE_MAX INT_MAX
+#endif
+
#ifdef __linux__
#ifndef PATH_MAX
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 374e7e6159a..7c1194d4dd1 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
@@ -4,6 +4,12 @@ add_header(
error-number-macros.h
)
+add_header(
+ dirent_macros
+ HDR
+ dirent-macros.h
+)
+
add_header(
fcntl_macros
HDR
@@ -40,6 +46,12 @@ add_header(
sys-ipc-macros.h
)
+add_header(
+ sys_mount_macros
+ HDR
+ sys-mount-macros.h
+)
+
add_header(
sys_personality_macros
HDR
@@ -70,12 +82,24 @@ add_header(
net-if-macros.h
)
+add_header(
+ netdb_macros
+ HDR
+ netdb-macros.h
+)
+
add_header(
sys_wait_macros
HDR
sys-wait-macros.h
)
+add_header(
+ sys_sysmacros_macros
+ HDR
+ sys-sysmacros-macros.h
+)
+
add_header(
time_macros
HDR
@@ -94,6 +118,12 @@ add_header(
sys-stat-macros.h
)
+add_header(
+ sys_statfs_macros
+ HDR
+ sys-statfs-macros.h
+)
+
add_header(
sys_time_macros
HDR
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/dirent-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/dirent-macros.h
new file mode 100644
index 00000000000..7d9347593a4
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/dirent-macros.h
@@ -0,0 +1,26 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 macros from dirent.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_DIRENT_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_DIRENT_MACROS_H
+
+#define DT_UNKNOWN 0
+#define DT_FIFO 1
+#define DT_CHR 2
+#define DT_DIR 4
+#define DT_BLK 6
+#define DT_REG 8
+#define DT_LNK 10
+#define DT_SOCK 12
+
+#endif // LLVM_LIBC_MACROS_LINUX_DIRENT_MACROS_H
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 74d406f742f..8dcc177434c 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
@@ -9,35 +9,35 @@
#ifndef LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
#define LLVM_LIBC_MACROS_LINUX_FCNTL_MACROS_H
-// File creation flags
-#define O_CLOEXEC 02000000
-#define O_CREAT 00000100
+// File creation and file status flags.
+#define O_APPEND 000002000
+#define O_ASYNC 000020000
+#define O_CLOEXEC 002000000
+#define O_CREAT 000000100
+#define O_DSYNC 000010000
+#define O_EXCL 000000200
+#define O_NOATIME 001000000
+#define O_NOCTTY 000000400
+#define O_NONBLOCK 000004000
+#define O_NDELAY O_NONBLOCK
#define O_PATH 010000000
+#define O_SYNC 004010000
+#define O_TRUNC 000001000
#ifdef __aarch64__
-#define O_DIRECTORY 040000
+#define O_DIRECT 000200000
+#define O_DIRECTORY 000040000
+#define O_NOFOLLOW 000100000
+#define O_LARGEFILE 000040000
+#define O_TMPFILE 020040000
#else
-#define O_DIRECTORY 00200000
+#define O_DIRECT 000040000
+#define O_DIRECTORY 000200000
+#define O_NOFOLLOW 000400000
+#define O_LARGEFILE 000100000
+#define O_TMPFILE 020200000
#endif
-#define O_EXCL 00000200
-#define O_NOCTTY 00000400
-
-#ifdef __aarch64__
-#define O_NOFOLLOW 0100000
-#else
-#define O_NOFOLLOW 00400000
-#endif
-
-#define O_TRUNC 00001000
-#define O_TMPFILE (020000000 | O_DIRECTORY)
-
-// File status flags
-#define O_APPEND 00002000
-#define O_DSYNC 00010000
-#define O_NONBLOCK 00004000
-#define O_SYNC 04000000 | O_DSYNC
-
// File access mode mask
#define O_ACCMODE 00000003
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
new file mode 100644
index 00000000000..7bc06982f45
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/netdb-macros.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 netdb.h header file for Linux.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_NETDB_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_NETDB_MACROS_H
+
+#define EAI_BADFLAGS -1
+#define EAI_NONAME -2
+#define EAI_AGAIN -3
+#define EAI_FAIL -4
+#define EAI_FAMILY -6
+#define EAI_SOCKTYPE -7
+#define EAI_SERVICE -8
+#define EAI_MEMORY -10
+#define EAI_SYSTEM -11
+#define EAI_OVERFLOW -12
+
+#endif // LLVM_LIBC_MACROS_LINUX_NETDB_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sched-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sched-macros.h
index 28719b59d01..c65d52d6f8c 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sched-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sched-macros.h
@@ -23,6 +23,34 @@
#define SCHED_IDLE 5
#define SCHED_DEADLINE 6
+// Linux-specific flags for clone.
+#define CLONE_CHILD_CLEARTID 0x00200000
+#define CLONE_CHILD_SETTID 0x01000000
+#define CLONE_CLEAR_SIGHAND 0x100000000
+#define CLONE_DETACHED 0x00400000
+#define CLONE_FILES 0x00000400
+#define CLONE_FS 0x00000200
+#define CLONE_INTO_CGROUP 0x200000000
+#define CLONE_IO 0x80000000
+#define CLONE_NEWCGROUP 0x02000000
+#define CLONE_NEWIPC 0x08000000
+#define CLONE_NEWNET 0x40000000
+#define CLONE_NEWNS 0x00020000
+#define CLONE_NEWPID 0x20000000
+#define CLONE_NEWUSER 0x10000000
+#define CLONE_NEWUTS 0x04000000
+#define CLONE_PARENT 0x00008000
+#define CLONE_PARENT_SETTID 0x00100000
+#define CLONE_PIDFD 0x00001000
+#define CLONE_PTRACE 0x00002000
+#define CLONE_SETTLS 0x00080000
+#define CLONE_SIGHAND 0x00000800
+#define CLONE_SYSVSEM 0x00040000
+#define CLONE_THREAD 0x00010000
+#define CLONE_UNTRACED 0x00800000
+#define CLONE_VFORK 0x00004000
+#define CLONE_VM 0x00000100
+
#define CPU_SETSIZE __CPU_SETSIZE
#define NCPUBITS __NCPUBITS
#define CPU_AND_S(setsize, destset, srcset1, srcset2) \
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/signal-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/signal-macros.h
index a58dbf2b5f1..9254c39957d 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/signal-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/signal-macros.h
@@ -45,22 +45,23 @@
#define SIGPWR 30
#define SIGSYS 31
-// Max signal number
-#define NSIG 64
+// All signal numbers need to be less than this constant.
+#define NSIG 65
+#define _NSIG NSIG
// SIGRTMIN is current set to the minimum usable from user mode programs. If
// the libc itself uses some of these signal numbers for private operations,
// then it has to be adjusted in future to reflect that.
#define SIGRTMIN 32
-
-#define SIGRTMAX NSIG
+// SIGRTMAX is the largest allowed value for the runtime signal.
+#define SIGRTMAX (NSIG - 1)
// The kernel sigset is stored as an array of long values. Each bit of this
// array corresponds to a signal, adjusted by 1. That is, bit 0 corresponds
// to signal number 1, bit 1 corresponds to signal number 2 and so on. The
// below macro denotes the size of that array (in number of long words and
// not bytes).
-#define __NSIGSET_WORDS (NSIG / (sizeof(unsigned long) * 8))
+#define __NSIGSET_WORDS ((NSIG - 1) / (sizeof(unsigned long) * 8))
#define SIG_BLOCK 0 // For blocking signals
#define SIG_UNBLOCK 1 // For unblocking signals
@@ -136,11 +137,29 @@
#define CLD_STOPPED 5 // child has stopped
#define CLD_CONTINUED 6 // stopped child has continued
+// SIGPOLL si_codes
+#define POLL_IN 1 // Data input available
+#define POLL_OUT 2 // Output buffers available
+#define POLL_MSG 3 // Input message available
+#define POLL_ERR 4 // I/O error
+#define POLL_PRI 5 // High priority input available
+#define POLL_HUP 6 // Device disconnected
+
// Other si_codes.
#define SI_USER 0 // Sent by kill()
#define SI_QUEUE (-1) // Sent by sigqueue()
#define SI_TIMER (-2) // Expiration of a timer set by timer_settime()
#define SI_ASYNCIO (-4) // Completion of an synchronous I/O request
#define SI_MESGQ (-3) // Arrival of a message on an empty message queue
+#define SI_SIGIO (-5) // Queued SIGIO, on older versions of Linux
+#define SI_TKILL (-6) // Sent by tkill or tgkill
+#define SI_ASYNCNL (-60) // Async name lookup completion
+#define SI_KERNEL 128 // Sent by the kernel
+
+// `sigev_notify` values for `struct sigevent`.
+#define SIGEV_SIGNAL 0
+#define SIGEV_NONE 1
+#define SIGEV_THREAD 2
+#define SIGEV_THREAD_ID 4
#endif // LLVM_LIBC_MACROS_LINUX_SIGNAL_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-mount-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-mount-macros.h
new file mode 100644
index 00000000000..a18cd8f811e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-mount-macros.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
+/// Linux specific declarations of macros from sys/mount.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_MOUNT_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_MOUNT_MACROS_H
+
+#define MS_RDONLY (1 << 0)
+#define MS_NOSUID (1 << 1)
+#define MS_NODEV (1 << 2)
+#define MS_NOEXEC (1 << 3)
+#define MS_SYNCHRONOUS (1 << 4)
+#define MS_REMOUNT (1 << 5)
+#define MS_MANDLOCK (1 << 6)
+#define MS_DIRSYNC (1 << 7)
+#define MS_NOSYMFOLLOW (1 << 8)
+#define MS_NOATIME (1 << 10)
+#define MS_NODIRATIME (1 << 11)
+#define MS_BIND (1 << 12)
+#define MS_MOVE (1 << 13)
+#define MS_REC (1 << 14)
+#define MS_SILENT (1 << 15)
+#define MS_UNBINDABLE (1 << 17)
+#define MS_PRIVATE (1 << 18)
+#define MS_SLAVE (1 << 19)
+#define MS_SHARED (1 << 20)
+#define MS_RELATIME (1 << 21)
+#define MS_STRICTATIME (1 << 24)
+#define MS_LAZYTIME (1 << 25)
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_MOUNT_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 419761e01c4..9f1e04a339c 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
@@ -30,4 +30,8 @@
#define RLIM_INFINITY ((rlim_t) - 1)
+#define RUSAGE_SELF 0
+#define RUSAGE_CHILDREN (-1)
+#define RUSAGE_THREAD 1
+
#endif // LLVM_LIBC_MACROS_LINUX_SYS_RESOURCE_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-socket-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-socket-macros.h
index 5478521be02..2c7d55c1143 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-socket-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-socket-macros.h
@@ -12,11 +12,12 @@
// IEEE Std 1003.1-2017 - basedefs/sys_socket.h.html
// Macro values come from the Linux syscall interface.
-#define AF_UNSPEC 0 // Unspecified
-#define AF_UNIX 1 // Unix domain sockets
-#define AF_LOCAL 1 // POSIX name for AF_UNIX
-#define AF_INET 2 // Internet IPv4 Protocol
-#define AF_INET6 10 // IP version 6
+#define AF_UNSPEC 0 // Unspecified
+#define AF_UNIX 1 // Unix domain sockets
+#define AF_LOCAL 1 // POSIX name for AF_UNIX
+#define AF_INET 2 // Internet IPv4 Protocol
+#define AF_INET6 10 // IP version 6
+#define AF_NETLINK 16 // Netlink sockets
// 4.2BSD protocol families
#define PF_UNSPEC AF_UNSPEC
@@ -24,6 +25,7 @@
#define PF_LOCAL AF_LOCAL
#define PF_INET AF_INET
#define PF_INET6 AF_INET6
+#define PF_NETLINK AF_NETLINK
#define SOCK_STREAM 1
#define SOCK_DGRAM 2
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-statfs-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-statfs-macros.h
new file mode 100644
index 00000000000..1e3dbc2cc45
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-statfs-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
+/// Linux specific declarations of macros from sys/statfs.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_STATFS_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_STATFS_MACROS_H
+
+// There are numerous possible values for f_type field, defined in
+// the Linux kernel header. Include it directly.
+#include <linux/magic.h>
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_STATFS_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-sysmacros-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-sysmacros-macros.h
new file mode 100644
index 00000000000..c3e25d7f83c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/sys-sysmacros-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
+/// Linux specific declarations of macros from sys/sysmacros.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_LINUX_SYS_SYSMACROS_MACROS_H
+#define LLVM_LIBC_MACROS_LINUX_SYS_SYSMACROS_MACROS_H
+
+#define major(dev) major(dev)
+#define minor(dev) minor(dev)
+#define makedev(maj, min) makedev(maj, min)
+
+#endif // LLVM_LIBC_MACROS_LINUX_SYS_SYSMACROS_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/time-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/time-macros.h
index 407a1eb30ee..a779f4bb60e 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/time-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/linux/time-macros.h
@@ -23,4 +23,7 @@
#define CLOCKS_PER_SEC 1000000
+// timer flags
+#define TIMER_ABSTIME 1
+
#endif // LLVM_LIBC_MACROS_LINUX_TIME_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 4ee55b812f4..49409f83711 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
@@ -21,9 +21,10 @@
#define R_OK 4
#define _SC_ARG_MAX 0
-#define _SC_PAGESIZE 1
-#define _SC_PAGE_SIZE _SC_PAGESIZE
+#define _SC_CLK_TCK 2
#define _SC_OPEN_MAX 4
+#define _SC_PAGESIZE 30
+#define _SC_PAGE_SIZE _SC_PAGESIZE
#define _SC_THREADS 67
#define _SC_NPROCESSORS_CONF 83
#define _SC_NPROCESSORS_ONLN 84
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/math-function-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/math-function-macros.h
index 21d09f1f5e1..1fbcd603d20 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/math-function-macros.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/math-function-macros.h
@@ -9,6 +9,7 @@
#ifndef LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
#define LLVM_LIBC_MACROS_MATH_FUNCTION_MACROS_H
+#include "float16-macros.h" // LIBC_TYPES_HAS_FLOAT16, LIBC_TYPES_HAS_FLOAT128
#include "math-macros.h"
#ifndef __cplusplus
@@ -17,11 +18,34 @@
float: issignalingf, \
double: issignaling, \
long double: issignalingl)(x)
+
+// 'iscanonical' is a C23 type-generic macro (7.12.3.1). The '_Float16' and
+// 'float128' associations are only added when those types exist, and 'float128'
+// only when it is distinct from 'long double' (otherwise _Generic would have
+// two associations with compatible types). The 'float128' guard mirrors
+// LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE in
+// src/__support/macros/properties/types.h, which public headers cannot include.
+#ifdef LIBC_TYPES_HAS_FLOAT16
+#define __LIBC_MATH_ISCANONICAL_F16 _Float16 : iscanonicalf16,
+#else
+#define __LIBC_MATH_ISCANONICAL_F16
+#endif
+#if defined(LIBC_TYPES_HAS_FLOAT128) && (LDBL_MANT_DIG != 113)
+#define __LIBC_MATH_ISCANONICAL_F128 \
+ float128: \
+ iscanonicalf128,
+#else
+#define __LIBC_MATH_ISCANONICAL_F128
+#endif
+// clang-format off
#define iscanonical(x) \
_Generic((x), \
+ __LIBC_MATH_ISCANONICAL_F16 \
+ __LIBC_MATH_ISCANONICAL_F128 \
float: iscanonicalf, \
double: iscanonical, \
long double: iscanonicall)(x)
+// clang-format on
#endif
#define isfinite(x) __builtin_isfinite(x)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/netdb-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/netdb-macros.h
new file mode 100644
index 00000000000..46804d0eaec
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/netdb-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 netdb.h header file.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_NETDB_MACROS_H
+#define LLVM_LIBC_MACROS_NETDB_MACROS_H
+
+#ifdef __linux__
+#include "linux/netdb-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_NETDB_MACROS_H
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 d6518189f1c..58717200b5f 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
@@ -77,4 +77,7 @@
#define PTHREAD_RWLOCK_PREFER_WRITER_NP 1
#define PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP 2
+// llvm libc extensions
+#define PTHREAD_STACK_DYNAMIC_NP 0
+
#endif // LLVM_LIBC_MACROS_PTHREAD_MACRO_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/semaphore-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/semaphore-macros.h
new file mode 100644
index 00000000000..cd21afc44be
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/semaphore-macros.h
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 macros from semaphore.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SEMAPHORE_MACROS_H
+#define LLVM_LIBC_MACROS_SEMAPHORE_MACROS_H
+
+// The value returned by sem_open on failure.
+#define SEM_FAILED ((sem_t *)0)
+
+#endif // LLVM_LIBC_MACROS_SEMAPHORE_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mount-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mount-macros.h
new file mode 100644
index 00000000000..6f19343f1df
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-mount-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/mount.h header file.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYS_MOUNT_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_MOUNT_MACROS_H
+
+#ifdef __linux__
+#include "linux/sys-mount-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_SYS_MOUNT_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-statfs-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-statfs-macros.h
new file mode 100644
index 00000000000..36dcec917ae
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-statfs-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/statfs.h header file.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYS_STATFS_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_STATFS_MACROS_H
+
+#ifdef __linux__
+#include "linux/sys-statfs-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_SYS_STATFS_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-sysmacros-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-sysmacros-macros.h
new file mode 100644
index 00000000000..29e4ad6ac3b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/sys-sysmacros-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
+/// Definition of macros from sys/sysmacros.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYS_SYSMACROS_MACROS_H
+#define LLVM_LIBC_MACROS_SYS_SYSMACROS_MACROS_H
+
+#ifdef __linux__
+#include "linux/sys-sysmacros-macros.h"
+#endif
+
+#endif // LLVM_LIBC_MACROS_SYS_SYSMACROS_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/syslog-macros.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/syslog-macros.h
new file mode 100644
index 00000000000..688127a67ea
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/syslog-macros.h
@@ -0,0 +1,53 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 macros from syslog.h.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_MACROS_SYSLOG_MACROS_H
+#define LLVM_LIBC_MACROS_SYSLOG_MACROS_H
+
+// Options for openlog
+#define LOG_PID 0x01
+#define LOG_CONS 0x02
+#define LOG_ODELAY 0x04
+#define LOG_NDELAY 0x08
+#define LOG_NOWAIT 0x10
+
+// Facilities for openlog
+#define LOG_KERN (0 << 3)
+#define LOG_USER (1 << 3)
+#define LOG_MAIL (2 << 3)
+#define LOG_DAEMON (3 << 3)
+#define LOG_AUTH (4 << 3)
+#define LOG_LPR (6 << 3)
+#define LOG_NEWS (7 << 3)
+#define LOG_UUCP (8 << 3)
+#define LOG_CRON (9 << 3)
+#define LOG_LOCAL0 (16 << 3)
+#define LOG_LOCAL1 (17 << 3)
+#define LOG_LOCAL2 (18 << 3)
+#define LOG_LOCAL3 (19 << 3)
+#define LOG_LOCAL4 (20 << 3)
+#define LOG_LOCAL5 (21 << 3)
+#define LOG_LOCAL6 (22 << 3)
+#define LOG_LOCAL7 (23 << 3)
+
+// Priorities for syslog
+#define LOG_EMERG 0
+#define LOG_ALERT 1
+#define LOG_CRIT 2
+#define LOG_ERR 3
+#define LOG_WARNING 4
+#define LOG_NOTICE 5
+#define LOG_INFO 6
+#define LOG_DEBUG 7
+
+#endif // LLVM_LIBC_MACROS_SYSLOG_MACROS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/windows/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/windows/CMakeLists.txt
index 48afc795178..70837bf8a28 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/windows/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-macros/windows/CMakeLists.txt
@@ -3,4 +3,3 @@ add_header(
HDR
time-macros-ext.h
)
-
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-proxy/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-proxy/CMakeLists.txt
new file mode 100644
index 00000000000..31196c6532d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-proxy/CMakeLists.txt
@@ -0,0 +1,58 @@
+file(MAKE_DIRECTORY ${LIBC_INCLUDE_DIR}/llvm-libc-proxy)
+
+add_gen_header(
+ elf_proxy
+ YAML_FILE
+ ../libc/include/llvm-libc-proxy/elf_proxy.yaml
+ GEN_HDR
+ elf_proxy.h
+ DEPENDS
+ libc.include.llvm_libc_common_h
+ libc.include.llvm-libc-macros.elf_macros
+ libc.include.llvm-libc-macros.sys_auxv_macros
+ libc.include.llvm-libc-types.Elf32_Addr
+ libc.include.llvm-libc-types.Elf32_Chdr
+ libc.include.llvm-libc-types.Elf32_Dyn
+ libc.include.llvm-libc-types.Elf32_Ehdr
+ libc.include.llvm-libc-types.Elf32_Half
+ libc.include.llvm-libc-types.Elf32_Lword
+ libc.include.llvm-libc-types.Elf32_Nhdr
+ libc.include.llvm-libc-types.Elf32_Off
+ libc.include.llvm-libc-types.Elf32_Phdr
+ libc.include.llvm-libc-types.Elf32_Rel
+ libc.include.llvm-libc-types.Elf32_Rela
+ libc.include.llvm-libc-types.Elf32_Shdr
+ libc.include.llvm-libc-types.Elf32_Sword
+ libc.include.llvm-libc-types.Elf32_Sym
+ libc.include.llvm-libc-types.Elf32_Verdaux
+ libc.include.llvm-libc-types.Elf32_Verdef
+ libc.include.llvm-libc-types.Elf32_Vernaux
+ libc.include.llvm-libc-types.Elf32_Verneed
+ libc.include.llvm-libc-types.Elf32_Versym
+ libc.include.llvm-libc-types.Elf32_Word
+ libc.include.llvm-libc-types.Elf32_Xword
+ libc.include.llvm-libc-types.Elf32_auxv_t
+ libc.include.llvm-libc-types.Elf64_Addr
+ libc.include.llvm-libc-types.Elf64_Chdr
+ libc.include.llvm-libc-types.Elf64_Dyn
+ libc.include.llvm-libc-types.Elf64_Ehdr
+ libc.include.llvm-libc-types.Elf64_Half
+ libc.include.llvm-libc-types.Elf64_Lword
+ libc.include.llvm-libc-types.Elf64_Nhdr
+ libc.include.llvm-libc-types.Elf64_Off
+ libc.include.llvm-libc-types.Elf64_Phdr
+ libc.include.llvm-libc-types.Elf64_Rel
+ libc.include.llvm-libc-types.Elf64_Rela
+ libc.include.llvm-libc-types.Elf64_Shdr
+ libc.include.llvm-libc-types.Elf64_Sword
+ libc.include.llvm-libc-types.Elf64_Sxword
+ libc.include.llvm-libc-types.Elf64_Sym
+ libc.include.llvm-libc-types.Elf64_Verdaux
+ libc.include.llvm-libc-types.Elf64_Verdef
+ libc.include.llvm-libc-types.Elf64_Vernaux
+ libc.include.llvm-libc-types.Elf64_Verneed
+ libc.include.llvm-libc-types.Elf64_Versym
+ libc.include.llvm-libc-types.Elf64_Word
+ libc.include.llvm-libc-types.Elf64_Xword
+ libc.include.llvm-libc-types.Elf64_auxv_t
+)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-proxy/elf_proxy.yaml b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-proxy/elf_proxy.yaml
new file mode 100644
index 00000000000..42788f3b3f0
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-proxy/elf_proxy.yaml
@@ -0,0 +1,673 @@
+header: elf_proxy.h
+standards:
+ - svid
+macros:
+ # ELF Header
+ - macro_name: EI_NIDENT
+ macro_value: 16
+ - macro_name: EI_MAG0
+ macro_value: 0
+ - macro_name: EI_MAG1
+ macro_value: 1
+ - macro_name: EI_MAG2
+ macro_value: 2
+ - macro_name: EI_MAG3
+ macro_value: 3
+ - macro_name: EI_CLASS
+ macro_value: 4
+ - macro_name: EI_DATA
+ macro_value: 5
+ - macro_name: EI_VERSION
+ macro_value: 6
+ - macro_name: EI_OSABI
+ macro_value: 7
+ - macro_name: EI_ABIVERSION
+ macro_value: 8
+ - macro_name: EI_PAD
+ macro_value: 9
+ - macro_name: EI_NIDENT
+ macro_value: 16
+ - macro_name: ELFMAG0
+ macro_value: '0x7f'
+ - macro_name: ELFMAG1
+ macro_value: "'E'"
+ - macro_name: ELFMAG2
+ macro_value: "'L'"
+ - macro_name: ELFMAG3
+ macro_value: "'F'"
+ - macro_name: ELFMAG
+ macro_value: '"\177ELF"'
+ - macro_name: SELFMAG
+ macro_value: 4
+ - macro_name: ELFCLASSNONE
+ macro_value: 0
+ - macro_name: ELFCLASS32
+ macro_value: 1
+ - macro_name: ELFCLASS64
+ macro_value: 2
+ - macro_name: ELFDATANONE
+ macro_value: 0
+ - macro_name: ELFDATA2LSB
+ macro_value: 1
+ - macro_name: ELFDATA2MSB
+ macro_value: 2
+ - macro_name: ELFOSABI_NONE
+ macro_value: 0
+ - macro_name: ELFOSABI_LINUX
+ macro_value: 3
+ - macro_name: ET_NONE
+ macro_value: 0
+ - macro_name: ET_REL
+ macro_value: 1
+ - macro_name: ET_EXEC
+ macro_value: 2
+ - macro_name: ET_DYN
+ macro_value: 3
+ - macro_name: ET_CORE
+ macro_value: 4
+ - macro_name: ET_LOOS
+ macro_value: '0xfe00'
+ - macro_name: ET_HIOS
+ macro_value: '0xfeff'
+ - macro_name: ET_LOPROC
+ macro_value: '0xff00'
+ - macro_name: ET_HIPROC
+ macro_value: '0xffff'
+ - macro_name: EM_NONE
+ macro_value: 0
+ - macro_name: EM_386
+ macro_value: 3
+ - macro_name: EM_PPC64
+ macro_value: 21
+ - macro_name: EM_ARM
+ macro_value: 40
+ - macro_name: EM_X86_64
+ macro_value: 62
+ - macro_name: EM_AARCH64
+ macro_value: 183
+ - macro_name: EM_RISCV
+ macro_value: 243
+ - macro_name: EV_NONE
+ macro_value: 0
+ - macro_name: EV_CURRENT
+ macro_value: 1
+ # Sections
+ - macro_name: SHN_UNDEF
+ macro_value: 0
+ - macro_name: SHN_LORESERVE
+ macro_value: '0xff00'
+ - macro_name: SHN_LOPROC
+ macro_value: '0xff00'
+ - macro_name: SHN_HIPROC
+ macro_value: '0xff1f'
+ - macro_name: SHN_LOOS
+ macro_value: '0xff20'
+ - macro_name: SHN_HIOS
+ macro_value: '0xff3f'
+ - macro_name: SHN_ABS
+ macro_value: '0xfff1'
+ - macro_name: SHN_COMMON
+ macro_value: '0xfff2'
+ - macro_name: SHN_XINDEX
+ macro_value: '0xffff'
+ - macro_name: SHN_HIRESERVE
+ macro_value: '0xffff'
+ - macro_name: SHT_NULL
+ macro_value: 0
+ - macro_name: SHT_PROGBITS
+ macro_value: 1
+ - macro_name: SHT_SYMTAB
+ macro_value: 2
+ - macro_name: SHT_STRTAB
+ macro_value: 3
+ - macro_name: SHT_RELA
+ macro_value: 4
+ - macro_name: SHT_HASH
+ macro_value: 5
+ - macro_name: SHT_DYNAMIC
+ macro_value: 6
+ - macro_name: SHT_NOTE
+ macro_value: 7
+ - macro_name: SHT_NOBITS
+ macro_value: 8
+ - macro_name: SHT_REL
+ macro_value: 9
+ - macro_name: SHT_SHLIB
+ macro_value: 10
+ - macro_name: SHT_DYNSYM
+ macro_value: 11
+ - macro_name: SHT_INIT_ARRAY
+ macro_value: 14
+ - macro_name: SHT_FINI_ARRAY
+ macro_value: 15
+ - macro_name: SHT_PREINIT_ARRAY
+ macro_value: 16
+ - macro_name: SHT_GROUP
+ macro_value: 17
+ - macro_name: SHT_SYMTAB_SHNDX
+ macro_value: 18
+ - macro_name: SHT_LOOS
+ macro_value: '0x60000000'
+ - macro_name: SHT_HIOS
+ macro_value: '0x6fffffff'
+ - macro_name: SHT_LOPROC
+ macro_value: '0x70000000'
+ - macro_name: SHT_HIPROC
+ macro_value: '0x7fffffff'
+ - macro_name: SHT_LOUSER
+ macro_value: '0x80000000'
+ - macro_name: SHT_HIUSER
+ macro_value: '0xffffffff'
+ - macro_name: SHF_WRITE
+ macro_value: '0x1'
+ - macro_name: SHF_ALLOC
+ macro_value: '0x2'
+ - macro_name: SHF_EXECINSTR
+ macro_value: '0x4'
+ - macro_name: SHF_MERGE
+ macro_value: '0x10'
+ - macro_name: SHF_STRINGS
+ macro_value: '0x20'
+ - macro_name: SHF_INFO_LINK
+ macro_value: '0x40'
+ - macro_name: SHF_LINK_ORDER
+ macro_value: '0x80'
+ - macro_name: SHF_OS_NONCONFORMING
+ macro_value: '0x100'
+ - macro_name: SHF_GROUP
+ macro_value: '0x200'
+ - macro_name: SHF_TLS
+ macro_value: '0x400'
+ - macro_name: SHF_COMPRESSED
+ macro_value: '0x800'
+ - macro_name: SHF_MASKOS
+ macro_value: '0x0ff00000'
+ - macro_name: SHF_MASKPROC
+ macro_value: '0xf0000000'
+ - macro_name: ELFCOMPRESS_ZLIB
+ macro_value: 1
+ - macro_name: ELFCOMPRESS_ZSTD
+ macro_value: 2
+ - macro_name: ELFCOMPRESS_LOOS
+ macro_value: '0x60000000'
+ - macro_name: ELFCOMPRESS_HIOS
+ macro_value: '0x6fffffff'
+ - macro_name: ELFCOMPRESS_LOPROC
+ macro_value: '0x70000000'
+ - macro_name: ELFCOMPRESS_HIPROC
+ macro_value: '0x7fffffff'
+ # Symbol Table
+ - macro_name: STN_UNDEF
+ macro_value: 0
+ - macro_name: STB_LOCAL
+ macro_value: 0
+ - macro_name: STB_GLOBAL
+ macro_value: 1
+ - macro_name: STB_WEAK
+ macro_value: 2
+ - macro_name: STB_LOOS
+ macro_value: 10
+ - macro_name: STB_HIOS
+ macro_value: 12
+ - macro_name: STB_LOPROC
+ macro_value: 13
+ - macro_name: STB_HIPROC
+ macro_value: 15
+ - macro_name: STT_NOTYPE
+ macro_value: 0
+ - macro_name: STT_OBJECT
+ macro_value: 1
+ - macro_name: STT_FUNC
+ macro_value: 2
+ - macro_name: STT_SECTION
+ macro_value: 3
+ - macro_name: STT_FILE
+ macro_value: 4
+ - macro_name: STT_COMMON
+ macro_value: 5
+ - macro_name: STT_TLS
+ macro_value: 6
+ - macro_name: STT_LOOS
+ macro_value: 10
+ - macro_name: STT_GNU_IFUNC
+ macro_value: 10
+ standards:
+ - gnu
+ - macro_name: STT_HIOS
+ macro_value: 12
+ - macro_name: STT_LOPROC
+ macro_value: 13
+ - macro_name: STT_HIPROC
+ macro_value: 15
+ - macro_name: STV_DEFAULT
+ macro_value: 0
+ - macro_name: STV_INTERNAL
+ macro_value: 1
+ - macro_name: STV_HIDDEN
+ macro_value: 2
+ - macro_name: STV_PROTECTED
+ macro_value: 3
+ # Program Loading
+ - macro_name: PT_NULL
+ macro_value: 0
+ - macro_name: PT_LOAD
+ macro_value: 1
+ - macro_name: PT_DYNAMIC
+ macro_value: 2
+ - macro_name: PT_INTERP
+ macro_value: 3
+ - macro_name: PT_NOTE
+ macro_value: 4
+ - macro_name: PT_SHLIB
+ macro_value: 5
+ - macro_name: PT_PHDR
+ macro_value: 6
+ - macro_name: PT_TLS
+ macro_value: 7
+ - macro_name: PT_LOOS
+ macro_value: '0x60000000'
+ - macro_name: PT_HIOS
+ macro_value: '0x6fffffff'
+ - macro_name: PT_LOPROC
+ macro_value: '0x70000000'
+ - macro_name: PT_HIPROC
+ macro_value: '0x7fffffff'
+ - macro_name: PT_GNU_EH_FRAME
+ macro_value: '0x6474e550'
+ standards:
+ - gnu
+ - macro_name: PT_GNU_STACK
+ macro_value: '0x6474e551'
+ standards:
+ - gnu
+ - macro_name: PT_GNU_RELRO
+ macro_value: '0x6474e552'
+ standards:
+ - gnu
+ - macro_name: PT_GNU_PROPERTY
+ macro_value: '0x6474e553'
+ - macro_name: PF_X
+ macro_value: '0x1'
+ - macro_name: PF_W
+ macro_value: '0x2'
+ - macro_name: PF_R
+ macro_value: '0x4'
+ - macro_name: PF_MASKOS
+ macro_value: '0x0ff00000'
+ - macro_name: PF_MASKPROC
+ macro_value: '0xf0000000'
+ # Dynamic Linking
+ - macro_name: DT_NULL
+ macro_value: 0
+ - macro_name: DT_NEEDED
+ macro_value: 1
+ - macro_name: DT_PLTRELSZ
+ macro_value: 2
+ - macro_name: DT_PLTGOT
+ macro_value: 3
+ - macro_name: DT_HASH
+ macro_value: 4
+ - macro_name: DT_STRTAB
+ macro_value: 5
+ - macro_name: DT_SYMTAB
+ macro_value: 6
+ - macro_name: DT_RELA
+ macro_value: 7
+ - macro_name: DT_RELASZ
+ macro_value: 8
+ - macro_name: DT_RELAENT
+ macro_value: 9
+ - macro_name: DT_STRSZ
+ macro_value: 10
+ - macro_name: DT_SYMENT
+ macro_value: 11
+ - macro_name: DT_INIT
+ macro_value: 12
+ - macro_name: DT_FINI
+ macro_value: 13
+ - macro_name: DT_SONAME
+ macro_value: 14
+ - macro_name: DT_RPATH
+ macro_value: 15
+ - macro_name: DT_SYMBOLIC
+ macro_value: 16
+ - macro_name: DT_REL
+ macro_value: 17
+ - macro_name: DT_RELSZ
+ macro_value: 18
+ - macro_name: DT_RELENT
+ macro_value: 19
+ - macro_name: DT_PLTREL
+ macro_value: 20
+ - macro_name: DT_DEBUG
+ macro_value: 21
+ - macro_name: DT_TEXTREL
+ macro_value: 22
+ - macro_name: DT_JMPREL
+ macro_value: 23
+ - macro_name: DT_BIND_NOW
+ macro_value: 24
+ - macro_name: DT_INIT_ARRAY
+ macro_value: 25
+ - macro_name: DT_FINI_ARRAY
+ macro_value: 26
+ - macro_name: DT_INIT_ARRAYSZ
+ macro_value: 27
+ - macro_name: DT_FINI_ARRAYSZ
+ macro_value: 28
+ - macro_name: DT_RUNPATH
+ macro_value: 29
+ - macro_name: DT_FLAGS
+ macro_value: 30
+ - macro_name: DT_ENCODING
+ macro_value: 32
+ - macro_name: DT_PREINIT_ARRAY
+ macro_value: 32
+ - macro_name: DT_PREINIT_ARRAYSZ
+ macro_value: 33
+ - macro_name: DT_SYMTAB_SHNDX
+ macro_value: 34
+ - macro_name: DT_LOOS
+ macro_value: '0x6000000D'
+ - macro_name: DT_HIOS
+ macro_value: '0x6ffff000'
+ - macro_name: DT_LOPROC
+ macro_value: '0x70000000'
+ - macro_name: DT_HIPROC
+ macro_value: '0x7fffffff'
+ - macro_name: DT_ADDRRNGLO
+ macro_value: '0x6ffffe00'
+ - macro_name: DT_GNU_HASH
+ macro_value: '0x6ffffef5'
+ standards:
+ - gnu
+ - macro_name: DT_TLSDESC_PLT
+ macro_value: '0x6ffffef6'
+ standards:
+ - gnu
+ - macro_name: DT_TLSDESC_GOT
+ macro_value: '0x6ffffef7'
+ standards:
+ - gnu
+ - macro_name: DT_GNU_CONFLICT
+ macro_value: '0x6ffffef8'
+ standards:
+ - gnu
+ - macro_name: DT_GNU_LIBLIST
+ macro_value: '0x6ffffef9'
+ standards:
+ - gnu
+ - macro_name: DT_CONFIG
+ macro_value: '0x6ffffefa'
+ - macro_name: DT_DEPAUDIT
+ macro_value: '0x6ffffefb'
+ - macro_name: DT_AUDIT
+ macro_value: '0x6ffffefc'
+ - macro_name: DT_PLTPAD
+ macro_value: '0x6ffffefd'
+ - macro_name: DT_MOVETAB
+ macro_value: '0x6ffffefe'
+ - macro_name: DT_SYMINFO
+ macro_value: '0x6ffffeff'
+ - macro_name: DT_ADDRRNGHI
+ macro_value: '0x6ffffeff'
+ - macro_name: DT_VERSYM
+ macro_value: '0x6ffffff0'
+ - macro_name: DT_RELACOUNT
+ macro_value: '0x6ffffff9'
+ - macro_name: DT_RELCOUNT
+ macro_value: '0x6ffffffa'
+ - macro_name: DT_VERDEF
+ macro_value: '0x6ffffffc'
+ - macro_name: DT_VERDEFNUM
+ macro_value: '0x6ffffffd'
+ - macro_name: DT_VERNEED
+ macro_value: '0x6ffffffe'
+ - macro_name: DT_VERNEEDNUM
+ macro_value: '0x6fffffff'
+ - macro_name: DF_ORIGIN
+ macro_value: '0x1'
+ - macro_name: DF_SYMBOLIC
+ macro_value: '0x2'
+ - macro_name: DF_TEXTREL
+ macro_value: '0x4'
+ - macro_name: DF_BIND_NOW
+ macro_value: '0x8'
+ - macro_name: DF_STATIC_TLS
+ macro_value: '0x10'
+ # Notes used in ET_CORE.
+ - macro_name: NN_PRSTATUS
+ macro_value: '"CORE"'
+ - macro_name: NT_PRSTATUS
+ macro_value: 1
+ - macro_name: NN_PRFPREG
+ macro_value: '"CORE"'
+ - macro_name: NT_PRFPREG
+ macro_value: 2
+ - macro_name: NT_FPREGSET
+ macro_value: 2
+ - macro_name: NN_PRPSINFO
+ macro_value: '"CORE"'
+ - macro_name: NT_PRPSINFO
+ macro_value: 3
+ - macro_name: NN_TASKSTRUCT
+ macro_value: '"CORE"'
+ - macro_name: NT_TASKSTRUCT
+ macro_value: 4
+ - macro_name: NT_PRXREG
+ macro_value: 4
+ - macro_name: NT_PLATFORM
+ macro_value: 5
+ - macro_name: NN_AUXV
+ macro_value: '"CORE"'
+ - macro_name: NT_AUXV
+ macro_value: 6
+ - macro_name: NN_SIGINFO
+ macro_value: '"CORE"'
+ - macro_name: NT_SIGINFO
+ macro_value: '0x53494749'
+ - macro_name: NN_FILE
+ macro_value: '"CORE"'
+ - macro_name: NT_FILE
+ macro_value: '0x46494c45'
+ - macro_name: NT_PRFPXREG
+ macro_value: 20
+ # Notes used by GNU toolchain.
+ - macro_name: NT_GNU_ABI_TAG
+ macro_value: 1
+ standards:
+ - gnu
+ - macro_name: NT_GNU_HWCAP
+ macro_value: 2
+ standards:
+ - gnu
+ - macro_name: NT_GNU_BUILD_ID
+ macro_value: 3
+ standards:
+ - gnu
+ - macro_name: NT_GNU_GOLD_VERSION
+ macro_value: 4
+ standards:
+ - gnu
+ - macro_name: NT_GNU_PROPERTY_TYPE_0
+ macro_value: 5
+ standards:
+ - gnu
+ # Symbol Versioning
+ - macro_name: VER_DEF_NONE
+ macro_value: 0
+ - macro_name: VER_DEF_CURRENT
+ macro_value: 1
+ - macro_name: VER_DEF_NUM
+ macro_value: 2
+ - macro_name: VER_FLG_BASE
+ macro_value: '0x1'
+ - macro_name: VER_FLG_WEAK
+ macro_value: '0x2'
+ - macro_name: VER_NDX_LOCAL
+ macro_value: 0
+ - macro_name: VER_NDX_GLOBAL
+ macro_value: 1
+ - macro_name: VER_NDX_LORESERVE
+ macro_value: '0xff00'
+ - macro_name: VER_NDX_ELIMINATE
+ macro_value: '0xff01'
+ # Values used in the .note.gnu.property section.
+ - macro_name: GNU_PROPERTY_X86_FEATURE_1_AND
+ macro_value: '0xc0000002'
+ - macro_name: GNU_PROPERTY_X86_FEATURE_1_SHSTK
+ macro_value: '0x00000002'
+ # Architecture-specific IRELATIVE relocation types
+ - macro_name: R_AARCH64_IRELATIVE
+ macro_value: 1032
+ - macro_name: R_ARM_IRELATIVE
+ macro_value: 160
+ - macro_name: R_RISCV_IRELATIVE
+ macro_value: 58
+ - macro_name: R_X86_64_IRELATIVE
+ macro_value: 37
+ - macro_name: ELF32_ST_BIND
+ macro_header: elf-macros.h
+ - macro_name: ELF32_ST_TYPE
+ macro_header: elf-macros.h
+ - macro_name: ELF32_ST_INFO
+ macro_header: elf-macros.h
+ - macro_name: ELF64_ST_BIND
+ macro_header: elf-macros.h
+ - macro_name: ELF64_ST_TYPE
+ macro_header: elf-macros.h
+ - macro_name: ELF64_ST_INFO
+ macro_header: elf-macros.h
+ - macro_name: ELF32_ST_VISIBILITY
+ macro_header: elf-macros.h
+ - macro_name: ELF64_ST_VISIBILITY
+ macro_header: elf-macros.h
+ - macro_name: ELF32_R_SYM
+ macro_header: elf-macros.h
+ - macro_name: ELF32_R_TYPE
+ macro_header: elf-macros.h
+ - macro_name: ELF32_R_INFO
+ macro_header: elf-macros.h
+ - macro_name: ELF64_R_SYM
+ macro_header: elf-macros.h
+ - macro_name: ELF64_R_TYPE
+ macro_header: elf-macros.h
+ - macro_name: ELF64_R_INFO
+ macro_header: elf-macros.h
+ - macro_name: PT_AARCH64_MEMTAG_MTE
+ macro_value: '0x70000002'
+ - macro_name: PN_XNUM
+ macro_value: '0xffff'
+ - macro_name: ELFCLASSNUM
+ macro_value: 3
+ - macro_name: EV_NUM
+ macro_value: 2
+ - macro_name: AT_NULL
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_IGNORE
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_EXECFD
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_PHDR
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_PHENT
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_PHNUM
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_PAGESZ
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_BASE
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_FLAGS
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_ENTRY
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_NOTELF
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_UID
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_EUID
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_GID
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_EGID
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_PLATFORM
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_HWCAP
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_CLKTCK
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_SECURE
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_BASE_PLATFORM
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_RANDOM
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_HWCAP2
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_RSEQ_FEATURE_SIZE
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_RSEQ_ALIGN
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_HWCAP3
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_HWCAP4
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_EXECFN
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_SYSINFO
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_SYSINFO_EHDR
+ macro_header: sys-auxv-macros.h
+ - macro_name: AT_MINSIGSTKSZ
+ macro_header: sys-auxv-macros.h
+types:
+ - type_name: Elf32_Addr
+ - type_name: Elf32_Chdr
+ - type_name: Elf32_Dyn
+ - type_name: Elf32_Ehdr
+ - type_name: Elf32_Half
+ - type_name: Elf32_Lword
+ - type_name: Elf32_Nhdr
+ - type_name: Elf32_Off
+ - type_name: Elf32_Phdr
+ - type_name: Elf32_Rel
+ - type_name: Elf32_Rela
+ - type_name: Elf32_Shdr
+ - type_name: Elf32_Sword
+ - type_name: Elf32_Sym
+ - type_name: Elf32_Verdaux
+ - type_name: Elf32_Verdef
+ - type_name: Elf32_Vernaux
+ - type_name: Elf32_Verneed
+ - type_name: Elf32_Versym
+ - type_name: Elf32_Word
+ - type_name: Elf32_Xword
+ - type_name: Elf32_auxv_t
+ - type_name: Elf64_Addr
+ - type_name: Elf64_Chdr
+ - type_name: Elf64_Dyn
+ - type_name: Elf64_Ehdr
+ - type_name: Elf64_Half
+ - type_name: Elf64_Lword
+ - type_name: Elf64_Nhdr
+ - type_name: Elf64_Off
+ - type_name: Elf64_Phdr
+ - type_name: Elf64_Rel
+ - type_name: Elf64_Rela
+ - type_name: Elf64_Shdr
+ - type_name: Elf64_Sword
+ - type_name: Elf64_Sxword
+ - type_name: Elf64_Sym
+ - type_name: Elf64_Verdaux
+ - type_name: Elf64_Verdef
+ - type_name: Elf64_Vernaux
+ - type_name: Elf64_Verneed
+ - type_name: Elf64_Versym
+ - type_name: Elf64_Word
+ - type_name: Elf64_Xword
+ - type_name: Elf64_auxv_t
+enums: []
+objects: []
+functions: []
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 9dd7548aa51..02b9adf88bc 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
@@ -11,6 +11,7 @@ add_header(
.size_t
libc.include.llvm-libc-macros.annex_k_macros
)
+add_header(reclen_t HDR reclen_t.h)
add_header(ssize_t HDR ssize_t.h)
add_header(__atfork_callback_t HDR __atfork_callback_t.h)
add_header(__search_compare_t HDR __search_compare_t.h)
@@ -118,12 +119,29 @@ add_header(pthread_spinlock_t HDR pthread_spinlock_t.h DEPENDS .pid_t)
add_header(pthread_t HDR pthread_t.h DEPENDS .__thread_type)
add_header(pthread_id_np_t HDR pthread_id_np_t.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
add_header(rlim_t HDR rlim_t.h)
+add_header(sem_t HDR sem_t.h DEPENDS .__futex_word)
add_header(time_t HDR time_t_64.h DEST_HDR time_t.h)
+add_header(timer_t HDR timer_t.h)
+add_header(sig_t HDR sig_t.h)
add_header(sighandler_t HDR sighandler_t.h)
add_header(stack_t HDR stack_t.h DEPENDS .size_t)
add_header(suseconds_t HDR suseconds_t.h)
-add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t)
+add_header(struct_dirent HDR struct_dirent.h DEPENDS .ino_t .off_t .reclen_t)
+add_header(struct_posix_dent HDR struct_posix_dent.h DEPENDS .ino_t .off_t .reclen_t)
add_header(struct_dl_phdr_info HDR struct_dl_phdr_info.h DEPENDS .size_t libc.include.llvm-libc-macros.link_macros)
+add_header(
+ struct_link_map
+ HDR struct_link_map.h
+ DEPENDS
+ libc.include.llvm-libc-macros.link_macros
+)
+add_header(
+ struct_r_debug
+ HDR struct_r_debug.h
+ DEPENDS
+ .struct_link_map
+ libc.include.llvm-libc-macros.link_macros
+)
add_header(dl_info HDR Dl_info.h)
add_header(struct_f_owner_ex HDR struct_f_owner_ex.h DEPENDS .pid_t)
add_header(struct_flock HDR struct_flock.h DEPENDS .off_t .pid_t)
@@ -187,7 +205,9 @@ add_header(__jmp_buf HDR __jmp_buf.h DEPENDS .sigset_t)
add_header(jmp_buf HDR jmp_buf.h DEPENDS .__jmp_buf)
add_header(sigjmp_buf HDR sigjmp_buf.h DEPENDS .__jmp_buf)
add_header(struct_sigaction HDR struct_sigaction.h DEPENDS .sigset_t .siginfo_t)
+add_header(struct_sigevent HDR struct_sigevent.h DEPENDS .union_sigval .pthread_attr_t .pid_t)
add_header(struct_timespec HDR struct_timespec.h DEPENDS .time_t)
+add_header(struct_itimerspec HDR struct_itimerspec.h DEPENDS .struct_timespec)
add_header(
struct_stat
HDR struct_stat.h
@@ -196,6 +216,13 @@ add_header(
.blksize_t .blkcnt_t
)
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_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)
@@ -211,14 +238,14 @@ add_header(__getoptargv_t HDR __getoptargv_t.h)
add_header(wchar_t HDR wchar_t.h)
add_header(char8_t HDR char8_t.h)
add_header(
- char16_t
+ char16_t
HDR
char16_t.h
DEPENDS
libc.include.llvm-libc-macros.stdint_macros
)
add_header(
- char32_t
+ char32_t
HDR
char32_t.h
DEPENDS
@@ -229,9 +256,10 @@ add_header(wctype_t HDR wctype_t.h)
add_header(sa_family_t HDR sa_family_t.h)
add_header(socklen_t HDR socklen_t.h)
add_header(struct_sockaddr HDR struct_sockaddr.h DEPENDS .sa_family_t)
+add_header(struct_addrinfo HDR struct_addrinfo.h DEPENDS .socklen_t .struct_sockaddr)
add_header(struct_sockaddr_in HDR struct_sockaddr_in.h DEPENDS .in_port_t .sa_family_t .struct_in_addr)
add_header(
- struct_sockaddr_in6
+ struct_sockaddr_in6
HDR
struct_sockaddr_in6.h
DEPENDS
@@ -259,8 +287,10 @@ add_header(
)
add_header(struct_sockaddr_un HDR struct_sockaddr_un.h DEPENDS .sa_family_t)
add_header(struct_ifreq HDR struct_ifreq.h DEPENDS libc.include.llvm-libc-macros.net_if_macros .struct_sockaddr)
+add_header(struct_if_nameindex HDR struct_if_nameindex.h)
add_header(struct_iovec HDR struct_iovec.h DEPENDS .size_t)
add_header(struct_linger HDR struct_linger.h)
+add_header(struct_ucred HDR struct_ucred.h DEPENDS .pid_t .uid_t .gid_t)
add_header(struct_cmsghdr HDR struct_cmsghdr.h DEPENDS .size_t)
add_header(struct_msghdr HDR struct_msghdr.h DEPENDS .size_t .socklen_t .struct_iovec)
add_header(struct_mmsghdr HDR struct_mmsghdr.h DEPENDS .struct_msghdr)
@@ -299,11 +329,21 @@ add_header(fsblkcnt_t HDR fsblkcnt_t.h)
add_header(fsfilcnt_t HDR fsfilcnt_t.h)
add_header(
struct_statvfs
-HDR
- struct_statvfs.h
-DEPENDS
- .fsblkcnt_t
- .fsfilcnt_t
+ HDR
+ struct_statvfs.h
+ DEPENDS
+ .fsblkcnt_t
+ .fsfilcnt_t
+)
+add_header(fsid_t HDR fsid_t.h)
+add_header(
+ struct_statfs
+ HDR
+ struct_statfs.h
+ DEPENDS
+ .fsblkcnt_t
+ .fsfilcnt_t
+ .fsid_t
)
add_header(locale_t HDR locale_t.h)
add_header(struct_lconv HDR struct_lconv.h)
@@ -436,7 +476,7 @@ add_header(
HDR
Elf32_Versym.h
DEPENDS
- .Elf32_Half
+ .Elf32_Half
)
add_header(Elf64_Addr HDR Elf64_Addr.h DEPENDS libc.include.llvm-libc-macros.stdint_macros)
@@ -560,7 +600,7 @@ add_header(
HDR
Elf64_Versym.h
DEPENDS
- .Elf64_Half
+ .Elf64_Half
)
# UEFI
@@ -687,18 +727,18 @@ add_header(EFI_SYSTEM_TABLE
.EFI_TABLE_HEADER
.char16_t
)
-add_header(__action_closure_fn_t
- HDR
- __action_closure_fn_t.h
- DEPENDS
- .posix_tnode
+add_header(__action_closure_fn_t
+ HDR
+ __action_closure_fn_t.h
+ DEPENDS
+ .posix_tnode
.VISIT
)
-add_header(__action_fn_t
- HDR
- __action_fn_t.h
- DEPENDS
- .posix_tnode
+add_header(__action_fn_t
+ HDR
+ __action_fn_t.h
+ DEPENDS
+ .posix_tnode
.VISIT
)
add_header(__free_fn_t HDR __free_fn_t.h)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/float128.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/float128.h
index 82ebb79f1f5..5bbb9910990 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/float128.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/float128.h
@@ -19,17 +19,17 @@
// https://github.com/llvm/llvm-project/issues/80195
#if defined(__STDC_IEC_60559_BFP__) && !defined(__clang__) && \
!defined(__cplusplus)
-#define LIBC_TYPES_HAS_FLOAT128
+#define LIBC_TYPES_HAS_NATIVE_FLOAT128
typedef _Float128 float128;
#elif defined(__FLOAT128__) || defined(__SIZEOF_FLOAT128__)
// Use __float128 type. gcc and clang sometime use __SIZEOF_FLOAT128__ to
// notify the availability of __float128.
// clang also uses __FLOAT128__ macro to notify the availability of __float128
// type: https://reviews.llvm.org/D15120
-#define LIBC_TYPES_HAS_FLOAT128
+#define LIBC_TYPES_HAS_NATIVE_FLOAT128
typedef __float128 float128;
#elif (LDBL_MANT_DIG == 113)
-#define LIBC_TYPES_HAS_FLOAT128
+#define LIBC_TYPES_HAS_NATIVE_FLOAT128
typedef long double float128;
#endif
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fsid_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fsid_t.h
new file mode 100644
index 00000000000..f7fd52e976b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/fsid_t.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
+/// Definition of fsid_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_FSID_T_H
+#define LLVM_LIBC_TYPES_FSID_T_H
+
+typedef struct {
+ int __val[2];
+} fsid_t;
+
+#endif // LLVM_LIBC_TYPES_FSID_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/CMakeLists.txt
index ccb986a7b54..d937ffe30e6 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/CMakeLists.txt
@@ -3,3 +3,9 @@ add_header(
HDR
loff_t.h
)
+
+add_header(
+ struct_sysinfo
+ HDR
+ struct_sysinfo.h
+)
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/struct_sysinfo.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/struct_sysinfo.h
new file mode 100644
index 00000000000..a8bcc93facf
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/linux/struct_sysinfo.h
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sysinfo for Linux.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_LINUX_STRUCT_SYSINFO_H
+#define LLVM_LIBC_TYPES_LINUX_STRUCT_SYSINFO_H
+
+#include <linux/sysinfo.h>
+
+#endif // LLVM_LIBC_TYPES_LINUX_STRUCT_SYSINFO_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/reclen_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/reclen_t.h
new file mode 100644
index 00000000000..64a028ee626
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/reclen_t.h
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 reclen_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_RECLEN_T_H
+#define LLVM_LIBC_TYPES_RECLEN_T_H
+
+typedef unsigned short reclen_t;
+
+#endif // LLVM_LIBC_TYPES_RECLEN_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/sem_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/sem_t.h
new file mode 100644
index 00000000000..4a2d2fc15dd
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/sem_t.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
+/// Definition of the sem_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_SEM_T_H
+#define LLVM_LIBC_TYPES_SEM_T_H
+
+#include "__futex_word.h"
+
+typedef struct {
+ // The semaphore count. Waiters block on this word.
+ __futex_word __value;
+ // Set to a fixed value by sem_init/sem_open and cleared by sem_destroy, so
+ // that operations on an uninitialized or destroyed semaphore can be detected.
+ unsigned int __canary;
+ // Whether the semaphore is shared between processes.
+ unsigned int __is_shared : 1;
+} sem_t;
+
+#endif // LLVM_LIBC_TYPES_SEM_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/sig_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/sig_t.h
new file mode 100644
index 00000000000..ad6b1aeb561
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/sig_t.h
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sig_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_SIG_T_H
+#define LLVM_LIBC_TYPES_SIG_T_H
+
+// BSD type for signal handlers.
+typedef void (*sig_t)(int);
+
+#endif // LLVM_LIBC_TYPES_SIG_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/siginfo_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/siginfo_t.h
index 20fdd461bb6..67366e40b1e 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/siginfo_t.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/siginfo_t.h
@@ -33,7 +33,7 @@ typedef struct {
/* POSIX.1b timers */
struct {
int si_tid; /* timer id */
- int _overrun; /* overrun count */
+ int si_overrun; /* overrun count */
union sigval si_sigval; /* same as below */
} _timer;
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_addrinfo.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_addrinfo.h
new file mode 100644
index 00000000000..0c0233982b1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_addrinfo.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
+/// Definition of struct addrinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_ADDRINFO_H
+#define LLVM_LIBC_TYPES_STRUCT_ADDRINFO_H
+
+#include "socklen_t.h"
+#include "struct_sockaddr.h"
+
+struct addrinfo {
+ int ai_flags;
+ int ai_family;
+ int ai_socktype;
+ int ai_protocol;
+ socklen_t ai_addrlen;
+ struct sockaddr *ai_addr;
+ char *ai_canonname;
+ struct addrinfo *ai_next;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_ADDRINFO_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_dirent.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_dirent.h
index f950869fc77..0272e76369d 100644
--- a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_dirent.h
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_dirent.h
@@ -11,12 +11,13 @@
#include "ino_t.h"
#include "off_t.h"
+#include "reclen_t.h"
struct dirent {
ino_t d_ino;
#ifdef __linux__
off_t d_off;
- unsigned short d_reclen;
+ reclen_t d_reclen;
#endif
unsigned char d_type;
// The user code should use strlen to determine actual the size of d_name.
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_group.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_group.h
new file mode 100644
index 00000000000..0a3e7077b44
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-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
+/// Definition of struct group.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_GROUP_H
+#define LLVM_LIBC_TYPES_STRUCT_GROUP_H
+
+#include "gid_t.h"
+
+// Structure representing group information in the group database.
+struct group {
+ char *gr_name; // The name of the group.
+ char *gr_passwd; // Group password.
+ gid_t gr_gid; // Numerical group ID.
+ char **gr_mem; // Pointer to a null-terminated array of member names.
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_GROUP_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_if_nameindex.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_if_nameindex.h
new file mode 100644
index 00000000000..12bd79f7b61
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_if_nameindex.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 struct if_nameindex.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_IF_NAMEINDEX_H
+#define LLVM_LIBC_TYPES_STRUCT_IF_NAMEINDEX_H
+
+/// Structure storing a network interface index and its corresponding name.
+struct if_nameindex {
+ unsigned int if_index;
+ char *if_name;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_IF_NAMEINDEX_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_itimerspec.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_itimerspec.h
new file mode 100644
index 00000000000..05f6f315c8e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_itimerspec.h
@@ -0,0 +1,24 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 itimerspec.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_ITIMERSPEC_H
+#define LLVM_LIBC_TYPES_STRUCT_ITIMERSPEC_H
+
+#include "struct_timespec.h"
+
+struct itimerspec {
+ struct timespec it_interval;
+ struct timespec it_value;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_ITIMERSPEC_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_link_map.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_link_map.h
new file mode 100644
index 00000000000..ebc02b60d15
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_link_map.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
+/// Definition of type struct link_map.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_LINK_MAP_H
+#define LLVM_LIBC_TYPES_STRUCT_LINK_MAP_H
+
+#include "../llvm-libc-macros/link-macros.h"
+
+// NB: This structure is accessed by debuggers and similar tools, which have
+// their own definition of the structure. Changing the layout here will likely
+// break those tools.
+struct link_map {
+ ElfW(Addr) l_addr;
+ char *l_name;
+ ElfW(Dyn) * l_ld;
+ struct link_map *l_next, *l_prev;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_LINK_MAP_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_passwd.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_passwd.h
new file mode 100644
index 00000000000..c51d3349f7c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_passwd.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
+/// Definition of struct passwd.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_PASSWD_H
+#define LLVM_LIBC_TYPES_STRUCT_PASSWD_H
+
+#include "gid_t.h"
+#include "uid_t.h"
+
+/// Structure representing user account information from the password database.
+struct passwd {
+ char *pw_name; // User's login name.
+ char *pw_passwd; // Encrypted password.
+ uid_t pw_uid; // Numerical user ID.
+ gid_t pw_gid; // Numerical group ID.
+ char *pw_gecos; // User info / real name.
+ char *pw_dir; // Initial working directory.
+ char *pw_shell; // Program to use as shell.
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_PASSWD_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_posix_dent.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_posix_dent.h
new file mode 100644
index 00000000000..0b46268506f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_posix_dent.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 posix_dent.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_POSIX_DENT_H
+#define LLVM_LIBC_TYPES_STRUCT_POSIX_DENT_H
+
+#include "ino_t.h"
+#include "off_t.h"
+#include "reclen_t.h"
+
+struct posix_dent {
+ ino_t d_ino;
+#ifdef __linux__
+ off_t d_off;
+#endif
+ reclen_t d_reclen;
+ unsigned char d_type;
+ // The user code should use strlen to determine the actual size of d_name.
+ // Likewise, it is incorrect and prohibited by the POSIX standard to determine
+ // the size of struct posix_dent type using sizeof. The size should be got
+ // using a different method, for example, from the d_reclen field.
+ char d_name[1];
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_POSIX_DENT_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_r_debug.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_r_debug.h
new file mode 100644
index 00000000000..68c99608265
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_r_debug.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
+/// Definition of type struct r_debug.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_R_DEBUG_H
+#define LLVM_LIBC_TYPES_STRUCT_R_DEBUG_H
+
+#include "../llvm-libc-macros/link-macros.h"
+#include "struct_link_map.h"
+
+enum { RT_CONSISTENT = 0, RT_ADD = 1, RT_DELETE = 2 };
+
+// NB: This structure and the related constants are accessed by debuggers and
+// similar tools, which have their own definition of the structure. Changing
+// their definition here will likely break those tools.
+struct r_debug {
+ int r_version;
+ struct link_map *r_map;
+ ElfW(Addr) r_brk;
+ int r_state;
+ ElfW(Addr) r_ldbase;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_R_DEBUG_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_sigevent.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_sigevent.h
new file mode 100644
index 00000000000..fb394da129a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_sigevent.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 sigevent type.
+/// https://man7.org/linux/man-pages/man3/sigevent.3type.html
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_SIGEVENT_H
+#define LLVM_LIBC_TYPES_STRUCT_SIGEVENT_H
+
+#include "pid_t.h"
+#include "pthread_attr_t.h"
+#include "union_sigval.h"
+
+struct sigevent {
+ int sigev_notify;
+ int sigev_signo;
+ union sigval sigev_value;
+ void (*sigev_notify_function)(union sigval);
+ pthread_attr_t *sigev_notify_attributes;
+#ifdef __linux__
+ pid_t sigev_notify_thread_id;
+#endif
+};
+
+// Self-define for compatibility with code assuming a macro.
+#define sigev_notify_thread_id sigev_notify_thread_id
+
+#endif // LLVM_LIBC_TYPES_STRUCT_SIGEVENT_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_statfs.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_statfs.h
new file mode 100644
index 00000000000..2767d445071
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_statfs.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
+/// Definition of type struct statfs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_STATFS_H
+#define LLVM_LIBC_TYPES_STRUCT_STATFS_H
+
+#include "fsblkcnt_t.h"
+#include "fsfilcnt_t.h"
+#include "fsid_t.h"
+
+// NOTE: This structure may have different layouts on architectures we don't
+// fully support (e.g. s390 or MIPS).
+
+struct statfs {
+ unsigned long f_type;
+ unsigned long f_bsize;
+ fsblkcnt_t f_blocks;
+ fsblkcnt_t f_bfree;
+ fsblkcnt_t f_bavail;
+ fsfilcnt_t f_files;
+ fsfilcnt_t f_ffree;
+ fsid_t f_fsid;
+ unsigned long f_namelen;
+ unsigned long f_frsize;
+ unsigned long f_flags;
+ unsigned long f_spare[4];
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_STATFS_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_sysinfo.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_sysinfo.h
new file mode 100644
index 00000000000..996ddd1423f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_sysinfo.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
+/// Definition of struct sysinfo.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_SYSINFO_H
+#define LLVM_LIBC_TYPES_STRUCT_SYSINFO_H
+
+#if defined(__linux__)
+#include "linux/struct_sysinfo.h"
+#endif
+
+#endif // LLVM_LIBC_TYPES_STRUCT_SYSINFO_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_ucred.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_ucred.h
new file mode 100644
index 00000000000..727e18f0004
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/struct_ucred.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 ucred.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_STRUCT_UCRED_H
+#define LLVM_LIBC_TYPES_STRUCT_UCRED_H
+
+#include "gid_t.h"
+#include "pid_t.h"
+#include "uid_t.h"
+
+// Credentials of a peer process connected to a socket.
+struct ucred {
+ pid_t pid;
+ uid_t uid;
+ gid_t gid;
+};
+
+#endif // LLVM_LIBC_TYPES_STRUCT_UCRED_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/timer_t.h b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/timer_t.h
new file mode 100644
index 00000000000..cefb2993c02
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/llvm-libc-types/timer_t.h
@@ -0,0 +1,19 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 timer_t type.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_TYPES_TIMER_T_H
+#define LLVM_LIBC_TYPES_TIMER_T_H
+
+typedef void *timer_t;
+
+#endif // LLVM_LIBC_TYPES_TIMER_T_H
diff --git a/deps/v8/third_party/llvm-libc/src/include/math.yaml b/deps/v8/third_party/llvm-libc/src/include/math.yaml
index 14e243168ad..006233e579f 100644
--- a/deps/v8/third_party/llvm-libc/src/include/math.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/math.yaml
@@ -138,7 +138,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: atan2f16
standards:
- stdc
@@ -201,7 +201,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: canonicalizef16
standards:
- stdc
@@ -253,7 +253,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ceilf16
standards:
- stdc
@@ -288,7 +288,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: copysignf16
standards:
- stdc
@@ -356,7 +356,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: daddl
standards:
- stdc
@@ -371,7 +371,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ddivl
standards:
- stdc
@@ -387,7 +387,7 @@ functions:
- type: float128
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: dfmal
standards:
- stdc
@@ -403,7 +403,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: dmull
standards:
- stdc
@@ -417,7 +417,7 @@ functions:
return_type: double
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: dsqrtl
standards:
- stdc
@@ -431,7 +431,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: dsubl
standards:
- stdc
@@ -771,7 +771,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fabsf16
standards:
- stdc
@@ -799,7 +799,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: faddl
standards:
- stdc
@@ -828,7 +828,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fdimf16
standards:
- stdc
@@ -858,7 +858,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fdivl
standards:
- stdc
@@ -882,7 +882,7 @@ functions:
- type: float128
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ffmal
standards:
- stdc
@@ -909,7 +909,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: floorf16
standards:
- stdc
@@ -969,7 +969,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmaxf16
standards:
- stdc
@@ -1013,7 +1013,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmaximum_mag_numf16
standards:
- stdc
@@ -1043,7 +1043,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmaximum_magf16
standards:
- stdc
@@ -1080,7 +1080,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmaximum_numf16
standards:
- stdc
@@ -1110,7 +1110,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmaximumf16
standards:
- stdc
@@ -1154,7 +1154,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fminf16
standards:
- stdc
@@ -1198,7 +1198,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fminimum_mag_numf16
standards:
- stdc
@@ -1228,7 +1228,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fminimum_magf16
standards:
- stdc
@@ -1265,7 +1265,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fminimum_numf16
standards:
- stdc
@@ -1295,7 +1295,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fminimumf16
standards:
- stdc
@@ -1339,7 +1339,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmodf16
standards:
- stdc
@@ -1369,7 +1369,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fmull
standards:
- stdc
@@ -1398,7 +1398,7 @@ functions:
arguments:
- type: float128
- type: int *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: frexpf16
standards:
- stdc
@@ -1438,7 +1438,7 @@ functions:
- type: float128
- type: int
- type: unsigned int
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fromfpf16
standards:
- stdc
@@ -1480,7 +1480,7 @@ functions:
- type: float128
- type: int
- type: unsigned int
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fromfpxf16
standards:
- stdc
@@ -1516,7 +1516,7 @@ functions:
return_type: float
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fsub
standards:
- stdc
@@ -1531,7 +1531,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: fsubl
standards:
- stdc
@@ -1557,7 +1557,7 @@ functions:
return_type: float128
arguments:
- type: float128 *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: getpayloadf16
standards:
- stdc
@@ -1611,7 +1611,7 @@ functions:
return_type: int
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ilogbf16
standards:
- stdc
@@ -1643,7 +1643,7 @@ functions:
return_type: int
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: isnanl
standards:
- bsd
@@ -1678,7 +1678,7 @@ functions:
arguments:
- type: float128
- type: int
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ldexpf16
standards:
- stdc
@@ -1758,7 +1758,7 @@ functions:
return_type: long
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: llogbf16
standards:
- stdc
@@ -1790,7 +1790,7 @@ functions:
return_type: long long
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: llrintf16
standards:
- stdc
@@ -1822,7 +1822,7 @@ functions:
return_type: long long
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: llroundf16
standards:
- stdc
@@ -1924,7 +1924,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: logbf16
standards:
- stdc
@@ -1969,7 +1969,7 @@ functions:
return_type: long
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: lrintf16
standards:
- stdc
@@ -2001,7 +2001,7 @@ functions:
return_type: long
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: lroundf16
standards:
- stdc
@@ -2036,7 +2036,7 @@ functions:
arguments:
- type: float128
- type: float128 *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: modff16
standards:
- stdc
@@ -2070,7 +2070,7 @@ functions:
return_type: float128
arguments:
- type: const char *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: nanf16
standards:
- stdc
@@ -2102,7 +2102,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: nearbyintf16
standards:
- stdc
@@ -2137,7 +2137,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: nextafterf16
standards:
- stdc
@@ -2171,7 +2171,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: nextdownf16
standards:
- stdc
@@ -2232,7 +2232,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: nextupf16
standards:
- stdc
@@ -2295,7 +2295,7 @@ functions:
arguments:
- type: float128
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: remainderf16
standards:
- stdc
@@ -2335,7 +2335,7 @@ functions:
- type: float128
- type: float128
- type: int *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: remquof16
standards:
- stdc
@@ -2371,7 +2371,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: rintf16
standards:
- stdc
@@ -2409,7 +2409,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: roundevenf16
standards:
- stdc
@@ -2435,7 +2435,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: roundf16
standards:
- stdc
@@ -2483,7 +2483,7 @@ functions:
arguments:
- type: float128
- type: long
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: scalblnf16
standards:
- stdc
@@ -2528,7 +2528,7 @@ functions:
arguments:
- type: float128
- type: int
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: scalbnf16
standards:
- stdc
@@ -2565,7 +2565,7 @@ functions:
arguments:
- type: float128 *
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: setpayloadf16
standards:
- stdc
@@ -2602,7 +2602,7 @@ functions:
arguments:
- type: float128 *
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: setpayloadsigf16
standards:
- stdc
@@ -2697,7 +2697,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: sqrtf16
standards:
- stdc
@@ -2777,7 +2777,7 @@ functions:
arguments:
- type: const float128 *
- type: const float128 *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: totalorderf16
standards:
- stdc
@@ -2821,7 +2821,7 @@ functions:
arguments:
- type: const float128 *
- type: const float128 *
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: totalordermagf16
standards:
- stdc
@@ -2848,7 +2848,7 @@ functions:
return_type: float128
arguments:
- type: float128
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: truncf16
standards:
- stdc
@@ -2886,7 +2886,7 @@ functions:
- type: float128
- type: int
- type: unsigned int
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ufromfpf16
standards:
- stdc
@@ -2928,7 +2928,7 @@ functions:
- type: float128
- type: int
- type: unsigned int
- guard: LIBC_TYPES_HAS_FLOAT128
+ guard: LIBC_TYPES_HAS_NATIVE_FLOAT128
- name: ufromfpxf16
standards:
- stdc
diff --git a/deps/v8/third_party/llvm-libc/src/include/memory.yaml b/deps/v8/third_party/llvm-libc/src/include/memory.yaml
new file mode 100644
index 00000000000..81a84e4a802
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/memory.yaml
@@ -0,0 +1,5 @@
+header: memory.h
+public_includes:
+ - string.h
+standards:
+ - posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/net/if.yaml b/deps/v8/third_party/llvm-libc/src/include/net/if.yaml
index 51034d84e44..3b6d807e2fc 100644
--- a/deps/v8/third_party/llvm-libc/src/include/net/if.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/net/if.yaml
@@ -6,9 +6,16 @@ macros:
macro_header: net-if-macros.h
types:
- type_name: struct_ifreq
+ - type_name: struct_if_nameindex
enums: []
objects: []
functions:
+ - name: if_freenameindex
+ standards:
+ - posix
+ return_type: void
+ arguments:
+ - type: struct if_nameindex *
- name: if_indextoname
standards:
- posix
@@ -16,6 +23,11 @@ functions:
arguments:
- type: unsigned int
- type: char *
+ - name: if_nameindex
+ standards:
+ - posix
+ return_type: struct if_nameindex *
+ arguments: []
- name: if_nametoindex
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/netdb.yaml b/deps/v8/third_party/llvm-libc/src/include/netdb.yaml
new file mode 100644
index 00000000000..b98f30fd1a2
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/netdb.yaml
@@ -0,0 +1,44 @@
+header: netdb.h
+standards:
+ - posix
+macros:
+ - macro_name: EAI_AGAIN
+ macro_header: netdb-macros.h
+ - macro_name: EAI_BADFLAGS
+ macro_header: netdb-macros.h
+ - macro_name: EAI_FAIL
+ macro_header: netdb-macros.h
+ - macro_name: EAI_FAMILY
+ macro_header: netdb-macros.h
+ - macro_name: EAI_MEMORY
+ macro_header: netdb-macros.h
+ - macro_name: EAI_NONAME
+ macro_header: netdb-macros.h
+ - macro_name: EAI_SERVICE
+ macro_header: netdb-macros.h
+ - macro_name: EAI_SOCKTYPE
+ macro_header: netdb-macros.h
+ - macro_name: EAI_SYSTEM
+ macro_header: netdb-macros.h
+ - macro_name: EAI_OVERFLOW
+ macro_header: netdb-macros.h
+types:
+ - type_name: struct_addrinfo
+enums: []
+objects: []
+functions:
+ - name: freeaddrinfo
+ standards:
+ - posix
+ return_type: void
+ arguments:
+ - type: struct addrinfo *
+ - name: getaddrinfo
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *__restrict
+ - type: const char *__restrict
+ - type: const struct addrinfo *__restrict
+ - type: struct addrinfo **__restrict
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 c3e967c67ee..784b1c207b9 100644
--- a/deps/v8/third_party/llvm-libc/src/include/pthread.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/pthread.yaml
@@ -50,6 +50,10 @@ macros:
standards:
- gnu
macro_header: pthread-macros.h
+ - macro_name: "PTHREAD_STACK_DYNAMIC_NP"
+ standards:
+ - llvm_libc_ext
+ macro_header: pthread-macros.h
types:
- type_name: pthread_t
- type_name: pthread_once_t
@@ -242,6 +246,14 @@ functions:
return_type: void *
arguments:
- type: pthread_key_t
+ - name: pthread_getstack_np
+ standards:
+ - llvm_libc_ext
+ return_type: int
+ arguments:
+ - type: pthread_t
+ - type: void **__restrict
+ - type: size_t *__restrict
- name: pthread_join
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
new file mode 100644
index 00000000000..40db5690e98
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/pwd.yaml
@@ -0,0 +1,26 @@
+header: pwd.h
+standards:
+ - posix
+types:
+ - type_name: struct_passwd
+ - type_name: gid_t
+ - type_name: uid_t
+ - type_name: size_t
+enums: []
+objects: []
+functions:
+ - name: getpwent
+ standards:
+ - posix
+ return_type: struct passwd *
+ arguments: []
+ - name: setpwent
+ standards:
+ - posix
+ return_type: void
+ arguments: []
+ - name: endpwent
+ standards:
+ - posix
+ return_type: void
+ arguments: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/semaphore.yaml b/deps/v8/third_party/llvm-libc/src/include/semaphore.yaml
new file mode 100644
index 00000000000..4c51174359f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/semaphore.yaml
@@ -0,0 +1,86 @@
+header: semaphore.h
+standards:
+ - posix
+macros:
+ - macro_name: SEM_FAILED
+ macro_header: semaphore-macros.h
+types:
+ - type_name: clockid_t
+ - type_name: mode_t
+ - type_name: sem_t
+ - type_name: struct_timespec
+functions:
+ - name: sem_clockwait
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *__restrict
+ - type: clockid_t
+ - type: const struct timespec *__restrict
+ - name: sem_close
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *
+ - name: sem_destroy
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *
+ - name: sem_getvalue
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *__restrict
+ - type: int *__restrict
+ - name: sem_init
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *
+ - type: int
+ - type: unsigned
+ - name: sem_open
+ standards:
+ - posix
+ return_type: sem_t *
+ arguments:
+ - type: const char *
+ - type: int
+ - type: '...'
+ - name: sem_post
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *
+ - name: sem_timedwait
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *__restrict
+ - type: const struct timespec *__restrict
+ - name: sem_trywait
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *
+ - name: sem_unlink
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *
+ - name: sem_wait
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: sem_t *
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 7ab557875af..88c931edd51 100644
--- a/deps/v8/third_party/llvm-libc/src/include/signal.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/signal.yaml
@@ -20,14 +20,28 @@ macros:
macro_header: signal-macros.h
- macro_name: SIG_IGN
macro_header: signal-macros.h
+ - macro_name: SIGEV_SIGNAL
+ macro_header: signal-macros.h
+ - macro_name: SIGEV_NONE
+ macro_header: signal-macros.h
+ - macro_name: SIGEV_THREAD
+ macro_header: signal-macros.h
+ - macro_name: SIGEV_THREAD_ID
+ macro_header: signal-macros.h
types:
- type_name: pid_t
- type_name: sig_atomic_t
+ - type_name: sig_t
+ standards:
+ - bsd
- type_name: sighandler_t
+ standards:
+ - gnu
- type_name: siginfo_t
- type_name: sigset_t
- type_name: stack_t
- type_name: struct_sigaction
+ - type_name: struct_sigevent
- type_name: union_sigval
enums: []
objects: []
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 4b12698e248..ef725dd4fe6 100644
--- a/deps/v8/third_party/llvm-libc/src/include/stdio.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/stdio.yaml
@@ -146,6 +146,14 @@ functions:
arguments:
- type: const char *
- type: const char *
+ - name: freopen
+ standards:
+ - stdc
+ return_type: FILE *
+ arguments:
+ - type: const char *__restrict
+ - type: const char *__restrict
+ - type: FILE *__restrict
- name: fopencookie
standards:
- gnu
@@ -396,6 +404,12 @@ functions:
- type: const char *__restrict
- type: const char *__restrict
- type: '...'
+ - name: tmpfile
+ standards:
+ - stdc
+ return_type: FILE *
+ arguments:
+ - type: void
- name: ungetc
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 0533fe04aec..efbd4702919 100644
--- a/deps/v8/third_party/llvm-libc/src/include/stdlib.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/stdlib.yaml
@@ -185,6 +185,12 @@ functions:
- type: void **
- type: size_t
- type: size_t
+ - name: putenv
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: char *
- name: qsort
standards:
- stdc
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/fcntl.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/fcntl.yaml
new file mode 100644
index 00000000000..c21755d0984
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/fcntl.yaml
@@ -0,0 +1,5 @@
+header: sys/fcntl.h
+public_includes:
+ - fcntl.h
+standards:
+ - posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/mount.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/mount.yaml
new file mode 100644
index 00000000000..9c2964ff43e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/mount.yaml
@@ -0,0 +1,15 @@
+# NOTE: Semantics of sys/mount.h is different on Linux and BSD systems.
+header: sys/mount.h
+standards:
+ - linux
+macros:
+ # MS_ macro are defined only on Linux systems. Instead of listing
+ # them all here, do a shortcut (for now), and only reference a single
+ # one to ensure the inclusion of sys-mount-macros.h that would dispatch
+ # to system-specific ones.
+ - macro_name: MS_RDONLY
+ macro_header: sys-mount-macros.h
+types: []
+enums: []
+objects: []
+functions: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/poll.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/poll.yaml
new file mode 100644
index 00000000000..204e832388e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/poll.yaml
@@ -0,0 +1,5 @@
+header: sys/poll.h
+public_includes:
+ - poll.h
+standards:
+ - posix
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 faf263d3d58..a26dfb5f77b 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
@@ -4,9 +4,18 @@ standards:
macros:
- macro_name: RLIMIT_CPU
macro_header: sys-resource-macros.h
+ - macro_name: RUSAGE_SELF
+ macro_header: sys-resource-macros.h
+ - macro_name: RUSAGE_CHILDREN
+ macro_header: sys-resource-macros.h
+ - macro_name: RUSAGE_THREAD
+ macro_header: sys-resource-macros.h
+ standards:
+ - gnu
types:
- type_name: struct_rlimit
- type_name: rlim_t
+ - type_name: struct_rusage
enums: []
objects: []
functions:
@@ -17,6 +26,13 @@ functions:
arguments:
- type: int
- type: struct rlimit *
+ - name: getrusage
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: int
+ - type: struct rusage *
- name: setrlimit
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/signal.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/signal.yaml
new file mode 100644
index 00000000000..6c678fd9f7e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/signal.yaml
@@ -0,0 +1,5 @@
+header: sys/signal.h
+public_includes:
+ - signal.h
+standards:
+ - posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/socket.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/socket.yaml
index fb121fa805f..64a3a566031 100644
--- a/deps/v8/third_party/llvm-libc/src/include/sys/socket.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/socket.yaml
@@ -15,6 +15,9 @@ types:
- type_name: struct_msghdr
- type_name: struct_iovec
- type_name: struct_linger
+ - type_name: struct_ucred
+ standards:
+ - linux
- type_name: size_t
- type_name: ssize_t
enums: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/statfs.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/statfs.yaml
new file mode 100644
index 00000000000..337a3e33357
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/statfs.yaml
@@ -0,0 +1,19 @@
+header: sys/statfs.h
+standards:
+ - linux
+macros:
+ - macro_name: ADFS_SUPER_MAGIC
+ macro_header: sys-statfs-macros.h
+types:
+ - type_name: struct_statfs
+functions:
+ - name: fstatfs
+ return_type: int
+ arguments:
+ - type: int
+ - type: struct statfs *
+ - name: statfs
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: struct statfs *
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/syscall.h.def b/deps/v8/third_party/llvm-libc/src/include/sys/syscall.h.def
index 486947709b5..f3670a234c6 100644
--- a/deps/v8/third_party/llvm-libc/src/include/sys/syscall.h.def
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/syscall.h.def
@@ -169,6 +169,10 @@
#define SYS_clock_getres __NR_clock_getres
#endif
+#ifdef __NR_clock_getres_time64
+#define SYS_clock_getres_time64 __NR_clock_getres_time64
+#endif
+
#ifdef __NR_clock_gettime
#define SYS_clock_gettime __NR_clock_gettime
#endif
@@ -197,6 +201,10 @@
#define SYS_clone2 __NR_clone2
#endif
+#ifdef __NR_clone3
+#define SYS_clone3 __NR_clone3
+#endif
+
#ifdef __NR_close
#define SYS_close __NR_close
#endif
@@ -2213,10 +2221,18 @@
#define SYS_timer_gettime __NR_timer_gettime
#endif
+#ifdef __NR_timer_gettime64
+#define SYS_timer_gettime64 __NR_timer_gettime64
+#endif
+
#ifdef __NR_timer_settime
#define SYS_timer_settime __NR_timer_settime
#endif
+#ifdef __NR_timer_settime64
+#define SYS_timer_settime64 __NR_timer_settime64
+#endif
+
#ifdef __NR_timerfd
#define SYS_timerfd __NR_timerfd
#endif
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/sysinfo.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/sysinfo.yaml
new file mode 100644
index 00000000000..77533eb7b02
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/sysinfo.yaml
@@ -0,0 +1,10 @@
+header: sys/sysinfo.h
+standards:
+ - linux
+types:
+ - type_name: struct_sysinfo
+functions:
+ - name: sysinfo
+ return_type: int
+ arguments:
+ - type: struct sysinfo *
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/syslog.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/syslog.yaml
new file mode 100644
index 00000000000..402b9388ff2
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/syslog.yaml
@@ -0,0 +1,5 @@
+header: sys/syslog.h
+public_includes:
+ - syslog.h
+standards:
+ - posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/sysmacros.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/sysmacros.yaml
new file mode 100644
index 00000000000..70f7a5ad6e7
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/sysmacros.yaml
@@ -0,0 +1,26 @@
+header: sys/sysmacros.h
+standards:
+ - linux
+macros:
+ - macro_name: major
+ macro_header: sys-sysmacros-macros.h
+ - macro_name: minor
+ macro_header: sys-sysmacros-macros.h
+ - macro_name: makedev
+ macro_header: sys-sysmacros-macros.h
+enums: []
+objects: []
+functions:
+ - name: major
+ return_type: unsigned int
+ arguments:
+ - type: dev_t
+ - name: minor
+ return_type: unsigned int
+ arguments:
+ - type: dev_t
+ - name: makedev
+ return_type: dev_t
+ arguments:
+ - type: unsigned int
+ - type: unsigned int
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/types.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/types.yaml
index dcd65c8707a..8130e48eec2 100644
--- a/deps/v8/third_party/llvm-libc/src/include/sys/types.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/types.yaml
@@ -32,6 +32,7 @@ types:
- type_name: ssize_t
- type_name: suseconds_t
- type_name: time_t
+ - type_name: timer_t
- type_name: u_char
- type_name: u_int
- type_name: u_int16_t
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/unistd.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/unistd.yaml
new file mode 100644
index 00000000000..e00f7d53321
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/unistd.yaml
@@ -0,0 +1,5 @@
+header: sys/unistd.h
+public_includes:
+ - unistd.h
+standards:
+ - posix
diff --git a/deps/v8/third_party/llvm-libc/src/include/sys/vfs.yaml b/deps/v8/third_party/llvm-libc/src/include/sys/vfs.yaml
new file mode 100644
index 00000000000..61b37d01a02
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/sys/vfs.yaml
@@ -0,0 +1,5 @@
+header: sys/vfs.h
+public_includes:
+ - sys/statfs.h
+standards:
+ - linux
diff --git a/deps/v8/third_party/llvm-libc/src/include/syslog.yaml b/deps/v8/third_party/llvm-libc/src/include/syslog.yaml
new file mode 100644
index 00000000000..2452b22ad50
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/include/syslog.yaml
@@ -0,0 +1,68 @@
+header: syslog.h
+standards:
+ - posix
+macros:
+ - macro_name: LOG_PID
+ macro_header: syslog-macros.h
+ - macro_name: LOG_CONS
+ macro_header: syslog-macros.h
+ - macro_name: LOG_NDELAY
+ macro_header: syslog-macros.h
+ - macro_name: LOG_ODELAY
+ macro_header: syslog-macros.h
+ - macro_name: LOG_NOWAIT
+ macro_header: syslog-macros.h
+ - macro_name: LOG_KERN
+ macro_header: syslog-macros.h
+ - macro_name: LOG_USER
+ macro_header: syslog-macros.h
+ - macro_name: LOG_MAIL
+ macro_header: syslog-macros.h
+ - macro_name: LOG_NEWS
+ macro_header: syslog-macros.h
+ - macro_name: LOG_UUCP
+ macro_header: syslog-macros.h
+ - macro_name: LOG_DAEMON
+ macro_header: syslog-macros.h
+ - macro_name: LOG_AUTH
+ macro_header: syslog-macros.h
+ - macro_name: LOG_CRON
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LPR
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL0
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL1
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL2
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL3
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL4
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL5
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL6
+ macro_header: syslog-macros.h
+ - macro_name: LOG_LOCAL7
+ macro_header: syslog-macros.h
+ - macro_name: LOG_EMERG
+ macro_header: syslog-macros.h
+ - macro_name: LOG_ALERT
+ macro_header: syslog-macros.h
+ - macro_name: LOG_CRIT
+ macro_header: syslog-macros.h
+ - macro_name: LOG_ERR
+ macro_header: syslog-macros.h
+ - macro_name: LOG_WARNING
+ macro_header: syslog-macros.h
+ - macro_name: LOG_NOTICE
+ macro_header: syslog-macros.h
+ - macro_name: LOG_INFO
+ macro_header: syslog-macros.h
+ - macro_name: LOG_DEBUG
+ macro_header: syslog-macros.h
+types: []
+enums: []
+objects: []
+functions: []
diff --git a/deps/v8/third_party/llvm-libc/src/include/time.yaml b/deps/v8/third_party/llvm-libc/src/include/time.yaml
index bd62379205d..44044604a64 100644
--- a/deps/v8/third_party/llvm-libc/src/include/time.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/time.yaml
@@ -6,20 +6,31 @@ macros:
macro_header: null-macro.h
- macro_name: CLOCKS_PER_SEC
macro_header: time-macros.h
+ - macro_name: TIMER_ABSTIME
+ macro_header: time-macros.h
types:
- type_name: struct_timeval
- type_name: clockid_t
- type_name: errno_t
- type_name: struct_timespec
+ - type_name: struct_itimerspec
- type_name: struct_tm
- type_name: time_t
+ - type_name: timer_t
- type_name: clock_t
- type_name: rsize_t
- type_name: size_t
- type_name: locale_t
- type_name: tm_gmtoff_t
+ - type_name: pid_t
enums: []
-objects: []
+objects:
+ - object_name: tzname
+ object_type: char *[2]
+ - object_name: timezone
+ object_type: long
+ - object_name: daylight
+ object_type: int
functions:
- name: asctime
standards:
@@ -132,6 +143,14 @@ functions:
- type: const char *__restrict
- type: const struct tm *__restrict
- type: locale_t
+ - name: strptime
+ standards:
+ - stdc
+ return_type: char *
+ arguments:
+ - type: const char *__restrict
+ - type: const char *__restrict
+ - type: struct tm *__restrict
- name: time
standards:
- stdc
@@ -145,3 +164,46 @@ functions:
arguments:
- type: struct timespec *
- type: int
+ - name: timer_create
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: clockid_t
+ - type: struct sigevent *__restrict
+ - type: timer_t *__restrict
+ - name: timer_delete
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: timer_t
+ - name: timer_gettime
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: timer_t
+ - type: struct itimerspec *
+ - name: timer_settime
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: timer_t
+ - type: int
+ - type: const struct itimerspec *__restrict
+ - type: struct itimerspec *__restrict
+ - name: tzset
+ standards:
+ - posix
+ return_type: void
+ arguments:
+ - type: void
+ - name: clock_getcpuclockid
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: pid_t
+ - type: clockid_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 c1ae4567bfc..d6c0235dd83 100644
--- a/deps/v8/third_party/llvm-libc/src/include/unistd.yaml
+++ b/deps/v8/third_party/llvm-libc/src/include/unistd.yaml
@@ -16,12 +16,14 @@ macros:
macro_header: unistd-macros.h
- macro_name: _SC_ARG_MAX
macro_header: unistd-macros.h
+ - macro_name: _SC_CLK_TCK
+ macro_header: unistd-macros.h
+ - macro_name: _SC_OPEN_MAX
+ 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_OPEN_MAX
- macro_header: unistd-macros.h
- macro_name: _SC_THREADS
macro_header: unistd-macros.h
- macro_name: _SC_NPROCESSORS_CONF
@@ -42,6 +44,7 @@ types:
- type_name: __getoptargv_t
- type_name: __exec_envp_t
- type_name: __exec_argv_t
+ - type_name: useconds_t
enums: []
objects:
- object_name: environ
@@ -100,6 +103,14 @@ functions:
- type: const char *
- type: uid_t
- type: gid_t
+ - name: confstr
+ standards:
+ - posix
+ return_type: size_t
+ arguments:
+ - type: int
+ - type: char *
+ - type: size_t
- name: close
standards:
- posix
@@ -127,6 +138,14 @@ functions:
- type: int
- type: int
- type: int
+ - name: execle
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: const char *
+ - type: const char *
+ - type: '...'
- name: execv
standards:
- posix
@@ -384,6 +403,12 @@ functions:
return_type: pid_t
arguments:
- type: void
+ - name: sleep
+ standards:
+ - posix
+ return_type: unsigned int
+ arguments:
+ - type: unsigned int
- name: symlink
standards:
- posix
@@ -426,6 +451,12 @@ functions:
- type: int
- type: const char *
- type: int
+ - name: usleep
+ standards:
+ - posix
+ return_type: int
+ arguments:
+ - type: useconds_t
- name: write
standards:
- posix
diff --git a/deps/v8/third_party/llvm-libc/src/shared/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/shared/CMakeLists.txt
index d27484909f6..1237254aeeb 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/shared/CMakeLists.txt
@@ -1,16 +1,16 @@
set(LLVM_LIBC_SHARED_RPC_EXPORT_HEADERS
- "${CMAKE_CURRENT_SOURCE_DIR}/rpc.h"
- "${CMAKE_CURRENT_SOURCE_DIR}/rpc_util.h"
- "${CMAKE_CURRENT_SOURCE_DIR}/rpc_dispatch.h"
- "${CMAKE_CURRENT_SOURCE_DIR}/rpc_server.h"
- "${CMAKE_CURRENT_SOURCE_DIR}/rpc_opcodes.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/rpc.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/rpc_util.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/rpc_dispatch.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/rpc_server.h"
+ "${CMAKE_CURRENT_SOURCE_DIR}/rpc_opcodes.h"
)
# Install the freestanding RPC interface to the compiler tree.
if(LIBC_TARGET_OS_IS_GPU)
foreach(header_path IN LISTS LLVM_LIBC_SHARED_RPC_EXPORT_HEADERS)
install(FILES "${header_path}"
- DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/shared"
- COMPONENT libc-headers)
+ DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/shared"
+ COMPONENT libc-headers)
endforeach()
endif()
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins.h b/deps/v8/third_party/llvm-libc/src/shared/builtins.h
index ced054cb025..21c2bed4a0a 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/builtins.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins.h
@@ -23,11 +23,45 @@
#include "builtins/divdf3.h"
#include "builtins/divsf3.h"
#include "builtins/divtf3.h"
+#include "builtins/extenddftf2.h"
+#include "builtins/extendsfdf2.h"
+#include "builtins/extendsftf2.h"
+#include "builtins/extendxftf2.h"
+#include "builtins/fixdfdi.h"
+#include "builtins/fixdfsi.h"
+#include "builtins/fixdfti.h"
+#include "builtins/fixsfdi.h"
+#include "builtins/fixsfsi.h"
+#include "builtins/fixsfti.h"
+#include "builtins/fixunsdfdi.h"
+#include "builtins/fixunsdfsi.h"
+#include "builtins/fixunsdfti.h"
+#include "builtins/fixunssfdi.h"
+#include "builtins/fixunssfsi.h"
+#include "builtins/fixunssfti.h"
+#include "builtins/floatdidf.h"
+#include "builtins/floatdisf.h"
+#include "builtins/floatsidf.h"
+#include "builtins/floatsisf.h"
+#include "builtins/floattidf.h"
+#include "builtins/floattisf.h"
+#include "builtins/floatundidf.h"
+#include "builtins/floatundisf.h"
+#include "builtins/floatunsidf.h"
+#include "builtins/floatunsisf.h"
+#include "builtins/floatuntidf.h"
+#include "builtins/floatuntisf.h"
#include "builtins/muldf3.h"
#include "builtins/mulsf3.h"
#include "builtins/multf3.h"
+#include "builtins/negdf2.h"
+#include "builtins/negsf2.h"
#include "builtins/subdf3.h"
#include "builtins/subsf3.h"
#include "builtins/subtf3.h"
+#include "builtins/truncdfsf2.h"
+#include "builtins/trunctfdf2.h"
+#include "builtins/trunctfsf2.h"
+#include "builtins/trunctfxf2.h"
#endif // LLVM_LIBC_SHARED_BUILTINS_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/addtf3.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/addtf3.h
index 33534beeb91..6249771abd4 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/builtins/addtf3.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/addtf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/addtf3.h"
@@ -30,6 +30,6 @@ using builtins::addtf3;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_ADDTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/divtf3.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/divtf3.h
index ca69e6f5fc0..5b55bc4fbd9 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/builtins/divtf3.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/divtf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/divtf3.h"
@@ -30,6 +30,6 @@ using builtins::divtf3;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_DIVTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/extenddftf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/extenddftf2.h
new file mode 100644
index 00000000000..d4159d8cf28
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/extenddftf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extenddftf2 implementation as
+/// shared::extenddftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDDFTF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDDFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extenddftf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extenddftf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDDFTF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/extendsfdf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/extendsfdf2.h
new file mode 100644
index 00000000000..4f361ff9b4b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/extendsfdf2.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
+/// This header exposes LLVM-libc's __extendsfdf2 implementation as
+/// shared::extendsfdf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDSFDF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDSFDF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendsfdf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendsfdf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDSFDF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/extendsftf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/extendsftf2.h
new file mode 100644
index 00000000000..a79b809da29
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/extendsftf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extendsftf2 implementation as
+/// shared::extendsftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDSFTF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDSFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendsftf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendsftf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDSFTF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/extendxftf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/extendxftf2.h
new file mode 100644
index 00000000000..1f690ba29f9
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/extendxftf2.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extendxftf2 implementation as
+/// shared::extendxftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_EXTENDXFTF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_EXTENDXFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128) && \
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/extendxftf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::extendxftf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128 &&
+ // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_EXTENDXFTF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfdi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfdi.h
new file mode 100644
index 00000000000..2a0eb4da645
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfdi.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
+/// This header exposes LLVM-libc's __fixdfdi implementation as shared::fixdfdi
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXDFDI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXDFDI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixdfdi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixdfdi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXDFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfsi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfsi.h
new file mode 100644
index 00000000000..ab7dae3688c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfsi.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
+/// This header exposes LLVM-libc's __fixdfsi implementation as shared::fixdfsi
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXDFSI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXDFSI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixdfsi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixdfsi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXDFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfti.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfti.h
new file mode 100644
index 00000000000..bd83e706fd9
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixdfti.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixdfti implementation as shared::fixdfti
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXDFTI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXDFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixdfti.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixdfti;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXDFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfdi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfdi.h
new file mode 100644
index 00000000000..ff969a6551a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfdi.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
+/// This header exposes LLVM-libc's __fixsfdi implementation as shared::fixsfdi
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXSFDI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXSFDI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixsfdi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixsfdi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXSFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfsi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfsi.h
new file mode 100644
index 00000000000..debd82aefc8
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfsi.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
+/// This header exposes LLVM-libc's __fixsfsi implementation as shared::fixsfsi
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXSFSI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXSFSI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixsfsi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixsfsi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXSFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfti.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfti.h
new file mode 100644
index 00000000000..191fb5292b9
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixsfti.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixsfti implementation as shared::fixsfti
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXSFTI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXSFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixsfti.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixsfti;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXSFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfdi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfdi.h
new file mode 100644
index 00000000000..9c2472e771a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfdi.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
+/// This header exposes LLVM-libc's __fixunsdfdi implementation as
+/// shared::fixunsdfdi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFDI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFDI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixunsdfdi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixunsdfdi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfsi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfsi.h
new file mode 100644
index 00000000000..c463298e576
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfsi.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
+/// This header exposes LLVM-libc's __fixunsdfsi implementation as
+/// shared::fixunsdfsi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFSI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFSI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixunsdfsi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixunsdfsi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfti.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfti.h
new file mode 100644
index 00000000000..5929f937814
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunsdfti.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixunsdfti implementation as
+/// shared::fixunsdfti so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFTI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixunsdfti.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixunsdfti;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXUNSDFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfdi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfdi.h
new file mode 100644
index 00000000000..7a1b16cb6bc
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfdi.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
+/// This header exposes LLVM-libc's __fixunssfdi implementation as
+/// shared::fixunssfdi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFDI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFDI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixunssfdi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixunssfdi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfsi.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfsi.h
new file mode 100644
index 00000000000..8ed7ed6103d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfsi.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
+/// This header exposes LLVM-libc's __fixunssfsi implementation as
+/// shared::fixunssfsi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFSI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFSI_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixunssfsi.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixunssfsi;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfti.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfti.h
new file mode 100644
index 00000000000..b47dd08ab04
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/fixunssfti.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixunssfti implementation as
+/// shared::fixunssfti so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFTI_H
+#define LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/fixunssfti.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::fixunssfti;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FIXUNSSFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatdidf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatdidf.h
new file mode 100644
index 00000000000..6d5d54994cf
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatdidf.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
+/// This header exposes LLVM-libc's __floatdidf implementation as
+/// shared::floatdidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATDIDF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATDIDF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatdidf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatdidf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATDIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatdisf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatdisf.h
new file mode 100644
index 00000000000..b0f29485dc9
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatdisf.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
+/// This header exposes LLVM-libc's __floatdisf implementation as
+/// shared::floatdisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATDISF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATDISF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatdisf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatdisf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATDISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatsidf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatsidf.h
new file mode 100644
index 00000000000..f1d4708ac66
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatsidf.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
+/// This header exposes LLVM-libc's __floatsidf implementation as
+/// shared::floatsidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATSIDF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATSIDF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatsidf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatsidf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATSIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatsisf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatsisf.h
new file mode 100644
index 00000000000..0d318b26cd7
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatsisf.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
+/// This header exposes LLVM-libc's __floatsisf implementation as
+/// shared::floatsisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATSISF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATSISF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatsisf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatsisf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATSISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floattidf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floattidf.h
new file mode 100644
index 00000000000..4aaecb88d47
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floattidf.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floattidf implementation as
+/// shared::floattidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATTIDF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATTIDF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floattidf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floattidf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATTIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floattisf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floattisf.h
new file mode 100644
index 00000000000..d2667cbb6d1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floattisf.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floattisf implementation as
+/// shared::floattisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATTISF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATTISF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floattisf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floattisf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATTISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatundidf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatundidf.h
new file mode 100644
index 00000000000..34f78a01f6a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatundidf.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
+/// This header exposes LLVM-libc's __floatundidf implementation as
+/// shared::floatundidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATUNDIDF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATUNDIDF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatundidf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatundidf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATUNDIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatundisf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatundisf.h
new file mode 100644
index 00000000000..3905e4157f1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatundisf.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
+/// This header exposes LLVM-libc's __floatundisf implementation as
+/// shared::floatundisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATUNDISF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATUNDISF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatundisf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatundisf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATUNDISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatunsidf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatunsidf.h
new file mode 100644
index 00000000000..a1509fa1a6b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatunsidf.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
+/// This header exposes LLVM-libc's __floatunsidf implementation as
+/// shared::floatunsidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATUNSIDF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATUNSIDF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatunsidf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatunsidf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATUNSIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatunsisf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatunsisf.h
new file mode 100644
index 00000000000..c2190df469d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatunsisf.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
+/// This header exposes LLVM-libc's __floatunsisf implementation as
+/// shared::floatunsisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATUNSISF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATUNSISF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatunsisf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatunsisf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATUNSISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatuntidf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatuntidf.h
new file mode 100644
index 00000000000..4a3f1ebaa74
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatuntidf.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatuntidf implementation as
+/// shared::floatuntidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATUNTIDF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATUNTIDF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatuntidf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatuntidf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATUNTIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/floatuntisf.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatuntisf.h
new file mode 100644
index 00000000000..100924f91a9
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/floatuntisf.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatuntisf implementation as
+/// shared::floatuntisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_FLOATUNTISF_H
+#define LLVM_LIBC_SHARED_BUILTINS_FLOATUNTISF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/floatuntisf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::floatuntisf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_FLOATUNTISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/multf3.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/multf3.h
index cfc2964fd6a..802802f5dcb 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/builtins/multf3.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/multf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/multf3.h"
@@ -30,6 +30,6 @@ using builtins::multf3;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_MULTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/negdf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/negdf2.h
new file mode 100644
index 00000000000..3322730f39d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/negdf2.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
+/// This header exposes LLVM-libc's __negdf2 implementation as shared::negdf2 so
+/// that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_NEGDF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_NEGDF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/negdf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::negdf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_NEGDF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/negsf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/negsf2.h
new file mode 100644
index 00000000000..f8919935d8e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/negsf2.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
+/// This header exposes LLVM-libc's __negsf2 implementation as shared::negsf2 so
+/// that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_NEGSF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_NEGSF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/negsf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::negsf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_NEGSF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/subtf3.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/subtf3.h
index a7cecef8b04..2e201fd256c 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/builtins/subtf3.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/subtf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/builtins/subtf3.h"
@@ -30,6 +30,6 @@ using builtins::subtf3;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_BUILTINS_SUBTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/truncdfsf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/truncdfsf2.h
new file mode 100644
index 00000000000..7145b45c5ed
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/truncdfsf2.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
+/// This header exposes LLVM-libc's __truncdfsf2 implementation as
+/// shared::truncdfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCDFSF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCDFSF2_H
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/truncdfsf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::truncdfsf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCDFSF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfdf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfdf2.h
new file mode 100644
index 00000000000..68c4281150f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfdf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __trunctfdf2 implementation as
+/// shared::trunctfdf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFDF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFDF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/trunctfdf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::trunctfdf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFDF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfsf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfsf2.h
new file mode 100644
index 00000000000..3b6234d52ac
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfsf2.h
@@ -0,0 +1,35 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __trunctfsf2 implementation as
+/// shared::trunctfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFSF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFSF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/trunctfsf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::trunctfsf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFSF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfxf2.h b/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfxf2.h
new file mode 100644
index 00000000000..c9c4218b731
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/builtins/trunctfxf2.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __trunctfxf2 implementation as
+/// shared::trunctfxf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_BUILTINS_TRUNCTFXF2_H
+#define LLVM_LIBC_SHARED_BUILTINS_TRUNCTFXF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128) && \
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+
+#include "shared/libc_common.h"
+#include "src/__support/builtins/trunctfxf2.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using builtins::trunctfxf2;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128 &&
+ // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
+#endif // LLVM_LIBC_SHARED_BUILTINS_TRUNCTFXF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math.h b/deps/v8/third_party/llvm-libc/src/shared/math.h
index b86fcbc0abc..7b52cedf99c 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math.h
@@ -310,6 +310,7 @@
#include "math/ldexpf128.h"
#include "math/ldexpf16.h"
#include "math/ldexpl.h"
+#include "math/lgammaf.h"
#include "math/lgammaf16.h"
#include "math/llogb.h"
#include "math/llogbbf16.h"
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/atan2f128.h b/deps/v8/third_party/llvm-libc/src/shared/math/atan2f128.h
index d7aee40c695..7a7fab1c376 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/atan2f128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/atan2f128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_ATAN2F128_H
#define LLVM_LIBC_SHARED_MATH_ATAN2F128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/atan2f128.h"
@@ -24,6 +20,4 @@ using math::atan2f128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_ATAN2F128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/bf16addf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/bf16addf128.h
index 98b985de7a9..c2051076027 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/bf16addf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/bf16addf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/bf16addf128.h"
@@ -24,6 +24,6 @@ using math::bf16addf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_BF16ADDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/bf16divf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/bf16divf128.h
index 54a6d2703ab..e01ed30af68 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/bf16divf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/bf16divf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/bf16divf128.h"
@@ -24,6 +24,6 @@ using math::bf16divf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_BF16DIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/bf16fmaf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/bf16fmaf128.h
index c2bfeb849b8..4d867a1e929 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/bf16fmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/bf16fmaf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/bf16fmaf128.h"
@@ -24,6 +24,6 @@ using math::bf16fmaf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_BF16FMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/bf16mulf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/bf16mulf128.h
index a2754beecf6..1f52895f1fb 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/bf16mulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/bf16mulf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/bf16mulf128.h"
@@ -24,6 +24,6 @@ using math::bf16mulf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_BF16MULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/bf16subf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/bf16subf128.h
index 377b220d361..e073a713f01 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/bf16subf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/bf16subf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/bf16subf128.h"
@@ -24,6 +24,6 @@ using math::bf16subf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_BF16SUBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/canonicalizef128.h b/deps/v8/third_party/llvm-libc/src/shared/math/canonicalizef128.h
index dfc5f89afee..3e58766807f 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/canonicalizef128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/canonicalizef128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/canonicalizef128.h"
@@ -24,6 +24,6 @@ using math::canonicalizef128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_CANONICALIZEF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ceilf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ceilf128.h
index b9e6655393e..397c343fe6f 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ceilf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ceilf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_CEILF128_H
#define LLVM_LIBC_SHARED_MATH_CEILF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/ceilf128.h"
@@ -24,6 +20,4 @@ using math::ceilf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_CEILF128_H
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 24059a6fc97..1b23f61f910 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/copysignf128.h"
@@ -24,6 +24,6 @@ using math::copysignf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/daddf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/daddf128.h
index ae0fd22e6f8..5a1adbf1be6 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/daddf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/daddf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/daddf128.h"
@@ -24,6 +24,6 @@ using math::daddf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_DADDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ddivf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ddivf128.h
index 01c59481d8a..90248f4398a 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ddivf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ddivf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/ddivf128.h"
@@ -24,6 +24,6 @@ using math::ddivf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_DDIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/dfmaf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/dfmaf128.h
index 540de730b8f..3c302d45e5d 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/dfmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/dfmaf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/dfmaf128.h"
@@ -24,6 +24,6 @@ using math::dfmaf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_DFMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/dmulf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/dmulf128.h
index f255117689d..a32907a19bc 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/dmulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/dmulf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/dmulf128.h"
@@ -24,6 +24,6 @@ using math::dmulf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_DMULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/dsqrtf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/dsqrtf128.h
index 858d242e098..e32e4d133d4 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/dsqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/dsqrtf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/dsqrtf128.h"
@@ -24,6 +24,6 @@ using math::dsqrtf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_DSQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/dsubf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/dsubf128.h
index b08b941fb80..cc3df7bae8d 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/dsubf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/dsubf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/dsubf128.h"
@@ -24,6 +24,6 @@ using math::dsubf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_DSUBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/f16addf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/f16addf128.h
index 40321695a63..d691acaa7b3 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/f16addf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/f16addf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/f16addf128.h"
@@ -27,6 +27,6 @@ using math::f16addf128;
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_F16ADDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/f16divf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/f16divf128.h
index 60edfc07512..58b242e7d05 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/f16divf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/f16divf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/f16divf128.h"
@@ -26,7 +26,7 @@ using math::f16divf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LLVM_LIBC_SHARED_MATH_F16DIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/f16fmaf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/f16fmaf128.h
index c1bf1ab1359..d08ab31ab6b 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/f16fmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/f16fmaf128.h
@@ -12,7 +12,7 @@
#include "include/llvm-libc-macros/float16-macros.h"
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#ifdef LIBC_TYPES_HAS_FLOAT16
#include "shared/libc_common.h"
@@ -27,6 +27,6 @@ using math::f16fmaf128;
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_F16FMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/f16mulf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/f16mulf128.h
index f540675b97e..9d434eb5324 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/f16mulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/f16mulf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/f16mulf128.h"
@@ -26,7 +26,7 @@ using math::f16mulf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LLVM_LIBC_SHARED_MATH_F16MULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/f16sqrtf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/f16sqrtf128.h
index 9a8bb4d1c85..fc3db9e4401 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/f16sqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/f16sqrtf128.h
@@ -12,7 +12,7 @@
#include "include/llvm-libc-macros/float16-macros.h"
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#ifdef LIBC_TYPES_HAS_FLOAT16
#include "shared/libc_common.h"
@@ -27,6 +27,6 @@ using math::f16sqrtf128;
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_F16SQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/f16subf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/f16subf128.h
index 3e8466b37ae..4bdb8c3cba0 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/f16subf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/f16subf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/f16subf128.h"
@@ -26,7 +26,7 @@ using math::f16subf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LLVM_LIBC_SHARED_MATH_F16SUBF128_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 02b50364201..88e4d036868 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fabsf128.h"
@@ -24,6 +24,6 @@ using math::fabsf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/faddf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/faddf128.h
index bfd7fba1e50..88afd815551 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/faddf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/faddf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/faddf128.h"
@@ -24,6 +24,6 @@ using math::faddf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FADDF128_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 cfc41b70868..0cac3ce9a67 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fdimf128.h"
@@ -24,6 +24,6 @@ using math::fdimf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/fdivf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fdivf128.h
index cb96aebcd90..9b0acc612a2 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fdivf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fdivf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fdivf128.h"
@@ -24,6 +24,6 @@ using math::fdivf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FDIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ffmaf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ffmaf128.h
index b22e6a1f08d..ae2ad7bec76 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ffmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ffmaf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/ffmaf128.h"
@@ -24,6 +24,6 @@ using math::ffmaf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FFMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/floorf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/floorf128.h
index d7fb3220a81..a198c7e6102 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/floorf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/floorf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FLOORF128_H
#define LLVM_LIBC_SHARED_MATH_FLOORF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/floorf128.h"
@@ -24,6 +20,4 @@ using math::floorf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FLOORF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmaxf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmaxf128.h
index 157e003cdf6..8d506828703 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmaxf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmaxf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMAXF128_H
#define LLVM_LIBC_SHARED_MATH_FMAXF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fmaxf128.h"
@@ -24,6 +20,4 @@ using math::fmaxf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMAXF128_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 26fcc8e1db5..de2d21e4244 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fmaximum_mag_numf128.h"
@@ -24,6 +24,6 @@ using math::fmaximum_mag_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 4e409aa6ed0..93996933d10 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fmaximum_magf128.h"
@@ -24,6 +24,6 @@ using math::fmaximum_magf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 4bdd100dcc2..f26724d537a 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fmaximum_numf128.h"
@@ -24,6 +24,6 @@ using math::fmaximum_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 01e563c6eb6..12b53d74e4f 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fmaximumf128.h"
@@ -24,6 +24,6 @@ using math::fmaximumf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/fminf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fminf128.h
index 2970bc3fd1c..44d7c883784 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fminf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fminf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_FMINF128_H
#define LLVM_LIBC_SHARED_MATH_FMINF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/fminf128.h"
@@ -24,6 +20,4 @@ using math::fminf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_FMINF128_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 3a386602c9f..416a9c610bf 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fminimum_mag_numf128.h"
@@ -24,6 +24,6 @@ using math::fminimum_mag_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 13ebd6f9404..cf8794c5b16 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fminimum_magf128.h"
@@ -24,6 +24,6 @@ using math::fminimum_magf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 798040f12b3..dcacd52b18a 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fminimum_numf128.h"
@@ -24,6 +24,6 @@ using math::fminimum_numf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 9faa71c486c..1f31c05d73c 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fminimumf128.h"
@@ -24,6 +24,6 @@ using math::fminimumf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FMINIMUMF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmodf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmodf128.h
index 9d1c48477d7..00008935467 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmodf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmodf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fmodf128.h"
@@ -24,6 +24,6 @@ using math::fmodf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FMODF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fmulf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fmulf128.h
index 279d9a84d12..7004f2c94ac 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fmulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fmulf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fmulf128.h"
@@ -24,6 +24,6 @@ using math::fmulf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FMULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/frexpf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/frexpf128.h
index 6b922bd7312..13b48635a77 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/frexpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/frexpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/frexpf128.h"
@@ -24,6 +24,6 @@ using math::frexpf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FREXPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fromfpf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fromfpf128.h
index 4e4c55b6efc..a0e5085de11 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fromfpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fromfpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fromfpf128.h"
@@ -24,6 +24,6 @@ using math::fromfpf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FROMFPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fromfpxf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fromfpxf128.h
index dbdb89cc2d8..1f1aba101d1 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fromfpxf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fromfpxf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fromfpxf128.h"
@@ -24,6 +24,6 @@ using math::fromfpxf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FROMFPXF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fsqrtf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fsqrtf128.h
index 38f990e9a7e..aee925c7869 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fsqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fsqrtf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fsqrtf128.h"
@@ -24,6 +24,6 @@ using math::fsqrtf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
//
#endif // LLVM_LIBC_SHARED_MATH_FSQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/fsubf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/fsubf128.h
index b8cf101704d..1b5dbbeb3eb 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/fsubf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/fsubf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/fsubf128.h"
@@ -24,6 +24,6 @@ using math::fsubf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_FSUBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/getpayloadf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/getpayloadf128.h
index 92b87f7e823..1a3845e631a 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/getpayloadf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/getpayloadf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/getpayloadf128.h"
@@ -24,6 +24,6 @@ using math::getpayloadf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_GETPAYLOADF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ilogbf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ilogbf128.h
index 411449bd957..072cd1bbb77 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ilogbf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ilogbf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/ilogbf128.h"
@@ -24,6 +24,6 @@ using math::ilogbf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_ILOGBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/iscanonicalf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/iscanonicalf128.h
index f8494304a80..fa2a3ccf2ac 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/iscanonicalf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/iscanonicalf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_ISCANONICALF128_H
#define LLVM_LIBC_SHARED_MATH_ISCANONICALF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/iscanonicalf128.h"
@@ -24,6 +20,4 @@ using math::iscanonicalf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_ISCANONICALF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/isnanf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/isnanf128.h
index 3d9ee44b607..c5d812bb5a7 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/isnanf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/isnanf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_ISNANF128_H
#define LLVM_LIBC_SHARED_MATH_ISNANF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/isnanf128.h"
@@ -24,6 +20,4 @@ using math::isnanf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_ISNANF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/issignalingf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/issignalingf128.h
index 08c295c6406..cddc1e0d395 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/issignalingf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/issignalingf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_ISSIGNALINGF128_H
#define LLVM_LIBC_SHARED_MATH_ISSIGNALINGF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/issignalingf128.h"
@@ -24,6 +20,4 @@ using math::issignalingf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_ISSIGNALINGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ldexpf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ldexpf128.h
index d4066beb809..d221d716655 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ldexpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ldexpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/ldexpf128.h"
@@ -24,6 +24,6 @@ using math::ldexpf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_LDEXPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/lgammaf.h b/deps/v8/third_party/llvm-libc/src/shared/math/lgammaf.h
new file mode 100644
index 00000000000..6976109fe98
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/lgammaf.h
@@ -0,0 +1,23 @@
+//===-- Shared lgammaf function ---------------------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_MATH_LGAMMAF_H
+#define LLVM_LIBC_SHARED_MATH_LGAMMAF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/lgammaf.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::lgammaf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_LGAMMAF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/llogbf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/llogbf128.h
index 46529c8b07f..f6f945c372f 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/llogbf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/llogbf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/llogbf128.h"
@@ -24,6 +24,6 @@ using math::llogbf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_LLOGBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/llrintf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/llrintf128.h
index 02e4edc2357..1553aab6bfb 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/llrintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/llrintf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_LLRINTF128_H
#define LLVM_LIBC_SHARED_MATH_LLRINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/llrintf128.h"
@@ -24,6 +20,4 @@ using math::llrintf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_LLRINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/llroundf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/llroundf128.h
index 7e4654c4ff5..20af856951e 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/llroundf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/llroundf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_LLROUNDF128_H
#define LLVM_LIBC_SHARED_MATH_LLROUNDF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/llroundf128.h"
@@ -24,6 +20,4 @@ using math::llroundf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_LLROUNDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/logbf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/logbf128.h
index aa2807fc707..95c37fe88b8 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/logbf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/logbf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/logbf128.h"
@@ -24,6 +24,6 @@ using math::logbf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_LOGBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/lrintf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/lrintf128.h
index 86fc0b3b081..f6b87d205c6 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/lrintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/lrintf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_LRINTF128_H
#define LLVM_LIBC_SHARED_MATH_LRINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/lrintf128.h"
@@ -24,6 +20,4 @@ using math::lrintf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_LRINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/lroundf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/lroundf128.h
index 2fe4b0b84b2..a5e445fb08a 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/lroundf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/lroundf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_LROUNDF128_H
#define LLVM_LIBC_SHARED_MATH_LROUNDF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/lroundf128.h"
@@ -24,6 +20,4 @@ using math::lroundf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_LROUNDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/modff128.h b/deps/v8/third_party/llvm-libc/src/shared/math/modff128.h
index bbc6b8e4d09..480dc16d4fe 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/modff128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/modff128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/modff128.h"
@@ -24,6 +24,6 @@ using math::modff128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_MODFF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/nanf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/nanf128.h
index 60ce05a3d5e..313b6ed6234 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/nanf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/nanf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/nanf128.h"
@@ -24,6 +24,6 @@ using math::nanf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_NANF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/nearbyintf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/nearbyintf128.h
index 824c5c98baf..00d842b9136 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/nearbyintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/nearbyintf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_NEARBYINTF128_H
#define LLVM_LIBC_SHARED_MATH_NEARBYINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/nearbyintf128.h"
@@ -24,6 +20,4 @@ using math::nearbyintf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_NEARBYINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/nextafterf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/nextafterf128.h
index e25c2ea1fee..95bece2ba87 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/nextafterf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/nextafterf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/nextafterf128.h"
@@ -24,6 +24,6 @@ using math::nextafterf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_NEXTAFTERF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/nextdownf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/nextdownf128.h
index 1632717defc..958d1f2cc52 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/nextdownf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/nextdownf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/nextdownf128.h"
@@ -24,6 +24,6 @@ using math::nextdownf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_NEXTDOWNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/nextupf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/nextupf128.h
index 68756071c1d..4d8312efa93 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/nextupf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/nextupf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/nextupf128.h"
@@ -24,6 +24,6 @@ using math::nextupf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_NEXTUPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/remainderf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/remainderf128.h
index 97ff5e2eaf4..b1d02de64c2 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/remainderf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/remainderf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/remainderf128.h"
@@ -24,6 +24,6 @@ using math::remainderf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_REMAINDERF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/remquof128.h b/deps/v8/third_party/llvm-libc/src/shared/math/remquof128.h
index d2054c266fc..4331c02bb99 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/remquof128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/remquof128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/remquof128.h"
@@ -24,6 +24,6 @@ using math::remquof128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_REMQUOF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/rintf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/rintf128.h
index 13e2bf502c3..3714cfa28bc 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/rintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/rintf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_RINTF128_H
#define LLVM_LIBC_SHARED_MATH_RINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/rintf128.h"
@@ -24,6 +20,4 @@ using math::rintf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_RINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/roundevenf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/roundevenf128.h
index 5d47fd5d267..f3b8513c869 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/roundevenf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/roundevenf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_ROUNDEVENF128_H
#define LLVM_LIBC_SHARED_MATH_ROUNDEVENF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/roundevenf128.h"
@@ -24,6 +20,4 @@ using math::roundevenf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_ROUNDEVENF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/roundf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/roundf128.h
index ea0fd23fce1..44eb2854842 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/roundf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/roundf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_ROUNDF128_H
#define LLVM_LIBC_SHARED_MATH_ROUNDF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/roundf128.h"
@@ -24,6 +20,4 @@ using math::roundf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_ROUNDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/scalblnf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/scalblnf128.h
index 088c6b39e97..dfb15bed117 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/scalblnf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/scalblnf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/scalblnf128.h"
@@ -24,6 +24,6 @@ using math::scalblnf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_SCALBLNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/scalbnf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/scalbnf128.h
index 5b232910ff5..74c8defc0e6 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/scalbnf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/scalbnf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/scalbnf128.h"
@@ -24,6 +24,6 @@ using math::scalbnf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_SCALBNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadf128.h
index 64cd601536e..a1f889e89ed 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/setpayloadf128.h"
@@ -24,6 +24,6 @@ using math::setpayloadf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_SETPAYLOADF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadsigf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadsigf128.h
index 29b47b181d1..3169b610ccb 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadsigf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/setpayloadsigf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/setpayloadsigf128.h"
@@ -24,6 +24,6 @@ using math::setpayloadsigf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_SETPAYLOADSIGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/sqrtf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/sqrtf128.h
index 609b8921ab3..39120396012 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/sqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/sqrtf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_SQRTF128_H
#define LLVM_LIBC_SHARED_MATH_SQRTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/sqrtf128.h"
@@ -24,6 +20,4 @@ using math::sqrtf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_SQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/static_rounding/expf.h b/deps/v8/third_party/llvm-libc/src/shared/math/static_rounding/expf.h
new file mode 100644
index 00000000000..0f4aeef673b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/static_rounding/expf.h
@@ -0,0 +1,28 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 shared statically-rounded expf(x) function
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_MATH_STATIC_ROUNDING_EXPF_H
+#define LLVM_LIBC_SHARED_MATH_STATIC_ROUNDING_EXPF_H
+
+#include "shared/libc_common.h"
+#include "src/__support/math/expf_integer_eval.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace shared {
+
+using math::static_rounding::expf;
+
+} // namespace shared
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SHARED_MATH_STATIC_ROUNDING_EXPF_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/totalorderf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/totalorderf128.h
index fe1d1d4dcbc..8427aa0df98 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/totalorderf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/totalorderf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/totalorderf128.h"
@@ -24,6 +24,6 @@ using math::totalorderf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_TOTALORDERF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/totalordermagf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/totalordermagf128.h
index c8f541d7c72..663a3c4dc9f 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/totalordermagf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/totalordermagf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/totalordermagf128.h"
@@ -24,6 +24,6 @@ using math::totalordermagf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_TOTALORDERMAGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/truncf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/truncf128.h
index 7694a8e4955..e9de5418e0b 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/truncf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/truncf128.h
@@ -9,10 +9,6 @@
#ifndef LLVM_LIBC_SHARED_MATH_TRUNCF128_H
#define LLVM_LIBC_SHARED_MATH_TRUNCF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "shared/libc_common.h"
#include "src/__support/math/truncf128.h"
@@ -24,6 +20,4 @@ using math::truncf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SHARED_MATH_TRUNCF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpf128.h
index f2438a45878..91195943c1e 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/ufromfpf128.h"
@@ -24,6 +24,6 @@ using math::ufromfpf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_UFROMFPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpxf128.h b/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpxf128.h
index 99bc8f995ae..4be803c6087 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpxf128.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/math/ufromfpxf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "shared/libc_common.h"
#include "src/__support/math/ufromfpxf128.h"
@@ -24,6 +24,6 @@ using math::ufromfpxf128;
} // namespace shared
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SHARED_MATH_UFROMFPXF128_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 5bc518ab97a..bd55bc34870 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/rpc.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/rpc.h
@@ -74,8 +74,8 @@ static_assert(sizeof(Buffer) == 64, "Buffer size mismatch");
/// A target specific struct containing a doorbell to wake the server-side
/// thread.
struct alignas(64) Doorbell {
- uint64_t *value;
- uint64_t *mailbox;
+ RPC_GLOBAL uint64_t *value;
+ RPC_GLOBAL uint64_t *mailbox;
uint32_t event_id;
};
@@ -112,26 +112,26 @@ template <bool Invert> struct Process {
RPC_ATTRS ~Process() = default;
const uint32_t port_count = 0;
- Doorbell *const doorbell = nullptr;
- const uint32_t *const inbox = nullptr;
- uint32_t *const outbox = nullptr;
- Header *const header = nullptr;
- Buffer *const packet = nullptr;
+ RPC_GLOBAL Doorbell *const doorbell = nullptr;
+ RPC_GLOBAL const uint32_t *const inbox = nullptr;
+ RPC_GLOBAL uint32_t *const outbox = nullptr;
+ RPC_GLOBAL Header *const header = nullptr;
+ RPC_GLOBAL Buffer *const packet = nullptr;
static constexpr uint64_t NUM_BITS_IN_WORD = sizeof(uint32_t) * 8;
uint32_t lock[MAX_PORT_COUNT / NUM_BITS_IN_WORD] = {0};
+ // The buffer is supplied by the host unqualified, so the casts below are
+ // C-style as they need to change the address space.
RPC_ATTRS Process(uint32_t port_count, void *buffer)
- : port_count(port_count), doorbell(reinterpret_cast<Doorbell *>(
- advance(buffer, doorbell_offset()))),
- inbox(reinterpret_cast<uint32_t *>(
- advance(buffer, inbox_offset(port_count)))),
- outbox(reinterpret_cast<uint32_t *>(
- advance(buffer, outbox_offset(port_count)))),
- header(reinterpret_cast<Header *>(
- advance(buffer, header_offset(port_count)))),
- packet(reinterpret_cast<Buffer *>(
- advance(buffer, buffer_offset(port_count)))) {}
+ : port_count(port_count),
+ doorbell((RPC_GLOBAL Doorbell *)advance(buffer, doorbell_offset())),
+ inbox((RPC_GLOBAL uint32_t *)advance(buffer, inbox_offset(port_count))),
+ outbox(
+ (RPC_GLOBAL uint32_t *)advance(buffer, outbox_offset(port_count))),
+ header((RPC_GLOBAL Header *)advance(buffer, header_offset(port_count))),
+ packet(
+ (RPC_GLOBAL Buffer *)advance(buffer, buffer_offset(port_count))) {}
/// Allocate a memory buffer sufficient to store the following equivalent
/// representation in memory.
@@ -156,8 +156,10 @@ template <bool Invert> struct Process {
uint32_t event_id = rpc::broadcast_value(lane_mask, doorbell->event_id);
if (rpc::is_first_lane(lane_mask)) {
+ // The interrupt is optional and is skipped if there is no mailbox.
if (!__scoped_atomic_fetch_add(doorbell->value, 1UL, __ATOMIC_RELAXED,
- __MEMORY_SCOPE_SYSTEM)) {
+ __MEMORY_SCOPE_SYSTEM) &&
+ doorbell->mailbox) {
__scoped_atomic_store_n(doorbell->mailbox,
static_cast<uint64_t>(doorbell->event_id),
__ATOMIC_RELAXED, __MEMORY_SCOPE_SYSTEM);
@@ -223,7 +225,7 @@ template <bool Invert> struct Process {
/// The packet is a linearly allocated array of buffers used to communicate
/// with the other process. This function returns the appropriate slot in this
/// array such that the process can operate on an entire warp or wavefront.
- RPC_ATTRS Buffer *get_packet(uint32_t index, uint32_t lane_size) {
+ RPC_ATTRS RPC_GLOBAL Buffer *get_packet(uint32_t index, uint32_t lane_size) {
return &packet[index * lane_size];
}
@@ -354,7 +356,7 @@ template <bool Invert> struct Process {
/// Invokes a function across every active buffer across the total lane size.
template <typename F>
RPC_ATTRS static void invoke_rpc(F &&fn, uint32_t lane_size, uint64_t lane_mask,
- Buffer *slot) {
+ RPC_GLOBAL Buffer *slot) {
if constexpr (is_process_gpu()) {
fn(&slot[rpc::get_lane_id()], rpc::get_lane_id());
} else {
@@ -525,7 +527,7 @@ template <bool T>
template <typename W>
RPC_ATTRS void Port<T>::recv_and_send(W work) {
recv(work);
- send([](Buffer *, uint32_t) { /* no-op */ });
+ send([](RPC_GLOBAL Buffer *, uint32_t) { /* no-op */ });
}
/// Helper routine to simplify the interface when sending from the GPU using
@@ -541,28 +543,28 @@ RPC_ATTRS void Port<T>::send_n(const void *src, uint64_t size) {
/// multiples of the packet length.
template <bool T>
RPC_ATTRS void Port<T>::send_n(const void *const *src, uint64_t *size) {
+ constexpr uint64_t BUFFER_SIZE = sizeof(Buffer::data);
+ constexpr uint64_t FIRST_CHUNK = BUFFER_SIZE - sizeof(uint64_t);
uint64_t num_sends = 0;
- send([&](Buffer *buffer, uint32_t id) {
+ send([&](RPC_GLOBAL Buffer *buffer, uint32_t id) {
reinterpret_cast<uint64_t *>(buffer->data)[0] = lane_value(size, id);
num_sends = is_process_gpu() ? lane_value(size, id)
: rpc::max(lane_value(size, id), num_sends);
uint64_t len =
- lane_value(size, id) > sizeof(Buffer::data) - sizeof(uint64_t)
- ? sizeof(Buffer::data) - sizeof(uint64_t)
- : lane_value(size, id);
+ lane_value(size, id) > FIRST_CHUNK ? FIRST_CHUNK : lane_value(size, id);
rpc_memcpy(&buffer->data[1], lane_value(src, id), len);
});
- uint64_t idx = sizeof(Buffer::data) - sizeof(uint64_t);
+ uint64_t idx = FIRST_CHUNK;
uint64_t mask = process.header[index].mask;
- while (rpc::ballot(mask, idx < num_sends)) {
- send([=](Buffer *buffer, uint32_t id) {
- uint64_t len = lane_value(size, id) - idx > sizeof(Buffer::data)
- ? sizeof(Buffer::data)
+ while (rpc::ballot(mask, idx < num_sends && num_sends > FIRST_CHUNK)) {
+ send([=](RPC_GLOBAL Buffer *buffer, uint32_t id) {
+ uint64_t len = lane_value(size, id) - idx > BUFFER_SIZE
+ ? BUFFER_SIZE
: lane_value(size, id) - idx;
if (idx < lane_value(size, id))
rpc_memcpy(buffer->data, advance(lane_value(src, id), idx), len);
});
- idx += sizeof(Buffer::data);
+ idx += BUFFER_SIZE;
}
}
@@ -572,30 +574,30 @@ RPC_ATTRS void Port<T>::send_n(const void *const *src, uint64_t *size) {
template <bool T>
template <typename A>
RPC_ATTRS void Port<T>::recv_n(void **dst, uint64_t *size, A &&alloc) {
+ constexpr uint64_t BUFFER_SIZE = sizeof(Buffer::data);
+ constexpr uint64_t FIRST_CHUNK = BUFFER_SIZE - sizeof(uint64_t);
uint64_t num_recvs = 0;
- recv([&](Buffer *buffer, uint32_t id) {
+ recv([&](RPC_GLOBAL Buffer *buffer, uint32_t id) {
lane_value(size, id) = reinterpret_cast<uint64_t *>(buffer->data)[0];
lane_value(dst, id) =
reinterpret_cast<uint8_t *>(alloc(lane_value(size, id)));
num_recvs = is_process_gpu() ? lane_value(size, id)
: rpc::max(lane_value(size, id), num_recvs);
uint64_t len =
- lane_value(size, id) > sizeof(Buffer::data) - sizeof(uint64_t)
- ? sizeof(Buffer::data) - sizeof(uint64_t)
- : lane_value(size, id);
+ lane_value(size, id) > FIRST_CHUNK ? FIRST_CHUNK : lane_value(size, id);
rpc_memcpy(lane_value(dst, id), &buffer->data[1], len);
});
- uint64_t idx = sizeof(Buffer::data) - sizeof(uint64_t);
+ uint64_t idx = FIRST_CHUNK;
uint64_t mask = process.header[index].mask;
- while (rpc::ballot(mask, idx < num_recvs)) {
- recv([=](Buffer *buffer, uint32_t id) {
- uint64_t len = lane_value(size, id) - idx > sizeof(Buffer::data)
- ? sizeof(Buffer::data)
+ while (rpc::ballot(mask, idx < num_recvs && num_recvs > FIRST_CHUNK)) {
+ recv([=](RPC_GLOBAL Buffer *buffer, uint32_t id) {
+ uint64_t len = lane_value(size, id) - idx > BUFFER_SIZE
+ ? BUFFER_SIZE
: lane_value(size, id) - idx;
if (idx < lane_value(size, id))
rpc_memcpy(advance(lane_value(dst, id), idx), buffer->data, len);
});
- idx += sizeof(Buffer::data);
+ idx += BUFFER_SIZE;
}
}
@@ -605,7 +607,7 @@ template <typename Ty>
RPC_ATTRS void Port<T>::send_n(const Ty *src) {
for (uint64_t idx = 0; idx < sizeof(Ty); idx += sizeof(Buffer::data)) {
const uint64_t bytes = rpc::min(sizeof(Ty) - idx, sizeof(Buffer::data));
- send([&](Buffer *buffer, uint32_t id) {
+ send([&](RPC_GLOBAL Buffer *buffer, uint32_t id) {
rpc_memcpy(buffer->data, advance(&lane_value(src, id), idx), bytes);
});
}
@@ -617,7 +619,7 @@ template <typename Ty>
RPC_ATTRS void Port<T>::recv_n(Ty *dst) {
for (uint64_t idx = 0; idx < sizeof(Ty); idx += sizeof(Buffer::data)) {
const uint64_t bytes = rpc::min(sizeof(Ty) - idx, sizeof(Buffer::data));
- recv([&](Buffer *buffer, uint32_t id) {
+ recv([&](RPC_GLOBAL Buffer *buffer, uint32_t id) {
rpc_memcpy(advance(&lane_value(dst, id), idx), buffer->data, bytes);
});
}
diff --git a/deps/v8/third_party/llvm-libc/src/shared/rpc_util.h b/deps/v8/third_party/llvm-libc/src/shared/rpc_util.h
index 09a97c63b56..5fabeb8069f 100644
--- a/deps/v8/third_party/llvm-libc/src/shared/rpc_util.h
+++ b/deps/v8/third_party/llvm-libc/src/shared/rpc_util.h
@@ -32,6 +32,14 @@
#endif
#endif
+#ifndef RPC_GLOBAL
+#ifdef RPC_TARGET_IS_GPU
+#define RPC_GLOBAL __gpu_global
+#else
+#define RPC_GLOBAL
+#endif
+#endif
+
namespace rpc {
template <typename T> struct type_identity {
@@ -452,19 +460,21 @@ template <typename T, typename U> RPC_ATTRS T *advance(T *ptr, U bytes) {
}
/// Wrapper around the optimal memory copy implementation for the target.
-RPC_ATTRS void rpc_memcpy(void *dst, const void *src, uint64_t count) {
+template <typename D, typename S>
+RPC_ATTRS void rpc_memcpy(D *dst, S *src, uint64_t count) {
#if __has_builtin(__builtin_memcpy)
if (count)
__builtin_memcpy(dst, src, count);
#else
+ // The casts are C-style as they may need to change the address space.
for (uint64_t i = 0; i < count; ++i)
- static_cast<uint8_t *>(dst)[i] = static_cast<const uint8_t *>(src)[i];
+ ((uint8_t *)dst)[i] = ((const uint8_t *)src)[i];
#endif
}
/// Minimal string length function.
-RPC_ATTRS constexpr uint64_t string_length(const char *s) {
- const char *end = s;
+template <typename T> RPC_ATTRS constexpr uint64_t string_length(const T *s) {
+ const T *end = s;
for (; *end != '\0'; ++end)
;
return static_cast<uint64_t>(end - s + 1);
diff --git a/deps/v8/third_party/llvm-libc/src/shared/static_rounding_math.h b/deps/v8/third_party/llvm-libc/src/shared/static_rounding_math.h
new file mode 100644
index 00000000000..5488354a9b5
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/shared/static_rounding_math.h
@@ -0,0 +1,20 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 statically rounded implementations of math functions
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SHARED_STATIC_ROUNDING_MATH_H
+#define LLVM_LIBC_SHARED_STATIC_ROUNDING_MATH_H
+
+#include "shared/libc_common.h"
+#include "shared/math/static_rounding/expf.h"
+
+#endif // LLVM_LIBC_SHARED_STATIC_ROUNDING_MATH_H
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 12761e6a524..897a4c63e60 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
@@ -51,12 +51,28 @@ add_object_library(
.freelist
)
+add_header_library(
+ tlsf_table
+ HDRS
+ tlsf_table.h
+ DEPENDS
+ .block
+ .freelist
+ libc.src.__support.CPP.array
+ libc.src.__support.CPP.bit
+ libc.src.__support.CPP.limits
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.math_extras
+)
+
add_header_library(
freestore
HDRS
freestore.h
DEPENDS
.freetrie
+ .tlsf_table
)
libc_set_definition(libc_freelist_malloc_size "LIBC_FREELIST_MALLOC_SIZE=${LIBC_CONF_FREELIST_MALLOC_BUFFER_SIZE}")
@@ -101,9 +117,11 @@ add_header_library(
macros/properties/compiler.h
macros/attributes.h
macros/config.h
+ macros/hardening.h
DEPENDS
libc.hdr.stdint_proxy
libc.src.__support.CPP.bit
+ libc.src.__support.macros.hardening
)
add_header_library(
@@ -162,10 +180,10 @@ list(APPEND wctype_utils_deps
libc.hdr.types.wchar_t
)
-if ("${LIBC_CONF_WCTYPE_MODE}" STREQUAL "LIBC_WCTYPE_MODE_UTF8")
+if("${LIBC_CONF_WCTYPE_MODE}" STREQUAL "LIBC_WCTYPE_MODE_UTF8")
list(APPEND wctype_utils_deps
- libc.src.__support.wctype.wctype_classification_utils
- libc.src.__support.wctype.wctype_conversion_utils
+ libc.src.__support.wctype.wctype_classification_utils
+ libc.src.__support.wctype.wctype_conversion_utils
)
endif()
@@ -329,6 +347,8 @@ add_header_library(
DEPENDS
.libc_assert
libc.src.__support.CPP.array
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.macros.config
libc.src.string.memory_utils.inline_memset
)
@@ -375,6 +395,15 @@ add_header_library(
libc.src.__support.macros.config
)
+add_header_library(
+ frac64
+ HDRS
+ frac64.h
+ DEPENDS
+ .big_int
+ libc.src.__support.macros.config
+)
+
add_header_library(
uint128
HDRS
@@ -389,6 +418,8 @@ if(LIBC_COPT_USE_C_ASSERT OR NOT LLVM_LIBC_FULL_BUILD)
libc_assert
HDRS
libc_assert.h
+ DEPENDS
+ libc.src.__support.macros.hardening
)
else()
add_header_library(
@@ -399,6 +430,7 @@ else()
.integer_to_string
libc.src.__support.OSUtil.osutil
libc.src.__support.macros.optimization
+ libc.src.__support.macros.hardening
)
endif()
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 49cb07f3291..8256caebfe7 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
@@ -84,14 +84,18 @@ add_header_library(
HDRS
string.h
DEPENDS
+ .algorithm
.string_view
libc.hdr.func.free
libc.hdr.func.malloc
libc.hdr.func.realloc
+ libc.hdr.stdint_proxy
libc.src.__support.common
libc.src.__support.integer_to_string
+ libc.src.__support.libc_assert
libc.src.__support.macros.null_check
libc.src.string.memory_utils.inline_memcpy
+ libc.src.string.memory_utils.inline_memmove
libc.src.string.memory_utils.inline_memset
libc.src.string.string_utils
)
@@ -110,6 +114,9 @@ add_header_library(
optional
HDRS
optional.h
+ DEPENDS
+ .type_traits
+ .utility
)
add_header_library(
@@ -239,6 +246,7 @@ add_header_library(
simd.h
DEPENDS
libc.src.__support.macros.optimization
+ libc.src.__support.macros.properties.cpu_features
.utility
.tuple
)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/expected.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/expected.h
index d416422ba2b..165ac72002d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/expected.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/expected.h
@@ -40,6 +40,7 @@ template <class T, class E> class expected {
bool is_expected;
public:
+ LIBC_INLINE constexpr expected() : exp(), is_expected(true) {}
LIBC_INLINE constexpr expected(T exp) : exp(exp), is_expected(true) {}
LIBC_INLINE constexpr expected(unexpected<E> unexp)
: unexp(unexp.error()), is_expected(false) {}
@@ -59,6 +60,29 @@ public:
LIBC_INLINE constexpr const T *operator->() const { return &exp; }
};
+template <class E> class expected<void, E> {
+ union {
+ char dummy;
+ E unexp;
+ };
+ bool is_expected;
+
+public:
+ LIBC_INLINE constexpr expected() : dummy(), is_expected(true) {}
+ LIBC_INLINE constexpr expected(unexpected<E> unexp)
+ : unexp(unexp.error()), is_expected(false) {}
+
+ LIBC_INLINE constexpr bool has_value() const { return is_expected; }
+
+ LIBC_INLINE constexpr void value() const {}
+ LIBC_INLINE constexpr E &error() { return unexp; }
+ LIBC_INLINE constexpr const E &error() const { return unexp; }
+
+ LIBC_INLINE constexpr explicit operator bool() const { return is_expected; }
+
+ LIBC_INLINE constexpr void operator*() const {}
+};
+
} // namespace cpp
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/optional.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/optional.h
index aed2269db1b..3b3153f6f19 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/optional.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/optional.h
@@ -131,6 +131,17 @@ public:
LIBC_INLINE constexpr T &&operator*() && {
return move(storage.stored_value);
}
+
+ template <typename U>
+ LIBC_INLINE constexpr T value_or(U &&default_value) const & {
+ return has_value() ? storage.stored_value
+ : static_cast<T>(forward<U>(default_value));
+ }
+
+ template <typename U> LIBC_INLINE constexpr T value_or(U &&default_value) && {
+ return has_value() ? move(storage.stored_value)
+ : static_cast<T>(forward<U>(default_value));
+ }
};
} // namespace cpp
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/simd.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/simd.h
index 93fecc71d36..0a7f1eefbd4 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/simd.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/simd.h
@@ -22,6 +22,7 @@
#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 <stddef.h>
@@ -208,9 +209,22 @@ LIBC_INLINE constexpr static simd<T, N> abs(simd<T, N> x) {
return __builtin_elementwise_abs(x);
}
template <typename T, size_t N>
-LIBC_INLINE constexpr static simd<T, N> fma(simd<T, N> x, simd<T, N> y,
- simd<T, N> z) {
- return __builtin_elementwise_fma(x, y, z);
+LIBC_INLINE constexpr static simd<T, N> multiply_add(simd<T, N> x, simd<T, N> y,
+ simd<T, N> z) {
+#if __has_builtin(__builtin_elementwise_fma)
+#ifdef LIBC_TARGET_CPU_HAS_FMA_FLOAT
+ if constexpr (cpp::is_same_v<T, float>)
+ return __builtin_elementwise_fma(x, y, z);
+#endif // LIBC_TARGET_CPU_HAS_FMA_FLOAT
+
+#ifdef LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+ if constexpr (cpp::is_same_v<T, double>)
+ return __builtin_elementwise_fma(x, y, z);
+#endif // LIBC_TARGET_CPU_HAS_FMA_DOUBLE
+#endif // __has_builtin(__builtin_elementwise_fma)
+
+ simd<T, N> mul = x * y;
+ return mul + z;
}
template <typename T, size_t N>
LIBC_INLINE constexpr static simd<T, N> ceil(simd<T, N> x) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/string.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/string.h
index 0de0e11a583..a82ab45487d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/string.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/string.h
@@ -12,11 +12,15 @@
#include "hdr/func/free.h"
#include "hdr/func/malloc.h"
#include "hdr/func/realloc.h"
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/algorithm.h"
#include "src/__support/CPP/string_view.h"
#include "src/__support/integer_to_string.h" // IntegerToString
+#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/null_check.h"
#include "src/string/memory_utils/inline_memcpy.h"
+#include "src/string/memory_utils/inline_memmove.h"
#include "src/string/memory_utils/inline_memset.h"
#include "src/string/string_utils.h" // string_length
@@ -33,6 +37,19 @@ char *realloc_or_die(char *ptr, size_t size) {
return reinterpret_cast<char *>(new_ptr);
}
+char *malloc_or_die(size_t size) { return realloc_or_die(nullptr, size); }
+
+// Returns whether the address of a is less than or equal to the address of b.
+LIBC_INLINE bool ptr_le(const char *a, const char *b) {
+ return reinterpret_cast<uintptr_t>(a) <= reinterpret_cast<uintptr_t>(b);
+}
+
+// Whether the memory spanned by a and b have any overlap.
+LIBC_INLINE bool memory_overlaps(cpp::string_view a, cpp::string_view b) {
+ return !(ptr_le(b.data() + b.size(), a.data()) ||
+ ptr_le(a.data() + a.size(), b.data()));
+}
+
} // namespace
// This class mimics std::string but does not intend to be a full fledged
@@ -67,6 +84,50 @@ private:
buffer_[size_] = NULL_CHARACTER;
}
+ // Assigns the new buffer, capacity, and size to this string,
+ // freeing the current internal buffer.
+ void move_assign_from_buffer(char *new_buffer, size_t new_capacity,
+ size_t new_size) {
+ if (buffer_ != get_empty_string())
+ ::free(buffer_);
+
+ buffer_ = new_buffer;
+ size_ = new_size;
+ capacity_ = new_capacity;
+ }
+
+ // The size of the buffer that should be allocated for requested_capacity.
+ LIBC_INLINE static size_t amortized_capacity(size_t requested_capacity) {
+ size_t new_capacity = requested_capacity + 1; // +1 for the terminating '\0'
+
+ // We extend the capacity to amortize buffer_ reallocations.
+ // We choose to augment the value by 11 / 8, this is about +40% and division
+ // by 8 is cheap. We guard the extension so the operation doesn't overflow.
+ if (new_capacity < SIZE_MAX / 11)
+ new_capacity = new_capacity * 11 / 8;
+ return new_capacity;
+ }
+
+ // Replaces the current buffer with a new larger one that is the concatenation
+ // the first keep_prefix_size bytes of the current string, new_data, and the
+ // last keep_suffix_size bytes of the current string.
+ LIBC_INLINE void grow_and_replace(size_t keep_prefix_size,
+ cpp::string_view new_data,
+ size_t keep_suffix_size) {
+ size_t new_size = keep_prefix_size + new_data.size() + keep_suffix_size;
+ size_t new_capacity = amortized_capacity(new_size);
+ char *new_buffer = malloc_or_die(new_capacity);
+
+ inline_memcpy(new_buffer, buffer_, keep_prefix_size);
+ inline_memcpy(new_buffer + keep_prefix_size, new_data.data(),
+ new_data.size());
+ inline_memcpy(new_buffer + keep_prefix_size + new_data.size(),
+ buffer_ + size_ - keep_suffix_size, keep_suffix_size);
+
+ move_assign_from_buffer(new_buffer, new_capacity, new_size);
+ set_size_and_add_null_character(new_size);
+ }
+
public:
LIBC_INLINE constexpr string() {}
LIBC_INLINE string(const string &other) { this->operator+=(other); }
@@ -78,7 +139,7 @@ public:
resize(count);
inline_memcpy(buffer_, cstr, count);
}
- LIBC_INLINE string(const string_view &view)
+ LIBC_INLINE explicit string(const string_view &view)
: string(view.data(), view.size()) {}
LIBC_INLINE string(const char *cstr)
: string(cstr, ::LIBC_NAMESPACE::internal::string_length(cstr)) {}
@@ -88,31 +149,40 @@ public:
inline_memset((void *)buffer_, static_cast<uint8_t>(value), size_);
}
- LIBC_INLINE string &operator=(const string &other) {
- resize(0);
- return (*this) += other;
+ LIBC_INLINE string &assign(cpp::string_view view) {
+ if (view.empty()) {
+ set_size_and_add_null_character(0);
+ return *this;
+ }
+
+ if (capacity() < view.size()) {
+ grow_and_replace(/* keep_prefix_size= */ 0, view,
+ /* keep_suffix_size= */ 0);
+ return *this;
+ }
+
+ inline_memmove(buffer_, view.data(), view.size());
+ set_size_and_add_null_character(view.size());
+ return *this;
}
+ LIBC_INLINE string &operator=(const string &other) { return assign(other); }
+
LIBC_INLINE string &operator=(char other) {
- resize(0);
- return (*this) += other;
+ return assign(string_view(&other, 1));
}
+ LIBC_INLINE string &operator=(string_view view) { return assign(view); }
+
LIBC_INLINE string &operator=(string &&other) {
- if (buffer_ != get_empty_string())
- ::free(buffer_);
+ if (this == &other)
+ return *this;
- buffer_ = other.buffer_;
- size_ = other.size_;
- capacity_ = other.capacity_;
+ move_assign_from_buffer(other.buffer_, other.capacity_, other.size_);
other.reset_no_deallocate();
return *this;
}
- LIBC_INLINE string &operator=(const string_view &view) {
- return *this = string(view);
- }
-
LIBC_INLINE ~string() {
if (buffer_ != get_empty_string())
::free(buffer_);
@@ -155,18 +225,12 @@ public:
}
LIBC_INLINE void reserve(size_t new_cap) {
- size_t allocation_size = new_cap + 1; // +1 for terminating '\0'
- if (allocation_size <= capacity_)
+ if (new_cap <= capacity())
return;
-
- // We extend the capacity to amortize buffer_ reallocations.
- // We choose to augment the value by 11 / 8, this is about +40% and division
- // by 8 is cheap. We guard the extension so the operation doesn't overflow.
- if (allocation_size < SIZE_MAX / 11)
- allocation_size = allocation_size * 11 / 8;
+ size_t allocation_size = amortized_capacity(new_cap);
if (buffer_ == get_empty_string()) {
- buffer_ = realloc_or_die(nullptr, allocation_size);
+ buffer_ = malloc_or_die(allocation_size);
buffer_[0] = NULL_CHARACTER;
} else {
buffer_ = realloc_or_die(buffer_, allocation_size);
@@ -197,7 +261,7 @@ public:
if (buffer_ == get_empty_string()) {
// Ensure the buffer is heap allocated,
// so that it may later be passed to `free`.
- char *res = realloc_or_die(nullptr, 1);
+ char *res = malloc_or_die(1);
res[0] = '\0';
return res;
}
@@ -207,18 +271,58 @@ public:
return res;
}
- LIBC_INLINE string &operator+=(const string &rhs) {
- const size_t new_size = size_ + rhs.size();
- reserve(new_size);
- inline_memcpy(buffer_ + size_, rhs.data(), rhs.size());
+ LIBC_INLINE string &append(cpp::string_view view) {
+ if (view.empty())
+ return *this;
+
+ if (capacity() - size_ < view.size()) {
+ grow_and_replace(/* keep_prefix_size= */ size_, view,
+ /* keep_suffix_size= */ 0);
+ return *this;
+ }
+
+ size_t new_size = size_ + view.size();
+ inline_memcpy(buffer_ + size_, view.data(), view.size());
set_size_and_add_null_character(new_size);
return *this;
}
+ LIBC_INLINE string &operator+=(string_view rhs) { return append(rhs); }
+
LIBC_INLINE string &operator+=(const char c) {
- const size_t new_size = size_ + 1;
- reserve(new_size);
- buffer_[size_] = c;
+ return append(string_view(&c, 1));
+ }
+
+ // Replaces the span [pos, pos + count) in this string with `str`.
+ LIBC_INLINE string &replace(size_t pos, size_t count, string_view str) {
+ LIBC_ASSERT(pos <= size_); // Out of bounds.
+
+ count = min(count, size_ - pos);
+ size_t new_size = str.size() + size_ - count;
+
+ if (new_size > capacity()) {
+ grow_and_replace(/* keep_prefix_size= */ pos, str, size_ - pos - count);
+ return *this;
+ }
+
+ // If the input references a section of this string that will be edited,
+ // fall back to a slow approach. libc++ implements this efficiently via
+ // pointer arithmetic. If self-referential replace is used frequently,
+ // this can be updated to avoid the extra temporary.
+ bool has_overlap =
+ memory_overlaps(str, string_view(buffer_ + pos, size_ - pos));
+ string tmp;
+ if (LIBC_UNLIKELY(has_overlap)) {
+ // Save str in a temp string, then update the view to reference it.
+ tmp = str;
+ str = tmp;
+ }
+
+ if (str.size() != count)
+ inline_memmove(buffer_ + pos + str.size(), buffer_ + pos + count,
+ size_ - pos - count);
+
+ inline_memcpy(buffer_ + pos, str.data(), str.size());
set_size_and_add_null_character(new_size);
return *this;
}
@@ -257,7 +361,7 @@ LIBC_INLINE string operator+(const char *lhs, const string &rhs) {
namespace internal {
template <typename T> string to_dec_string(T value) {
const IntegerToString<T> buffer(value);
- return buffer.view();
+ return string(buffer.view());
}
} // namespace internal
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/type_traits/is_floating_point.h b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/type_traits/is_floating_point.h
index 283c4fcefb6..4a5984e38a8 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/CPP/type_traits/is_floating_point.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/CPP/type_traits/is_floating_point.h
@@ -12,7 +12,7 @@
#include "src/__support/CPP/type_traits/remove_cv.h"
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
-#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_FLOAT128
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_NATIVE_FLOAT128
namespace LIBC_NAMESPACE_DECL {
namespace cpp {
@@ -36,7 +36,7 @@ public:
// float128
float16
#endif
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
,
float128
#endif
@@ -44,7 +44,10 @@ public:
bfloat16
,
- fputil::Float128>();
+ fputil::Float128
+
+ ,
+ fputil::Float80>();
};
template <typename T>
LIBC_INLINE_VAR constexpr bool is_floating_point_v =
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 8b6ac8027b5..a32244e4785 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
@@ -303,6 +303,26 @@ add_header_library(
.comparison_operations
.dyadic_float
libc.hdr.stdint_proxy
+ libc.src.__support.CPP.limits
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.generic.add_sub
+ libc.src.__support.FPUtil.generic.div
+ libc.src.__support.FPUtil.generic.mul
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.uint128
+)
+
+add_header_library(
+ float80
+ HDRS
+ float80.h
+ DEPENDS
+ .cast
+ .comparison_operations
+ .dyadic_float
+ .float128
+ libc.hdr.stdint_proxy
libc.src.__support.CPP.type_traits
libc.src.__support.FPUtil.generic.add_sub
libc.src.__support.FPUtil.generic.div
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FPBits.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FPBits.h
index 83219b7573f..6127dede03f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FPBits.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/FPBits.h
@@ -22,7 +22,7 @@
#include "src/__support/libc_assert.h" // LIBC_ASSERT
#include "src/__support/macros/attributes.h" // LIBC_INLINE, LIBC_INLINE_VAR
#include "src/__support/macros/config.h"
-#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_FLOAT128
+#include "src/__support/macros/properties/types.h" // LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/math_extras.h" // mask_trailing_ones
#include "src/__support/sign.h" // Sign
#include "src/__support/uint128.h"
@@ -794,20 +794,21 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
else if constexpr (cpp::is_same_v<UnqualT, double> && DBL_MANT_DIG == 53)
return FPType::IEEE754_Binary64;
else if constexpr (cpp::is_same_v<UnqualT, long double>) {
- if constexpr (LDBL_MANT_DIG == 53)
- return FPType::IEEE754_Binary64;
- else if constexpr (LDBL_MANT_DIG == 64)
- return FPType::X86_Binary80;
+#if defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64)
+ return FPType::IEEE754_Binary64;
+#elif defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+ return FPType::X86_Binary80;
+#else
// TODO: properly treat double-double type.
- // else if constexpr (LDBL_MANT_DIG == 113)
- else
- return FPType::IEEE754_Binary128;
+ // #elif defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
+ return FPType::IEEE754_Binary128;
+#endif
}
#if defined(LIBC_TYPES_HAS_FLOAT16)
else if constexpr (cpp::is_same_v<UnqualT, float16>)
return FPType::IEEE754_Binary16;
#endif
-#if defined(LIBC_TYPES_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
else if constexpr (cpp::is_same_v<UnqualT, float128>)
return FPType::IEEE754_Binary128;
#endif
@@ -815,6 +816,8 @@ template <typename T> LIBC_INLINE static constexpr FPType get_fp_type() {
return FPType::BFloat16;
else if constexpr (cpp::is_same_v<UnqualT, Float128>)
return FPType::IEEE754_Binary128;
+ else if constexpr (cpp::is_same_v<UnqualT, Float80>)
+ return FPType::X86_Binary80;
else
static_assert(cpp::always_false<UnqualT>, "Unsupported type");
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/cast.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/cast.h
index 4fc5ea0893e..2a9bfd5a9f6 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/cast.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/cast.h
@@ -33,7 +33,9 @@ cast(InType x) {
if constexpr (cpp::is_same_v<OutType, bfloat16> ||
cpp::is_same_v<InType, bfloat16> ||
cpp::is_same_v<OutType, Float128> ||
- cpp::is_same_v<InType, Float128>
+ cpp::is_same_v<InType, Float128> ||
+ cpp::is_same_v<OutType, Float80> ||
+ cpp::is_same_v<InType, Float80>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<OutType, float16> ||
cpp::is_same_v<InType, float16>
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 c2186321319..e32906e3cf9 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
@@ -256,10 +256,12 @@ template <size_t Bits> struct DyadicFloat {
static_cast<StorageType>(unbiased_exp + FPBits::EXP_BIAS);
}
- MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
- round = (mantissa & round_mask) != 0;
- MantissaType sticky_mask = round_mask - 1;
- sticky = (mantissa & sticky_mask) != 0;
+ if (extra_fraction_len > 0) {
+ MantissaType round_mask = MantissaType(1) << (extra_fraction_len - 1);
+ round = (mantissa & round_mask) != 0;
+ MantissaType sticky_mask = round_mask - 1;
+ sticky = (mantissa & sticky_mask) != 0;
+ }
out_mantissa = static_cast<StorageType>(mantissa >> extra_fraction_len);
}
@@ -438,11 +440,12 @@ template <size_t Bits> struct DyadicFloat {
(FPBits<T>::FRACTION_LEN < Bits),
void>>
LIBC_INLINE LIBC_CONSTEXPR_DEFAULT T as() const {
- if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, Float128>
+ if constexpr (cpp::is_same_v<T, bfloat16> || cpp::is_same_v<T, Float128> ||
+ cpp::is_same_v<T, Float80>
#if defined(LIBC_TYPES_HAS_FLOAT16) && !defined(__LIBC_USE_FLOAT16_CONVERSION)
|| cpp::is_same_v<T, float16>
#endif
-#if defined(LIBC_TYPES_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
|| cpp::is_same_v<T, float128>
#endif
)
@@ -472,7 +475,11 @@ template <size_t Bits> struct DyadicFloat {
// exponents coming in to this function _shouldn't_ be that large). The
// result should always end up as a positive size_t.
size_t shift = -static_cast<size_t>(exponent);
- new_mant >>= shift;
+ size_t limit = cpp::numeric_limits<MantissaType>::digits;
+ if (shift >= limit)
+ new_mant = 0;
+ else
+ new_mant >>= shift;
}
if (sign.is_neg()) {
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float128.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float128.h
index b1bcafefd61..1dd1abd4177 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float128.h
@@ -10,6 +10,7 @@
#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT128_H
#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/limits.h"
#include "src/__support/CPP/type_traits.h"
#include "src/__support/FPUtil/cast.h"
#include "src/__support/FPUtil/comparison_operations.h"
@@ -69,13 +70,27 @@ struct Float128 {
template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
LIBC_INLINE constexpr explicit operator T() const {
+ constexpr T MIN_T = cpp::numeric_limits<T>::min();
+ constexpr T MAX_T = cpp::numeric_limits<T>::max();
FPBits<Float128> x_bits(*this);
// Raise FE_INVALID for inf and NaN
if (x_bits.is_inf_or_nan()) {
raise_except_if_required(FE_INVALID);
+ return x_bits.is_neg() ? MIN_T : MAX_T;
}
- int x_bits_exp =
- x_bits.get_explicit_exponent() - FPBits<Float128>::FRACTION_LEN;
+ int exponent = x_bits.get_explicit_exponent();
+ constexpr int EXPONENT_LIMIT = cpp::numeric_limits<T>::digits;
+ if (exponent > EXPONENT_LIMIT) {
+ raise_except_if_required(FE_INVALID);
+ return x_bits.is_neg() ? MIN_T : MAX_T;
+ } else if (exponent == EXPONENT_LIMIT) {
+ if (x_bits.is_pos() || x_bits.get_mantissa() != 0) {
+ raise_except_if_required(FE_INVALID);
+ return x_bits.is_neg() ? MIN_T : MAX_T;
+ }
+ }
+
+ int x_bits_exp = exponent - FPBits<Float128>::FRACTION_LEN;
// sign * 2^(exp-bias) * mantissa
DyadicFloat<FPBits<Float128>::STORAGE_LEN> xd(
x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa());
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
new file mode 100644
index 00000000000..25c7ba9251a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/float80.h
@@ -0,0 +1,156 @@
+//===-- Definition for Float80 data 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT80_H
+#define LLVM_LIBC_SRC___SUPPORT_FPUTIL_FLOAT80_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/comparison_operations.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/float128.h"
+#include "src/__support/FPUtil/generic/add_sub.h"
+#include "src/__support/FPUtil/generic/div.h"
+#include "src/__support/FPUtil/generic/mul.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+
+struct Float80 {
+ UInt128 bits;
+
+ LIBC_INLINE Float80() = default;
+ LIBC_INLINE constexpr Float80(const Float80 &) = default;
+ LIBC_INLINE constexpr Float80(Float80 &&) = default;
+ LIBC_INLINE constexpr Float80 &operator=(const Float80 &) = default;
+ LIBC_INLINE constexpr Float80 &operator=(Float80 &&) = default;
+
+ // Floating point type and integer type
+ template <typename T>
+ LIBC_INLINE constexpr explicit Float80(T value) : bits(0U) {
+ if constexpr (cpp::is_floating_point_v<T>) {
+ bits = fputil::cast<Float80>(value).bits;
+ } else if constexpr (cpp::is_integral_v<T>) {
+ Sign sign = Sign::POS;
+ auto unsigned_value = static_cast<cpp::make_unsigned_t<T>>(value);
+
+ if constexpr (cpp::is_signed_v<T>) {
+ if (value < 0) {
+ sign = Sign::NEG;
+ unsigned_value = -unsigned_value;
+ }
+ }
+
+ fputil::DyadicFloat<FPBits<Float80>::STORAGE_LEN> xd(sign, 0,
+ unsigned_value);
+ bits = xd.template as<Float80, /*ShouldSignalExceptions=*/true>().bits;
+
+ } else if constexpr (cpp::is_convertible_v<T, Float80>) {
+ bits = value.operator Float80().bits;
+ } else {
+ bits = fputil::cast<Float80>(static_cast<float>(value)).bits;
+ }
+ }
+
+ template <typename T, cpp::enable_if_t<cpp::is_floating_point_v<T> &&
+ !cpp::is_same_v<T, Float80>,
+ int> = 0>
+ LIBC_INLINE LIBC_CONSTEXPR_DEFAULT operator T() const {
+ return fputil::cast<T>(*this);
+ }
+
+ template <typename T, cpp::enable_if_t<cpp::is_integral_v<T>, int> = 0>
+ LIBC_INLINE constexpr explicit operator T() const {
+ constexpr T MIN_T = cpp::numeric_limits<T>::min();
+ constexpr T MAX_T = cpp::numeric_limits<T>::max();
+ FPBits<Float80> x_bits(*this);
+ // Raise FE_INVALID for inf and NaN
+ if (x_bits.is_inf_or_nan()) {
+ raise_except_if_required(FE_INVALID);
+ return x_bits.is_neg() ? MIN_T : MAX_T;
+ }
+ int exponent = x_bits.get_explicit_exponent();
+ constexpr int EXPONENT_LIMIT = cpp::numeric_limits<T>::digits;
+ if (exponent > EXPONENT_LIMIT) {
+ raise_except_if_required(FE_INVALID);
+ return x_bits.is_neg() ? MIN_T : MAX_T;
+ } else if (exponent == EXPONENT_LIMIT) {
+ if (x_bits.is_pos() || x_bits.get_mantissa() != 0) {
+ raise_except_if_required(FE_INVALID);
+ return x_bits.is_neg() ? MIN_T : MAX_T;
+ }
+ }
+
+ int x_bits_exp = exponent - FPBits<Float80>::FRACTION_LEN;
+ // sign * 2^(exp-bias) * mantissa
+ DyadicFloat<FPBits<Float80>::STORAGE_LEN> xd(
+ x_bits.sign(), x_bits_exp, x_bits.get_explicit_mantissa());
+ return static_cast<T>(xd.as_mantissa_type());
+ }
+
+ // unary operator
+ LIBC_INLINE LIBC_BIT_CAST_CONSTEXPR Float80 operator-() const {
+ fputil::FPBits<Float80> result(*this);
+ result.set_sign(result.is_pos() ? Sign::NEG : Sign::POS);
+ return result.get_val();
+ }
+
+ LIBC_INLINE constexpr Float80 operator+(const Float80 &other) const {
+ return fputil::generic::add<Float80>(fputil::cast<Float128>(*this),
+ fputil::cast<Float128>(other));
+ }
+
+ LIBC_INLINE constexpr Float80 operator-(const Float80 &other) const {
+ return fputil::generic::sub<Float80>(fputil::cast<Float128>(*this),
+ fputil::cast<Float128>(other));
+ }
+
+ LIBC_INLINE constexpr Float80 operator*(const Float80 &other) const {
+ return fputil::generic::mul<Float80>(fputil::cast<Float128>(*this),
+ fputil::cast<Float128>(other));
+ }
+
+ LIBC_INLINE constexpr Float80 operator/(const Float80 &other) const {
+ return fputil::generic::div<Float80>(fputil::cast<Float128>(*this),
+ fputil::cast<Float128>(other));
+ }
+
+ // Comparison operators
+ LIBC_INLINE constexpr bool operator==(const Float80 &other) const {
+ return fputil::equals(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator!=(const Float80 &other) const {
+ return !fputil::equals(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator<(const Float80 &other) const {
+ return fputil::less_than(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator<=(const Float80 &other) const {
+ return fputil::less_than_or_equals(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator>(const Float80 &other) const {
+ return fputil::greater_than(*this, other);
+ }
+
+ LIBC_INLINE constexpr bool operator>=(const Float80 &other) const {
+ return fputil::greater_than_or_equals(*this, other);
+ }
+};
+
+} // namespace fputil
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FPUTIL_Float80_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/generic/add_sub.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/generic/add_sub.h
index 7f6a6a97877..47ffe5f2f62 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/generic/add_sub.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/generic/add_sub.h
@@ -120,10 +120,13 @@ add_or_sub(InType x, InType y) {
#ifdef LIBC_USE_CONSTEXPR
InType tmp = y;
#else
+ // This prevents it from declaring InType as volatile for emulated types
+ using InTypeTemp = cpp::conditional_t<cpp::is_class_v<InType>, InType,
+ volatile InType>;
+ InTypeTemp tmp = y;
// volatile prevents Clang from converting tmp to OutType and then
// immediately back to InType before negating it, resulting in double
// rounding.
- volatile InType tmp = y;
#endif // LIBC_USE_CONSTEXPR
if constexpr (IsSub)
tmp = -tmp;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/sqrt.h b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/sqrt.h
index b06503bca4e..fbc279a128f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/sqrt.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/FPUtil/sqrt.h
@@ -48,7 +48,7 @@ template <> LIBC_INLINE long double sqrt<long double>(long double x) {
#else // __builtin_elementwise_sqrt
// Use inline assembly when __builtin_elementwise_sqrt is not available.
-#if defined(LIBC_TARGET_CPU_HAS_SSE2)
+#if defined(LIBC_TARGET_CPU_HAS_SSE2) && defined(LIBC_TARGET_ARCH_IS_X86_64)
#include "x86_64/sqrt.h"
#elif defined(LIBC_TARGET_ARCH_IS_AARCH64) && defined(__ARM_FP)
#include "aarch64/sqrt.h"
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/File/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/File/CMakeLists.txt
index 7fcca3c1397..f369fec9a91 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/File/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/File/CMakeLists.txt
@@ -1,5 +1,5 @@
if(NOT (TARGET libc.src.__support.threads.mutex)
- OR LIBC_TARGET_OS_IS_GPU)
+ OR LIBC_TARGET_OS_IS_GPU)
# Not all platforms have a mutex implementation. If mutex is unvailable,
# we just skip everything about files.
return()
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 bb4def114d3..67879e6c993 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
@@ -165,6 +165,18 @@ protected:
static_cast<ModeFlags>(OpenMode::PLUS));
}
+ void reset_stream_state_unlocked(ModeFlags new_mode) {
+ mode = new_mode;
+ pos = 0;
+ prev_op = FileOp::NONE;
+ read_limit = 0;
+ eof = false;
+ err = false;
+ orientation = Orientation::UNORIENTED;
+ mbstate = internal::mbstate();
+ adjust_buf();
+ }
+
public:
// We want this constructor to be constexpr so that global file objects
// like stdout do not require invocation of the constructor which can
@@ -385,6 +397,15 @@ private:
// The implementation of this function is provided by the platform_file
// library.
ErrorOr<File *> openfile(const char *path, const char *mode);
+// Reopens a file stream.
+// Note: On failure, `reopenfile` will place the file stream in an invalid state
+// (closing the underlying file descriptor) but will not deallocate the `File`
+// object itself, ensuring static streams like stdin/stdout/stderr are
+// preserved.
+int reopenfile(File *f, const char *path, const char *mode);
+// Expected to be implemented by the platform file, will be called after
+// locking.
+int reopenfile_unlocked(File *f, const char *path, const char *mode);
// The platform_file library should implement it if it relevant for that
// platform.
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 91f94d8f5ab..67b69b9f026 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
@@ -15,6 +15,7 @@
#include "src/__support/CPP/new.h"
#include "src/__support/File/file.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"
#include "src/__support/OSUtil/linux/syscall_wrappers/lseek.h"
#include "src/__support/OSUtil/linux/syscall_wrappers/open.h"
@@ -52,21 +53,23 @@ ErrorOr<off_t> linux_file_seek(File *f, off_t offset, int whence) {
int linux_file_close(File *f) {
File::remove_file(f);
auto *lf = reinterpret_cast<LinuxFile *>(f);
- auto ret = linux_syscalls::close(lf->get_fd());
- if (!ret) {
- return ret.error();
+ int retval = 0;
+ if (lf->get_fd() >= 0) {
+ // Linux closes the file descriptor early in the syscall, so we assume it's
+ // always closed after the call. That means we should also delete the
+ // LinuxFile on error.
+ auto result = linux_syscalls::close(lf->get_fd());
+ if (!result)
+ retval = result.error();
+ } else {
+ retval = EBADF;
}
delete lf;
- return 0;
+ return retval;
}
-ErrorOr<File *> openfile(const char *path, const char *mode) {
+static int mode_flags_to_open_flags(File::ModeFlags modeflags) {
using ModeFlags = File::ModeFlags;
- auto modeflags = File::mode_flags(mode);
- if (modeflags == 0) {
- // return {nullptr, EINVAL};
- return Error(EINVAL);
- }
int open_flags = 0;
if (modeflags & ModeFlags(File::OpenMode::APPEND)) {
open_flags = O_CREAT | O_APPEND;
@@ -86,6 +89,15 @@ ErrorOr<File *> openfile(const char *path, const char *mode) {
else
open_flags |= O_RDONLY;
}
+ return open_flags;
+}
+
+ErrorOr<File *> openfile(const char *path, const char *mode) {
+ auto modeflags = File::mode_flags(mode);
+ if (modeflags == 0) {
+ return Error(EINVAL);
+ }
+ int open_flags = mode_flags_to_open_flags(modeflags);
// File created will have 0666 permissions.
constexpr mode_t OPEN_MODE =
@@ -125,10 +137,18 @@ ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
int fd_flags = result.value();
using OpenMode = File::OpenMode;
- if (((fd_flags & O_ACCMODE) == O_RDONLY &&
- !(modeflags & static_cast<ModeFlags>(OpenMode::READ))) ||
- ((fd_flags & O_ACCMODE) == O_WRONLY &&
- !(modeflags & static_cast<ModeFlags>(OpenMode::WRITE)))) {
+ 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))) {
return Error(EINVAL);
}
@@ -169,9 +189,138 @@ ErrorOr<LinuxFile *> create_file_from_fd(int fd, const char *mode) {
return file;
}
+int LinuxFile::reopen_unlocked(const char *path, const char *mode) {
+ flush_unlocked();
+
+ auto modeflags = File::mode_flags(mode);
+
+ if (path != nullptr) {
+ int old_fd = get_fd();
+
+ if (modeflags == 0) {
+ if (old_fd >= 0) {
+ linux_syscalls::close(old_fd);
+ set_fd(-1);
+ }
+ reset_stream_state_unlocked(modeflags);
+ 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;
+
+ ErrorOr<int> new_fd = linux_syscalls::open(path, open_flags, OPEN_MODE);
+
+ // If the new file fails to open, POSIX says we still have to close the old
+ // file.
+ if (!new_fd) {
+ if (old_fd >= 0) {
+ // POSIX: "Failure to close the file descriptor successfully shall be
+ // ignored"
+ linux_syscalls::close(old_fd);
+
+ set_fd(-1);
+ }
+ reset_stream_state_unlocked(modeflags);
+ return new_fd.error();
+ }
+
+ // Else the new file successfully opened, so we move it into the fd the old
+ // file was using if the old fd exists.
+ if (old_fd >= 0) {
+ 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);
+ return dup_result.error();
+ }
+ auto close_result = linux_syscalls::close(new_fd.value());
+ if (!close_result) {
+ reset_stream_state_unlocked(modeflags);
+ return close_result.error();
+ }
+ } else {
+ set_fd(new_fd.value());
+ }
+
+ reset_stream_state_unlocked(modeflags);
+ return 0;
+ }
+
+ if (modeflags == 0)
+ return EINVAL;
+
+ if (fd < 0)
+ return EBADF;
+
+ auto result = linux_syscalls::fcntl(fd, F_GETFL);
+ if (!result.has_value())
+ 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))) {
+ return EBADF;
+ }
+
+ bool do_seek = false;
+ bool is_append = modeflags & static_cast<ModeFlags>(OpenMode::APPEND);
+ bool has_append_flag = fd_flags & O_APPEND;
+
+ if (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) {
+ if (!linux_syscalls::fcntl(fd, F_SETFL,
+ reinterpret_cast<void *>(fd_flags & ~O_APPEND))
+ .has_value()) {
+ return EBADF;
+ }
+ }
+
+ reset_stream_state_unlocked(modeflags);
+
+ if (do_seek) {
+ auto seek_result = linux_file_seek(this, 0, SEEK_END);
+ if (!seek_result.has_value())
+ return seek_result.error();
+ }
+ return 0;
+}
+
int get_fileno(File *f) {
auto *lf = reinterpret_cast<LinuxFile *>(f);
return lf->get_fd();
}
+int reopenfile(File *f, const char *path, const char *mode) {
+ f->lock();
+ int ret = reopenfile_unlocked(f, path, mode);
+ f->unlock();
+
+ return ret;
+}
+
+int reopenfile_unlocked(File *f, const char *path, const char *mode) {
+ auto *lf = reinterpret_cast<LinuxFile *>(f);
+ return lf->reopen_unlocked(path, mode);
+}
+
} // namespace LIBC_NAMESPACE_DECL
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 16d72a60f86..700db415156 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
@@ -29,6 +29,9 @@ public:
fd(file_descriptor) {}
int get_fd() const { return fd; }
+ void set_fd(int new_fd) { fd = new_fd; }
+
+ int reopen_unlocked(const char *path, const char *mode);
};
// Create a File object and associate it with a fd.
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/GPU/utils.h b/deps/v8/third_party/llvm-libc/src/src/__support/GPU/utils.h
index e12684bf25c..420830d4744 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/GPU/utils.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/GPU/utils.h
@@ -25,7 +25,7 @@ namespace gpu {
template <typename T> using Private = __gpu_private T;
template <typename T> using Constant = __gpu_constant T;
template <typename T> using Local = __gpu_local T;
-template <typename T> using Global = __gpu_local T;
+template <typename T> using Global = __gpu_global T;
LIBC_INLINE uint32_t get_num_blocks_x() { return __gpu_num_blocks(0); }
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/HashTable/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/HashTable/CMakeLists.txt
index 6dfe2391e73..f6494dc6e87 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/HashTable/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/HashTable/CMakeLists.txt
@@ -12,7 +12,7 @@ add_header_library(
)
list(FIND TARGET_ENTRYPOINT_NAME_LIST getrandom getrandom_index)
-if (NOT ${getrandom_index} EQUAL -1)
+if(NOT ${getrandom_index} EQUAL -1)
message(STATUS "Using getrandom for hashtable randomness")
libc_set_definition(randomness_compile_flags LIBC_HASHTABLE_USE_GETRANDOM)
set(randomness_extra_depends
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 9e69bf7d0cb..c0420e554dc 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
@@ -12,7 +12,7 @@ add_object_library(
io.h
syscall.h
DEPENDS
- .${LIBC_TARGET_ARCHITECTURE}.darwin_${LIBC_TARGET_ARCHITECTURE}_util
+ .${LIBC_TARGET_ARCHITECTURE}.darwin_${LIBC_TARGET_ARCHITECTURE}_util
libc.src.__support.common
libc.src.__support.CPP.string_view
libc.include.sys_syscall
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/CMakeLists.txt
index 87d0fb862fa..93f3d6d5190 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/CMakeLists.txt
@@ -40,6 +40,22 @@ add_header_library(
libc.src.__support.threads.callonce
)
+add_header_library(
+ network_syscall_policy
+ HDRS
+ network_syscall_policy.h
+ DEPENDS
+ libc.hdr.types.socklen_t
+ libc.hdr.types.ssize_t
+ libc.hdr.types.struct_sockaddr
+ libc.src.__support.OSUtil.linux.syscall_wrappers.close
+ libc.src.__support.OSUtil.linux.syscall_wrappers.recvfrom
+ libc.src.__support.OSUtil.linux.syscall_wrappers.sendto
+ libc.src.__support.OSUtil.linux.syscall_wrappers.socket
+ libc.src.__support.common
+ libc.src.__support.error_or
+)
+
add_header_library(
path
HDRS
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/network_syscall_policy.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/network_syscall_policy.h
new file mode 100644
index 00000000000..f02111800db
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/network_syscall_policy.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+/// Policy class wrapper for network-related system calls.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_NETWORK_SYSCALL_POLICY_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_NETWORK_SYSCALL_POLICY_H
+
+#include "hdr/types/socklen_t.h"
+#include "hdr/types/ssize_t.h"
+#include "hdr/types/struct_sockaddr.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/close.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/recvfrom.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/sendto.h"
+#include "src/__support/OSUtil/linux/syscall_wrappers/socket.h"
+#include "src/__support/common.h"
+#include "src/__support/error_or.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace net {
+
+struct DefaultNetworkSyscallPolicy {
+ LIBC_INLINE static ErrorOr<int> socket(int domain, int type, int protocol) {
+ return linux_syscalls::socket(domain, type, protocol);
+ }
+
+ LIBC_INLINE static ErrorOr<ssize_t> sendto(int fd, const void *buf,
+ size_t len, int flags,
+ const struct sockaddr *dest_addr,
+ socklen_t addrlen) {
+ return linux_syscalls::sendto(fd, buf, len, flags, dest_addr, addrlen);
+ }
+
+ LIBC_INLINE static ErrorOr<ssize_t> recvfrom(int fd, void *buf, size_t len,
+ int flags,
+ struct sockaddr *src_addr,
+ socklen_t *addrlen) {
+ return linux_syscalls::recvfrom(fd, buf, len, flags, src_addr, addrlen);
+ }
+
+ LIBC_INLINE static ErrorOr<int> close(int fd) {
+ return linux_syscalls::close(fd);
+ }
+};
+
+} // namespace net
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_NETWORK_SYSCALL_POLICY_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/stat/stat_via_statx.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/stat/stat_via_statx.h
index e9d78099b59..6c7d641e0b4 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/stat/stat_via_statx.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/stat/stat_via_statx.h
@@ -30,14 +30,14 @@ namespace LIBC_NAMESPACE_DECL {
namespace internal {
/// Populates `statbuf` via a call to the `statx` syscall.
-LIBC_INLINE ErrorOr<int> stat_via_statx(int dirfd, const char *__restrict path,
- int flags,
- struct stat *__restrict statbuf) {
+LIBC_INLINE ErrorOr<void> stat_via_statx(int dirfd, const char *__restrict path,
+ int flags,
+ struct stat *__restrict statbuf) {
kernel_statx_buf xbuf;
ErrorOr<int> result = linux_syscalls::statx(
dirfd, path, flags, KERNEL_STATX_BASIC_STATS_MASK, &xbuf);
if (!result)
- return result;
+ return Error(result.error());
statbuf->st_dev = MKDEV(xbuf.stx_dev_major, xbuf.stx_dev_minor);
statbuf->st_ino = static_cast<decltype(statbuf->st_ino)>(xbuf.stx_ino);
@@ -57,7 +57,7 @@ LIBC_INLINE ErrorOr<int> stat_via_statx(int dirfd, const char *__restrict path,
statbuf->st_blocks =
static_cast<decltype(statbuf->st_blocks)>(xbuf.stx_blocks);
- return 0;
+ return {};
}
} // namespace internal
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 7d5f94513d0..30fbda86f6b 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
@@ -745,7 +745,6 @@ add_header_library(
libc.include.sys_syscall
)
-
add_header_library(
dup
HDRS
@@ -895,6 +894,200 @@ add_header_library(
HDRS
sysinfo.h
DEPENDS
+ libc.hdr.types.struct_sysinfo
+ 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(
+ statfs
+ HDRS
+ statfs.h
+ DEPENDS
+ libc.hdr.types.struct_statfs
+ 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(
+ fstatfs
+ HDRS
+ fstatfs.h
+ DEPENDS
+ libc.hdr.types.struct_statfs
+ 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(
+ nanosleep
+ HDRS
+ nanosleep.h
+ DEPENDS
+ libc.hdr.types.struct_timespec
+ libc.hdr.time_macros
+ 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(
+ rt_sigaction
+ HDRS
+ rt_sigaction.h
+ DEPENDS
+ libc.hdr.types.sigset_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(
+ clone3
+ HDRS
+ clone3.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(
+ execle
+ HDRS
+ execle.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(
+ wait4
+ HDRS
+ wait4.h
+ DEPENDS
+ libc.hdr.signal_macros
+ libc.hdr.sys_wait_macros
+ libc.hdr.types.pid_t
+ libc.hdr.types.siginfo_t
+ libc.hdr.types.struct_rusage
+ 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(
+ execve
+ HDRS
+ execve.h
+ DEPENDS
+ libc.hdr.fcntl_macros
+ 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(
+ timer_create
+ HDRS
+ timer_create.h
+ DEPENDS
+ libc.hdr.signal_macros
+ libc.hdr.types.clockid_t
+ libc.hdr.types.pid_t
+ libc.hdr.types.struct_sigevent
+ libc.hdr.types.timer_t
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ timer_delete
+ HDRS
+ timer_delete.h
+ DEPENDS
+ libc.hdr.types.timer_t
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ timer_gettime
+ HDRS
+ timer_gettime.h
+ DEPENDS
+ libc.hdr.types.struct_itimerspec
+ libc.hdr.types.timer_t
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ timer_settime
+ HDRS
+ timer_settime.h
+ DEPENDS
+ libc.hdr.types.struct_itimerspec
+ libc.hdr.types.timer_t
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ clock_getres
+ HDRS
+ clock_getres.h
+ DEPENDS
+ libc.hdr.types.clockid_t
+ libc.hdr.types.struct_timespec
+ libc.include.sys_syscall
+ libc.src.__support.OSUtil.osutil
+ libc.src.__support.common
+ libc.src.__support.error_or
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ getrusage
+ HDRS
+ getrusage.h
+ DEPENDS
+ libc.hdr.types.struct_rusage
libc.src.__support.OSUtil.osutil
libc.src.__support.common
libc.src.__support.error_or
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/clock_getres.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/clock_getres.h
new file mode 100644
index 00000000000..7f94eee2326
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/clock_getres.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
+/// Implementation header for clock_getres syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CLOCK_GETRES_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CLOCK_GETRES_H
+
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/struct_timespec.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>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> clock_getres(clockid_t clockid, timespec *res) {
+#if defined(SYS_clock_getres_time64)
+ static_assert(
+ sizeof(time_t) == sizeof(int64_t),
+ "SYS_clock_getres_time64 requires struct timespec with 64-bit members.");
+ return syscall_checked<int>(SYS_clock_getres_time64, clockid, res);
+#elif defined(SYS_clock_getres)
+ static_assert(
+ sizeof(timespec::tv_nsec) == sizeof(long),
+ "This is only safe on platforms where tv_nsec "
+ "matches the register size (long). It is unsafe on 32-bit platforms "
+ "with 64-bit tv_nsec.");
+ return syscall_checked<int>(SYS_clock_getres, clockid, res);
+#else
+#error "SYS_clock_getres and SYS_clock_getres_time64 syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CLOCK_GETRES_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/clone3.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/clone3.h
new file mode 100644
index 00000000000..a5bf42d759a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/clone3.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 clone3.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CLONE3_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CLONE3_H
+
+#include "hdr/types/pid_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 <linux/sched.h> // For struct clone_args
+#include <sys/syscall.h> // For syscall numbers
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<pid_t> clone3(struct clone_args *cl_args, size_t size) {
+ return syscall_checked<pid_t>(SYS_clone3, cl_args, size);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_CLONE3_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/execle.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/execle.h
new file mode 100644
index 00000000000..3b0d2a87917
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/execle.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
+/// Implementation header for execle.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_EXECLE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_EXECLE_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 {
+
+template <typename... Args>
+LIBC_INLINE ErrorOr<int> execle(const char *path, Args... args) {
+ // All this logic because the standard says the environment pointer goes at
+ // the end. It's annoying but it's all compile time so it's not actually a
+ // problem.
+ const void *all[] = {reinterpret_cast<const void *>(args)...};
+ constexpr size_t total = sizeof...(Args);
+ static_assert(total >= 2,
+ "execle requires at least (arg0, ..., nullptr, envp)");
+ char *const *envp =
+ static_cast<char *const *>(const_cast<void *>(all[total - 1]));
+
+ const char *argv[total];
+ for (size_t i = 0; i < total - 1; ++i)
+ argv[i] = reinterpret_cast<const char *>(all[i]);
+ argv[total - 1] = nullptr;
+
+ return syscall_checked<int>(SYS_execve, path, argv, envp);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_EXECLE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/execve.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/execve.h
new file mode 100644
index 00000000000..9c88b7603e8
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/execve.h
@@ -0,0 +1,44 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 execve.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_EXECVE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_EXECVE_H
+
+#include "hdr/fcntl_macros.h"
+#include "src/__support/OSUtil/linux/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 linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> execve(const char *path, char *const argv[],
+ char *const envp[]) {
+#if defined(SYS_execve)
+ int ret = syscall_impl<int>(SYS_execve, path, argv, envp);
+#elif defined(SYS_execveat)
+ int ret = syscall_impl<int>(SYS_execveat, AT_FDCWD, path, argv, envp, 0);
+#else
+#error "execve and execveat syscalls not available."
+#endif
+ if (ret < 0)
+ return Error(-ret);
+ return ret;
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_EXECVE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fstatfs.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fstatfs.h
new file mode 100644
index 00000000000..39c48bd0120
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/fstatfs.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 fstatfs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FSTATFS_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FSTATFS_H
+
+#include "hdr/types/struct_statfs.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> fstatfs(int fd, struct statfs *buf) {
+#ifdef SYS_fstatfs64
+ static_assert(sizeof(statfs::f_blocks) == 8,
+ "Can only be used with 64-bit version of the struct");
+ return syscall_checked<int>(SYS_fstatfs64, fd, sizeof(*buf), buf);
+#else
+ static_assert(
+ sizeof(statfs::f_blocks) == sizeof(long),
+ "The fallback is unsafe on 32-bit platforms with 64-bit f_blocks.");
+ return syscall_checked<int>(SYS_fstatfs, fd, buf);
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_FSTATFS_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
new file mode 100644
index 00000000000..ed44014a955
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/getrusage.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 getrusage
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
+
+#include "hdr/types/struct_rusage.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 {
+
+// The wrapper returns an int (casting from `long` returned by the syscall)
+// because its libc counterpart returns an int and the set of possible return
+// values fits: 0, -EFAULT (-14) or -EINVAL (-22).
+LIBC_INLINE ErrorOr<int> getrusage(int who, struct rusage *ru) {
+ return syscall_checked<int>(SYS_getrusage, who, ru);
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_LINUX_SYSCALL_WRAPPERS_GETRUSAGE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h
new file mode 100644
index 00000000000..694becbd395
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/nanosleep.h
@@ -0,0 +1,51 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 nanosleep syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_NANOSLEEP_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_NANOSLEEP_H
+
+#include "hdr/time_macros.h"
+#include "hdr/types/struct_timespec.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>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace linux_syscalls {
+
+LIBC_INLINE ErrorOr<int> nanosleep(const timespec *req, timespec *rem) {
+#if defined(SYS_clock_nanosleep_time64)
+ static_assert(
+ sizeof(time_t) == sizeof(int64_t),
+ "SYS_clock_nanosleep_time64 requires struct timespec with 64-bit "
+ "members.");
+ return syscall_checked<int>(SYS_clock_nanosleep_time64, CLOCK_REALTIME, 0,
+ req, rem);
+#elif defined(SYS_nanosleep)
+ static_assert(
+ sizeof(timespec::tv_nsec) == sizeof(long),
+ "This legacy syscall fallback is only safe on platforms where tv_nsec "
+ "matches the register size (long). It is unsafe on 32-bit platforms "
+ "with 64-bit tv_nsec.");
+ return syscall_checked<int>(SYS_nanosleep, req, rem);
+#else
+#error "SYS_nanosleep and SYS_clock_nanosleep_time64 syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_NANOSLEEP_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/rt_sigaction.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/rt_sigaction.h
new file mode 100644
index 00000000000..72f9e749305
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/rt_sigaction.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 rt_sigaction.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RT_SIGACTION_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RT_SIGACTION_H
+
+#include "hdr/types/sigset_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> rt_sigaction(int signum, const void *act,
+ void *oldact) {
+ return syscall_checked<int>(SYS_rt_sigaction, signum, act, oldact,
+ sizeof(sigset_t));
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_RT_SIGACTION_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/statfs.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/statfs.h
new file mode 100644
index 00000000000..1c1cbd4ec4e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/statfs.h
@@ -0,0 +1,43 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 statfs.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_STATFS_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_STATFS_H
+
+#include "hdr/types/struct_statfs.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> statfs(const char *path, struct statfs *buf) {
+#ifdef SYS_statfs64
+ static_assert(sizeof(statfs::f_blocks) == 8,
+ "Can only be used with 64-bit version of the struct");
+ return syscall_checked<int>(SYS_statfs64, path, sizeof(*buf), buf);
+#else
+ static_assert(
+ sizeof(statfs::f_blocks) == sizeof(long),
+ "The fallback is unsafe on 32-bit platforms with 64-bit f_blocks.");
+ return syscall_checked<int>(SYS_statfs, path, buf);
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_STATFS_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/sysinfo.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/sysinfo.h
index 7487d05353c..ef2b7a3f582 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/sysinfo.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/sysinfo.h
@@ -14,17 +14,17 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SYSINFO_H
#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_SYSINFO_H
+#include "hdr/types/struct_sysinfo.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 <linux/sysinfo.h> // For struct sysinfo
-#include <sys/syscall.h> // For syscall numbers
+#include <sys/syscall.h> // For syscall numbers
namespace LIBC_NAMESPACE_DECL {
namespace linux_syscalls {
-LIBC_INLINE ErrorOr<int> sysinfo(struct ::sysinfo *info) {
+LIBC_INLINE ErrorOr<int> sysinfo(struct sysinfo *info) {
return syscall_checked<int>(SYS_sysinfo, info);
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_create.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_create.h
new file mode 100644
index 00000000000..25abfffe7ac
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_create.h
@@ -0,0 +1,91 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 timer_create syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_CREATE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_CREATE_H
+
+#include "hdr/signal_macros.h"
+#include "hdr/types/clockid_t.h"
+#include "hdr/types/pid_t.h"
+#include "hdr/types/struct_sigevent.h"
+#include "hdr/types/timer_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 {
+
+#define __SIGEV_MAX_SIZE 64
+#define __SIGEV_PAD_SIZE \
+ ((__SIGEV_MAX_SIZE - sizeof(int) * 2 - sizeof(sigval)) / sizeof(int))
+
+// Linux kernel ABI layout for struct sigevent (64 bytes total):
+// https://github.com/torvalds/linux/blob/master/include/uapi/asm-generic/siginfo.h
+// https://man7.org/linux/man-pages/man2/timer_create.2.html
+struct KernelSigevent {
+ sigval sigev_value;
+ int sigev_signo;
+ int sigev_notify;
+ union {
+ int _pad[__SIGEV_PAD_SIZE];
+ pid_t _tid;
+ struct {
+ void (*_function)(sigval);
+ void *_attribute;
+ } _sigev_thread;
+ } _sigev_un;
+
+ LIBC_INLINE KernelSigevent() = default;
+
+ LIBC_INLINE KernelSigevent(const sigevent &sev) : _sigev_un{} {
+ sigev_value = sev.sigev_value;
+ sigev_signo = sev.sigev_signo;
+ sigev_notify = sev.sigev_notify;
+ for (unsigned i = 0; i < __SIGEV_PAD_SIZE; ++i)
+ _sigev_un._pad[i] = 0;
+ // Linux kernel treats SIGEV_THREAD_ID as a bitwise mask, while the
+ // remaining POSIX values as distinct enums:
+ // https://github.com/torvalds/linux/blob/master/kernel/time/posix-timers.c#L405
+ // https://github.com/torvalds/linux/blob/master/kernel/time/posix-timers.c#L525
+ if ((sev.sigev_notify & SIGEV_THREAD_ID) != 0) {
+ _sigev_un._tid = sev.sigev_notify_thread_id;
+ } else if (sev.sigev_notify == SIGEV_THREAD) {
+ _sigev_un._sigev_thread._function = sev.sigev_notify_function;
+ _sigev_un._sigev_thread._attribute = sev.sigev_notify_attributes;
+ }
+ }
+};
+
+#undef __SIGEV_MAX_SIZE
+#undef __SIGEV_PAD_SIZE
+
+LIBC_INLINE ErrorOr<int> timer_create(clockid_t clockid, const sigevent *sevp,
+ timer_t *timerid) {
+#ifdef SYS_timer_create
+ if (!sevp)
+ return syscall_checked<int>(SYS_timer_create, clockid, nullptr, timerid);
+
+ KernelSigevent ksev(*sevp);
+ return syscall_checked<int>(SYS_timer_create, clockid, &ksev, timerid);
+#else
+#error "SYS_timer_create syscall not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_CREATE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_delete.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_delete.h
new file mode 100644
index 00000000000..bc41a6d6d2e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_delete.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 timer_delete syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_DELETE_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_DELETE_H
+
+#include "hdr/types/timer_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> timer_delete(timer_t timerid) {
+#ifdef SYS_timer_delete
+ return syscall_checked<int>(SYS_timer_delete, timerid);
+#else
+#error "SYS_timer_delete syscall not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_DELETE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_gettime.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_gettime.h
new file mode 100644
index 00000000000..ae31d1a498c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_gettime.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
+/// Implementation header for timer_gettime syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_GETTIME_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_GETTIME_H
+
+#include "hdr/types/struct_itimerspec.h"
+#include "hdr/types/timer_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> timer_gettime(timer_t timerid, itimerspec *val) {
+#if defined(SYS_timer_gettime64)
+ static_assert(
+ sizeof(time_t) == sizeof(int64_t),
+ "SYS_timer_gettime64 requires struct timespec with 64-bit members.");
+ return syscall_checked<int>(SYS_timer_gettime64, timerid, val);
+#elif defined(SYS_timer_gettime)
+ static_assert(
+ sizeof(timespec::tv_nsec) == sizeof(long),
+ "This legacy syscall fallback is only safe on platforms where tv_nsec "
+ "matches the register size (long). It is unsafe on 32-bit platforms "
+ "with 64-bit tv_nsec.");
+ return syscall_checked<int>(SYS_timer_gettime, timerid, val);
+#else
+#error "SYS_timer_gettime and SYS_timer_gettime64 syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_GETTIME_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_settime.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_settime.h
new file mode 100644
index 00000000000..d7a44da4054
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/timer_settime.h
@@ -0,0 +1,50 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 timer_settime syscall wrapper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_SETTIME_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_SETTIME_H
+
+#include "hdr/types/struct_itimerspec.h"
+#include "hdr/types/timer_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> timer_settime(timer_t timerid, int flags,
+ const itimerspec *val, itimerspec *old) {
+#if defined(SYS_timer_settime64)
+ static_assert(
+ sizeof(time_t) == sizeof(int64_t),
+ "SYS_timer_settime64 requires struct timespec with 64-bit members.");
+ return syscall_checked<int>(SYS_timer_settime64, timerid, flags, val, old);
+#elif defined(SYS_timer_settime)
+ static_assert(
+ sizeof(timespec::tv_nsec) == sizeof(long),
+ "This legacy syscall fallback is only safe on platforms where tv_nsec "
+ "matches the register size (long). It is unsafe on 32-bit platforms "
+ "with 64-bit tv_nsec.");
+ return syscall_checked<int>(SYS_timer_settime, timerid, flags, val, old);
+#else
+#error "SYS_timer_settime and SYS_timer_settime64 syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_TIMER_SETTIME_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/wait4.h b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/wait4.h
new file mode 100644
index 00000000000..ac17b93166a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/OSUtil/linux/syscall_wrappers/wait4.h
@@ -0,0 +1,99 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 wait4.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_WAIT4_H
+#define LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_WAIT4_H
+
+#include "hdr/signal_macros.h"
+#include "hdr/sys_wait_macros.h"
+#include "hdr/types/pid_t.h"
+#include "hdr/types/siginfo_t.h"
+#include "hdr/types/struct_rusage.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<pid_t> wait4(pid_t pid, int *wstatus, int options,
+ struct rusage *rusage) {
+#ifdef SYS_wait4
+ return syscall_checked<pid_t>(SYS_wait4, pid, wstatus, options, rusage);
+#elif defined(SYS_waitid)
+ // Architectures without wait4 (e.g. riscv32) provide waitid instead.
+ int idtype = P_PID;
+ if (pid == -1) {
+ idtype = P_ALL;
+ } else if (pid < -1) {
+ idtype = P_PGID;
+ pid *= -1;
+ } else if (pid == 0) {
+ idtype = P_PGID;
+ }
+
+ options |= WEXITED;
+
+ // Linux always writes si_pid and si_signo (see SYSCALL_DEFINE5(waitid) in
+ // kernel/exit.c), zeroing them when WNOHANG found nothing, so si_pid is a
+ // reliable "was anything reaped" flag. Initialize it anyway: POSIX only
+ // requires this since POSIX.1-2008 TC1.
+ siginfo_t info;
+ info.si_pid = 0;
+ auto result =
+ syscall_checked<pid_t>(SYS_waitid, idtype, pid, &info, options, rusage);
+ if (!result.has_value())
+ return result;
+
+ // WNOHANG with nothing to reap. Return 0 without touching wstatus, which is
+ // what wait4 does; falling through would clobber it via the default case.
+ if (info.si_pid == 0)
+ return 0;
+
+ if (wstatus) {
+ switch (info.si_code) {
+ case CLD_EXITED:
+ *wstatus = W_EXITCODE(info.si_status, 0);
+ break;
+ case CLD_DUMPED:
+ *wstatus = info.si_status | WCOREFLAG;
+ break;
+ case CLD_KILLED:
+ *wstatus = info.si_status;
+ break;
+ case CLD_TRAPPED:
+ case CLD_STOPPED:
+ *wstatus = W_STOPCODE(info.si_status);
+ break;
+ case CLD_CONTINUED:
+ // Set wstatus to a value that the caller can check via WIFCONTINUED.
+ // glibc has a non-POSIX macro definition __W_CONTINUED for this value.
+ *wstatus = 0xffff;
+ break;
+ default:
+ *wstatus = 0;
+ break;
+ }
+ }
+ return info.si_pid;
+#else
+#error "wait4 and waitid syscalls not available."
+#endif
+}
+
+} // namespace linux_syscalls
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_OSUTIL_SYSCALL_WRAPPERS_WAIT4_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 29da5b9866b..5d2675909f2 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
@@ -124,10 +124,14 @@ LIBC_INLINE constexpr DoubleWide<word> mul2(word a, word b) {
word no_carry = 0;
word carry = 0;
[[maybe_unused]] word _ = 0; // unused carry variable.
- lo_digit = add_with_carry<word>(lo_digit, shiftl(step2), no_carry, carry);
- hi_digit = add_with_carry<word>(hi_digit, shiftr(step2), carry, _);
- lo_digit = add_with_carry<word>(lo_digit, shiftl(step3), no_carry, carry);
- hi_digit = add_with_carry<word>(hi_digit, shiftr(step3), carry, _);
+ lo_digit = LIBC_NAMESPACE::add_with_carry<word>(lo_digit, shiftl(step2),
+ no_carry, carry);
+ hi_digit =
+ LIBC_NAMESPACE::add_with_carry<word>(hi_digit, shiftr(step2), carry, _);
+ lo_digit = LIBC_NAMESPACE::add_with_carry<word>(lo_digit, shiftl(step3),
+ no_carry, carry);
+ hi_digit =
+ LIBC_NAMESPACE::add_with_carry<word>(hi_digit, shiftr(step3), carry, _);
return DoubleWide<word>(lo_digit, hi_digit);
}
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/CMakeLists.txt
index f5b5ffe3e07..366b35bd0de 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/CMakeLists.txt
@@ -1,3 +1,42 @@
+add_header_library(
+ cmp_helper
+ HDRS
+ cmp_helper.h
+ DEPENDS
+ libc.src.__support.FPUtil.comparison_operations
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.c
+)
+
+add_header_library(
+ floatint_helper
+ HDRS
+ floatint_helper.h
+ DEPENDS
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.dyadic_float
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.sign
+)
+
+add_header_library(
+ fpconvert_helper
+ HDRS
+ fpconvert_helper.h
+ DEPENDS
+ libc.hdr.fenv_macros
+ libc.src.__support.CPP.algorithm
+ libc.src.__support.CPP.bit
+ libc.src.__support.CPP.type_traits
+ libc.src.__support.FPUtil.dyadic_float
+ libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+)
+
add_header_library(
addtf3
HDRS
@@ -83,13 +122,30 @@ add_header_library(
libc.src.__support.macros.config
)
+add_header_library(
+ negsf2
+ HDRS
+ negsf2.h
+ DEPENDS
+ libc.src.__support.macros.config
+ libc.src.__support.FPUtil.fp_bits
+)
+
+add_header_library(
+ negdf2
+ HDRS
+ negdf2.h
+ DEPENDS
+ libc.src.__support.macros.config
+ libc.src.__support.FPUtil.fp_bits
+)
+
add_header_library(
subsf3
HDRS
subsf3.h
DEPENDS
libc.src.__support.FPUtil.generic.add_sub
- libc.src.__support.macros.config
)
add_header_library(
@@ -109,3 +165,335 @@ add_header_library(
libc.src.__support.FPUtil.generic.div
libc.src.__support.macros.config
)
+
+add_header_library(
+ extendsftf2
+ HDRS
+ extendsftf2.h
+ DEPENDS
+ libc.include.llvm-libc-types.float128
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ extenddftf2
+ HDRS
+ extenddftf2.h
+ DEPENDS
+ libc.include.llvm-libc-types.float128
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ extendxftf2
+ HDRS
+ extendxftf2.h
+ DEPENDS
+ libc.include.llvm-libc-types.float128
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+ trunctfdf2
+ HDRS
+ trunctfdf2.h
+ DEPENDS
+ libc.include.llvm-libc-types.float128
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ trunctfsf2
+ HDRS
+ trunctfsf2.h
+ DEPENDS
+ libc.include.llvm-libc-types.float128
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ trunctfxf2
+ HDRS
+ trunctfxf2.h
+ DEPENDS
+ libc.include.llvm-libc-types.float128
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+ extendsfdf2
+ HDRS
+ extendsfdf2.h
+ DEPENDS
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ truncdfsf2
+ HDRS
+ truncdfsf2.h
+ DEPENDS
+ libc.src.__support.builtins.fpconvert_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixdfdi
+ HDRS
+ fixdfdi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixdfti
+ HDRS
+ fixdfti.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.uint128
+)
+
+add_header_library(
+ fixdfsi
+ HDRS
+ fixdfsi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixsfsi
+ HDRS
+ fixsfsi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixsfdi
+ HDRS
+ fixsfdi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixsfti
+ HDRS
+ fixsfti.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.uint128
+)
+
+add_header_library(
+ fixunsdfsi
+ HDRS
+ fixunsdfsi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixunsdfdi
+ HDRS
+ fixunsdfdi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixunsdfti
+ HDRS
+ fixunsdfti.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.uint128
+)
+
+add_header_library(
+ fixunssfsi
+ HDRS
+ fixunssfsi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixunssfdi
+ HDRS
+ fixunssfdi.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ fixunssfti
+ HDRS
+ fixunssfti.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.fixint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+ libc.src.__support.uint128
+)
+
+add_header_library(
+ floatsidf
+ HDRS
+ floatsidf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floatdidf
+ HDRS
+ floatdidf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floattidf
+ HDRS
+ floattidf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+ floatsisf
+ HDRS
+ floatsisf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floatdisf
+ HDRS
+ floatdisf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floattisf
+ HDRS
+ floattisf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+ floatunsidf
+ HDRS
+ floatunsidf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floatundidf
+ HDRS
+ floatundidf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floatuntidf
+ HDRS
+ floatuntidf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
+
+add_header_library(
+ floatunsisf
+ HDRS
+ floatunsisf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floatundisf
+ HDRS
+ floatundisf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+)
+
+add_header_library(
+ floatuntisf
+ HDRS
+ floatuntisf.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.src.__support.builtins.floatint_helper
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
+)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/addtf3.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/addtf3.h
index f33036f53ec..74a3fd57a32 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/addtf3.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/addtf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -33,6 +33,6 @@ LIBC_INLINE float128 addtf3(float128 x, float128 y) {
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_ADDTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/cmp_helper.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/cmp_helper.h
new file mode 100644
index 00000000000..7cbfb70287f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/cmp_helper.h
@@ -0,0 +1,63 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 floating-point comparison results for compiler-rt's soft-float
+/// compare builtins. These mirror compiler-rt's GCC-compatible __le<f>2 /
+/// __ge<f>2 / __unord<f>2 (quiet: they raise no FP exceptions), reusing
+/// LLVM-libc's IEEE comparison predicates, so they can be reused by
+/// compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_CMP_HELPER_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_CMP_HELPER_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/comparison_operations.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// GCC soft-float compare, "LE" convention: -1 if a<b, 0 if a==b, 1 if a>b, and
+// 1 when unordered (either operand is NaN). Quiet -- raises no FP exceptions,
+// matching compiler-rt's __le<f>2 (which __eq/__ne/__lt/__cmp alias). NaN is
+// handled up front so the ordering predicates are only reached for non-NaN
+// inputs, where they never signal.
+template <typename T> LIBC_INLINE int cmp_le(T a, T b) {
+ using FPBits = fputil::FPBits<T>;
+ if (FPBits(a).is_nan() || FPBits(b).is_nan())
+ return 1; // LE_UNORDERED
+ if (fputil::equals(a, b))
+ return 0; // LE_EQUAL
+ return fputil::less_than(a, b) ? -1 : 1; // LE_LESS : LE_GREATER
+}
+
+// Same as cmp_le, but unordered yields -1; matches compiler-rt's __ge<f>2
+// (which __gt aliases).
+template <typename T> LIBC_INLINE int cmp_ge(T a, T b) {
+ using FPBits = fputil::FPBits<T>;
+ if (FPBits(a).is_nan() || FPBits(b).is_nan())
+ return -1; // GE_UNORDERED
+ if (fputil::equals(a, b))
+ return 0; // GE_EQUAL
+ return fputil::greater_than(a, b) ? 1 : -1; // GE_GREATER : GE_LESS
+}
+
+// 1 iff either operand is NaN, else 0; matches compiler-rt's __unord<f>2.
+template <typename T> LIBC_INLINE int cmp_unord(T a, T b) {
+ using FPBits = fputil::FPBits<T>;
+ return FPBits(a).is_nan() || FPBits(b).is_nan();
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_CMP_HELPER_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/divtf3.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/divtf3.h
index 7f25586cde6..ce448bcd18c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/divtf3.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/divtf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/div.h"
#include "src/__support/macros/config.h"
@@ -33,6 +33,6 @@ LIBC_INLINE float128 divtf3(float128 x, float128 y) {
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_DIVTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extenddftf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extenddftf2.h
new file mode 100644
index 00000000000..5b522d752c3
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extenddftf2.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extenddftf2 implementation as
+/// builtins::extenddftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDDFTF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDDFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend double to float128; mirrors compiler-rt's __extenddftf2.
+LIBC_INLINE float128 extenddftf2(double x) { return fpconvert<float128>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDDFTF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendsfdf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendsfdf2.h
new file mode 100644
index 00000000000..bcd57d10a4a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendsfdf2.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extendsfdf2 implementation as
+/// builtins::extendsfdf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFDF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFDF2_H
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend float to double; mirrors compiler-rt's __extendsfdf2.
+LIBC_INLINE double extendsfdf2(float x) { return fpconvert<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFDF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendsftf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendsftf2.h
new file mode 100644
index 00000000000..914d235a12a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendsftf2.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extendsftf2 implementation as
+/// builtins::extendsftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFTF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend float to float128; mirrors compiler-rt's __extendsftf2.
+LIBC_INLINE float128 extendsftf2(float x) { return fpconvert<float128>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDSFTF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendxftf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendxftf2.h
new file mode 100644
index 00000000000..1bb35a8e607
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/extendxftf2.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __extendxftf2 implementation as
+/// builtins::extendxftf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDXFTF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDXFTF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128) && \
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Extend long double to float128; mirrors compiler-rt's __extendxftf2.
+LIBC_INLINE float128 extendxftf2(long double x) {
+ return fpconvert<float128>(x);
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128 &&
+ // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_EXTENDXFTF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfdi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfdi.h
new file mode 100644
index 00000000000..9ca5afa20c5
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfdi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixdfdi implementation as
+/// builtins::fixdfdi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFDI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFDI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating double -> int64_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixdfdi.
+LIBC_INLINE int64_t fixdfdi(double x) { return fixint<int64_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfsi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfsi.h
new file mode 100644
index 00000000000..ef38849251f
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfsi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixdfsi implementation as
+/// builtins::fixdfsi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFSI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFSI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating double -> int32_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixdfsi.
+LIBC_INLINE int32_t fixdfsi(double x) { return fixint<int32_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfti.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfti.h
new file mode 100644
index 00000000000..bf2d2961ec1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixdfti.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
+/// This header exposes LLVM-libc's __fixdfti implementation as
+/// builtins::fixdfti so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFTI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating double -> Int128 conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixdfti.
+LIBC_INLINE Int128 fixdfti(double x) { return fixint<Int128>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXDFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixint_helper.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixint_helper.h
new file mode 100644
index 00000000000..ab2125ff243
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixint_helper.h
@@ -0,0 +1,84 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 truncating float-to-integer conversions, saturating on overflow.
+/// These mirror compiler-rt's __fix<f><i> / __fixuns<f><i> builtins via an
+/// FPBits unpack + shift, so they can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXINT_HELPER_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXINT_HELPER_H
+
+#include "src/__support/CPP/limits.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// TODO: use fputil::round_to_signed_integer after adding Float128/64/32/16
+// classes currently, we use these helpers to avoid an infinite loop that
+// happens because fputil::round_to_signed_integer calls the builtins if
+// the target doesn't have FPU.
+
+// Truncating conversion of F to the signed integer I (round toward zero).
+// Out-of-range magnitudes saturate to I's min/max; mirrors compiler-rt __fix*.
+template <typename I, typename F> LIBC_INLINE constexpr I fixint(F a) {
+ using FPBits = fputil::FPBits<F>;
+ using UI = cpp::make_unsigned_t<I>;
+ constexpr I FIXINT_MAX = cpp::numeric_limits<I>::max();
+ constexpr I FIXINT_MIN = cpp::numeric_limits<I>::min();
+
+ const FPBits bits(a);
+ const I sign = bits.is_neg() ? -1 : 1;
+ const int exponent = bits.get_exponent();
+ const typename FPBits::StorageType significand = bits.get_explicit_mantissa();
+
+ if (exponent < 0)
+ return 0;
+
+ if (static_cast<unsigned>(exponent) >= sizeof(I) * 8)
+ return sign == 1 ? FIXINT_MAX : FIXINT_MIN;
+
+ if (exponent < FPBits::FRACTION_LEN)
+ return sign *
+ static_cast<I>(significand >> (FPBits::FRACTION_LEN - exponent));
+ return sign * static_cast<I>(static_cast<UI>(significand)
+ << (exponent - FPBits::FRACTION_LEN));
+}
+
+// Truncating conversion of F to the unsigned integer U (round toward zero).
+// Negative or out-of-range values yield 0 / U's max; mirrors compiler-rt
+// __fixuns*.
+template <typename U, typename F> LIBC_INLINE constexpr U fixuint(F a) {
+ using FPBits = fputil::FPBits<F>;
+
+ const FPBits bits(a);
+ const int exponent = bits.get_exponent();
+ const typename FPBits::StorageType significand = bits.get_explicit_mantissa();
+
+ if (bits.is_neg() || exponent < 0)
+ return 0;
+
+ if (static_cast<unsigned>(exponent) >= sizeof(U) * 8)
+ return ~U(0);
+
+ if (exponent < FPBits::FRACTION_LEN)
+ return static_cast<U>(significand >> (FPBits::FRACTION_LEN - exponent));
+ return static_cast<U>(static_cast<U>(significand)
+ << (exponent - FPBits::FRACTION_LEN));
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXINT_HELPER_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfdi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfdi.h
new file mode 100644
index 00000000000..87b10f3d8c1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfdi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixsfdi implementation as
+/// builtins::fixsfdi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFDI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFDI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating float -> int64_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixsfdi.
+LIBC_INLINE int64_t fixsfdi(float x) { return fixint<int64_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfsi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfsi.h
new file mode 100644
index 00000000000..1eded97192e
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfsi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixsfsi implementation as
+/// builtins::fixsfsi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFSI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFSI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating float -> int32_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixsfsi.
+LIBC_INLINE int32_t fixsfsi(float x) { return fixint<int32_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfti.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfti.h
new file mode 100644
index 00000000000..1c39301fbdf
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixsfti.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
+/// This header exposes LLVM-libc's __fixsfti implementation as
+/// builtins::fixsfti so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFTI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating float -> Int128 conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixsfti.
+LIBC_INLINE Int128 fixsfti(float x) { return fixint<Int128>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXSFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfdi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfdi.h
new file mode 100644
index 00000000000..c9531ceac4a
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfdi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixunsdfdi implementation as
+/// builtins::fixunsdfdi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFDI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFDI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating double -> uint64_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixunsdfdi.
+LIBC_INLINE uint64_t fixunsdfdi(double x) { return fixuint<uint64_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfsi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfsi.h
new file mode 100644
index 00000000000..4a6117c4022
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfsi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixunsdfsi implementation as
+/// builtins::fixunsdfsi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFSI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFSI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating double -> uint32_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixunsdfsi.
+LIBC_INLINE uint32_t fixunsdfsi(double x) { return fixuint<uint32_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfti.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfti.h
new file mode 100644
index 00000000000..596e9c7bc51
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunsdfti.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
+/// This header exposes LLVM-libc's __fixunsdfti implementation as
+/// builtins::fixunsdfti so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFTI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating double -> UInt128 conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixunsdfti.
+LIBC_INLINE UInt128 fixunsdfti(double x) { return fixuint<UInt128>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSDFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfdi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfdi.h
new file mode 100644
index 00000000000..68befe8331d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfdi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixunssfdi implementation as
+/// builtins::fixunssfdi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFDI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFDI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating float -> uint64_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixunssfdi.
+LIBC_INLINE uint64_t fixunssfdi(float x) { return fixuint<uint64_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFDI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfsi.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfsi.h
new file mode 100644
index 00000000000..fe0dbe62d49
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfsi.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __fixunssfsi implementation as
+/// builtins::fixunssfsi so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFSI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFSI_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating float -> uint32_t conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixunssfsi.
+LIBC_INLINE uint32_t fixunssfsi(float x) { return fixuint<uint32_t>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFSI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfti.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfti.h
new file mode 100644
index 00000000000..567d5de8159
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fixunssfti.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
+/// This header exposes LLVM-libc's __fixunssfti implementation as
+/// builtins::fixunssfti so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFTI_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFTI_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/fixint_helper.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/uint128.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncating float -> UInt128 conversion, saturating on overflow.
+// Mirrors compiler-rt's __fixunssfti.
+LIBC_INLINE UInt128 fixunssfti(float x) { return fixuint<UInt128>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FIXUNSSFTI_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatdidf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatdidf.h
new file mode 100644
index 00000000000..c9843d53d55
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatdidf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatdidf implementation as
+/// builtins::floatdidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATDIDF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATDIDF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// double <- int64_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatdidf.
+LIBC_INLINE double floatdidf(int64_t x) { return floatint<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATDIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatdisf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatdisf.h
new file mode 100644
index 00000000000..b53595a782c
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatdisf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatdisf implementation as
+/// builtins::floatdisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATDISF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATDISF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// float <- int64_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatdisf.
+LIBC_INLINE float floatdisf(int64_t x) { return floatint<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATDISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatint_helper.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatint_helper.h
new file mode 100644
index 00000000000..8aaf9f78e8d
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatint_helper.h
@@ -0,0 +1,59 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 integer-to-floating-point conversions, rounded to nearest with ties
+/// to even. These mirror compiler-rt's __float<i><f> / __floatun<i><f>
+/// builtins via an LLVM-libc DyadicFloat, so they can be reused by
+/// compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATINT_HELPER_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATINT_HELPER_H
+
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/sign.h"
+
+#include <stddef.h>
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// TODO: use constructors after adding Float128/64/32/16 classes.
+
+// Convert the integer I to the floating-point type F, rounding to nearest
+// (ties to even) per the current rounding mode. Handles signed and unsigned
+// I alike; mirrors compiler-rt's __float<i><f> / __floatun<i><f>.
+template <typename F, typename I> LIBC_INLINE constexpr F floatint(I x) {
+ using UI = cpp::make_unsigned_t<I>;
+
+ Sign sign = Sign::POS;
+ UI mag = static_cast<UI>(x);
+ if constexpr (cpp::is_signed_v<I>) {
+ if (x < 0) {
+ sign = Sign::NEG;
+ mag = static_cast<UI>(-mag); // modular negation; correct for I's min too
+ }
+ }
+
+ // A mantissa wide enough for I and for F's fraction, rounded up to a whole
+ // number of 64-bit words (UInt's width requirement). With exponent 0 the
+ // dyadic value is exactly `mag`, which as<F>() then rounds to F.
+ constexpr size_t NEED = (sizeof(I) > sizeof(F) ? sizeof(I) : sizeof(F)) * 8;
+ constexpr size_t BITS = ((NEED + 63) / 64) * 64;
+ return static_cast<F>(fputil::DyadicFloat<BITS>(sign, 0, mag));
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATINT_HELPER_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatsidf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatsidf.h
new file mode 100644
index 00000000000..28b0c27bb59
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatsidf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatsidf implementation as
+/// builtins::floatsidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATSIDF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATSIDF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// double <- int32_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatsidf.
+LIBC_INLINE double floatsidf(int32_t x) { return floatint<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATSIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatsisf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatsisf.h
new file mode 100644
index 00000000000..75ab24c7680
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatsisf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatsisf implementation as
+/// builtins::floatsisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATSISF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATSISF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// float <- int32_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatsisf.
+LIBC_INLINE float floatsisf(int32_t x) { return floatint<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATSISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floattidf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floattidf.h
new file mode 100644
index 00000000000..2e6d85fa332
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floattidf.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floattidf implementation as
+/// builtins::floattidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATTIDF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATTIDF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// double <- Int128 conversion, round to nearest.
+// Mirrors compiler-rt's __floattidf.
+LIBC_INLINE double floattidf(Int128 x) { return floatint<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATTIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floattisf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floattisf.h
new file mode 100644
index 00000000000..7bb8d8adc11
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floattisf.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floattisf implementation as
+/// builtins::floattisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATTISF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATTISF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// float <- Int128 conversion, round to nearest.
+// Mirrors compiler-rt's __floattisf.
+LIBC_INLINE float floattisf(Int128 x) { return floatint<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATTISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatundidf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatundidf.h
new file mode 100644
index 00000000000..c368602892b
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatundidf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatundidf implementation as
+/// builtins::floatundidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNDIDF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNDIDF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// double <- uint64_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatundidf.
+LIBC_INLINE double floatundidf(uint64_t x) { return floatint<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNDIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatundisf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatundisf.h
new file mode 100644
index 00000000000..ba450937ff7
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatundisf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatundisf implementation as
+/// builtins::floatundisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNDISF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNDISF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// float <- uint64_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatundisf.
+LIBC_INLINE float floatundisf(uint64_t x) { return floatint<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNDISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatunsidf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatunsidf.h
new file mode 100644
index 00000000000..5fa90c64077
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatunsidf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatunsidf implementation as
+/// builtins::floatunsidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNSIDF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNSIDF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// double <- uint32_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatunsidf.
+LIBC_INLINE double floatunsidf(uint32_t x) { return floatint<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNSIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatunsisf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatunsisf.h
new file mode 100644
index 00000000000..cb8bd27a044
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatunsisf.h
@@ -0,0 +1,32 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatunsisf implementation as
+/// builtins::floatunsisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNSISF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNSISF_H
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// float <- uint32_t conversion, round to nearest.
+// Mirrors compiler-rt's __floatunsisf.
+LIBC_INLINE float floatunsisf(uint32_t x) { return floatint<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNSISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatuntidf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatuntidf.h
new file mode 100644
index 00000000000..105ba292bff
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatuntidf.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatuntidf implementation as
+/// builtins::floatuntidf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNTIDF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNTIDF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// double <- UInt128 conversion, round to nearest.
+// Mirrors compiler-rt's __floatuntidf.
+LIBC_INLINE double floatuntidf(UInt128 x) { return floatint<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNTIDF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatuntisf.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatuntisf.h
new file mode 100644
index 00000000000..c244ee1d534
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/floatuntisf.h
@@ -0,0 +1,38 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __floatuntisf implementation as
+/// builtins::floatuntisf so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNTISF_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNTISF_H
+
+#include "src/__support/macros/properties/types.h"
+
+#ifdef LIBC_TYPES_HAS_INT128
+
+#include "hdr/stdint_proxy.h"
+#include "src/__support/builtins/floatint_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// float <- UInt128 conversion, round to nearest.
+// Mirrors compiler-rt's __floatuntisf.
+LIBC_INLINE float floatuntisf(UInt128 x) { return floatint<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_INT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FLOATUNTISF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fpconvert_helper.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fpconvert_helper.h
new file mode 100644
index 00000000000..f892bc4d2a1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/fpconvert_helper.h
@@ -0,0 +1,83 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 float-to-float extend/truncate conversions, rounding to nearest
+/// (ties to even) when narrowing. These mirror compiler-rt's __extend<a><b>2 /
+/// __trunc<a><b>2 builtins, so they can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H
+
+#include "hdr/fenv_macros.h"
+#include "src/__support/CPP/algorithm.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/type_traits.h"
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// TODO: use fputil::cast after adding Float128/64/32/16 classes currently, we
+// are using this helper to avoid an infinity loop that happens because
+// fputil::cast is calling the builtins if the target doesn't have FPU.
+//
+// assembly (each body below compiles to a self-call):
+// // double f(float128 x) { return cast<double>(x); }
+// trunc_tf_df: callq __trunctfdf2@PLT
+// // float128 g(double x) { return cast<float128>(x); }
+// ext_df_tf: jmp __extenddftf2@PLT // TAILCALL
+
+// Convert the floating-point value x from From to To (extend or truncate).
+// Narrowing rounds to nearest, ties to even; mirrors compiler-rt __extend* /
+// __trunc*.
+template <typename To, typename From>
+LIBC_INLINE constexpr To fpconvert(From x) {
+ using FromBits = fputil::FPBits<From>;
+ using ToBits = fputil::FPBits<To>;
+ using ToStorageType = typename ToBits::StorageType;
+
+ FromBits x_bits(x);
+
+ if constexpr (cpp::is_same_v<To, From>)
+ return x;
+
+ if (x_bits.is_nan()) {
+ typename FromBits::StorageType x_frac = x_bits.get_mantissa();
+ if constexpr (ToBits::FRACTION_LEN >= FromBits::FRACTION_LEN) {
+ ToStorageType to_frac =
+ static_cast<ToStorageType>(x_frac)
+ << (ToBits::FRACTION_LEN - FromBits::FRACTION_LEN);
+ return ToBits::signaling_nan(x_bits.sign(), to_frac).get_val();
+ }
+ ToStorageType to_frac = static_cast<ToStorageType>(
+ x_frac >> (FromBits::FRACTION_LEN - ToBits::FRACTION_LEN));
+ return ToBits::quiet_nan(x_bits.sign(), to_frac).get_val();
+ }
+
+ if (x_bits.is_inf())
+ return ToBits::inf(x_bits.sign()).get_val();
+
+ // Zero and subnormals fall through: DyadicFloat(x) gives a zero mantissa for
+ // zero, which as<To>() maps back to a correctly-signed zero.
+ constexpr size_t MAX_FRACTION_LEN =
+ cpp::max(ToBits::FRACTION_LEN, FromBits::FRACTION_LEN);
+ fputil::DyadicFloat<cpp::bit_ceil(MAX_FRACTION_LEN)> xd(x);
+ return xd.template as<To, /*ShouldSignalExceptions=*/true>();
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_FPCONVERT_HELPER_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/multf3.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/multf3.h
index b6798325ff1..bde6d5497cf 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/multf3.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/multf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/mul.h"
#include "src/__support/macros/config.h"
@@ -33,6 +33,6 @@ LIBC_INLINE float128 multf3(float128 x, float128 y) {
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_MULTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/negdf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/negdf2.h
new file mode 100644
index 00000000000..9d290fc7750
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/negdf2.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __negdf2 implementation as builtins::negdf2
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_NEGDF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_NEGDF2_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Double-precision negation
+// Mirrors compiler-rt's __negdf2.
+LIBC_INLINE double negdf2(double x) {
+ using FPBits = fputil::FPBits<double>;
+
+ FPBits bits(x);
+ bits.set_sign(bits.sign().negate());
+ return bits.get_val();
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_NEGDF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/negsf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/negsf2.h
new file mode 100644
index 00000000000..81ab53ca775
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/negsf2.h
@@ -0,0 +1,37 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __negsf2 implementation as builtins::negsf2
+/// so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_NEGSF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_NEGSF2_H
+
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Single-precision negation
+// Mirrors compiler-rt's __negsf2.
+LIBC_INLINE float negsf2(float x) {
+ using FPBits = fputil::FPBits<float>;
+
+ FPBits bits(x);
+ bits.set_sign(bits.sign().negate());
+ return bits.get_val();
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_NEGSF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/subtf3.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/subtf3.h
index bd758cce0f5..0b048d4e3ce 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/subtf3.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/subtf3.h
@@ -17,7 +17,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -33,6 +33,6 @@ LIBC_INLINE float128 subtf3(float128 x, float128 y) {
} // namespace builtins
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_SUBTF3_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/truncdfsf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/truncdfsf2.h
new file mode 100644
index 00000000000..bb59a22e585
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/truncdfsf2.h
@@ -0,0 +1,30 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __truncdfsf2 implementation as
+/// builtins::truncdfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFSF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFSF2_H
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate double to float; mirrors compiler-rt's __truncdfsf2.
+LIBC_INLINE float truncdfsf2(double x) { return fpconvert<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCDFSF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfdf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfdf2.h
new file mode 100644
index 00000000000..5fa57437931
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfdf2.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __trunctfdf2 implementation as
+/// builtins::trunctfdf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFDF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFDF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float128 to double; mirrors compiler-rt's __trunctfdf2.
+LIBC_INLINE double trunctfdf2(float128 x) { return fpconvert<double>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFDF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfsf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfsf2.h
new file mode 100644
index 00000000000..1ca5c862f95
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfsf2.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __trunctfsf2 implementation as
+/// builtins::trunctfsf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFSF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFSF2_H
+
+#include "include/llvm-libc-types/float128.h"
+
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float128 to float; mirrors compiler-rt's __trunctfsf2.
+LIBC_INLINE float trunctfsf2(float128 x) { return fpconvert<float>(x); }
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFSF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfxf2.h b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfxf2.h
new file mode 100644
index 00000000000..698a2616dde
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/builtins/trunctfxf2.h
@@ -0,0 +1,41 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 header exposes LLVM-libc's __trunctfxf2 implementation as
+/// builtins::trunctfxf2 so that it can be reused by compiler-rt's builtins.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFXF2_H
+#define LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFXF2_H
+
+#include "include/llvm-libc-types/float128.h"
+#include "src/__support/macros/properties/types.h"
+
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128) && \
+ defined(LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80)
+
+#include "src/__support/builtins/fpconvert_helper.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+namespace builtins {
+
+// Truncate float128 to long double; mirrors compiler-rt's __trunctfxf2.
+LIBC_INLINE long double trunctfxf2(float128 x) {
+ return fpconvert<long double>(x);
+}
+
+} // namespace builtins
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128 &&
+ // LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
+
+#endif // LLVM_LIBC_SRC___SUPPORT_BUILTINS_TRUNCTFXF2_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/common.h b/deps/v8/third_party/llvm-libc/src/src/__support/common.h
index d90fe7b8ae9..454dfb43b74 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/common.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/common.h
@@ -15,8 +15,15 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/hardening.h"
#include "src/__support/macros/properties/architectures.h"
#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/os.h"
+
+#if defined(__APPLE__) || (defined(LIBC_TARGET_OS_IS_WINDOWS) && \
+ defined(LIBC_TARGET_ARCH_IS_X86_32))
+#define LIBC_TARGET_USES_LEADING_UNDERSCORE
+#endif
#ifndef LLVM_LIBC_FUNCTION_ATTR
#define LLVM_LIBC_FUNCTION_ATTR
@@ -44,29 +51,44 @@
#define LLVM_LIBC_ATTR(name) EXPAND_THEN_SECOND(LLVM_LIBC_FUNCTION_ATTR_##name)
-// At the moment, [[gnu::alias()]] is not supported on MacOS, and it is needed
-// to cleanly export and alias the C++ symbol `LIBC_NAMESPACE::func` with the C
-// symbol `func`. So for public packaging on MacOS, we will only export the C
-// symbol. Moreover, a C symbol `func` in macOS is mangled as `_func`.
+// Export both `func` and `LIBC_NAMESPACE::func` using an alias symbol.
+// This does not work on platfors with LIBC_TARGET_USES_LEADING_UNDERSCORE
+// so there this only exports `_func`.
#if defined(LIBC_COPT_PUBLIC_PACKAGING) && !defined(LIBC_COMPILER_IS_MSVC)
-#ifndef __APPLE__
+#ifndef LIBC_TARGET_USES_LEADING_UNDERSCORE
#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \
LLVM_LIBC_ATTR(name) \
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) \
__##name##_impl__ asm(c_alias); \
decltype(LIBC_NAMESPACE::name) name [[gnu::alias(c_alias)]]; \
type __##name##_impl__ arglist
-#else // __APPLE__
+
+#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
+ extern "C" decltype(LIBC_NAMESPACE::name) c_alias [[gnu::alias(#name)]]
+
+#else // LIBC_TARGET_USES_LEADING_UNDERSCORE
#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \
LLVM_LIBC_ATTR(name) \
LLVM_LIBC_FUNCTION_ATTR decltype(LIBC_NAMESPACE::name) name asm( \
"_" c_alias); \
type name arglist
-#endif // __APPLE__
+
+// clang-format off
+#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
+ asm(".text\n" \
+ ".global " "_" #c_alias "\n" \
+ ".type " "_" #c_alias ", @function\n" \
+ "_" #c_alias " = " "_" #name "\n")
+// clang-format on
+#endif // LIBC_TARGET_USES_LEADING_UNDERSCORE
#else // LIBC_COPT_PUBLIC_PACKAGING
#define LLVM_LIBC_FUNCTION_IMPL_4(type, name, arglist, c_alias) \
type name arglist
+
+#define LLVM_LIBC_ADD_FUNCTION_C_ALIAS(name, c_alias) \
+ static_assert(true, "Require semicolon.")
+
#endif // LIBC_COPT_PUBLIC_PACKAGING
#define LLVM_LIBC_FUNCTION_IMPL_3(type, name, arglist) \
@@ -78,25 +100,23 @@
GET_FIFTH(__VA_ARGS__, LLVM_LIBC_FUNCTION_IMPL_4, LLVM_LIBC_FUNCTION_IMPL_3, \
GET_NOTHING)(__VA_ARGS__)
-// At the moment, [[gnu::alias()]] is not supported on MacOS, and it is needed
-// to cleanly export and alias the C++ symbol `LIBC_NAMESPACE::func` with the C
-// symbol `func`. So for public packaging on MacOS, we will only export the C
-// symbol. Moreover, a C symbol `func` in macOS is mangled as `_func`.
+// See comment on LLVM_LIBC_FUNCTION_IMPL_4 for why this checks
+// LIBC_TARGET_USES_LEADING_UNDERSCORE.
#if defined(LIBC_COPT_PUBLIC_PACKAGING) && !defined(LIBC_COMPILER_IS_MSVC)
-#ifndef __APPLE__
+#ifndef LIBC_TARGET_USES_LEADING_UNDERSCORE
#define LLVM_LIBC_VARIABLE_IMPL(type, name) \
LLVM_LIBC_ATTR(name) \
extern LLVM_LIBC_VARIABLE_ATTR decltype(LIBC_NAMESPACE::name) \
__##name##_impl__ asm(#name); \
extern decltype(LIBC_NAMESPACE::name) name [[gnu::alias(#name)]]; \
type __##name##_impl__
-#else // __APPLE__
+#else // LIBC_TARGET_USES_LEADING_UNDERSCORE
#define LLVM_LIBC_VARIABLE_IMPL(type, name) \
LLVM_LIBC_ATTR(name) \
extern LLVM_LIBC_VARIABLE_ATTR decltype(LIBC_NAMESPACE::name) name asm( \
"_" #name); \
type name
-#endif // __APPLE__
+#endif // LIBC_TARGET_USES_LEADING_UNDERSCORE
#else // LIBC_COPT_PUBLIC_PACKAGING
#define LLVM_LIBC_VARIABLE_IMPL(type, name) type name
#endif // LIBC_COPT_PUBLIC_PACKAGING
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/fixedvector.h b/deps/v8/third_party/llvm-libc/src/src/__support/fixedvector.h
index 34601f86dc0..fdb4b733e10 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/fixedvector.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/fixedvector.h
@@ -1,43 +1,48 @@
-//===-- A data structure for a fixed capacity data store --------*- 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
+/// Defines the FixedVector class: a fixed-capacity container with vector-like
+/// operations.
+///
+//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H
#define LLVM_LIBC_SRC___SUPPORT_FIXEDVECTOR_H
#include "src/__support/CPP/array.h"
#include "src/__support/CPP/iterator.h"
+#include "src/__support/CPP/type_traits/is_trivially_copyable.h"
#include "src/__support/libc_assert.h"
#include "src/__support/macros/config.h"
#include "src/string/memory_utils/inline_memset.h"
namespace LIBC_NAMESPACE_DECL {
-// A fixed size data store backed by an underlying cpp::array data structure. It
-// supports vector like API but is not resizable like a vector.
+/// A fixed size data store backed by an underlying cpp::array data structure.
+/// It supports vector-like API but is not resizable like a vector.
template <typename T, size_t CAPACITY> class FixedVector {
+ static_assert(cpp::is_trivially_copyable_v<T>,
+ "Non-trivially-copyable types not currently supported!");
cpp::array<T, CAPACITY> store;
size_t item_count = 0;
public:
- LIBC_INLINE constexpr FixedVector() = default;
-
using iterator = typename cpp::array<T, CAPACITY>::iterator;
- LIBC_INLINE constexpr FixedVector(iterator begin, iterator end)
- : store{}, item_count{} {
- LIBC_ASSERT(begin + CAPACITY >= end);
- for (; begin != end; ++begin)
- push_back(*begin);
- }
-
using const_iterator = typename cpp::array<T, CAPACITY>::const_iterator;
+ using reverse_iterator = typename cpp::array<T, CAPACITY>::reverse_iterator;
+
+ LIBC_INLINE constexpr FixedVector() = default;
+
LIBC_INLINE constexpr FixedVector(const_iterator begin, const_iterator end)
: store{}, item_count{} {
- LIBC_ASSERT(begin + CAPACITY >= end);
+ LIBC_ASSERT(end >= begin);
+ LIBC_ASSERT(static_cast<size_t>(end - begin) <= CAPACITY);
for (; begin != end; ++begin)
push_back(*begin);
}
@@ -100,25 +105,24 @@ public:
// of the `reset` method. Considering that FixedVector is of fixed storage,
// a `destroy` method like this should not be required. However, FixedVector
// is used in a few places as an alternate for data structures which use
- // dynamically allocated storate. So, the `destroy` method like this
+ // dynamically allocated storage. So, the `destroy` method like this
// matches the `destroy` API of those other data structures so that users
// can easily swap one data structure for the other.
LIBC_INLINE static void destroy(FixedVector<T, CAPACITY> *store) {
store->reset();
}
- using reverse_iterator = typename cpp::array<T, CAPACITY>::reverse_iterator;
LIBC_INLINE constexpr reverse_iterator rbegin() {
- return reverse_iterator{&store[item_count]};
+ return reverse_iterator(begin() + item_count);
}
LIBC_INLINE constexpr reverse_iterator rend() { return store.rend(); }
LIBC_INLINE constexpr iterator begin() { return store.begin(); }
- LIBC_INLINE constexpr iterator end() { return iterator{&store[item_count]}; }
+ LIBC_INLINE constexpr iterator end() { return begin() + item_count; }
LIBC_INLINE constexpr const_iterator begin() const { return store.begin(); }
LIBC_INLINE constexpr const_iterator end() const {
- return const_iterator{&store[item_count]};
+ return begin() + item_count;
}
};
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/float_to_string.h b/deps/v8/third_party/llvm-libc/src/src/__support/float_to_string.h
index 6818b74c815..8b6e1e3741f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/float_to_string.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/float_to_string.h
@@ -619,7 +619,7 @@ public:
};
#if !defined(LIBC_INTERNAL_FLOAT_TO_STR_LD_USE_RYU_IMPL) || \
- defined(LIBC_TYPES_HAS_FLOAT128)
+ defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
// -------------------- LONG DOUBLE / FLOAT128 FUNCTIONS -----------------------
// This algorithm will work exactly the same for 80 bit and 128 bit long
@@ -627,7 +627,7 @@ public:
// constants should be calculated to be correct for any provided floating point
// type.
-#if defined(LIBC_TYPES_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
template <typename T> struct IsFloat128 : cpp::is_same<T, float128> {};
#else
template <typename T> struct IsFloat128 : cpp::bool_constant<false> {};
@@ -856,7 +856,8 @@ public:
}
};
-#endif // !LIBC_INTERNAL_FLOAT_TO_STR_LD_USE_RYU_IMPL || LIBC_TYPES_HAS_FLOAT128
+#endif // !LIBC_INTERNAL_FLOAT_TO_STR_LD_USE_RYU_IMPL ||
+ // LIBC_TYPES_HAS_NATIVE_FLOAT128
} // namespace LIBC_NAMESPACE_DECL
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
new file mode 100644
index 00000000000..bbb0d3bb309
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/frac64.h
@@ -0,0 +1,58 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 64-bit unsigned fractional type
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_FRAC64_H
+#define LLVM_LIBC_SRC___SUPPORT_FRAC64_H
+
+#include "src/__support/big_int.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+struct Frac64 : public UInt<64> {
+ using UInt<64>::UInt;
+
+ LIBC_INLINE constexpr Frac64 operator~() const { return Frac64(~val[0]); }
+
+ LIBC_INLINE constexpr Frac64 operator+(Frac64 other) const {
+ return Frac64(val[0] + other.val[0]);
+ }
+
+ LIBC_INLINE constexpr Frac64 operator-(Frac64 other) const {
+ return Frac64(val[0] - other.val[0]);
+ }
+
+ LIBC_INLINE constexpr Frac64 operator*(Frac64 other) const {
+ UInt<64> r = UInt<64>::quick_mul_hi(UInt<64>(other));
+ return Frac64(r.val[0]);
+ }
+
+ LIBC_INLINE constexpr Frac64 &operator+=(Frac64 other) {
+ *this = *this + other;
+ return *this;
+ }
+
+ LIBC_INLINE constexpr Frac64 &operator-=(Frac64 other) {
+ *this = *this - other;
+ return *this;
+ }
+
+ LIBC_INLINE constexpr Frac64 &operator*=(Frac64 other) {
+ *this = *this * other;
+ return *this;
+ }
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_FRAC64_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/freelist.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/freelist.cpp
index 2fdcaadbdb5..7690ebfc6c5 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/freelist.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/freelist.cpp
@@ -17,33 +17,42 @@ namespace LIBC_NAMESPACE_DECL {
void FreeList::push(Node *node) {
if (begin_) {
- LIBC_ASSERT(BlockRef::from_usable_space(node).outer_size() ==
- begin_->block().outer_size() &&
- "freelist entries must have the same size");
+ begin_->integrity_check();
// Since the list is circular, insert the node immediately before begin_.
- node->prev = begin_->prev;
- node->next = begin_;
- begin_->prev->next = node;
- begin_->prev = node;
+ node->prev_ = begin_->prev_;
+ node->next_ = begin_;
+ begin_->prev_->next_ = node;
+ begin_->prev_ = node;
} else {
- begin_ = node->prev = node->next = node;
+ begin_ = node->prev_ = node->next_ = node;
}
}
void FreeList::remove(Node *node) {
LIBC_ASSERT(begin_ && "cannot remove from empty list");
- Node *next = node->next;
+ node->integrity_check();
+ Node *next = node->next_;
if (node == next) {
LIBC_ASSERT(node == begin_ &&
"a self-referential node must be the only element");
begin_ = nullptr;
} else {
- Node *prev = node->prev;
- prev->next = next;
- next->prev = prev;
+ Node *prev = node->prev_;
+ prev->next_ = next;
+ next->prev_ = prev;
if (begin_ == node)
begin_ = next;
}
}
+void FreeList::integrity_check() const {
+ if (!begin_)
+ return;
+ Node *curr = begin_;
+ do {
+ curr->integrity_check();
+ curr = curr->next_;
+ } while (curr != begin_);
+}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/freelist.h b/deps/v8/third_party/llvm-libc/src/src/__support/freelist.h
index 48e70c7c29d..2e1c559e3eb 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/freelist.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/freelist.h
@@ -15,6 +15,7 @@
#define LLVM_LIBC_SRC___SUPPORT_FREELIST_H
#include "block.h"
+#include "src/__support/libc_assert.h"
namespace LIBC_NAMESPACE_DECL {
@@ -41,10 +42,21 @@ public:
/// @returns The inner size of blocks in the list containing this node.
LIBC_INLINE size_t size() const { return block().inner_size(); }
+ /// @returns The next node in the list containing this node.
+ LIBC_INLINE Node *next() const { return next_; }
+
+ protected:
+ LIBC_INLINE void integrity_check() const {
+ LIBC_HEAP_INTEGRITY_CHECK(next_->prev_ == this,
+ "FreeList node corruption detected");
+ LIBC_HEAP_INTEGRITY_CHECK(prev_->next_ == this,
+ "FreeList node corruption detected");
+ }
+
private:
// Circularly linked pointers to adjacent nodes.
- Node *prev;
- Node *next;
+ Node *prev_;
+ Node *next_;
friend class FreeList;
};
@@ -85,6 +97,9 @@ public:
/// Remove an arbitrary node from the list.
void remove(Node *node);
+ /// Verify integrity of all nodes in the list.
+ void integrity_check() const;
+
private:
Node *begin_;
};
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/freelist_heap.h b/deps/v8/third_party/llvm-libc/src/src/__support/freelist_heap.h
index 73a80754050..d2ec9339d72 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/freelist_heap.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/freelist_heap.h
@@ -51,6 +51,7 @@ public:
void *realloc(void *ptr, size_t size);
void *calloc(size_t num, size_t size);
size_t allocation_size(const void *ptr) const;
+ LIBC_INLINE void integrity_check() const { free_store.integrity_check(); }
cpp::span<cpp::byte> region() const { return {begin, end}; }
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/freestore.h b/deps/v8/third_party/llvm-libc/src/src/__support/freestore.h
index adc0e061ace..ccc4f9555c6 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/freestore.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/freestore.h
@@ -7,113 +7,265 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// Interface for freestore.
+/// This file contains a two-level segregated fit free block store.
///
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIBC_SRC___SUPPORT_FREESTORE_H
#define LLVM_LIBC_SRC___SUPPORT_FREESTORE_H
-#include "freetrie.h"
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/CPP/type_traits/bool_constant.h"
+#include "src/__support/block.h"
+#include "src/__support/freelist.h"
+#include "src/__support/freetrie.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/tlsf_table.h"
namespace LIBC_NAMESPACE_DECL {
-/// A best-fit store of variously-sized free blocks. Blocks can be inserted and
-/// removed in logarithmic time.
-class FreeStore {
- friend class FreeListHeap;
-
+// A two-level segregated fit store for free blocks.
+//
+// See TLSFTable in tlsf_table.h for the mathematical layout and bin mapping
+// logic.
+//
+// Generic memory workloads typically cluster around smaller allocation
+// requests, exhibiting an inverse relationship between request frequency
+// and block size. Furthermore, large allocations can suffer from severe
+// internal fragmentation if managed with overly coarse-grained binning.
+//
+// To accommodate these workload dynamics, this store organizes free blocks
+// into three specialized tiers, each employing a tailored management strategy:
+//
+// 1. Small Blocks (Exact-Fit Fast Path): Small blocks are maintained in linear,
+// exact-size bins. When a matching block is available, fast-path allocations
+// return an exact-fit block immediately in O(1) time without list traversal
+// or block splitting.
+// 2. Medium Blocks (Two-Level Segregated Fit Table): Mid-sized blocks are
+// managed across an exponential and linear bin grid. To preserve constant
+// O(1) allocation time on the fast path, the allocator preferentially pops
+// from an oversized bin first, accepting minor block splitting overhead to
+// prevent memory waste while guaranteeing bounded search latency.
+// 3. Large Blocks (Best-Fit Trie): For the coldest, largest block sizes, blocks
+// are stored in an ordered trie (when enabled). These allocations are
+// serviced using logarithmic best-fit searches, prioritizing space
+// efficiency and minimal fragmentation over immediate O(1) latency.
+template <typename CONFIG> class TLSFFreeStoreImpl {
public:
- FreeStore() = default;
- FreeStore(const FreeStore &other) = delete;
- FreeStore &operator=(const FreeStore &other) = delete;
-
- /// Sets the range of possible block sizes. This can only be called when the
- /// trie is empty.
- LIBC_INLINE void set_range(FreeTrie::SizeRange range) {
- large_trie.set_range(range);
- }
+ using Table = TLSFTable<CONFIG>;
+ static constexpr size_t TOTAL_BITS = Table::TOTAL_BINS;
+ static constexpr size_t TOTAL_BINS = Table::TOTAL_BINS;
+ static constexpr size_t MIN_OUTER_SIZE = Table::MIN_OUTER_SIZE;
+ static constexpr size_t MIN_INNER_SIZE = Table::MIN_INNER_SIZE;
+ static constexpr size_t LINEAR_BINS = Table::LINEAR_BINS;
+ static constexpr bool USE_TRIE = CONFIG::USE_TRIE_FOR_OVERFLOW_BIN;
- /// Insert a free block. If the block is too small to be tracked, nothing
- /// happens.
- void insert(BlockRef block);
+ /// Integrity check for the entire store.
+ LIBC_INLINE void integrity_check() const {
+ if constexpr (USE_TRIE)
+ trie.integrity_check();
+ else
+ overflow_list.integrity_check();
+ for (const FreeList &list : free_lists)
+ list.integrity_check();
+ }
- /// Remove a free block. If the block is too small to be tracked, nothing
- /// happens.
- void remove(BlockRef block);
+private:
+ LIBC_INLINE constexpr TLSFFreeStoreImpl(cpp::bool_constant<true>) : trie() {}
+ LIBC_INLINE constexpr TLSFFreeStoreImpl(cpp::bool_constant<false>)
+ : overflow_list() {}
- /// Remove a best-fit free block that can contain the given size when
- /// allocated. Returns nullptr if there is no such block.
- BlockRef remove_best_fit(size_t size);
+public:
+ LIBC_INLINE constexpr TLSFFreeStoreImpl()
+ : TLSFFreeStoreImpl(cpp::bool_constant<USE_TRIE>{}) {}
+ LIBC_INLINE TLSFFreeStoreImpl(const TLSFFreeStoreImpl &other) = delete;
+ LIBC_INLINE TLSFFreeStoreImpl &
+ operator=(const TLSFFreeStoreImpl &other) = delete;
-private:
- static constexpr size_t MIN_OUTER_SIZE = align_up(
- BlockRef::HEADER_SIZE + sizeof(FreeList::Node), BlockRef::MIN_ALIGN);
- static constexpr size_t MIN_LARGE_OUTER_SIZE = align_up(
- BlockRef::HEADER_SIZE + sizeof(FreeTrie::Node), BlockRef::MIN_ALIGN);
- static constexpr size_t NUM_SMALL_SIZES =
- (MIN_LARGE_OUTER_SIZE - MIN_OUTER_SIZE) / BlockRef::MIN_ALIGN;
+ LIBC_INLINE static constexpr size_t index_to_min_size(size_t index) {
+ return Table::bin_to_min_size(index);
+ }
+ LIBC_INLINE void set_range(FreeTrie::SizeRange range);
+ LIBC_INLINE void insert(BlockRef block);
+ LIBC_INLINE void remove(BlockRef block);
+ LIBC_INLINE BlockRef remove_best_fit(size_t size) {
+ return find_and_remove_fit(size);
+ }
+ LIBC_INLINE BlockRef find_and_remove_fit(size_t size);
+ LIBC_INLINE static constexpr size_t size_to_bit_index(size_t size) {
+ return Table::size_to_bin(size);
+ }
+protected:
LIBC_INLINE static bool too_small(BlockRef block) {
return block.outer_size() < MIN_OUTER_SIZE;
}
- LIBC_INLINE static bool is_small(BlockRef block) {
- return block.outer_size() < MIN_LARGE_OUTER_SIZE;
- }
- FreeList &small_list(BlockRef block);
- FreeList *find_best_small_fit(size_t size);
+ Table free_sizes;
+ cpp::array<FreeList, TOTAL_BITS - 1> free_lists;
+ union {
+ FreeTrie trie;
+ FreeList overflow_list;
+ };
- cpp::array<FreeList, NUM_SMALL_SIZES> small_lists;
- FreeTrie large_trie;
+ LIBC_INLINE BlockRef remove_first_fit_in_list(size_t index, size_t size);
+ LIBC_INLINE BlockRef find_and_remove_fit_in_trie(size_t size);
};
-LIBC_INLINE void FreeStore::insert(BlockRef block) {
+template <typename CONFIG>
+LIBC_INLINE void
+TLSFFreeStoreImpl<CONFIG>::set_range(FreeTrie::SizeRange range) {
+ if constexpr (USE_TRIE) {
+ size_t heap_max = range.min + range.width;
+ size_t overflow_min = index_to_min_size(TOTAL_BITS - 1);
+ size_t width = 1;
+ if (heap_max > overflow_min)
+ width = cpp::bit_ceil(heap_max - overflow_min);
+ trie.set_range(FreeTrie::SizeRange(overflow_min, width));
+ }
+}
+
+template <typename CONFIG>
+LIBC_INLINE BlockRef
+TLSFFreeStoreImpl<CONFIG>::find_and_remove_fit_in_trie(size_t size) {
+ if (FreeTrie::Node *best_fit = trie.find_best_fit(size)) {
+ BlockRef block = best_fit->block();
+ trie.remove(best_fit);
+ if (trie.empty())
+ free_sizes.mark_vacant(TOTAL_BITS - 1);
+ return block;
+ }
+ return BlockRef();
+}
+
+template <typename CONFIG>
+LIBC_INLINE void TLSFFreeStoreImpl<CONFIG>::insert(BlockRef block) {
if (too_small(block))
return;
- if (is_small(block))
- small_list(block).push(block);
- else
- large_trie.push(block);
+ size_t bit_index = size_to_bit_index(block.inner_size());
+
+ if (bit_index == TOTAL_BITS - 1) {
+ if constexpr (USE_TRIE)
+ trie.push(block);
+ else
+ overflow_list.push(block);
+ free_sizes.mark_occupied(bit_index);
+ return;
+ }
+
+ free_lists[bit_index].push(block);
+ free_sizes.mark_occupied(bit_index);
}
-LIBC_INLINE void FreeStore::remove(BlockRef block) {
+template <typename CONFIG>
+LIBC_INLINE void TLSFFreeStoreImpl<CONFIG>::remove(BlockRef block) {
if (too_small(block))
return;
- if (is_small(block)) {
- small_list(block).remove(
- reinterpret_cast<FreeList::Node *>(block.usable_space()));
- } else {
- large_trie.remove(reinterpret_cast<FreeTrie::Node *>(block.usable_space()));
+ size_t bit_index = size_to_bit_index(block.inner_size());
+
+ if (bit_index == TOTAL_BITS - 1) {
+ if constexpr (USE_TRIE) {
+ trie.remove(reinterpret_cast<FreeTrie::Node *>(block.usable_space()));
+ if (trie.empty())
+ free_sizes.mark_vacant(bit_index);
+ } else {
+ overflow_list.remove(
+ reinterpret_cast<FreeList::Node *>(block.usable_space()));
+ if (overflow_list.empty())
+ free_sizes.mark_vacant(bit_index);
+ }
+ return;
}
+
+ free_lists[bit_index].remove(
+ reinterpret_cast<FreeList::Node *>(block.usable_space()));
+ if (free_lists[bit_index].empty())
+ free_sizes.mark_vacant(bit_index);
}
-LIBC_INLINE BlockRef FreeStore::remove_best_fit(size_t size) {
- if (FreeList *list = find_best_small_fit(size)) {
- BlockRef block = list->front();
- list->pop();
- return block;
+template <typename CONFIG>
+LIBC_INLINE BlockRef
+TLSFFreeStoreImpl<CONFIG>::remove_first_fit_in_list(size_t index, size_t size) {
+ FreeList &list =
+ (index == TOTAL_BITS - 1) ? overflow_list : free_lists[index];
+ FreeList::Node *begin_node = list.begin();
+ if (begin_node == nullptr)
+ return BlockRef();
+
+ FreeList::Node *cur = begin_node;
+ size_t count = 0;
+ do {
+ if (cur->size() >= size) {
+ list.remove(cur);
+ if (list.empty())
+ free_sizes.mark_vacant(index);
+ return cur->block();
+ }
+ cur = cur->next();
+ ++count;
+ } while (cur != begin_node && count < CONFIG::LINEAR_SCAN_LIMIT);
+
+ return BlockRef();
+}
+
+template <typename CONFIG>
+LIBC_INLINE BlockRef
+TLSFFreeStoreImpl<CONFIG>::find_and_remove_fit(size_t size) {
+
+ size_t bit_index = size_to_bit_index(size);
+
+ // Fast path for small linear bins if UNIT_SIZE == MIN_ALIGN
+ if constexpr (CONFIG::UNIT_SIZE == BlockRef::MIN_ALIGN) {
+ if (LIBC_LIKELY(bit_index < LINEAR_BINS &&
+ free_sizes.is_occupied(bit_index))) {
+ BlockRef block = free_lists[bit_index].front();
+ free_lists[bit_index].pop();
+ if (free_lists[bit_index].empty())
+ free_sizes.mark_vacant(bit_index);
+ return block;
+ }
}
- if (FreeTrie::Node *best_fit = large_trie.find_best_fit(size)) {
- BlockRef block = best_fit->block();
- large_trie.remove(best_fit);
+
+ if (LIBC_UNLIKELY(bit_index >= TOTAL_BITS - 1)) {
+ if constexpr (USE_TRIE)
+ return find_and_remove_fit_in_trie(size);
+ else
+ return remove_first_fit_in_list(TOTAL_BITS - 1, size);
+ }
+
+ // 1. Try oversized bins (guaranteed fit, but larger).
+ size_t oversized_bit = free_sizes.find_first_occupied_after(bit_index);
+ if (LIBC_LIKELY(oversized_bit < TOTAL_BITS)) {
+ if (LIBC_UNLIKELY(oversized_bit == TOTAL_BITS - 1)) {
+ if constexpr (USE_TRIE)
+ return find_and_remove_fit_in_trie(size);
+ else
+ return remove_first_fit_in_list(TOTAL_BITS - 1, size);
+ }
+
+ BlockRef block = free_lists[oversized_bit].front();
+ free_lists[oversized_bit].pop();
+ if (free_lists[oversized_bit].empty())
+ free_sizes.mark_vacant(oversized_bit);
return block;
}
+
+ // 2. Try exact fit (fallback).
+ if (free_sizes.is_occupied(bit_index)) {
+ if (BlockRef block = remove_first_fit_in_list(bit_index, size))
+ return block;
+ }
+
return BlockRef();
}
-LIBC_INLINE FreeList &FreeStore::small_list(BlockRef block) {
- LIBC_ASSERT(is_small(block) && "only legal for small blocks");
- return small_lists[(block.outer_size() - MIN_OUTER_SIZE) /
- BlockRef::MIN_ALIGN];
-}
+template <typename CONFIG = DefaultFreeStoreConfig>
+using TLSFFreeStore = TLSFFreeStoreImpl<CONFIG>;
-LIBC_INLINE FreeList *FreeStore::find_best_small_fit(size_t size) {
- for (FreeList &list : small_lists)
- if (!list.empty() && list.size() >= size)
- return &list;
- return nullptr;
-}
+using FreeStore = TLSFFreeStore<DefaultFreeStoreConfig>;
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.cpp b/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.cpp
index e76efe717f2..d0392342f22 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.cpp
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.cpp
@@ -7,11 +7,13 @@
//===----------------------------------------------------------------------===//
#include "freetrie.h"
+#include "src/__support/libc_assert.h"
namespace LIBC_NAMESPACE_DECL {
void FreeTrie::remove(Node *node) {
LIBC_ASSERT(!empty() && "cannot remove from empty trie");
+ node->integrity_check();
FreeList list = node;
list.pop();
Node *new_node = static_cast<Node *>(list.begin());
@@ -20,8 +22,11 @@ void FreeTrie::remove(Node *node) {
// This is legal because there is no relationship between the size of the
// root and its children.
Node *leaf = node;
- while (leaf->lower || leaf->upper)
+ while (leaf->lower || leaf->upper) {
+ leaf->integrity_check();
leaf = leaf->lower ? leaf->lower : leaf->upper;
+ }
+ leaf->integrity_check();
if (leaf == node) {
// If the root is a leaf, then removing it empties the subtrie.
replace_node(node, nullptr);
@@ -52,8 +57,8 @@ void FreeTrie::replace_node(Node *node, Node *new_node) {
"no reference to child node found in parent");
parent_child = new_node;
} else {
- LIBC_ASSERT(root == node && "non-root node had no parent");
- root = new_node;
+ LIBC_ASSERT(root_ == node && "non-root node had no parent");
+ root_ = new_node;
}
if (node->lower)
node->lower->parent = new_node;
@@ -61,4 +66,17 @@ void FreeTrie::replace_node(Node *node, Node *new_node) {
node->upper->parent = new_node;
}
+void FreeTrie::integrity_check() const {
+ auto integrity_check_trie_node = [&](auto &self, const Node *node) -> void {
+ if (!node)
+ return;
+ node->integrity_check();
+ FreeList list = const_cast<Node *>(node);
+ list.integrity_check();
+ self(self, node->lower);
+ self(self, node->upper);
+ };
+ integrity_check_trie_node(integrity_check_trie_node, root());
+}
+
} // namespace LIBC_NAMESPACE_DECL
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.h b/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.h
index 9e35463462b..1be34f45602 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/freetrie.h
@@ -15,6 +15,7 @@
#define LLVM_LIBC_SRC___SUPPORT_FREETRIE_H
#include "freelist.h"
+#include "src/__support/libc_assert.h"
namespace LIBC_NAMESPACE_DECL {
@@ -60,6 +61,20 @@ public:
Node *parent;
friend class FreeTrie;
+
+ LIBC_INLINE void integrity_check() const {
+ FreeList::Node::integrity_check();
+ if (lower)
+ LIBC_HEAP_INTEGRITY_CHECK(lower->parent == this,
+ "FreeTrie lower child corruption detected");
+ if (upper)
+ LIBC_HEAP_INTEGRITY_CHECK(upper->parent == this,
+ "FreeTrie upper child corruption detected");
+ if (parent)
+ LIBC_HEAP_INTEGRITY_CHECK(
+ parent->lower == this || parent->upper == this,
+ "FreeTrie parent pointer corruption detected");
+ }
};
/// Power-of-two range of sizes covered by a subtrie.
@@ -88,7 +103,8 @@ public:
};
LIBC_INLINE constexpr FreeTrie() : FreeTrie(SizeRange{0, 0}) {}
- LIBC_INLINE constexpr FreeTrie(SizeRange range) : range(range) {}
+ LIBC_INLINE constexpr FreeTrie(SizeRange range, Node *root = nullptr)
+ : root_(root), range(range) {}
/// Sets the range of possible block sizes. This can only be called when the
/// trie is empty.
@@ -98,7 +114,10 @@ public:
}
/// @returns Whether the trie contains any blocks.
- LIBC_INLINE bool empty() const { return !root; }
+ LIBC_INLINE bool empty() const { return !root_; }
+
+ /// @returns The root node of the trie.
+ LIBC_INLINE Node *root() const { return root_; }
/// Push a block to the trie.
void push(BlockRef block);
@@ -110,15 +129,18 @@ public:
/// nullptr.
Node *find_best_fit(size_t size);
+ /// Verify integrity of all nodes in the trie.
+ void integrity_check() const;
+
private:
/// @returns Whether a node is the head of its containing freelist.
- bool is_head(Node *node) const { return node->parent || node == root; }
+ bool is_head(Node *node) const { return node->parent || node == root_; }
/// Replaces references to one node with another (or nullptr) in all adjacent
/// parent and child nodes.
void replace_node(Node *node, Node *new_node);
- Node *root = nullptr;
+ Node *root_ = nullptr;
SizeRange range;
};
@@ -129,12 +151,13 @@ LIBC_INLINE void FreeTrie::push(BlockRef block) {
LIBC_ASSERT(range.contains(size) && "requested size out of trie range");
// Find the position in the tree to push to.
- Node **cur = &root;
+ Node **cur = &root_;
Node *parent = nullptr;
SizeRange cur_range = range;
while (*cur && (*cur)->size() != size) {
LIBC_ASSERT(cur_range.contains(size) && "requested size out of trie range");
parent = *cur;
+ (*cur)->integrity_check();
if (size <= cur_range.lower().max()) {
cur = &(*cur)->lower;
cur_range = cur_range.lower();
@@ -160,13 +183,14 @@ LIBC_INLINE FreeTrie::Node *FreeTrie::find_best_fit(size_t size) {
if (empty() || range.max() < size)
return nullptr;
- Node *cur = root;
+ Node *cur = root_;
SizeRange cur_range = range;
Node *best_fit = nullptr;
Node *deferred_upper_trie = nullptr;
FreeTrie::SizeRange deferred_upper_range{0, 0};
while (true) {
+ cur->integrity_check();
LIBC_ASSERT(cur_range.contains(cur->size()) &&
"trie node size out of range");
LIBC_ASSERT(cur_range.max() >= size &&
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/high_precision_decimal.h b/deps/v8/third_party/llvm-libc/src/src/__support/high_precision_decimal.h
index de22172fd8d..b9f3d90f5ca 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/high_precision_decimal.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/high_precision_decimal.h
@@ -135,7 +135,8 @@ class HighPrecisionDecimal {
// The maximum amount we can shift is the number of bits used in the
// accumulator, minus the number of bits needed to represent the base (in this
// case 4).
- static constexpr uint32_t MAX_SHIFT_AMOUNT = sizeof(uint64_t) - 4;
+ static constexpr uint32_t MAX_SHIFT_AMOUNT =
+ cpp::numeric_limits<uint64_t>::digits - 4;
// 800 is an arbitrary number of digits, but should be
// large enough for any practical number.
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/libc_assert.h b/deps/v8/third_party/llvm-libc/src/src/__support/libc_assert.h
index 26dd0fc2f95..81135fe1b3d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/libc_assert.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/libc_assert.h
@@ -9,27 +9,70 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H
#define LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H
+#include "src/__support/macros/attributes.h" // For LIBC_INLINE
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/hardening.h"
+#include "src/__support/macros/macro-utils.h"
+#include "src/__support/macros/optimization.h" // For LIBC_UNLIKELY
+#include "src/__support/macros/properties/os.h"
+
+#ifdef LIBC_FULL_BUILD
+#include "src/__support/OSUtil/exit.h"
+#include "src/__support/OSUtil/io.h"
+#include "src/__support/integer_to_string.h"
+#endif
+
+//===----------------------------------------------------------------------===//
+// LIBC_REQUIRE(COND, MSG) (always-on assert regardless of NDEBUG)
+//===----------------------------------------------------------------------===//
+#ifndef LIBC_FULL_BUILD
+#ifdef LIBC_TARGET_OS_IS_LINUX
+// __assert_fail is in Linux Standard Base (LSB), hence we should always be able
+// to use it here.
+#include <assert.h>
+#define LIBC_REQUIRE(COND, MSG) \
+ do { \
+ if (LIBC_UNLIKELY(!(COND))) \
+ __assert_fail(MSG, __FILE__, __LINE__, __PRETTY_FUNCTION__); \
+ } while (false)
+#else
+// Fallback path will just trap: we cannot reliably do anything else.
+#define LIBC_REQUIRE(COND, MSG) \
+ do { \
+ if (LIBC_UNLIKELY(!(COND))) \
+ __builtin_trap(); \
+ } while (false)
+#endif // LIBC_TARGET_OS_IS_LINUX
+#else
+// FIXME: Calling abort on assertion is actually required by standards like LSB.
+// Calling exit also confuses the debugger as exiting will not trigger
+// debugger's stop-on-signal behavior by default. Currently, adding abort will
+// result in cyclic dependency.
+#define LIBC_REQUIRE(COND, MSG) \
+ do { \
+ if (LIBC_UNLIKELY(!(COND))) { \
+ LIBC_NAMESPACE::write_to_stderr(__FILE__ ":" LLVM_LIBC_STRINGIFY( \
+ __LINE__) ": Assertion failed: '" MSG "' in function: '"); \
+ LIBC_NAMESPACE::write_to_stderr(__PRETTY_FUNCTION__); \
+ LIBC_NAMESPACE::write_to_stderr("'\n"); \
+ LIBC_NAMESPACE::internal::exit(0xFF); \
+ } \
+ } while (false)
+#endif // LIBC_FULL_BUILD
+
+//===----------------------------------------------------------------------===//
+// LIBC_ASSERT(COND) (NDEBUG guarded assertion)
+//===----------------------------------------------------------------------===//
#if defined(LIBC_COPT_USE_C_ASSERT) || !defined(LIBC_FULL_BUILD)
// The build is configured to just use the public <assert.h> API
// for libc's internal assertions.
-
#ifndef LIBC_ASSERT
#include <assert.h>
-
#define LIBC_ASSERT(COND) assert(COND)
#endif // LIBC_ASSERT
#else // Not LIBC_COPT_USE_C_ASSERT
-
-#include "src/__support/OSUtil/exit.h"
-#include "src/__support/OSUtil/io.h"
-#include "src/__support/integer_to_string.h"
-#include "src/__support/macros/attributes.h" // For LIBC_INLINE
-#include "src/__support/macros/config.h"
-#include "src/__support/macros/macro-utils.h"
-#include "src/__support/macros/optimization.h" // For LIBC_UNLIKELY
-
namespace LIBC_NAMESPACE_DECL {
// This is intended to be removed in a future patch to use a similar design to
@@ -54,30 +97,30 @@ LIBC_INLINE void report_assertion_failure(const char *assertion,
#error "Unexpected: LIBC_ASSERT macro already defined"
#endif
-// The public "assert" macro calls abort on failure. Should it be same here?
-// The libc internal assert can fire from anywhere inside the libc. So, to
-// avoid potential chicken-and-egg problems, it is simple to do an exit
-// on assertion failure instead of calling abort. We also don't want to use
-// __builtin_trap as it could potentially be implemented using illegal
-// instructions which can be very misleading when debugging.
#ifdef NDEBUG
#define LIBC_ASSERT(COND) \
do { \
} while (false)
#else
-
-#define LIBC_ASSERT(COND) \
- do { \
- if (LIBC_UNLIKELY(!(COND))) { \
- LIBC_NAMESPACE::write_to_stderr(__FILE__ ":" LLVM_LIBC_STRINGIFY( \
- __LINE__) ": Assertion failed: '" #COND "' in function: '"); \
- LIBC_NAMESPACE::write_to_stderr(__PRETTY_FUNCTION__); \
- LIBC_NAMESPACE::write_to_stderr("'\n"); \
- LIBC_NAMESPACE::internal::exit(0xFF); \
- } \
- } while (false)
+// Forward to LIBC_REQUIRE with the condition stringified.
+#define LIBC_ASSERT(COND) LIBC_REQUIRE(COND, #COND)
#endif // NDEBUG
#endif // LIBC_COPT_USE_C_ASSERT
+//===----------------------------------------------------------------------===//
+// Hardening runtime check
+//===----------------------------------------------------------------------===//
+
+#if LIBC_COPT_HARDENING_MODE == LIBC_HARDENING_MODE_NONE
+#define LIBC_HEAP_INTEGRITY_CHECK(COND, MSG) ((void)0)
+#elif LIBC_COPT_HARDENING_MODE == LIBC_HARDENING_MODE_FAST
+#define LIBC_HEAP_INTEGRITY_CHECK(COND, MSG) ((void)0)
+#elif LIBC_COPT_HARDENING_MODE == LIBC_HARDENING_MODE_EXTENSIVE
+#define LIBC_HEAP_INTEGRITY_CHECK(COND, MSG) LIBC_REQUIRE(COND, MSG)
+#elif LIBC_COPT_HARDENING_MODE == LIBC_HARDENING_MODE_DEBUG
+#define LIBC_HEAP_INTEGRITY_CHECK(COND, MSG) LIBC_REQUIRE(COND, MSG)
+#else
+#error "Unsupported hardening mode"
+#endif
#endif // LLVM_LIBC_SRC___SUPPORT_LIBC_ASSERT_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/macros/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/macros/CMakeLists.txt
index d0fb102911f..c9afc2829db 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/macros/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/macros/CMakeLists.txt
@@ -54,3 +54,10 @@ add_header_library(
.macro_utils
libc.src.__support.CPP.string_view
)
+
+add_header_library(
+ hardening
+ HDRS
+ hardening.h
+)
+
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/macros/config.h b/deps/v8/third_party/llvm-libc/src/src/__support/macros/config.h
index 38ad6054738..f256d5b9b99 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/macros/config.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/macros/config.h
@@ -26,6 +26,10 @@
#define __has_builtin(b) 0
#endif
+#ifndef __has_warning
+#define __has_warning(w) 0
+#endif
+
// Compiler feature-detection.
// clang.llvm.org/docs/LanguageExtensions.html#has-feature-and-has-extension
#ifdef __has_feature
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/macros/hardening.h b/deps/v8/third_party/llvm-libc/src/src/__support/macros/hardening.h
new file mode 100644
index 00000000000..98da80b8077
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/macros/hardening.h
@@ -0,0 +1,36 @@
+//===----------------------------------------------------------------------===//
+//
+// 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
+// Hardning mode macros.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_HARDENING_H
+#define LLVM_LIBC_SRC___SUPPORT_MACROS_HARDENING_H
+
+#define LIBC_HARDENING_MODE_NONE 0x0000'000F
+#define LIBC_HARDENING_MODE_FAST 0x0000'00F0
+#define LIBC_HARDENING_MODE_EXTENSIVE 0x0000'0F00
+#define LIBC_HARDENING_MODE_DEBUG 0x0000'F000
+
+#ifndef LIBC_COPT_HARDENING_MODE
+#define LIBC_COPT_HARDENING_MODE LIBC_HARDENING_MODE_NONE
+#endif
+
+#if (LIBC_COPT_HARDENING_MODE != LIBC_HARDENING_MODE_NONE && \
+ LIBC_COPT_HARDENING_MODE != LIBC_HARDENING_MODE_FAST && \
+ LIBC_COPT_HARDENING_MODE != LIBC_HARDENING_MODE_EXTENSIVE && \
+ LIBC_COPT_HARDENING_MODE != LIBC_HARDENING_MODE_DEBUG)
+#error \
+ "LIBC_COPT_HARDENING_MODE must be defined with one of the following values: \
+LIBC_HARDENING_MODE_NONE, LIBC_HARDENING_MODE_FAST, \
+LIBC_HARDENING_MODE_EXTENSIVE, LIBC_HARDENING_MODE_DEBUG"
+#endif
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MACROS_HARDENING_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/types.h b/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/types.h
index 505fa6d7957..aad4c41005c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/types.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/macros/properties/types.h
@@ -10,7 +10,7 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
#define LLVM_LIBC_SRC___SUPPORT_MACROS_PROPERTIES_TYPES_H
-#include "hdr/float_macros.h" // LDBL_MANT_DIG
+#include "hdr/float_macros.h" // LDBL_MANT_DIG, LDBL_MAX_EXP
#include "hdr/stdint_proxy.h" // UINT64_MAX, __SIZEOF_INT128__
#include "include/llvm-libc-macros/float16-macros.h" // LIBC_TYPES_HAS_FLOAT16
#include "include/llvm-libc-types/float128.h" // float128
@@ -20,10 +20,30 @@
#include "src/__support/macros/properties/cpu_features.h"
#include "src/__support/macros/properties/os.h"
+// Wide character encoding.
+#if defined(LIBC_COMPILER_IS_CLANG) || defined(LIBC_COMPILER_IS_GCC)
+#if defined(__SIZEOF_WCHAR_T__)
+#if __SIZEOF_WCHAR_T__ == 4
+#define LIBC_TYPES_WCHAR_T_IS_UTF32
+#elif __SIZEOF_WCHAR_T__ == 2
+#define LIBC_TYPES_WCHAR_T_IS_UTF16
+#endif
+#endif // __SIZEOF_WCHAR_T__
+#elif defined(LIBC_COMPILER_IS_MSVC)
+#define LIBC_TYPES_WCHAR_T_IS_UTF16
+#endif // LIBC_COMPILER
+
// 'long double' properties.
-#if (LDBL_MANT_DIG == 53)
+//
+// Note: we cannot distinguish between f64 and f80 by just checking for a 53-bit
+// mantissa. On FreeBSD, `long double` is an fp80, but the FPU rounds the
+// mantissa to 53 bits. On GCC this is TARGET_96_ROUND_53_LONG_DOUBLE, which
+// reports LDBL_MANT_DIG == 53. As such, we must also check the exponent's range
+// to distinguish between f64 and 53-bit rounded f80 for `long double`.
+#if (LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 1024)
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT64
-#elif (LDBL_MANT_DIG == 64)
+#elif (LDBL_MANT_DIG == 64) || \
+ ((LDBL_MANT_DIG == 53) && (LDBL_MAX_EXP == 16384))
#define LIBC_TYPES_LONG_DOUBLE_IS_X86_FLOAT80
#elif (LDBL_MANT_DIG == 113)
#define LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128
@@ -31,7 +51,7 @@
#define LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE
#endif
-#if defined(LIBC_TYPES_HAS_FLOAT128) && \
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128) && \
!defined(LIBC_TYPES_LONG_DOUBLE_IS_FLOAT128)
#define LIBC_TYPES_FLOAT128_IS_NOT_LONG_DOUBLE
#endif
@@ -55,7 +75,7 @@ using float16 = _Float16;
#endif // LIBC_TYPES_HAS_FLOAT16
// -- float128 support --------------------------------------------------------
-// LIBC_TYPES_HAS_FLOAT128 and 'float128' type are provided by
+// LIBC_TYPES_HAS_NATIVE_FLOAT128 and 'float128' type are provided by
// "include/llvm-libc-types/float128.h"
// -- Emulated float128 support ------------------------------------------------
@@ -67,12 +87,22 @@ struct Float128;
}
} // namespace LIBC_NAMESPACE_DECL
-// #ifndef LIBC_TYPES_HAS_FLOAT128
+// #ifndef LIBC_TYPES_HAS_NATIVE_FLOAT128
// using float128 = LIBC_NAMESPACE::fputil::Float128;
-// #endif // LIBC_TYPES_HAS_FLOAT128
+// #endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
// TODO: Commented till we modify all required functions to support emulated
// Float128.
+// -- Emulated float80 support ------------------------------------------------
+
+namespace LIBC_NAMESPACE_DECL {
+namespace fputil {
+struct Float80;
+}
+} // namespace LIBC_NAMESPACE_DECL
+
+using float80 = LIBC_NAMESPACE::fputil::Float80;
+
// -- bfloat16 support ---------------------------------------------------------
namespace LIBC_NAMESPACE_DECL {
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 9f4624682ea..272e9425a4e 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
@@ -314,13 +314,14 @@ add_header_library(
atan2f128.h
DEPENDS
.atan_utils
- libc.src.__support.integer_literals
- libc.src.__support.uint128
libc.src.__support.FPUtil.dyadic_float
libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.multiply_add
libc.src.__support.FPUtil.nearest_integer
+ libc.src.__support.integer_literals
libc.src.__support.macros.optimization
+ libc.src.__support.uint128
)
add_header_library(
@@ -813,7 +814,7 @@ add_header_library(
HDRS
ceilf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -1117,7 +1118,7 @@ add_header_library(
HDRS
fminf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.basic_operations
libc.src.__support.macros.config
)
@@ -1682,7 +1683,7 @@ add_header_library(
HDRS
iscanonicalf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.basic_operations
libc.src.__support.macros.config
)
@@ -1729,7 +1730,7 @@ add_header_library(
HDRS
isnanf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.fp_bits
libc.src.__support.macros.config
)
@@ -1786,7 +1787,7 @@ add_header_library(
HDRS
issignalingf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.basic_operations
libc.src.__support.macros.config
)
@@ -1891,7 +1892,7 @@ add_header_library(
HDRS
llrintf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -1948,7 +1949,7 @@ add_header_library(
HDRS
llroundf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -2005,7 +2006,7 @@ add_header_library(
HDRS
lrintf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -2062,7 +2063,7 @@ add_header_library(
HDRS
lroundf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -2240,7 +2241,7 @@ add_header_library(
HDRS
nearbyintf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -2417,7 +2418,7 @@ add_header_library(
HDRS
rintf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -2450,7 +2451,10 @@ add_header_library(
round.h
DEPENDS
libc.src.__support.FPUtil.nearest_integer_operations
+ libc.src.__support.macros.attributes
libc.src.__support.macros.config
+ libc.src.__support.macros.properties.compiler
+ libc.src.__support.macros.properties.cpu_features
FLAGS
ROUND_OPT
)
@@ -2506,7 +2510,7 @@ add_header_library(
HDRS
roundevenf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -2540,6 +2544,10 @@ add_header_library(
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.properties.compiler
+ libc.src.__support.macros.properties.cpu_features
FLAGS
ROUND_OPT
)
@@ -2549,7 +2557,7 @@ add_header_library(
HDRS
roundf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -3077,6 +3085,19 @@ add_header_library(
libc.src.__support.macros.optimization
)
+add_header_library(
+ expf_integer_eval
+ HDRS
+ expf_integer_eval.h
+ DEPENDS
+ .exp_constants
+ libc.src.__support.CPP.bit
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.frac64
+)
+
add_header_library(
expf16_utils
HDRS
@@ -3667,7 +3688,7 @@ add_header_library(
HDRS
floorf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
@@ -3733,7 +3754,7 @@ add_header_library(
HDRS
fmaxf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.basic_operations
libc.src.__support.macros.config
)
@@ -3784,6 +3805,17 @@ add_header_library(
libc.src.__support.FPUtil.generic.sqrt
)
+add_header_library(
+ gamma_util
+ HDRS
+ gamma_util.h
+ DEPENDS
+ libc.src.__support.CPP.bit
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.FPUtil.multiply_add
+ libc.src.__support.macros.config
+)
+
add_header_library(
getpayload
HDRS
@@ -3943,13 +3975,33 @@ add_header_library(
libc.include.llvm-libc-types.float128
)
+add_header_library(
+ lgammaf
+ HDRS
+ lgammaf.h
+ DEPENDS
+ libc.hdr.errno_macros
+ libc.hdr.fenv_macros
+ libc.src.__support.FPUtil.cast
+ libc.src.__support.FPUtil.double_double
+ libc.src.__support.FPUtil.except_value_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_operations
+ libc.src.__support.FPUtil.polyeval
+ libc.src.__support.macros.config
+ libc.src.__support.macros.optimization
+ libc.src.__support.math.gamma_util
+ libc.src.__support.math.log
+)
+
add_header_library(
lgammaf16
HDRS
lgammaf16.h
DEPENDS
libc.include.llvm-libc-macros.float16_macros
- libc.src.__support.CPP.bit
libc.src.__support.FPUtil.cast
libc.src.__support.FPUtil.fenv_impl
libc.src.__support.FPUtil.fp_bits
@@ -3959,6 +4011,7 @@ add_header_library(
libc.src.__support.macros.config
libc.src.__support.macros.optimization
libc.src.__support.macros.properties.types
+ libc.src.__support.math.gamma_util
)
add_header_library(
@@ -4457,7 +4510,7 @@ add_header_library(
)
add_header_library(
- nexttoward
+ nexttoward
HDRS
nexttoward.h
DEPENDS
@@ -5398,12 +5451,12 @@ add_header_library(
DEPENDS
libc.src.__support.CPP.bit
libc.src.__support.FPUtil.fenv_impl
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.fp_bits
libc.src.__support.FPUtil.rounding_mode
libc.src.__support.common
libc.src.__support.macros.optimization
libc.src.__support.uint128
- libc.include.llvm-libc-types.float128
)
add_header_library(
@@ -5703,7 +5756,7 @@ add_header_library(
HDRS
truncf128.h
DEPENDS
- libc.include.llvm-libc-types.float128
+ libc.src.__support.FPUtil.float128
libc.src.__support.FPUtil.nearest_integer_operations
libc.src.__support.macros.config
)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/atan2f128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/atan2f128.h
index f99de5be347..5df9071acc5 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/atan2f128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/atan2f128.h
@@ -9,13 +9,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "atan_utils.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/dyadic_float.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/FPUtil/nearest_integer.h"
#include "src/__support/integer_literals.h"
#include "src/__support/macros/config.h"
@@ -26,6 +23,8 @@ namespace LIBC_NAMESPACE_DECL {
namespace math {
+using LIBC_NAMESPACE::fputil::Float128;
+
// There are several range reduction steps we can take for atan2(y, x) as
// follow:
@@ -81,7 +80,7 @@ namespace math {
// and relative errors bounded by:
// |(atan(u) - P(u)) / P(u)| < 2^-114.
-LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
+LIBC_INLINE Float128 atan2f128(Float128 y, Float128 x) {
using DFloat128 = fputil::DyadicFloat<128>;
constexpr DFloat128 ZERO = {Sign::POS, 0, 0_u128};
@@ -97,7 +96,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
constexpr DFloat128 PI_OVER_4 = {Sign::POS, -128,
0xc90fdaa2'2168c234'c4c6628b'80dc1cd1_u128};
constexpr DFloat128 THREE_PI_OVER_4 = {
- Sign::POS, -128, 0x96cbe3f9'990e91a7'9394c9e8'a0a5159d_u128};
+ Sign::POS, -126, 0x96cbe3f9'990e91a7'9394c9e8'a0a5159d_u128};
// Adjustment for constant term:
// CONST_ADJ[x_sign][y_sign][recip]
@@ -106,7 +105,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
{{MPI, PI_OVER_2}, {MPI, PI_OVER_2}}};
using namespace atan_internal;
- using FPBits = fputil::FPBits<float128>;
+ using FPBits = fputil::FPBits<Float128>;
using DFloat128 = fputil::DyadicFloat<128>;
FPBits x_bits(x), y_bits(y);
@@ -130,8 +129,8 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
if (LIBC_UNLIKELY(max_exp >= 0x7fffU || min_exp == 0U)) {
if (x_bits.is_nan() || y_bits.is_nan())
return FPBits::quiet_nan().get_val();
- unsigned x_except = x == 0 ? 0 : (FPBits(x_abs).is_inf() ? 2 : 1);
- unsigned y_except = y == 0 ? 0 : (FPBits(y_abs).is_inf() ? 2 : 1);
+ unsigned x_except = x == Float128(0) ? 0 : (FPBits(x_abs).is_inf() ? 2 : 1);
+ unsigned y_except = y == Float128(0) ? 0 : (FPBits(y_abs).is_inf() ? 2 : 1);
// Exceptional cases:
// EXCEPT[y_except][x_except][x_is_neg]
@@ -151,7 +150,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
DFloat128 r = EXCEPTS[y_except][x_except][x_sign];
if (y_sign)
r.sign = r.sign.negate();
- return static_cast<float128>(r);
+ return r.template as<Float128, /*ShouldSignalExceptions=*/true>();
}
}
@@ -165,7 +164,7 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
DFloat128 result = quick_add(const_term, quotient);
if (final_sign)
result.sign = result.sign.negate();
- return static_cast<float128>(result);
+ return result.template as<Float128, /*ShouldSignalExceptions=*/true>();
}
// Take 24 leading bits of num and den to convert to float for fast division.
@@ -203,13 +202,11 @@ LIBC_INLINE float128 atan2f128(float128 y, float128 x) {
if (final_sign)
r.sign = r.sign.negate();
- return static_cast<float128>(r);
+ return r.template as<Float128, /*ShouldSignalExceptions=*/true>();
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ATAN2F128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16addf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16addf128.h
index 2bd1d10e38d..33a891992e3 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16addf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16addf128.h
@@ -11,7 +11,7 @@
#include "src/__support/macros/properties/types.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/generic/add_sub.h"
@@ -27,6 +27,6 @@ LIBC_INLINE bfloat16 bf16addf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_BF16ADDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16divf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16divf128.h
index 8ed5335099e..63d9cc28d1a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16divf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16divf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/generic/div.h"
@@ -28,6 +28,6 @@ LIBC_INLINE bfloat16 bf16divf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC__SUPPORT_MATH_BF16DIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16fmaf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16fmaf128.h
index 46a72b1646d..63769071521 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16fmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16fmaf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/FMA.h"
#include "src/__support/FPUtil/bfloat16.h"
@@ -27,6 +27,6 @@ LIBC_INLINE bfloat16 bf16fmaf128(float128 x, float128 y, float128 z) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_BF16FMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16mulf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16mulf128.h
index 4cc9314744c..848a7bca244 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16mulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16mulf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/generic/mul.h"
@@ -27,6 +27,6 @@ LIBC_INLINE bfloat16 bf16mulf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_BF16MULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16subf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16subf128.h
index 51e42118451..18c1f568e28 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16subf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/bf16subf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/bfloat16.h"
#include "src/__support/FPUtil/generic/add_sub.h"
@@ -28,6 +28,6 @@ LIBC_INLINE bfloat16 bf16subf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_BF16SUBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/canonicalizef128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/canonicalizef128.h
index 69fd62b1589..77ce2058bc8 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/canonicalizef128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/canonicalizef128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr int canonicalizef128(float128 *cx, const float128 *x) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_CANONICALIZEF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ceilf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ceilf128.h
index 8877594d58d..47f3fbbd86a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ceilf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ceilf128.h
@@ -9,21 +9,18 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_CEILF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_CEILF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 ceilf128(float128 x) { return fputil::ceil(x); }
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 ceilf128(Float128 x) { return fputil::ceil(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_CEILF128_H
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 23dc0d51f19..55b0c4caee2 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 copysignf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/daddf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/daddf128.h
index 3937250e5c6..4877455c059 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/daddf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/daddf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE double daddf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_DADDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ddivf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ddivf128.h
index 359b77d7406..61f9c6d22e3 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ddivf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ddivf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/div.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr double ddivf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_DDIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/dfmaf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/dfmaf128.h
index 54c8761af85..a4030d0c072 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/dfmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/dfmaf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/FMA.h"
#include "src/__support/common.h"
@@ -27,5 +27,5 @@ LIBC_INLINE double dfmaf128(float128 x, float128 y, float128 z) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_DFMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/dmulf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/dmulf128.h
index a76f2f19255..131bc7465cc 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/dmulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/dmulf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/mul.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr double dmulf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_DMULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/dsqrtf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/dsqrtf128.h
index 6b0521410dc..73d39f88935 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/dsqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/dsqrtf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/sqrt.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE LIBC_CONSTEXPR_DEFAULT double dsqrtf128(float128 x) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_DSQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/dsubf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/dsubf128.h
index e49c64a88b2..4aee93a1114 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/dsubf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/dsubf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE double dsubf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_DSUBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/erfcf16.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/erfcf16.h
index ad096527855..76085860019 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/erfcf16.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/erfcf16.h
@@ -93,7 +93,7 @@ LIBC_INLINE float16 erfcf16(float16 x) {
}
if (LIBC_UNLIKELY(x_abs == 0))
- return 1.0f16;
+ return fputil::cast<float16>(1.0f);
// Asymptotic behavior: erfc(x) rounds to 0 or 2 for |x| >= 4.0.
if (LIBC_UNLIKELY(x_abs >= 0x4400U)) { // |x| >= 4.0
@@ -109,7 +109,7 @@ LIBC_INLINE float16 erfcf16(float16 x) {
if (fputil::fenv_is_round_up())
return FPBits::min_subnormal().get_val();
#endif
- return 0.0f16;
+ return FPBits::zero().get_val();
}
// Polynomial approximation:
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/erff16.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/erff16.h
index 8e3a92c092e..68b65759579 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/erff16.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/erff16.h
@@ -134,9 +134,11 @@ LIBC_INLINE float16 erff16(float16 x) {
return x;
}
// Inf -> returns 1.0 or -1.0
- return is_neg ? -1.0f16 : 1.0f16;
+ constexpr float16 ONE_F16 = fputil::cast<float16>(1.0f);
+ return is_neg ? -ONE_F16 : ONE_F16;
}
+ // FIXME: Handle f16 constant emission without triggering -Wc++23-extensions
return fputil::cast<float16>(is_neg ? -1.0f - xf * 0x1.0p-28f
: 1.0f - xf * 0x1.0p-28f);
}
@@ -144,7 +146,8 @@ LIBC_INLINE float16 erff16(float16 x) {
// Polynomial approximation:
// erf(x) ~ x * (c0 + c1 * x^2 + c2 * x^4 + ... + c7 * x^14)
- int idx = static_cast<int>(xbits.abs().get_val() * 8.0f16);
+ constexpr float16 EIGHT_F16 = fputil::cast<float16>(8.0f);
+ int idx = static_cast<int>(xbits.abs().get_val() * EIGHT_F16);
float xsq = xf * xf;
float x4 = xsq * xsq;
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
new file mode 100644
index 00000000000..e48b459f880
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/expf_integer_eval.h
@@ -0,0 +1,284 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 statically rounded, integer-only implementation of
+/// expf(x)
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_INTEGER_EVAL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_EXPF_INTEGER_EVAL_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/frac64.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/check/exp_exceptions.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace shared {
+
+namespace math {
+
+namespace static_rounding {
+
+// print(2+round(1/log(2), 64, RN));
+// LSB(INV_LN2) = 2^-63
+LIBC_INLINE_VAR constexpr Frac64 INV_LN2 = Frac64(0xb8aa'3b29'5c17'f0bc);
+
+// 64-bit polynomial approximation of 2^x coefficients generated with Sollya:
+// > P = fpminimax(2^x, 11, [|1, 64...|], [0, 1], absolute, fixed);
+// Store the fractional part of the coefficients below
+// > dirtyinfnorm(2^x - P(x), [0, 1]);
+// 0x1.6238...p-58
+// LSB(EXPF_COEFFS[i]) = 2^-64
+LIBC_INLINE_VAR constexpr Frac64 EXPF_COEFFS[] = {
+ Frac64(0xb172'17f7'd1cf'b7cf), // x
+ Frac64(0x3d7f'7bff'057d'4a5e), // x^2
+ Frac64(0x0e35'846b'8363'9484), // x^3
+ Frac64(0x0276'556d'ec97'dcd4), // x^4
+ Frac64(0x0057'61ff'dc04'c7ff), // x^5
+ Frac64(0x000a'1847'b6e7'92ec), // x^6
+ Frac64(0x0000'ffe8'14e5'7033), // x^7
+ Frac64(0x0000'1628'b6e9'70c8), // x^8
+ Frac64(0x0000'01b8'8ce7'4088), // x^9
+ Frac64(0x0000'001c'18d5'cb29), // x^10
+ Frac64(0x0000'0002'b43f'4490), // x^11
+};
+
+// 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 FPBounds = LIBC_NAMESPACE::math::check::exp_internal::Bounds<float>;
+ FPBits xbits(x);
+
+ bool is_neg = xbits.is_neg();
+ uint32_t x_val = xbits.uintval();
+ uint32_t x_val_abs = x_val & 0x7fff'ffffU;
+
+ // When |x| >= smallest value that will cause overflow, |x| <= 2^-25, or x is
+ // NaN
+ if (LIBC_UNLIKELY(x_val_abs >= FPBounds::UPPER_BITS ||
+ x_val_abs <= 0x3300'0000U)) {
+ // |x| <= 2^-25
+ if (x_val_abs <= 0x3300'0000U) {
+#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ return 1.0f;
+#else
+ if (x_val_abs == 0)
+ return 1.0f;
+
+ if (rounding == FE_UPWARD && !is_neg)
+ return 0x1.000002p0f;
+
+ if ((rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO) && is_neg)
+ return 0x1.fffffep-1f;
+
+ return 1.0f;
+#endif // LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ }
+
+ if (xbits.is_nan()) {
+ // Per conversation with lntue, we don't need to raise exception here,
+ // as we're assuming no FPUs/fenv in this kind of environment
+ if (xbits.is_signaling_nan()) {
+ // silencing
+ return FPBits::quiet_nan().get_val();
+ }
+
+ // quiet NaN
+ return x;
+ }
+
+ // e^-inf = 0
+ // e^+inf = +inf
+ if (xbits.is_inf()) {
+ return is_neg ? 0.0f : FPBits::inf().get_val();
+ }
+
+ // Large finite positive
+ if (!is_neg) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (rounding == FE_DOWNWARD || rounding == FE_TOWARDZERO)
+ return FPBits::max_normal().get_val();
+
+ return FPBits::inf().get_val();
+#else
+ return FPBits::inf().get_val();
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ }
+
+ // x < log(2^-150) or NaN (NaN is already handled above)
+ if (xbits.uintval() >= 0xc2cf'f1b5U) {
+#ifndef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ if (rounding == FE_UPWARD)
+ return FPBits::min_subnormal().get_val();
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+
+ return 0.0f;
+ }
+ }
+
+ // Main calculations
+
+ uint16_t x_e = xbits.get_biased_exponent();
+ uint64_t x_u = xbits.get_mantissa();
+
+ // Range reduction
+ // The algorithm near the end of this function estimates 2^r,
+ // where r is the fractional part of x * log2(e) and is in [0, 1].
+ // See EXPF_COEFFS for more details on the approximation polynomial used.
+
+ // add leading bit = 1
+ x_u |= uint64_t(1) << FPBits::FRACTION_LEN;
+
+ // shift to top 32 bit --> decimal point at hidden bit that we've added
+ x_u <<= 32;
+
+ int x_e_unbiased = static_cast<int>(x_e) - FPBits::EXP_BIAS;
+
+ // shift for the decimal point to be at the hidden bit
+ if (x_e_unbiased > 0) {
+ x_u <<= x_e_unbiased;
+ } else if (x_e_unbiased < 0) {
+ x_u >>= -x_e_unbiased;
+ }
+
+ // LSB(x_u_frac) = 2^-55
+ Frac64 x_u_frac(x_u);
+
+ // LSB(x_ln2) = 2^-54
+ Frac64 x_ln2 = x_u_frac * INV_LN2;
+
+ constexpr uint64_t FRAC_MASK = (uint64_t(1) << 54) - 1;
+ uint64_t x_ln2_bit = x_ln2.val[0];
+
+ uint64_t e_y, l2y_r;
+ uint32_t e_y_unbiased;
+
+ // As Frac64 can't store the sign, we need to handle the sign separately:
+ // - Both branches are computing floor(x * log2(e)).
+ // - For negative x, we round up to the next multiple of 2^54, then clear the
+ // last 54 bits.
+ // - For positive x, we round down (just clear) the last 54 bits.
+ //
+ // Then, l2y_r is the remainder of x * log2(e) after removing the integer
+ // part, which is used to compute 2^l2y_r_frac - 1.
+ //
+ // e_y_unbiased is biased exponent field, but already bit-positioned to the
+ // exponent field of the float representation.
+ if (LIBC_UNLIKELY(is_neg)) {
+ e_y = (x_ln2_bit + FRAC_MASK) & ~FRAC_MASK;
+ l2y_r = e_y - x_ln2_bit;
+ e_y_unbiased = (FPBits::EXP_BIAS << 23) - static_cast<uint32_t>(e_y >> 31);
+ } else {
+ e_y = x_ln2_bit & ~FRAC_MASK;
+ l2y_r = x_ln2_bit - e_y;
+ e_y_unbiased = (FPBits::EXP_BIAS << 23) + static_cast<uint32_t>(e_y >> 31);
+ }
+
+ uint32_t k = static_cast<uint32_t>(e_y >> 54);
+ int d = static_cast<int>(k) - FPBits::EXP_BIAS;
+
+ // d >= 24 --> k >= 151
+ // --> guaranteed to below 2^-150
+ //
+ // underflow
+ if (LIBC_UNLIKELY(is_neg && d >= 24)) {
+ return 0.0f;
+ }
+
+ // LSB(l2y_r_frac) = LSB(l2y_r) * 2^-10 = 2^-64
+ Frac64 l2y_r_frac(l2y_r << 10);
+
+ // p = 2^l2y_r_frac - 1
+ Frac64 p = l2y_r_frac *
+ fputil::polyeval(l2y_r_frac, EXPF_COEFFS[0], EXPF_COEFFS[1],
+ EXPF_COEFFS[2], EXPF_COEFFS[3], EXPF_COEFFS[4],
+ EXPF_COEFFS[5], EXPF_COEFFS[6], EXPF_COEFFS[7],
+ EXPF_COEFFS[8], EXPF_COEFFS[9], EXPF_COEFFS[10]);
+
+ uint32_t shift_length = 40;
+ uint32_t leading_one = 0;
+
+ // We're computing with errors < worst-cast errors, so tie-rounding never
+ // happens. Hence, round-to-nearest, tie-to-even is equivalent to
+ // round-to-nearest, tie-to-away. Which is what we're implementing below
+ // in the following order:
+ //
+ // 1. Shift so that the rounding bit is at bit-0
+ // 2. Add 1 for rounding
+ // 3. Perform another shift by 1
+ // 4. Depending on the rounding modes, adjust accoringly:
+ // a. Add 1 if rounding-up (0 if not)
+ // b. Add e_y_unbiased to the result (0 if the result is subnormal)
+
+ // subnormal
+ if (LIBC_UNLIKELY(is_neg && d >= 0)) {
+ e_y_unbiased = 0;
+ leading_one = 1 << (23 - d);
+
+ // In the below shifts, we're shifting by (shift_length + 1) at max, while
+ // shift_length is already 40, and if d = 23 --> shift_length + d = 63, and
+ // we'll shift by whole 64 bits, which is undefined behavior in C++.
+ //
+ // So, we'll truncate the last 2 bits.
+ if (d >= 22) {
+ d -= 2;
+ p.val[0] >>= 2;
+ }
+
+ shift_length += d + 1;
+ }
+
+#ifdef LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+ uint32_t result =
+ (static_cast<uint32_t>(p.val[0] >> shift_length) + (leading_one + 1));
+ result >>= 1;
+ result += e_y_unbiased;
+
+ return cpp::bit_cast<float>(result);
+#else
+ if (rounding == FE_TONEAREST) {
+ uint32_t result =
+ (static_cast<uint32_t>(p.val[0] >> shift_length) + (leading_one + 1));
+ result >>= 1;
+ result += e_y_unbiased;
+
+ return cpp::bit_cast<float>(result);
+ }
+
+ uint32_t should_round_up = 0;
+
+ if (LIBC_UNLIKELY(rounding == FE_UPWARD)) {
+ uint64_t round_up_mask = (uint64_t(1) << (shift_length + 1)) - 1;
+ should_round_up = static_cast<uint32_t>((p.val[0] & round_up_mask) != 0);
+ }
+
+ uint32_t result = (static_cast<uint32_t>(p.val[0] >> (shift_length + 1)) +
+ should_round_up + (leading_one >> 1));
+ result += e_y_unbiased;
+
+ return cpp::bit_cast<float>(result);
+#endif // !LIBC_MATH_HAS_ASSUME_ROUND_NEAREST_ONLY
+}
+
+} // namespace static_rounding
+
+} // namespace math
+
+} // namespace shared
+
+} // 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/expm1.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/expm1.h
index 3d2aa57b589..a357699cbed 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/expm1.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/expm1.h
@@ -126,13 +126,13 @@ LIBC_INLINE DoubleDouble poly_approx_dd(const DoubleDouble &dx) {
}
#ifdef DEBUGDEBUG
-std::ostream &operator<<(std::ostream &OS, const DFloat128 &r) {
+LIBC_INLINE std::ostream &operator<<(std::ostream &OS, const DFloat128 &r) {
OS << (r.sign == Sign::NEG ? "-(" : "(") << r.mantissa.val[0] << " + "
<< r.mantissa.val[1] << " * 2^64) * 2^" << r.exponent << "\n";
return OS;
}
-std::ostream &operator<<(std::ostream &OS, const DoubleDouble &r) {
+LIBC_INLINE std::ostream &operator<<(std::ostream &OS, const DoubleDouble &r) {
OS << std::hexfloat << "(" << r.hi << " + " << r.lo << ")"
<< std::defaultfloat << "\n";
return OS;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16addf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16addf128.h
index d4316ce24b1..8127b7d2a6f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16addf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16addf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -29,6 +29,6 @@ LIBC_INLINE constexpr float16 f16addf128(float128 x, float128 y) {
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16ADDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16divf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16divf128.h
index e0a93f60bfe..011c136c546 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16divf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16divf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/div.h"
#include "src/__support/macros/config.h"
@@ -29,7 +29,7 @@ LIBC_INLINE float16 f16divf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16DIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16fmaf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16fmaf128.h
index a8ba4bce9eb..c6bcd7ff175 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16fmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16fmaf128.h
@@ -12,7 +12,7 @@
#include "include/llvm-libc-macros/float16-macros.h"
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#ifdef LIBC_TYPES_HAS_FLOAT16
#include "src/__support/FPUtil/FMA.h"
@@ -32,6 +32,6 @@ LIBC_INLINE float16 f16fmaf128(float128 x, float128 y, float128 z) {
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16FMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16mulf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16mulf128.h
index 54a90957269..c1d4aa532a2 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16mulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16mulf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/mul.h"
#include "src/__support/macros/config.h"
@@ -29,7 +29,7 @@ LIBC_INLINE float16 f16mulf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16MULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16sqrtf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16sqrtf128.h
index 3ef74136cba..40104ec5d79 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16sqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16sqrtf128.h
@@ -12,7 +12,7 @@
#include "include/llvm-libc-macros/float16-macros.h"
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#ifdef LIBC_TYPES_HAS_FLOAT16
#include "src/__support/FPUtil/sqrt.h"
@@ -28,6 +28,6 @@ LIBC_INLINE float16 f16sqrtf128(float128 x) { return fputil::sqrt<float16>(x); }
} // namespace LIBC_NAMESPACE_DECL
#endif // LIBC_TYPES_HAS_FLOAT16
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16SQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16subf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16subf128.h
index a85b30fba53..ce56475413f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/f16subf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/f16subf128.h
@@ -13,7 +13,7 @@
#include "include/llvm-libc-types/float128.h"
#ifdef LIBC_TYPES_HAS_FLOAT16
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -29,7 +29,7 @@ LIBC_INLINE float16 f16subf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LIBC_TYPES_HAS_FLOAT16
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_F16SUBF128_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 ed9f9eba811..242c91ff8e3 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -24,6 +24,6 @@ LIBC_INLINE constexpr float128 fabsf128(float128 x) { return fputil::abs(x); }
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/faddf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/faddf128.h
index 301412e39d6..d8dfeb901cb 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/faddf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/faddf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float faddf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FADDF128_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 25370706332..0f73f1c0561 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fdimf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/fdivf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fdivf128.h
index 2ab5ea31072..bb94dbb2085 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fdivf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fdivf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/div.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float fdivf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FDIVF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ffmaf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ffmaf128.h
index c4b5a58e145..5714421a60b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ffmaf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ffmaf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/FMA.h"
#include "src/__support/common.h"
@@ -29,6 +29,6 @@ LIBC_INLINE float ffmaf128(float128 x, float128 y, float128 z) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FFMAF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/floorf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/floorf128.h
index 85f92ee77fc..3eb5ac0bc63 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/floorf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/floorf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FLOORF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FLOORF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 floorf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 floorf128(Float128 x) {
return fputil::floor(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FLOORF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaxf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaxf128.h
index 65b7878ed05..c7994228d86 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaxf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmaxf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMAXF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMAXF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_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 fmaxf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fmaxf128(Float128 x, Float128 y) {
return fputil::fmax(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMAXF128_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 656ef803559..79e8842f81e 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fmaximum_mag_numf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 8c89ee5f498..b540e0940c9 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fmaximum_magf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 b3fc57031d7..ccee570de2c 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fmaximum_numf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 a769cd954c8..136b16419cd 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fmaximumf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/fminf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminf128.h
index ccea1a7ee11..da5d96c20a7 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fminf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fminf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_FMINF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_FMINF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_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 fminf128(float128 x, float128 y) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 fminf128(Float128 x, Float128 y) {
return fputil::fmin(x, y);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMINF128_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 8a1bc35a373..d8b23a38247 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fminimum_mag_numf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 f0f1739583f..ea571905fb7 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fminimum_magf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 3f9897b17ad..6f3ac894a7d 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fminimum_numf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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 ee8fb1a9c6b..cfbe36ba1fb 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fminimumf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#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/fmodf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmodf128.h
index b15c1e17caa..7ed105b81af 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmodf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmodf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/FMod.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 fmodf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMODF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmulf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmulf128.h
index 858befc0b54..e974a24f6d9 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fmulf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fmulf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/mul.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float fmulf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FMULF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/frexpf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/frexpf128.h
index 176a33f0d24..a16e401889c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/frexpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/frexpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"
@@ -29,6 +29,6 @@ LIBC_INLINE constexpr float128 frexpf128(float128 x, int *exp) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FREXPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpf128.h
index ea263ffd7e8..3415ce8e51f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 fromfpf128(float128 x, int rnd,
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FROMFPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpxf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpxf128.h
index 145f07f4268..4fa2599fad3 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpxf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fromfpxf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 fromfpxf128(float128 x, int rnd,
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FROMFPXF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fsqrtf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fsqrtf128.h
index 61353c8043d..db1050a6122 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fsqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fsqrtf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/sqrt.h"
#include "src/__support/common.h"
@@ -29,5 +29,5 @@ LIBC_INLINE LIBC_CONSTEXPR_DEFAULT float fsqrtf128(float128 x) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FSQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/fsubf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/fsubf128.h
index 74bcb87acc6..284ea093ec0 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/fsubf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/fsubf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/generic/add_sub.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float fsubf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_FSUBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/gamma_util.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/gamma_util.h
new file mode 100644
index 00000000000..007786368b7
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/gamma_util.h
@@ -0,0 +1,116 @@
+//===-- Shared helpers for gamma family math 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_GAMMA_UTIL_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_GAMMA_UTIL_H
+
+#include "src/__support/CPP/bit.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+namespace gamma_internal {
+
+template <typename T> LIBC_INLINE constexpr bool is_integer(T x) {
+ using FPBits = fputil::FPBits<T>;
+ using StorageType = typename FPBits::StorageType;
+ FPBits xbits(x);
+ StorageType x_u = xbits.uintval();
+ unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
+ unsigned lsb = static_cast<unsigned>(
+ cpp::countr_zero(static_cast<StorageType>(x_u | FPBits::EXP_MASK)));
+ constexpr unsigned UNIT_EXPONENT =
+ static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
+ return x_e + lsb >= UNIT_EXPONENT;
+}
+
+// sin(pi*x) for x in (0, 1), written as (0.25 - u^2) * P(u^2) where u = x-0.5.
+// Coefficients for P are a degree-7 polynomial in u^2
+// approximating sin(pi*(u+0.5)) / (pi*(0.25-u^2))
+// with max error ~2^{-55}, generated by Sollya with:
+// > P = fpminimax(sin(pi*(x+0.5))/(pi*(0.25-x^2)),
+// [|0,2,4,6,8,10,12,14|], [|D...|], [-0.5, 0.5]);
+LIBC_INLINE double lg_sinpi(double x) {
+ constexpr double COEFFS[8] = {0x000000000000001p+2, -0x1.de9e64df22ea4p+1,
+ 0x1.472be122401f8p+0, -0x1.d4fcd82df91bp-3,
+ 0x1.9f05c97e0aab2p-6, -0x1.f3091c427b611p-10,
+ 0x1.b22c9bfdca547p-14, -0x1.15484325ef569p-18};
+ double u = x - 0.5;
+ double u2 = u * u, u4 = u2 * u2, u8 = u4 * u4;
+ double p01 = fputil::multiply_add(u2, COEFFS[1], COEFFS[0]);
+ double p23 = fputil::multiply_add(u2, COEFFS[3], COEFFS[2]);
+ double p45 = fputil::multiply_add(u2, COEFFS[5], COEFFS[4]);
+ double p67 = fputil::multiply_add(u2, COEFFS[7], COEFFS[6]);
+ double p03 = fputil::multiply_add(u4, p23, p01);
+ double p47 = fputil::multiply_add(u4, p67, p45);
+ // Compute (0.25 - u^2) = (0.5 - u) * (0.5 + u) to avoid ~10-digit
+ // catastrophic cancellation when |u| ~ 0.5 (i.e. x near 0 or 1).
+ return (0.5 - u) * (0.5 + u) * fputil::multiply_add(u8, p47, p03);
+}
+
+// Natural logarithm of x (x > 0), using 16-entry table + degree-7 polynomial.
+// Range reduction: x = 2^e * m where m in [1, 2), decomposed as
+// m = (1+i/16)*(1+z) so log(x) = e*log(2) + log(1+i/16) + log(1+z)
+// = e*log(2) + IL[i] + z*P(z).
+// P approximates log(1+z)/z on z in [-1/16, 1/16] with max
+// error ~2^{-54}, generated by Sollya with:
+// > P = fpminimax(log(1+x)/x, [|0,1,2,3,4,5,6,7|], [|D...|], [-1/16, 1/16]);
+LIBC_INLINE double lg_ln(double x) {
+ using FPBits = fputil::FPBits<double>;
+ uint64_t u = FPBits(x).uintval();
+ int e = static_cast<int>(FPBits(x).get_biased_exponent()) - 0x3ff;
+
+ // Coefficients for log(1 + z)/z on z in [-1/16, 1/16]
+ constexpr double COEFFS[8] = {0x1.fffffffffff24p-1, -0x1.ffffffffd1d67p-2,
+ 0x1.55555537802dep-2, -0x1.ffffeca81b866p-3,
+ 0x1.999611761d772p-3, -0x1.54f3e581b61bfp-3,
+ 0x1.1e642b4cb5143p-3, -0x1.9115a5af1e1edp-4};
+ // IL[i] = log(1 + i/16) for i = 0..15
+ constexpr double IL[16] = {
+ 0x1.59caeec280116p-57, 0x1.f0a30c01162aap-5, 0x1.e27076e2af2ebp-4,
+ 0x1.5ff3070a793d6p-3, 0x1.c8ff7c79a9a2p-3, 0x1.1675cababa60fp-2,
+ 0x1.4618bc21c5ec2p-2, 0x1.739d7f6bbd007p-2, 0x1.9f323ecbf984dp-2,
+ 0x1.c8ff7c79a9a21p-2, 0x1.f128f5faf06ecp-2, 0x1.0be72e4252a83p-1,
+ 0x1.1e85f5e7040d1p-1, 0x1.307d7334f10bep-1, 0x1.41d8fe84672afp-1,
+ 0x1.52a2d265bc5abp-1};
+ // IX[i] = 1 / (1 + i/16) for i = 0..15
+ constexpr double IX[16] = {
+ 0x000000000000001p+0, 0x1.e1e1e1e1e1e1ep-1, 0x1.c71c71c71c71cp-1,
+ 0x1.af286bca1af28p-1, 0x1.999999999999ap-1, 0x1.8618618618618p-1,
+ 0x1.745d1745d1746p-1, 0x1.642c8590b2164p-1, 0x1.5555555555555p-1,
+ 0x1.47ae147ae147bp-1, 0x1.3b13b13b13b14p-1, 0x1.2f684bda12f68p-1,
+ 0x1.2492492492492p-1, 0x1.1a7b9611a7b96p-1, 0x1.1111111111111p-1,
+ 0x1.0842108421084p-1};
+
+ int i = static_cast<int>((u >> 48) & 0xf);
+ // Reduce to mantissa in [1, 2)
+ uint64_t mant_u = (u & (~uint64_t(0) >> 12)) | (uint64_t(0x3ff) << 52);
+ double mant = FPBits(mant_u).get_val();
+ double z = IX[i] * mant - 1.0, z2 = z * z, z4 = z2 * z2;
+ double q01 = fputil::multiply_add(z, COEFFS[1], COEFFS[0]);
+ double q23 = fputil::multiply_add(z, COEFFS[3], COEFFS[2]);
+ double q45 = fputil::multiply_add(z, COEFFS[5], COEFFS[4]);
+ double q67 = fputil::multiply_add(z, COEFFS[7], COEFFS[6]);
+ double q03 = fputil::multiply_add(z2, q23, q01);
+ double q47 = fputil::multiply_add(z2, q67, q45);
+ return e * 0x1.62e42fefa39efp-1 + IL[i] +
+ z * fputil::multiply_add(z4, q47, q03);
+}
+
+} // namespace gamma_internal
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_GAMMA_UTIL_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/getpayloadf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/getpayloadf128.h
index 9e9231f2a89..aed53ee4adb 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/getpayloadf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/getpayloadf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 getpayloadf128(const float128 *x) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_GETPAYLOADF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ilogbf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ilogbf128.h
index a2a4a3b1940..9ea71fc47c7 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ilogbf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ilogbf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"
@@ -29,6 +29,6 @@ LIBC_INLINE constexpr int ilogbf128(float128 x) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ILOGBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/iscanonicalf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/iscanonicalf128.h
index 6153879dfa7..d517038ec6d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/iscanonicalf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/iscanonicalf128.h
@@ -9,24 +9,21 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ISCANONICALF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ISCANONICALF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_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 int iscanonicalf128(float128 x) {
- float128 temp{};
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr int iscanonicalf128(Float128 x) {
+ Float128 temp{};
return fputil::canonicalize(temp, x) == 0;
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ISCANONICALF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/isnanf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/isnanf128.h
index 4676764808a..422b8c453a6 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/isnanf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/isnanf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ISNANF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ISNANF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE LIBC_CONSTEXPR int isnanf128(float128 x) {
- return fputil::FPBits<float128>(x).is_nan();
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE LIBC_CONSTEXPR int isnanf128(Float128 x) {
+ return fputil::FPBits<Float128>(x).is_nan();
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ISNANF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/issignalingf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/issignalingf128.h
index 6887ffe5866..62949159c33 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/issignalingf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/issignalingf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ISSIGNALINGF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ISSIGNALINGF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_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 int issignalingf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr int issignalingf128(Float128 x) {
return fputil::issignaling_impl(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ISSIGNALINGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ldexpf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ldexpf128.h
index 571d2f95129..74e4c354ff8 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ldexpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ldexpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"
@@ -29,6 +29,6 @@ LIBC_INLINE constexpr float128 ldexpf128(float128 x, int exp) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LDEXPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf.h
new file mode 100644
index 00000000000..8749136ecf0
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf.h
@@ -0,0 +1,505 @@
+//===-- Implementation header for lgammaf -----------------------*- 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
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LGAMMAF_H
+#define LLVM_LIBC_SRC___SUPPORT_MATH_LGAMMAF_H
+
+#include "src/__support/FPUtil/FEnvImpl.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/PolyEval.h"
+#include "src/__support/FPUtil/cast.h"
+#include "src/__support/FPUtil/except_value_utils.h"
+#include "src/__support/FPUtil/multiply_add.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math/gamma_util.h"
+#include "src/__support/math/log.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+namespace math {
+
+namespace lgammaf_internal {
+
+// P_M2(d), d = t - 1.5, approximates lgamma(t)/((t-1)(t-2)) on [1, 2].
+// Degree 18 centered-monomial coefficients from a 250-bit Chebyshev fit,
+// max relative error 2^-51.6
+LIBC_INLINE double lgamma_m2_poly(double d) {
+ constexpr double POLY_M2[19] = {
+ 0x1.eeb95b094c191p-2, -0x1.2aed059bd613dp-3, 0x1.01af62a292eb9p-4,
+ -0x1.007aa83cc458bp-5, 0x1.13342351db068p-6, -0x1.34dbda42244dep-7,
+ 0x1.64f066cf96646p-8, -0x1.a5033bab00972p-9, 0x1.f814855fdfeb8p-10,
+ -0x1.31418be9f2e14p-10, 0x1.7510b1d1fa536p-11, -0x1.caccf4395927bp-12,
+ 0x1.1c0d19e4fef05p-12, -0x1.67d43c4be68f7p-13, 0x1.c3d6281f9ac35p-14,
+ -0x1.dd9e09255e712p-15, 0x1.2550c8f33e895p-15, -0x1.6cd0f980284cbp-15,
+ 0x1.dbd1c21b8dfa7p-16};
+ double d2 = d * d, d4 = d2 * d2, d8 = d4 * d4, d16 = d8 * d8;
+ double p01 = fputil::multiply_add(d, POLY_M2[1], POLY_M2[0]);
+ double p23 = fputil::multiply_add(d, POLY_M2[3], POLY_M2[2]);
+ double p45 = fputil::multiply_add(d, POLY_M2[5], POLY_M2[4]);
+ double p67 = fputil::multiply_add(d, POLY_M2[7], POLY_M2[6]);
+ double p89 = fputil::multiply_add(d, POLY_M2[9], POLY_M2[8]);
+ double p1011 = fputil::multiply_add(d, POLY_M2[11], POLY_M2[10]);
+ double p1213 = fputil::multiply_add(d, POLY_M2[13], POLY_M2[12]);
+ double p1415 = fputil::multiply_add(d, POLY_M2[15], POLY_M2[14]);
+ double p1617 = fputil::multiply_add(d, POLY_M2[17], POLY_M2[16]);
+ double q03 = fputil::multiply_add(d2, p23, p01);
+ double q47 = fputil::multiply_add(d2, p67, p45);
+ double q811 = fputil::multiply_add(d2, p1011, p89);
+ double q1215 = fputil::multiply_add(d2, p1415, p1213);
+ double q1618 = fputil::multiply_add(d2, POLY_M2[18], p1617);
+ double r07 = fputil::multiply_add(d4, q47, q03);
+ double r815 = fputil::multiply_add(d4, q1215, q811);
+ double s015 = fputil::multiply_add(d8, r815, r07);
+ return fputil::multiply_add(d16, q1618, s015);
+}
+
+} // namespace lgammaf_internal
+
+LIBC_INLINE float lgammaf(float x) {
+ using namespace gamma_internal;
+ using namespace lgammaf_internal;
+ using FPBits = fputil::FPBits<float>;
+
+ FPBits xbits(x);
+ uint32_t x_abs = xbits.abs().uintval();
+
+ // NaN / Inf
+ if (LIBC_UNLIKELY(x_abs >= 0x7f800000u)) {
+ if (x_abs == 0x7f800000u)
+ return FPBits::inf().get_val();
+ if (xbits.is_signaling_nan()) {
+ fputil::raise_except_if_required(FE_INVALID);
+ return FPBits::quiet_nan().get_val();
+ }
+ return x;
+ }
+
+ // +/- 0 -> +Inf pole
+ if (LIBC_UNLIKELY(x_abs == 0)) {
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ fputil::set_errno_if_required(ERANGE);
+ return FPBits::inf().get_val();
+ }
+
+ // Negative integers and lgamma(1) = lgamma(2) = 0.
+ if (LIBC_UNLIKELY(is_integer(x))) {
+ if (xbits.is_neg()) {
+ fputil::raise_except_if_required(FE_DIVBYZERO);
+ fputil::set_errno_if_required(ERANGE);
+ return FPBits::inf().get_val();
+ }
+ if (x_abs == 0x3f800000u || x_abs == 0x40000000u)
+ return FPBits::zero().get_val();
+ }
+
+ double xd = fputil::cast<double>(x);
+ double abs_xd = xd < 0.0 ? -xd : xd;
+ double lgamma_val;
+
+ // For very tiny |x| (< 2^-23), use the truncated Laurent series:
+ // lgamma(x) = -log(x) - gamma*x + O(x^2) for tiny x > 0
+ // lgamma(-y) = -log(y) + gamma*y + O(y^2) for tiny y > 0
+ // Even though gamma*|x| < 2^-25 is below 1 float ULP of |result|, it tips
+ // rounding at boundary cases. The x^2 term is at most gamma*2^-46 << 2^-50.
+ if (x_abs < 0x34000000u) { // |x| < 2^-23
+ constexpr fputil::ExceptValues<float, 4> LGAMMAF_EXCEPTS_TINY{{
+ // input, toward-zero result, RU, RD, RN
+ {0x9b7679ffu, 0x4247c72cu, 1, 0, 1},
+ {0x9e88452du, 0x4236bd8bu, 1, 0, 1},
+ {0xa77a8e47u, 0x42052b94u, 1, 0, 1},
+ {0xb0e17820u, 0x41a1d37bu, 1, 0, 0},
+ }};
+ if (auto r = LGAMMAF_EXCEPTS_TINY.lookup(xbits.uintval());
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ constexpr double EULER_GAMMA = 0x1.2788cfc6fb619p-1;
+ double sign_corr = xbits.is_neg() ? EULER_GAMMA : -EULER_GAMMA;
+ return fputil::cast<float>(
+ fputil::multiply_add(sign_corr, abs_xd, -math::log(abs_xd)));
+ }
+
+ if (x_abs < 0x3f290000u) {
+ if (xbits.is_neg()) {
+ // Small negative: x in (-0.66015625, -2^-23). Degree-25 monomial fit
+ // of g(x) = (lgamma(x) + log(-x)) / x (smooth on [-0.66, 0]), then
+ // lgamma(x) = x*g(x) - log(-x). d = x - MID is exact.
+ constexpr double MID_SN = -0x1.5200000000000p-2;
+ constexpr double POLY_SN[26] = {
+ -0x1.cf99908bbb1d7p-1, 0x1.386ced0346de0p+0, -0x1.d0b4c2d337e0fp-1,
+ 0x1.db2dcaaa022a9p-1, -0x1.1188790a072bap+0, 0x1.4e50420966212p+0,
+ -0x1.a787465391482p+0, 0x1.12d6375bce19ep+1, -0x1.6b05729f76a9cp+1,
+ 0x1.e602a94d73479p+1, -0x1.48d5f84ddbdefp+2, 0x1.c0e7f7d05fe6dp+2,
+ -0x1.34d52338a0d93p+3, 0x1.ab7e04eff787dp+3, -0x1.2724d2ace1c81p+4,
+ 0x1.9b17bee5ae20ap+4, -0x1.34beabd4deff5p+5, 0x1.bc510ff62dcf0p+5,
+ -0x1.7406b7594b6ddp+5, 0x1.b97b7265194a1p+5, -0x1.5e2ba44fee700p+8,
+ 0x1.18310d7d43c46p+9, 0x1.59472c8ca4419p+9, -0x1.2a61147e20ef1p+10,
+ -0x1.7cfcf784946edp+11, 0x1.2436ec1277b00p+12};
+ double d = xd - MID_SN;
+ double d2 = d * d, d4 = d2 * d2, d8 = d4 * d4, d16 = d8 * d8;
+ double p01 = fputil::multiply_add(d, POLY_SN[1], POLY_SN[0]);
+ double p23 = fputil::multiply_add(d, POLY_SN[3], POLY_SN[2]);
+ double p45 = fputil::multiply_add(d, POLY_SN[5], POLY_SN[4]);
+ double p67 = fputil::multiply_add(d, POLY_SN[7], POLY_SN[6]);
+ double p89 = fputil::multiply_add(d, POLY_SN[9], POLY_SN[8]);
+ double p1011 = fputil::multiply_add(d, POLY_SN[11], POLY_SN[10]);
+ double p1213 = fputil::multiply_add(d, POLY_SN[13], POLY_SN[12]);
+ double p1415 = fputil::multiply_add(d, POLY_SN[15], POLY_SN[14]);
+ double p1617 = fputil::multiply_add(d, POLY_SN[17], POLY_SN[16]);
+ double p1819 = fputil::multiply_add(d, POLY_SN[19], POLY_SN[18]);
+ double p2021 = fputil::multiply_add(d, POLY_SN[21], POLY_SN[20]);
+ double p2223 = fputil::multiply_add(d, POLY_SN[23], POLY_SN[22]);
+ double p2425 = fputil::multiply_add(d, POLY_SN[25], POLY_SN[24]);
+ double q03 = fputil::multiply_add(d2, p23, p01);
+ double q47 = fputil::multiply_add(d2, p67, p45);
+ double q811 = fputil::multiply_add(d2, p1011, p89);
+ double q1215 = fputil::multiply_add(d2, p1415, p1213);
+ double q1619 = fputil::multiply_add(d2, p1819, p1617);
+ double q2023 = fputil::multiply_add(d2, p2223, p2021);
+ double r07 = fputil::multiply_add(d4, q47, q03);
+ double r815 = fputil::multiply_add(d4, q1215, q811);
+ double r1623 = fputil::multiply_add(d4, q2023, q1619);
+ double s015 = fputil::multiply_add(d8, r815, r07);
+ double s1625 = fputil::multiply_add(d8, p2425, r1623);
+ double poly_g = fputil::multiply_add(d16, s1625, s015);
+ // lgamma(x) = x*g(x) - log(-x) with single rounding via FMA.
+ lgamma_val = fputil::multiply_add(xd, poly_g, -math::log(abs_xd));
+ } else {
+ // x = 0x1.f8a754p-9f
+ if (LIBC_UNLIKELY(xbits.uintval() == 0x3b7c53aau))
+ return fputil::round_result_slightly_up(0x1.63acc2p+2f);
+ // Small: t = x < 0.66015625. Degree-17 monomial fit of
+ // h(t) = (lgamma(t) + log(t)) / t (smooth on [0, 0.66]).
+ // d = t - MID is exact.
+ constexpr double MID_S = 0x1.5200000000000p-2;
+ constexpr double POLY_S[18] = {
+ -0x1.5dcd7586bfd88p-2, 0x1.3f88851c787c3p-1, -0x1.cdfaca3081737p-3,
+ 0x1.cfac7b321198bp-4, -0x1.0939a239f89b2p-4, 0x1.44cddc5f52a43p-5,
+ -0x1.9e4cc54acdcebp-6, 0x1.0f61691962355p-6, -0x1.6a429a6c89071p-7,
+ 0x1.ea573d148429cp-8, -0x1.4f6ad0c206ae6p-8, 0x1.cedaf9fc19cb5p-9,
+ -0x1.42333c4e88f7dp-9, 0x1.c2a0e3ffc858fp-10, -0x1.32153d4cb9316p-10,
+ 0x1.add42f56d3c7ap-11, -0x1.972ff2b1a91edp-11, 0x1.25f56c66e3049p-11};
+ double d = abs_xd - MID_S;
+ double d2 = d * d, d4 = d2 * d2, d8 = d4 * d4, d16 = d8 * d8;
+ double p01 = fputil::multiply_add(d, POLY_S[1], POLY_S[0]);
+ double p23 = fputil::multiply_add(d, POLY_S[3], POLY_S[2]);
+ double p45 = fputil::multiply_add(d, POLY_S[5], POLY_S[4]);
+ double p67 = fputil::multiply_add(d, POLY_S[7], POLY_S[6]);
+ double p89 = fputil::multiply_add(d, POLY_S[9], POLY_S[8]);
+ double p1011 = fputil::multiply_add(d, POLY_S[11], POLY_S[10]);
+ double p1213 = fputil::multiply_add(d, POLY_S[13], POLY_S[12]);
+ double p1415 = fputil::multiply_add(d, POLY_S[15], POLY_S[14]);
+ double p1617 = fputil::multiply_add(d, POLY_S[17], POLY_S[16]);
+ double q03 = fputil::multiply_add(d2, p23, p01);
+ double q47 = fputil::multiply_add(d2, p67, p45);
+ double q811 = fputil::multiply_add(d2, p1011, p89);
+ double q1215 = fputil::multiply_add(d2, p1415, p1213);
+ double r07 = fputil::multiply_add(d4, q47, q03);
+ double r815 = fputil::multiply_add(d4, q1215, q811);
+ double s015 = fputil::multiply_add(d8, r815, r07);
+ double poly_h = fputil::multiply_add(d16, p1617, s015);
+ // poly_val - log(abs_xd) with single rounding via FMA.
+ lgamma_val = fputil::multiply_add(abs_xd, poly_h, -math::log(abs_xd));
+ }
+ } else if (x_abs < 0x3f800000u) {
+ if (xbits.is_neg()) {
+ // x in (-1, -0.66015625]: Gamma(x) = Gamma(x+2)/(x(x+1)), so
+ // lgamma(x) = x(x+1)*P_M2(x+0.5) - log(-x(x+1)). x+0.5 and x+1 are
+ // exact (Sterbenz); x(x+1) = (t-1)(t-2) is the M2 prefactor.
+ double w = xd * (xd + 1.0);
+ double poly = lgamma_m2_poly(xd + 0.5);
+ lgamma_val = fputil::multiply_add(w, poly, -lg_ln(-w));
+ } else {
+ // M1: t in [0.66015625, 1.0). lgamma(t) = (t-1) * P_M1(d), d = t - MID.
+ // Degree-14 monomial fit of lgamma(t)/(t-1), max error 2^-51.3.
+ constexpr double MID_M1 = 0x1.a900000000000p-1;
+ constexpr double POLY_M1[15] = {
+ -0x1.75cb89aad8dc7p-1, 0x1.f958114ec790dp-1, -0x1.2b968b172a05cp-1,
+ 0x1.eaf0e2c8dc49fp-2, -0x1.c6efb493bfadfp-2, 0x1.c0a621f0e593ep-2,
+ -0x1.cb2416349da49p-2, 0x1.e19328033256dp-2, -0x1.010d0c64743f5p-1,
+ 0x1.162e14c80bdc9p-1, -0x1.3034dec6eb9a3p-1, 0x1.4ca601da8405ep-1,
+ -0x1.70f73638718d4p-1, 0x1.ded7569ab5a36p-1, -0x1.0fdd39040adfbp+0};
+ double d = abs_xd - MID_M1;
+ double d2 = d * d, d4 = d2 * d2, d8 = d4 * d4;
+ double p01 = fputil::multiply_add(d, POLY_M1[1], POLY_M1[0]);
+ double p23 = fputil::multiply_add(d, POLY_M1[3], POLY_M1[2]);
+ double p45 = fputil::multiply_add(d, POLY_M1[5], POLY_M1[4]);
+ double p67 = fputil::multiply_add(d, POLY_M1[7], POLY_M1[6]);
+ double p89 = fputil::multiply_add(d, POLY_M1[9], POLY_M1[8]);
+ double p1011 = fputil::multiply_add(d, POLY_M1[11], POLY_M1[10]);
+ double p1213 = fputil::multiply_add(d, POLY_M1[13], POLY_M1[12]);
+ double q03 = fputil::multiply_add(d2, p23, p01);
+ double q47 = fputil::multiply_add(d2, p67, p45);
+ double q811 = fputil::multiply_add(d2, p1011, p89);
+ double q1214 = fputil::multiply_add(d2, POLY_M1[14], p1213);
+ double r07 = fputil::multiply_add(d4, q47, q03);
+ double r814 = fputil::multiply_add(d4, q1214, q811);
+ double poly = fputil::multiply_add(d8, r814, r07);
+ lgamma_val = (abs_xd - 1.0) * poly;
+ }
+ } else if (x_abs < 0x40000000u) {
+ if (xbits.is_neg()) {
+ // x in (-2, -1): Gamma(x) = Gamma(x+3)/(x(x+1)(x+2)), so
+ // lgamma(x) = (x+1)(x+2)*P_M2(x+1.5) - log(x(x+1)(x+2)). The shifts
+ // are exact (Sterbenz); (x+1)(x+2) = (t-1)(t-2) is the M2 prefactor.
+ double u = (xd + 1.0) * (xd + 2.0);
+ double poly = lgamma_m2_poly(xd + 1.5);
+ lgamma_val = fputil::multiply_add(u, poly, -lg_ln(xd * u));
+ } else {
+ // M2: t in [1.0, 2.0). lgamma(t) = (t-1)*(t-2) * P_M2(t - 1.5).
+ double d = abs_xd - 0x1.8p+0;
+ lgamma_val = (abs_xd - 1.0) * (abs_xd - 2.0) * lgamma_m2_poly(d);
+ }
+ } else if (x_abs < 0x4057e000u) {
+ // M3: t in [2.0, 3.373046875). lgamma(t) = (t-2) * P_M3(d), d = t - MID.
+ // Degree-15 monomial fit of lgamma(t)/(t-2), max error 2^-49.7.
+ constexpr double MID_M3 = 0x1.57e0000000000p+1;
+ constexpr double POLY_M3[16] = {
+ 0x1.3c4e36a0b4775p-1, 0x1.01f945be1325fp-2, -0x1.4203a95730c77p-5,
+ 0x1.227f82db7c7a1p-7, -0x1.32f092b6ec5a3p-9, 0x1.61df821ae7829p-11,
+ -0x1.aed17eeca55e6p-13, 0x1.100a8e7dcd62cp-14, -0x1.609aa16f960a0p-16,
+ 0x1.d1e293fa801bbp-18, -0x1.38b436ce1b3b9p-19, 0x1.a838eec563338p-21,
+ -0x1.1a6a9cf4aee4bp-22, 0x1.8387c2a068b06p-24, -0x1.5ee6ae8c133f7p-25,
+ 0x1.f195cf3f4b24ep-27};
+ if (!xbits.is_neg()) {
+ double d = abs_xd - MID_M3;
+ double d2 = d * d, d4 = d2 * d2, d8 = d4 * d4;
+ double p01 = fputil::multiply_add(d, POLY_M3[1], POLY_M3[0]);
+ double p23 = fputil::multiply_add(d, POLY_M3[3], POLY_M3[2]);
+ double p45 = fputil::multiply_add(d, POLY_M3[5], POLY_M3[4]);
+ double p67 = fputil::multiply_add(d, POLY_M3[7], POLY_M3[6]);
+ double p89 = fputil::multiply_add(d, POLY_M3[9], POLY_M3[8]);
+ double p1011 = fputil::multiply_add(d, POLY_M3[11], POLY_M3[10]);
+ double p1213 = fputil::multiply_add(d, POLY_M3[13], POLY_M3[12]);
+ double p1415 = fputil::multiply_add(d, POLY_M3[15], POLY_M3[14]);
+ double q03 = fputil::multiply_add(d2, p23, p01);
+ double q47 = fputil::multiply_add(d2, p67, p45);
+ double q811 = fputil::multiply_add(d2, p1011, p89);
+ double q1215 = fputil::multiply_add(d2, p1415, p1213);
+ double r07 = fputil::multiply_add(d4, q47, q03);
+ double r815 = fputil::multiply_add(d4, q1215, q811);
+ double poly = fputil::multiply_add(d8, r815, r07);
+ lgamma_val = (abs_xd - 2.0) * poly;
+ } else {
+ // Near the regular lgamma zero at x ~= -2.7475: subtractive cancellation
+ // in the reflection formula kills precision. Use a Taylor expansion
+ // centered at the zero. Range bits in (0x402f95c2, 0x40301b93).
+ // Coefficients adopted from CORE-MATH (Sibidanov, 2023).
+ if (LIBC_UNLIKELY(x_abs > 0x402f95c2u && x_abs < 0x40301b93u)) {
+ double h = (xd + 0x1.5fb410a1bd901p+1) - 0x1.a19a96d2e6f85p-54;
+ constexpr double C[8] = {-0x1.ea12da904b18cp+0, 0x1.3267f3c265a54p+3,
+ -0x1.4185ac30cadb3p+4, 0x1.f504accc3f2e4p+5,
+ -0x1.8588444c679b4p+7, 0x1.43740491dc22p+9,
+ -0x1.12400ea23f9e6p+11, 0x1.dac829f365795p+12};
+ double h2 = h * h, h4 = h2 * h2;
+ double p01 = fputil::multiply_add(h, C[1], C[0]);
+ double p23 = fputil::multiply_add(h, C[3], C[2]);
+ double p45 = fputil::multiply_add(h, C[5], C[4]);
+ double p67 = fputil::multiply_add(h, C[7], C[6]);
+ double p03 = fputil::multiply_add(h2, p23, p01);
+ double p47 = fputil::multiply_add(h2, p67, p45);
+ lgamma_val = h * fputil::multiply_add(h4, p47, p03);
+ } else if (LIBC_UNLIKELY(x_abs > 0x401ceccbu && x_abs < 0x401d95cau)) {
+ // Near the regular lgamma zero at x ~= -2.3614: same issue
+ double h = (xd + 0x1.3a7fc9600f86cp+1) + 0x1.55f64f98af8dp-55;
+ constexpr double C[7] = {0x1.83fe966af535fp+0, 0x1.36eebb002f61ap+2,
+ 0x1.694a60589a0b3p+0, 0x1.1718d7aedb0b5p+3,
+ 0x1.733a045eca0d3p+2, 0x1.8d4297421205bp+4,
+ 0x1.7feea5fb29965p+4};
+ double h2 = h * h, h4 = h2 * h2;
+ double p01 = fputil::multiply_add(h, C[1], C[0]);
+ double p23 = fputil::multiply_add(h, C[3], C[2]);
+ double p45 = fputil::multiply_add(h, C[5], C[4]);
+ double p46 = fputil::multiply_add(h2, C[6], p45);
+ double p03 = fputil::multiply_add(h2, p23, p01);
+ lgamma_val = h * fputil::multiply_add(h4, p46, p03);
+ } else if (LIBC_UNLIKELY(x_abs > 0x40492009u && x_abs < 0x404940efu)) {
+ // Near the regular lgamma zero at x ~= -3.1431: same issue
+ double h = (xd + 0x1.9260dbc9e59afp+1) + 0x1.f717cd335a7b3p-53;
+ constexpr double C[7] = {0x1.f20a65f2fac55p+2, 0x1.9d4d297715105p+4,
+ 0x1.c1137124d5b21p+6, 0x1.267203d24de38p+9,
+ 0x1.99a63399a0b44p+11, 0x1.2941214faaf0cp+14,
+ 0x1.bb912c0c9cdd1p+16};
+ double h2 = h * h, h4 = h2 * h2;
+ double p01 = fputil::multiply_add(h, C[1], C[0]);
+ double p23 = fputil::multiply_add(h, C[3], C[2]);
+ double p45 = fputil::multiply_add(h, C[5], C[4]);
+ double p46 = fputil::multiply_add(h2, C[6], p45);
+ double p03 = fputil::multiply_add(h2, p23, p01);
+ lgamma_val = h * fputil::multiply_add(h4, p46, p03);
+ } else {
+ // x in (-3.373, -2): Gamma(x) = Gamma(x+5)/(x(x+1)(x+2)(x+3)(x+4)),
+ // t = x+5 in (1.627, 3), so lgamma(x) = (x+3)*Q_M3N(d) - log|prod|
+ // with d = x + 2.6865234375 (exact). Q_M3N is a degree-17 monomial
+ // fit of lgamma(t)/(t-2) on [1.627, 3]; the (t-2) = x+3 prefactor
+ // removes the lgamma zero at t = 2.
+ constexpr double POLY_M3N[18] = {
+ 0x1.091ff92b41f07p-1, 0x1.245eed13c42b0p-2,
+ -0x1.a6c3cf8a165cfp-5, 0x1.bc8d19a3ade02p-7,
+ -0x1.1231651010470p-8, 0x1.710f57a2abe2bp-10,
+ -0x1.061ddab9ab12cp-11, 0x1.81edb077ed799p-13,
+ -0x1.235fbc13dbf04p-14, 0x1.c02e6f8fb5dbfp-16,
+ -0x1.5d75e6a94d352p-17, 0x1.1384596ce083dp-18,
+ -0x1.b8da81a716039p-20, 0x1.61ac57fe0e288p-21,
+ -0x1.077101d536ad8p-22, 0x1.a59e2356ba870p-24,
+ -0x1.0cfcf8f102a43p-24, 0x1.c141a51f827f1p-26};
+ double d = xd + 0x1.57ep+1;
+ double d2 = d * d, d4 = d2 * d2, d8 = d4 * d4, d16 = d8 * d8;
+ double p01 = fputil::multiply_add(d, POLY_M3N[1], POLY_M3N[0]);
+ double p23 = fputil::multiply_add(d, POLY_M3N[3], POLY_M3N[2]);
+ double p45 = fputil::multiply_add(d, POLY_M3N[5], POLY_M3N[4]);
+ double p67 = fputil::multiply_add(d, POLY_M3N[7], POLY_M3N[6]);
+ double p89 = fputil::multiply_add(d, POLY_M3N[9], POLY_M3N[8]);
+ double p1011 = fputil::multiply_add(d, POLY_M3N[11], POLY_M3N[10]);
+ double p1213 = fputil::multiply_add(d, POLY_M3N[13], POLY_M3N[12]);
+ double p1415 = fputil::multiply_add(d, POLY_M3N[15], POLY_M3N[14]);
+ double p1617 = fputil::multiply_add(d, POLY_M3N[17], POLY_M3N[16]);
+ double q03 = fputil::multiply_add(d2, p23, p01);
+ double q47 = fputil::multiply_add(d2, p67, p45);
+ double q811 = fputil::multiply_add(d2, p1011, p89);
+ double q1215 = fputil::multiply_add(d2, p1415, p1213);
+ double r07 = fputil::multiply_add(d4, q47, q03);
+ double r815 = fputil::multiply_add(d4, q1215, q811);
+ double s015 = fputil::multiply_add(d8, r815, r07);
+ double poly = fputil::multiply_add(d16, p1617, s015);
+ double pa = xd * (xd + 1.0);
+ double pb = (xd + 2.0) * (xd + 3.0);
+ double prod = (pa * pb) * (xd + 4.0);
+ double aprod = prod < 0.0 ? -prod : prod;
+ lgamma_val = fputil::multiply_add(xd + 3.0, poly, -lg_ln(aprod));
+ }
+ }
+ } else {
+ // Large: |x| >= 3.373046875. Stirling + Bernoulli correction.
+ // lgamma(x) = (x-0.5)*log(x) - x + log(2*pi)/2 + (1/x)*P(1/x^2)
+ // = (x-0.5)*(log(x)-1) + STIR_CONST + (1/x)*P(1/x^2)
+ // STIR_CONST = log(2*pi)/2 - 0.5.
+ // For huge positive x, lgamma(x) overflows float. Use a linear
+ // approximation in double that maps to the correct Inf/max_normal.
+ if (LIBC_UNLIKELY(!xbits.is_neg() && x >= 0x1.895f1cp+121f)) {
+ fputil::set_errno_if_required(ERANGE);
+ fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+ double r = fputil::multiply_add(xd, 0x1.4d3398p+6, 0x1.10f35ep+103);
+ return fputil::cast<float>(r);
+ }
+
+ // No cancellation in (x-0.5)*(log(x)-1): log(x)-1 > 0.2 on this range.
+ // Relative error ~2^-48; anything closer to a rounding boundary is in
+ // the exceptional cases tables below.
+ double lz = lg_ln(abs_xd);
+ double xm = abs_xd - 0.5;
+ lgamma_val = fputil::multiply_add(xm, lz - 1.0, 0x1.acfe390c97d69p-2);
+
+ // For |x| >= 2^20 the 1/(12x) correction is below ~2^-47 of the result;
+ // skip it and the 1/x divide.
+ if (x_abs < 0x49800000u) {
+ double inv_x = 1.0 / abs_xd;
+ double inv_x2 = inv_x * inv_x;
+ if (x_abs > 0x44fa0000u) {
+ constexpr fputil::ExceptValues<float, 3> LGAMMAF_EXCEPTS_BERN2{{
+ // input, toward-zero result, RU, RD, RN
+ {0x46541516u, 0x47e1c01bu, 1, 0, 0},
+ {0x46b16323u, 0x48483adeu, 1, 0, 1},
+ {0xc6f7e151u, 0xc89116deu, 0, 1, 0},
+ }};
+ if (auto r = LGAMMAF_EXCEPTS_BERN2.lookup(xbits.uintval());
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ // |x| > 2000 -> 2-term BERN2.
+ constexpr double BERN2[2] = {0x1.5555555555555p-4,
+ -0x1.6c16bfb7c65a8p-9};
+ lgamma_val += inv_x * fputil::multiply_add(inv_x2, BERN2[1], BERN2[0]);
+ } else if (x_abs > 0x42920000u) {
+ // Exceptional cases of this range.
+ constexpr fputil::ExceptValues<float, 2> LGAMMAF_EXCEPTS_BERN4{{
+ // input, toward-zero result, RU, RD, RN
+ {0x449acf07u, 0x45ecd680u, 1, 0, 1},
+ {0xc33139a3u, 0xc43991afu, 0, 1, 0},
+ }};
+ if (auto r = LGAMMAF_EXCEPTS_BERN4.lookup(xbits.uintval());
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ // |x| > 73 -> 4-term BERN4.
+ constexpr double BERN4[4] = {
+ 0x1.5555555555555p-4, -0x1.6c16c16c15f75p-9, 0x1.a01a00593b36fp-11,
+ -0x1.37e91273668efp-11};
+ double inv_x4 = inv_x2 * inv_x2;
+ double p01 = fputil::multiply_add(inv_x2, BERN4[1], BERN4[0]);
+ double p23 = fputil::multiply_add(inv_x2, BERN4[3], BERN4[2]);
+ lgamma_val += inv_x * fputil::multiply_add(inv_x4, p23, p01);
+ } else {
+ // Exceptional cases of this range.
+ constexpr fputil::ExceptValues<float, 2> LGAMMAF_EXCEPTS_B10{{
+ // input, toward-zero result, RU, RD, RN
+ {0x42468b59u, 0x430f25a7u, 1, 0, 0},
+ {0xc134eb14u, 0xc1875615u, 0, 1, 0},
+ }};
+ if (auto r = LGAMMAF_EXCEPTS_B10.lookup(xbits.uintval());
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ // |x| in (3.373, 73]: degree-10 monomial fit of
+ // h(s) = stir_resid(1/sqrt(s)) / sqrt(s), s = 1/x^2, on [0, 0.088];
+ // correction = h(s) * (1/x). Max error 2^-53.2.
+ constexpr double MID_B10 = 0x1.6880000000000p-5;
+ constexpr double POLY_B10[11] = {
+ 0x1.54d6b78cee955p-4, -0x1.635a5fb0cdf9fp-9,
+ 0x1.7b5253f44b255p-11, -0x1.f32907e7a7adap-12,
+ 0x1.1f269b6438739p-11, -0x1.e95dc64c5042cp-11,
+ 0x1.17ebce09c49a7p-9, -0x1.91599e7728747p-8,
+ 0x1.5a01e1f07b127p-6, -0x1.90e956754bc6ap-4,
+ 0x1.dfbed80c6f035p-2};
+ double u = inv_x2 - MID_B10;
+ double u2 = u * u, u4 = u2 * u2, u8 = u4 * u4;
+ double p01 = fputil::multiply_add(u, POLY_B10[1], POLY_B10[0]);
+ double p23 = fputil::multiply_add(u, POLY_B10[3], POLY_B10[2]);
+ double p45 = fputil::multiply_add(u, POLY_B10[5], POLY_B10[4]);
+ double p67 = fputil::multiply_add(u, POLY_B10[7], POLY_B10[6]);
+ double p89 = fputil::multiply_add(u, POLY_B10[9], POLY_B10[8]);
+ double q03 = fputil::multiply_add(u2, p23, p01);
+ double q47 = fputil::multiply_add(u2, p67, p45);
+ double q810 = fputil::multiply_add(u2, POLY_B10[10], p89);
+ double r07 = fputil::multiply_add(u4, q47, q03);
+ double poly = fputil::multiply_add(u8, q810, r07);
+ lgamma_val += inv_x * poly;
+ }
+ } else {
+ constexpr fputil::ExceptValues<float, 3> LGAMMAF_EXCEPTS_HUGE{{
+ // input, toward-zero result, RU, RD, RN
+ {0x65fca09fu, 0x68cead59u, 1, 0, 1},
+ {0x716e5dd5u, 0x747e2bb9u, 1, 0, 0},
+ {0x77ac5674u, 0x7acf27b2u, 1, 0, 1},
+ }};
+ if (auto r = LGAMMAF_EXCEPTS_HUGE.lookup(xbits.uintval());
+ LIBC_UNLIKELY(r.has_value()))
+ return r.value();
+ }
+
+ if (xbits.is_neg()) {
+ // Reflection: lgamma(x) = log(pi) - lgamma(|x|) - log(|x|) -
+ // log(|sin(pi*frac_x)|). Reusing the already-computed lz = log(|x|)
+ // keeps the multiply out of the serial sinpi -> log chain.
+ double frac_x = xd - fputil::floor(xd);
+ lgamma_val = (0x1.250d048e7a1bdp+0 - lgamma_val) - lz;
+ lgamma_val -= lg_ln(lg_sinpi(frac_x));
+ }
+ }
+
+ float result = fputil::cast<float>(lgamma_val);
+ if (LIBC_UNLIKELY(FPBits(result).is_inf())) {
+ fputil::raise_except_if_required(FE_OVERFLOW | FE_INEXACT);
+ fputil::set_errno_if_required(ERANGE);
+ }
+ return result;
+}
+
+} // namespace math
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LGAMMAF_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf16.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf16.h
index 34f2c2717f4..28660fe92d5 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf16.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/lgammaf16.h
@@ -13,7 +13,6 @@
#ifdef LIBC_TYPES_HAS_FLOAT16
-#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
#include "src/__support/FPUtil/NearestIntegerOperations.h"
@@ -23,100 +22,14 @@
#include "src/__support/macros/config.h"
#include "src/__support/macros/optimization.h"
#include "src/__support/macros/properties/types.h"
+#include "src/__support/math/gamma_util.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-namespace lgammaf16_internal {
-
-LIBC_INLINE constexpr bool is_integer(float16 x) {
- using FPBits = fputil::FPBits<float16>;
- FPBits xbits(x);
- uint16_t x_u = xbits.uintval();
- unsigned x_e = static_cast<unsigned>(xbits.get_biased_exponent());
- unsigned lsb = static_cast<unsigned>(
- cpp::countr_zero(static_cast<uint16_t>(x_u | FPBits::EXP_MASK)));
- constexpr unsigned UNIT_EXPONENT =
- static_cast<unsigned>(FPBits::EXP_BIAS + FPBits::FRACTION_LEN);
- return x_e + lsb >= UNIT_EXPONENT;
-}
-
-// sin(pi*x) for x in (0, 1), written as (0.25 - u^2) * P(u^2) where u = x-0.5.
-// Coefficients for P are a degree-7 polynomial in u^2
-// approximating sin(pi*(u+0.5)) / (pi*(0.25-u^2))
-// with max error ~2^{-55}, generated by Sollya with:
-// > P = fpminimax(sin(pi*(x+0.5))/(pi*(0.25-x^2)),
-// [|0,2,4,6,8,10,12,14|], [|D...|], [-0.5, 0.5]);
-LIBC_INLINE constexpr double lg_sinpi(double x) {
- constexpr double COEFFS[8] = {0x000000000000001p+2, -0x1.de9e64df22ea4p+1,
- 0x1.472be122401f8p+0, -0x1.d4fcd82df91bp-3,
- 0x1.9f05c97e0aab2p-6, -0x1.f3091c427b611p-10,
- 0x1.b22c9bfdca547p-14, -0x1.15484325ef569p-18};
- double u = x - 0.5;
- double u2 = u * u, u4 = u2 * u2, u8 = u4 * u4;
- double p01 = fputil::multiply_add(u2, COEFFS[1], COEFFS[0]);
- double p23 = fputil::multiply_add(u2, COEFFS[3], COEFFS[2]);
- double p45 = fputil::multiply_add(u2, COEFFS[5], COEFFS[4]);
- double p67 = fputil::multiply_add(u2, COEFFS[7], COEFFS[6]);
- double p03 = fputil::multiply_add(u4, p23, p01);
- double p47 = fputil::multiply_add(u4, p67, p45);
- return (0.25 - u2) * fputil::multiply_add(u8, p47, p03);
-}
-
-// Natural logarithm of x (x > 0), using 16-entry table + degree-7 polynomial.
-// Range reduction: x = 2^e * m where m in [1, 2), decomposed as
-// m = (1+i/16)*(1+z) so log(x) = e*log(2) + log(1+i/16) + log(1+z)
-// = e*log(2) + IL[i] + z*P(z).
-// P approximates log(1+z)/z on z in [-1/16, 1/16] with max
-// error ~2^{-54}, generated by Sollya with:
-// > P = fpminimax(log(1+x)/x, [|0,1,2,3,4,5,6,7|], [|D...|], [-1/16, 1/16]);
-LIBC_INLINE double lg_ln(double x) {
- using FPBits = fputil::FPBits<double>;
- uint64_t u = FPBits(x).uintval();
- int e = static_cast<int>(FPBits(x).get_biased_exponent()) - 0x3ff;
-
- // Coefficients for log(1 + z)/z on z in [-1/16, 1/16]
- constexpr double COEFFS[8] = {0x1.fffffffffff24p-1, -0x1.ffffffffd1d67p-2,
- 0x1.55555537802dep-2, -0x1.ffffeca81b866p-3,
- 0x1.999611761d772p-3, -0x1.54f3e581b61bfp-3,
- 0x1.1e642b4cb5143p-3, -0x1.9115a5af1e1edp-4};
- // IL[i] = log(1 + i/16) for i = 0..15
- constexpr double IL[16] = {
- 0x1.59caeec280116p-57, 0x1.f0a30c01162aap-5, 0x1.e27076e2af2ebp-4,
- 0x1.5ff3070a793d6p-3, 0x1.c8ff7c79a9a2p-3, 0x1.1675cababa60fp-2,
- 0x1.4618bc21c5ec2p-2, 0x1.739d7f6bbd007p-2, 0x1.9f323ecbf984dp-2,
- 0x1.c8ff7c79a9a21p-2, 0x1.f128f5faf06ecp-2, 0x1.0be72e4252a83p-1,
- 0x1.1e85f5e7040d1p-1, 0x1.307d7334f10bep-1, 0x1.41d8fe84672afp-1,
- 0x1.52a2d265bc5abp-1};
- // IX[i] = 1 / (1 + i/16) for i = 0..15
- constexpr double IX[16] = {
- 0x000000000000001p+0, 0x1.e1e1e1e1e1e1ep-1, 0x1.c71c71c71c71cp-1,
- 0x1.af286bca1af28p-1, 0x1.999999999999ap-1, 0x1.8618618618618p-1,
- 0x1.745d1745d1746p-1, 0x1.642c8590b2164p-1, 0x1.5555555555555p-1,
- 0x1.47ae147ae147bp-1, 0x1.3b13b13b13b14p-1, 0x1.2f684bda12f68p-1,
- 0x1.2492492492492p-1, 0x1.1a7b9611a7b96p-1, 0x1.1111111111111p-1,
- 0x1.0842108421084p-1};
-
- int i = static_cast<int>((u >> 48) & 0xf);
- // Reduce to mantissa in [1, 2)
- uint64_t mant_u = (u & (~uint64_t(0) >> 12)) | (uint64_t(0x3ff) << 52);
- double mant = FPBits(mant_u).get_val();
- double z = IX[i] * mant - 1.0, z2 = z * z, z4 = z2 * z2;
- double q01 = fputil::multiply_add(z, COEFFS[1], COEFFS[0]);
- double q23 = fputil::multiply_add(z, COEFFS[3], COEFFS[2]);
- double q45 = fputil::multiply_add(z, COEFFS[5], COEFFS[4]);
- double q67 = fputil::multiply_add(z, COEFFS[7], COEFFS[6]);
- double q03 = fputil::multiply_add(z2, q23, q01);
- double q47 = fputil::multiply_add(z2, q67, q45);
- return e * 0x1.62e42fefa39efp-1 + IL[i] +
- z * fputil::multiply_add(z4, q47, q03);
-}
-
-} // namespace lgammaf16_internal
-
LIBC_INLINE float16 lgammaf16(float16 x) {
- using namespace lgammaf16_internal;
+ using namespace gamma_internal;
using FPBits = fputil::FPBits<float16>;
FPBits xbits(x);
@@ -156,7 +69,6 @@ LIBC_INLINE float16 lgammaf16(float16 x) {
double abs_xd = xd < 0.0 ? -xd : xd;
double lgamma_val;
- // |x| = 0.66015625
if (LIBC_UNLIKELY(x_abs < 0x3948u)) {
// Small path: |x| < 0.66015625
// For t = |x|: lgamma(t) = t*P(u) - log(t), where P(u) approximates
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/llogbf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/llogbf128.h
index 483c464fd3a..da925e81d1a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/llogbf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/llogbf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"
@@ -29,6 +29,6 @@ LIBC_INLINE constexpr long llogbf128(float128 x) {
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LLOGBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/llrintf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/llrintf128.h
index fe2c5c99969..07956468d5c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/llrintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/llrintf128.h
@@ -9,18 +9,17 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LLRINTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_LLRINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr long long llrintf128(float128 x) {
- return fputil::round_to_signed_integer_using_current_rounding_mode<float128,
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr long long llrintf128(Float128 x) {
+ return fputil::round_to_signed_integer_using_current_rounding_mode<Float128,
long long>(
x);
}
@@ -28,6 +27,4 @@ LIBC_INLINE constexpr long long llrintf128(float128 x) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LLRINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/llroundf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/llroundf128.h
index ece48eeb6a1..7a52ff5c804 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/llroundf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/llroundf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LLROUNDF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_LLROUNDF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr long long llroundf128(float128 x) {
- return fputil::round_to_signed_integer<float128, long long>(x);
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr long long llroundf128(Float128 x) {
+ return fputil::round_to_signed_integer<Float128, long long>(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LLROUNDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/logbf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/logbf128.h
index e7053fe8a4c..f4671c0a944 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/logbf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/logbf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/common.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 logbf128(float128 x) { return fputil::logb(x); }
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LOGBF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/lrintf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/lrintf128.h
index fa3c470d0ea..c83d54475cd 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/lrintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/lrintf128.h
@@ -9,24 +9,21 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LRINTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_LRINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr long lrintf128(float128 x) {
- return fputil::round_to_signed_integer_using_current_rounding_mode<float128,
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr long lrintf128(Float128 x) {
+ return fputil::round_to_signed_integer_using_current_rounding_mode<Float128,
long>(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LRINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/lroundf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/lroundf128.h
index 7945c597022..14e3c676acd 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/lroundf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/lroundf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_LROUNDF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_LROUNDF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr long lroundf128(float128 x) {
- return fputil::round_to_signed_integer<float128, long>(x);
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr long lroundf128(Float128 x) {
+ return fputil::round_to_signed_integer<Float128, long>(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_LROUNDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/modff128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/modff128.h
index 69688dd2551..b519298a50a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/modff128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/modff128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 modff128(float128 x, float128 *iptr) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_MODFF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/nanf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/nanf128.h
index bb5c4e0a4f1..5cc1010939d 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/nanf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/nanf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/libc_errno.h"
#include "src/__support/macros/config.h"
@@ -30,6 +30,6 @@ LIBC_INLINE constexpr float128 nanf128(const char *arg) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_NANF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/nearbyintf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/nearbyintf128.h
index 56d32cd61b5..8eb90f9c3b0 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/nearbyintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/nearbyintf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_NEARBYINTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_NEARBYINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 nearbyintf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 nearbyintf128(Float128 x) {
return fputil::round_using_current_rounding_mode(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_NEARBYINTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/nextafterf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/nextafterf128.h
index 2f15bd41c04..d9c07b4d6b6 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/nextafterf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/nextafterf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 nextafterf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_NEXTAFTERF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/nextdownf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/nextdownf128.h
index 8f5e5c015ef..b3a93c39090 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/nextdownf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/nextdownf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 nextdownf128(float128 x) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_NEXTDOWNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/nextupf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/nextupf128.h
index 36c1424518f..2b618e40959 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/nextupf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/nextupf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/ManipulationFunctions.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 nextupf128(float128 x) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_NEXTUPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/remainderf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/remainderf128.h
index bf749b569bd..cd3ed15a7b1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/remainderf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/remainderf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/DivisionAndRemainderOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 remainderf128(float128 x, float128 y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_REMAINDERF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/remquof128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/remquof128.h
index d2247afc1e4..d22b3359d43 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/remquof128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/remquof128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/DivisionAndRemainderOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr float128 remquof128(float128 x, float128 y, int *exp) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_REMQUOF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/rintf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/rintf128.h
index 2280bd0a601..8c36a540e7a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/rintf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/rintf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_RINTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_RINTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 rintf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 rintf128(Float128 x) {
return fputil::round_using_current_rounding_mode(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_RINTF128_H
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 8cbfa3ff79e..d35c9f437a6 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
@@ -10,13 +10,40 @@
#define LLVM_LIBC_SRC___SUPPORT_MATH_ROUND_H
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
+// For the following targets, clang will generate rounding instructions
+// by default:
+// - x86-64 with sse4.1 or after
+// - ARM v8
+// - RISC-V
+
+// Notes: gcc does not generate the instructions for x86-64 by default.
+
+// Notes: for x86-64, if `-ffp-model=strict` is set, `__builtin_round` will
+// generate a callback to `round` and it does not look like there is any way for
+// us to detect that just from the pre-defined macros. The only way to really
+// detect the call back is to compile and link with nostdlib.
+// This also affects `__builtin_elementwise_round`, making it behave identical
+// to `__builtin_round`.
+
+// Notes: `__builtin_elementwise_round` is slightly better than
+// `__builtin_round` in that it is not defined for x86-64 pre-SSE4.1, but it
+// still generate callback for ARM version < 8, and for x86-64 with
+// `-ffp-model=strict`.
+
LIBC_INLINE LIBC_CONSTEXPR double round(double x) {
-#if defined(__LIBC_USE_BUILTIN_ROUND) && !defined(LIBC_USE_CONSTEXPR)
+#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))))
return __builtin_round(x);
#else
return fputil::round(x);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/roundevenf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/roundevenf128.h
index 83524c0e8f1..c2e39220fb4 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/roundevenf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/roundevenf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDEVENF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDEVENF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 roundevenf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 roundevenf128(Float128 x) {
return fputil::round_using_specific_rounding_mode(x, FP_INT_TONEAREST);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDEVENF128_H
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 e20b9d2e7f7..5abe9ebad15 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
@@ -10,13 +10,40 @@
#define LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDF_H
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/compiler.h"
+#include "src/__support/macros/properties/cpu_features.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
+// For the following targets, clang will generate rounding instructions
+// by default:
+// - x86-64 with sse4.1 or after
+// - ARM v8
+// - RISC-V
+
+// Notes: gcc does not generate the instructions for x86-64 by default.
+
+// Notes: for x86-64, if `-ffp-model=strict` is set, `__builtin_round` will
+// generate a callback to `round` and it does not look like there is any way for
+// us to detect that just from the pre-defined macros. The only way to really
+// detect the call back is to compile and link with nostdlib.
+// This also affects `__builtin_elementwise_round`, making it behave identical
+// to `__builtin_round`.
+
+// Notes: `__builtin_elementwise_round` is slightly better than
+// `__builtin_round` in that it is not defined for x86-64 pre-SSE4.1, but it
+// still generate callback for ARM version < 8, and for x86-64 with
+// `-ffp-model=strict`.
+
LIBC_INLINE LIBC_CONSTEXPR float roundf(float x) {
-#if defined(__LIBC_USE_BUILTIN_ROUND) && !defined(LIBC_USE_CONSTEXPR)
+#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))))
return __builtin_roundf(x);
#else
return fputil::round(x);
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf128.h
index ccd5a6b10cf..3c04b2cd83e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/roundf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 roundf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 roundf128(Float128 x) {
return fputil::round(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_ROUNDF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/scalblnf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/scalblnf128.h
index 5265265487f..6bd6dd92b7e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/scalblnf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/scalblnf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "hdr/float_macros.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
@@ -31,6 +31,6 @@ LIBC_INLINE constexpr float128 scalblnf128(float128 x, long n) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SCALBLNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/scalbnf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/scalbnf128.h
index 58963d1702c..bb9b3ecfa40 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/scalbnf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/scalbnf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "hdr/float_macros.h"
#include "src/__support/FPUtil/ManipulationFunctions.h"
@@ -31,6 +31,6 @@ LIBC_INLINE constexpr float128 scalbnf128(float128 x, int n) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SCALBNF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadf128.h
index bacd17af658..4e022d8ec91 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/setpayloadf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr int setpayloadf128(float128 *res, float128 pl) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SETPAYLOADF128_H
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 fa49c1d5865..6a519209111 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
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE int setpayloadsigf128(float128 *res, float128 pl) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SETPAYLOADSIGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/sqrtf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/sqrtf128.h
index 14dcbec1acb..a1fe100ff4b 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/sqrtf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/sqrtf128.h
@@ -9,13 +9,10 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_SQRTF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_SQRTF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/CPP/bit.h"
#include "src/__support/FPUtil/FEnvImpl.h"
#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/FPUtil/rounding_mode.h"
#include "src/__support/common.h"
#include "src/__support/macros/optimization.h"
@@ -58,6 +55,8 @@
namespace LIBC_NAMESPACE_DECL {
namespace math {
+using LIBC_NAMESPACE::fputil::Float128;
+
namespace sqrtf128_internal {
template <typename T, typename U = T> LIBC_INLINE constexpr T prod_hi(T, U);
@@ -280,9 +279,9 @@ LIBC_INLINE constexpr uint64_t rsqrt_approx(uint64_t m) {
} // namespace sqrtf128_internal
-LIBC_INLINE float128 sqrtf128(float128 x) {
+LIBC_INLINE Float128 sqrtf128(Float128 x) {
using namespace sqrtf128_internal;
- using FPBits = fputil::FPBits<float128>;
+ using FPBits = fputil::FPBits<Float128>;
// Get rounding mode.
uint32_t rm = fputil::get_round();
@@ -441,12 +440,10 @@ LIBC_INLINE float128 sqrtf128(float128 x) {
// if(frac) fputil::raise_except_if_required(FE_INEXACT);
v += static_cast<UInt128>(e2) << FPBits::FRACTION_LEN; // place exponent
- return cpp::bit_cast<float128>(v);
+ return cpp::bit_cast<Float128>(v);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_SQRTF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/tan.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/tan.h
index 7ff6f4f795c..87f46acbf70 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/tan.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/tan.h
@@ -108,8 +108,9 @@ LIBC_INLINE double tan_eval(const DoubleDouble &u, DoubleDouble &result) {
// Calculation a / b = a * (1/b) for DFloat128.
// Using the initial approximation of q ~ (1/b), then apply 2 Newton-Raphson
// iterations, before multiplying by a.
-[[maybe_unused]] DFloat128 newton_raphson_div(const DFloat128 &a, DFloat128 b,
- double q) {
+[[maybe_unused]] LIBC_INLINE DFloat128 newton_raphson_div(const DFloat128 &a,
+ DFloat128 b,
+ double q) {
DFloat128 q0(q);
LIBC_BIT_CAST_CONSTEXPR_VAR DFloat128 TWO(2.0);
b.sign = (b.sign == Sign::POS) ? Sign::NEG : Sign::POS;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/totalorderf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/totalorderf128.h
index e1f36af36d8..3af00e711fa 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/totalorderf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/totalorderf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -26,6 +26,6 @@ LIBC_INLINE constexpr int totalorderf128(const float128 *x, const float128 *y) {
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_TOTALORDERF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/totalordermagf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/totalordermagf128.h
index 2c59a8ba30e..ea79011f8b0 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/totalordermagf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/totalordermagf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/BasicOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr int totalordermagf128(const float128 *x,
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_TOTALORDERMAGF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/truncf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/truncf128.h
index e10c3bf6672..72e3a100a09 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/truncf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/truncf128.h
@@ -9,23 +9,20 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATH_TRUNCF128_H
#define LLVM_LIBC_SRC___SUPPORT_MATH_TRUNCF128_H
-#include "include/llvm-libc-types/float128.h"
-
-#ifdef LIBC_TYPES_HAS_FLOAT128
-
#include "src/__support/FPUtil/NearestIntegerOperations.h"
+#include "src/__support/FPUtil/float128.h"
#include "src/__support/macros/config.h"
namespace LIBC_NAMESPACE_DECL {
namespace math {
-LIBC_INLINE constexpr float128 truncf128(float128 x) {
+using LIBC_NAMESPACE::fputil::Float128;
+
+LIBC_INLINE constexpr Float128 truncf128(Float128 x) {
return fputil::trunc(x);
}
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
-
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_TRUNCF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpf128.h
index d6fac3604e5..b7a3376924c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 ufromfpf128(float128 x, int rnd,
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_UFROMFPF128_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpxf128.h b/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpxf128.h
index 2f722179485..3543b62da84 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpxf128.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/math/ufromfpxf128.h
@@ -11,7 +11,7 @@
#include "include/llvm-libc-types/float128.h"
-#ifdef LIBC_TYPES_HAS_FLOAT128
+#ifdef LIBC_TYPES_HAS_NATIVE_FLOAT128
#include "src/__support/FPUtil/NearestIntegerOperations.h"
#include "src/__support/macros/config.h"
@@ -27,6 +27,6 @@ LIBC_INLINE constexpr float128 ufromfpxf128(float128 x, int rnd,
} // namespace math
} // namespace LIBC_NAMESPACE_DECL
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
#endif // LLVM_LIBC_SRC___SUPPORT_MATH_UFROMFPXF128_H
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 5fcb2feb2f4..6e5f3bbddc1 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
@@ -122,8 +122,10 @@ add_header_library(
HDRS
exp2f.h
DEPENDS
+ .expf_utils
libc.src.__support.CPP.simd
- libc.src.__support.math.exp2f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.common
)
add_header_library(
@@ -140,8 +142,10 @@ add_header_library(
HDRS
exp10f.h
DEPENDS
+ .expf_utils
libc.src.__support.CPP.simd
- libc.src.__support.math.exp10f
+ libc.src.__support.FPUtil.fp_bits
+ libc.src.__support.common
)
add_header_library(
@@ -289,4 +293,4 @@ add_header_library(
DEPENDS
libc.src.__support.CPP.simd
libc.src.__support.math.tanpif
-)
\ No newline at end of file
+)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp10f.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp10f.h
index 25a62fcbda9..d22baf16b40 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp10f.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp10f.h
@@ -14,19 +14,55 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP10F_H
#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP10F_H
+#include "expf_utils.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/exp10f.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/common.h"
namespace LIBC_NAMESPACE_DECL {
namespace mathvec {
+template <size_t N>
+LIBC_INLINE static cpp::simd<double, N> inline_exp10(cpp::simd<double, N> x) {
+ constexpr cpp::simd<double, N> shift = 0x1.800000000ffc0p+46;
+ constexpr cpp::simd<double, N> log2_10 = 0x1.a934f0979a371p+1;
+
+ // Rounds n to be (x * log2(10)) to the nearest multiple of 1/64
+ // While preparing z to be used as an index for the lookup in eval_exp
+ cpp::simd<double, N> z = cpp::multiply_add(x, log2_10, shift);
+ cpp::simd<double, N> n = z - shift;
+
+ constexpr cpp::simd<double, N> log2_10_lo = 0x1.7f2495fb7fa6dp-53;
+ constexpr cpp::simd<double, N> negative_ln2 = -0x1.62e42fefa39efp-1;
+
+ // Using 10^x = e^(x * ln(10)) = e^(x * log2(10) * ln(2))
+ // Reduces x into r as:
+ // r = (x * log2(10) - n) * ln(2), with |r| <= ln2/128,
+ // Computed as (n - x * log2(10)) * -ln(2) to avoid negating n.
+ cpp::simd<double, N> r;
+ r = cpp::multiply_add(-x, log2_10, n);
+ r = cpp::multiply_add(-x, log2_10_lo, r);
+ r = r * negative_ln2;
+
+ return eval_exp(r, z);
+}
+
template <size_t N>
LIBC_INLINE cpp::simd<float, N> exp10f(cpp::simd<float, N> x) {
- return cpp::map(x, [](float a) { return math::exp10f(a); });
+ using FPBits = typename fputil::FPBits<float>;
+
+ cpp::simd<bool, N> is_inf = x >= 0x1.344136p+5f;
+ cpp::simd<bool, N> is_zero = x <= -0x1.693c6bp+5f;
+ cpp::simd<bool, N> is_special = is_inf | is_zero;
+
+ cpp::simd<float, N> special_res = is_inf ? FPBits::inf().get_val() : 0.0f;
+
+ cpp::simd<double, N> x_d = cpp::simd_cast<double, float, N>(x);
+ cpp::simd<double, N> y = inline_exp10(x_d);
+ cpp::simd<float, N> ret = cpp::simd_cast<float, double, N>(y);
+
+ return is_special ? special_res : ret;
}
} // namespace mathvec
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp2f.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp2f.h
index fb9c79890a7..848b9647dd6 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp2f.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/exp2f.h
@@ -14,19 +14,51 @@
#ifndef LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP2F_H
#define LLVM_LIBC_SRC___SUPPORT_MATHVEC_EXP2F_H
+#include "expf_utils.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/exp2f.h"
+#include "src/__support/FPUtil/FPBits.h"
+#include "src/__support/common.h"
namespace LIBC_NAMESPACE_DECL {
namespace mathvec {
+template <size_t N>
+LIBC_INLINE static cpp::simd<double, N> inline_exp2(cpp::simd<double, N> x) {
+ constexpr cpp::simd<double, N> shift = 0x1.800000000ffc0p+46;
+
+ // Rounds n to be x to the nearest multiple of 1/64
+ // While preparing z to be used as an index for the lookup in eval_exp
+ cpp::simd<double, N> z = x + shift;
+ cpp::simd<double, N> n = z - shift;
+
+ // ln(2), with a bias of +768 FP64 ULP, which is enough to remove the
+ // hard to round cases when casting back to FP32.
+ constexpr cpp::simd<double, N> biased_ln2 = 0x1.62e42fefa3cefp-1;
+
+ // Using 2^x = e^(x * ln2),
+ // Reduces x into r as:
+ // r = (x - n) * ln(2), with |r| <= ln2/128.
+ // then computes 2^x = 2^n * exp(r).
+ cpp::simd<double, N> r = (x - n) * biased_ln2;
+ return eval_exp(r, z);
+}
+
template <size_t N>
LIBC_INLINE cpp::simd<float, N> exp2f(cpp::simd<float, N> x) {
- return cpp::map(x, [](float a) { return math::exp2f(a); });
+ using FPBits = typename fputil::FPBits<float>;
+
+ cpp::simd<bool, N> is_inf = x >= 0x1p7;
+ cpp::simd<bool, N> is_zero = x <= -0x1.2cp7f;
+ cpp::simd<bool, N> is_special = is_inf | is_zero;
+
+ cpp::simd<float, N> special_res = is_inf ? FPBits::inf().get_val() : 0.0f;
+
+ cpp::simd<double, N> x_d = cpp::simd_cast<double, float, N>(x);
+ cpp::simd<double, N> y = inline_exp2(x_d);
+ cpp::simd<float, N> ret = cpp::simd_cast<float, double, N>(y);
+
+ return is_special ? special_res : ret;
}
} // namespace mathvec
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf.h
index c27de2527e5..95f5a5dc768 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf.h
@@ -28,7 +28,7 @@ LIBC_INLINE static cpp::simd<double, N> inline_exp(cpp::simd<double, N> x) {
// inv_ln2 = round(1/log(2), D, RN);
constexpr cpp::simd<double, N> inv_ln2 = 0x1.71547652b82fep+0;
- cpp::simd<double, N> z = shift + x * inv_ln2;
+ cpp::simd<double, N> z = cpp::multiply_add(x, inv_ln2, shift);
cpp::simd<double, N> n = z - shift;
// ln2_hi = round(log(2), D, RN);
@@ -37,40 +37,18 @@ LIBC_INLINE static cpp::simd<double, N> inline_exp(cpp::simd<double, N> x) {
constexpr cpp::simd<double, N> ln2_lo = 0x1.abc9e3b39803fp-56;
cpp::simd<double, N> r = x;
- r = r - n * ln2_hi;
- r = r - n * ln2_lo;
-
- // Coefficients of exp approximation, generated by Sollya with:
- // poly = 1 + x;
- // for i from 2 to 5 do {
- // r = remez(exp(x)-poly(x), 5-i, [-log(2)/128;log(2)/128], x^i, 1e-10);
- // c = coeff(roundcoefficients(r, [|D ...|]), 0);
- // poly = poly + x^i*c;
- // c;
- // };
- constexpr cpp::simd<double, N> c0 = 0x1.fffffffffdbcep-2;
- constexpr cpp::simd<double, N> c1 = 0x1.55555555543c2p-3;
- constexpr cpp::simd<double, N> c2 = 0x1.555573c64f2e3p-5;
- constexpr cpp::simd<double, N> c3 = 0x1.111126b4eff73p-7;
-
- /* y = exp(r) - 1 ~= r + C0 r^2 + C1 r^3 + C2 r^4 + C3 r^5. */
- cpp::simd<double, N> r2 = r * r;
- cpp::simd<double, N> p01 = c0 + r * c1;
- cpp::simd<double, N> p23 = c2 + r * c3;
- cpp::simd<double, N> p04 = p01 + r2 * p23;
- cpp::simd<double, N> y = r + p04 * r2;
-
- cpp::simd<uint64_t, N> u = cpp::bit_cast<cpp::simd<uint64_t, N>>(z);
- cpp::simd<double, N> s = exp_lookup(u);
- return s + s * y;
+ r = cpp::multiply_add(-n, ln2_hi, r);
+ r = cpp::multiply_add(-n, ln2_lo, r);
+
+ return eval_exp(r, z);
}
template <size_t N>
LIBC_INLINE cpp::simd<float, N> expf(cpp::simd<float, N> x) {
using FPBits = typename fputil::FPBits<float>;
- cpp::simd<bool, N> is_inf = x >= 0x1.62e38p+9;
- cpp::simd<bool, N> is_zero = x <= -0x1.628c2ap+9;
+ cpp::simd<bool, N> is_inf = x >= 0x1.62e43p+6f;
+ cpp::simd<bool, N> is_zero = x <= -0x1.9fe36ap+6f;
cpp::simd<bool, N> is_special = is_inf | is_zero;
cpp::simd<float, N> special_res = is_inf ? FPBits::inf().get_val() : 0.0f;
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf_utils.h b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf_utils.h
index c23e286f656..8ce3d3c3b5e 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf_utils.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/mathvec/expf_utils.h
@@ -7,7 +7,7 @@
//===----------------------------------------------------------------------===//
///
/// \file
-/// This file contains utility functions for single-precision SIMD exp.
+/// This file contains utility functions for single-precision SIMD exp/2/10.
///
//===----------------------------------------------------------------------===//
@@ -32,6 +32,39 @@ LIBC_INLINE static cpp::simd<double, N> exp_lookup(cpp::simd<uint64_t, N> u) {
return cpp::bit_cast<cpp::simd<double, N>>(result);
}
+template <size_t N>
+LIBC_INLINE static cpp::simd<double, N> eval_exp(cpp::simd<double, N> r,
+ cpp::simd<double, N> z) {
+ // Coefficients of exp approximation, generated by Sollya with:
+ // poly = 1 + x;
+ // for i from 2 to 5 do {
+ // r = remez(exp(x)-poly(x), 5-i, [-log(2)/128;log(2)/128], x^i, 1e-10);
+ // c = coeff(roundcoefficients(r, [|D ...|]), 0);
+ // poly = poly + x^i*c;
+ // c;
+ // };
+ constexpr cpp::simd<double, N> c0 = 0x1.fffffffffdbcep-2;
+ constexpr cpp::simd<double, N> c1 = 0x1.55555555543c2p-3;
+ constexpr cpp::simd<double, N> c2 = 0x1.555573c64f2e3p-5;
+ constexpr cpp::simd<double, N> c3 = 0x1.111126b4eff73p-7;
+
+ // y = exp(r) - 1 ~= r + C0 r^2 + C1 r^3 + C2 r^4 + C3 r^5.
+ cpp::simd<double, N> r2 = r * r;
+ cpp::simd<double, N> p01 = cpp::multiply_add(c1, r, c0);
+ cpp::simd<double, N> p23 = cpp::multiply_add(c3, r, c2);
+ cpp::simd<double, N> p04 = cpp::multiply_add(p23, r2, p01);
+ cpp::simd<double, N> y = cpp::multiply_add(p04, r2, r);
+
+ // Table lookup for 2^n, where n is a multiple of 1/64
+ cpp::simd<uint64_t, N> u = cpp::bit_cast<cpp::simd<uint64_t, N>>(z);
+ cpp::simd<double, N> s = exp_lookup(u);
+
+ // e^x = 2^n * exp(r)
+ // Since y = exp(r) - 1, e^x = 2^n * (1 + y)
+ // Or as an FMA: e^x = 2^n + (2^n * y)
+ return cpp::multiply_add(y, s, s);
+}
+
} // namespace mathvec
} // namespace LIBC_NAMESPACE_DECL
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 a2e47e778a8..3617bb7ac1e 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
@@ -48,7 +48,7 @@ endif()
set(target_error_mapper libc.src.__support.printf_core.${LIBC_TARGET_OS}.error_mapper)
if(NOT TARGET ${target_error_mapper})
- set(target_error_mapper libc.src.__support.printf_core.generic.error_mapper)
+ set(target_error_mapper libc.src.__support.printf_core.generic.error_mapper)
endif()
if(LIBC_CONF_PRINTF_DISABLE_WIDE)
@@ -74,7 +74,7 @@ add_header_library(
printf_config
HDRS
printf_config.h
- ${printf_config_copts}
+ ${printf_config_copts}
)
add_header_library(
@@ -212,6 +212,5 @@ add_header_library(
libc.src.__support.arg_list
libc.src.__support.printf_core.printf_main
libc.src.__support.printf_core.writer
- ${use_system_file}
+ ${use_system_file}
)
-
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 bd7b78ebfab..72a521d15a6 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
@@ -44,9 +44,9 @@ struct int_type_of<T, cpp::enable_if_t<cpp::is_same_v<T, double>
#if !defined(LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE)
|| cpp::is_same_v<T, long double>
#endif // LIBC_TYPES_LONG_DOUBLE_IS_DOUBLE_DOUBLE
-#if defined(LIBC_TYPES_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
|| cpp::is_same_v<T, float128>
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
>> {
using type = typename fputil::FPBits<T>::StorageType;
};
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_config.h b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_config.h
index 0cf983f10d0..be6ab71958a 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_config.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/printf_core/printf_config.h
@@ -36,7 +36,7 @@
#define LIBC_INTERNAL_PRINTF_HAS_FIXED_POINT
#endif
-#if defined(LIBC_TYPES_HAS_FLOAT128) && \
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128) && \
!defined(LIBC_COPT_PRINTF_NO_CONVERT_FLOAT128)
#define LIBC_INTERNAL_PRINTF_CONVERT_FLOAT128
#endif
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 0d6c7901516..906af324d10 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
@@ -63,11 +63,11 @@ LIBC_INLINE int convert_write_int(Writer<write_mode> *writer,
#endif // LIBC_COPT_PRINTF_DISABLE_BITINT
*reinterpret_cast<uintmax_t *>(to_conv.conv_val_ptr) = written;
break;
-#if defined(LIBC_TYPES_HAS_FLOAT128)
+#if defined(LIBC_TYPES_HAS_NATIVE_FLOAT128)
case (LengthModifier::Q): // 'Q' is not valid for integer format; this case
// should not be reachable.
break;
-#endif // LIBC_TYPES_HAS_FLOAT128
+#endif // LIBC_TYPES_HAS_NATIVE_FLOAT128
}
return WRITE_OK;
}
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/str_to_float.h b/deps/v8/third_party/llvm-libc/src/src/__support/str_to_float.h
index ace2e130a5e..877cfbf88a7 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/str_to_float.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/str_to_float.h
@@ -418,14 +418,10 @@ LIBC_INLINE FloatConvertReturn<T> simple_decimal_conversion(
// Handle subnormals
if (exp2 <= 0) {
- // Shift right until there is a valid exponent
- while (exp2 < 0) {
- hpd.shift(-1);
- ++exp2;
- }
- // Shift right one more time to compensate for the left shift to get it
- // between 1 and 2.
- hpd.shift(-1);
+ // Shift right until there is a valid exponent, and once more to compensate
+ // for the left shift to get it between 1 and 2.
+ hpd.shift(exp2 - 1);
+ exp2 = 0;
final_mantissa = hpd.round_to_integer_type<StorageType>(round);
// Check if by shifting right we've caused this to round to a normal number.
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 cc51b4f239b..67a176f87a9 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
@@ -19,6 +19,19 @@ add_header_library(
libc.src.__support.CPP.atomic
)
+add_header_library(
+ thread_attributes
+ HDRS
+ thread_attributes.h
+ DEPENDS
+ libc.hdr.stdint_proxy
+ libc.hdr.types.size_t
+ libc.src.__support.CPP.atomic
+ libc.src.__support.macros.attributes
+ libc.src.__support.macros.config
+ libc.src.__support.macros.properties.architectures
+)
+
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS})
add_subdirectory(${LIBC_TARGET_OS})
endif()
@@ -111,6 +124,7 @@ add_header_library(
HDRS
thread.h
DEPENDS
+ .thread_attributes
libc.hdr.stdint_proxy
libc.hdr.types.struct_sched_param
libc.src.__support.common
@@ -169,7 +183,7 @@ if(TARGET libc.src.__support.threads.futex_utils)
)
endif()
-if (LLVM_LIBC_FULL_BUILD)
+if(LLVM_LIBC_FULL_BUILD)
set(identifier_dependency_on_thread libc.src.__support.threads.thread)
endif()
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/threads/identifier.h b/deps/v8/third_party/llvm-libc/src/src/__support/threads/identifier.h
index a570abfd5dc..dfc5bf41edc 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/threads/identifier.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/identifier.h
@@ -23,7 +23,7 @@ namespace internal {
LIBC_INLINE pid_t *get_tid_cache() {
#ifdef LIBC_FULL_BUILD
- return &self.attrib->tid;
+ return ¤t_thread().attrib->tid;
#else
// in non-full build mode, we do not control the fork routine. Therefore,
// we do not cache tid at all.
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 1124d1254ba..7d349f6d9bd 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
@@ -34,6 +34,7 @@ add_object_library(
libc.include.sys_syscall
libc.hdr.fcntl_macros
libc.hdr.errno_macros
+ libc.hdr.sched_macros
libc.hdr.sys_mman_macros
libc.src.errno.errno
libc.src.__support.CPP.atomic
@@ -55,9 +56,9 @@ add_object_library(
COMPILE_OPTIONS
${libc_opt_high_flag}
-fno-omit-frame-pointer # This allows us to sniff out the thread args from
- # the new thread's stack reliably.
- -Wno-frame-address # Yes, calling __builtin_return_address with a
- # value other than 0 is dangerous. We know.
+ # the new thread's stack reliably.
+ -Wno-frame-address # Yes, calling __builtin_return_address with a
+ # value other than 0 is dangerous. We know.
)
add_header_library(
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 704916fff95..231b7cf2903 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
@@ -34,11 +34,11 @@
#include "hdr/errno_macros.h"
#include "hdr/fcntl_macros.h"
+#include "hdr/sched_macros.h" // For CLONE_* flags.
#include "hdr/stdint_proxy.h"
#include "hdr/sys_mman_macros.h" // For PROT_* and MAP_* definitions.
#include <linux/param.h> // For EXEC_PAGESIZE.
#include <linux/prctl.h> // For PR_SET_NAME
-#include <linux/sched.h> // For CLONE_* flags.
#include <sys/syscall.h> // For syscall numbers.
namespace LIBC_NAMESPACE_DECL {
@@ -180,8 +180,8 @@ 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;
- self.attrib = attrib;
- self.attrib->atexit_callback_mgr = internal::get_thread_atexit_callback_mgr();
+ internal::self.attrib = attrib;
+ attrib->atexit_callback_mgr = internal::get_thread_atexit_callback_mgr();
if (attrib->style == ThreadStyle::POSIX) {
attrib->retval.posix_retval =
@@ -342,21 +342,22 @@ int Thread::run(ThreadStyle style, ThreadRunner runner, void *arg, void *stack,
}
int Thread::join(ThreadReturnValue &retval) {
- if (self.attrib) {
+ if (current_thread().attrib) {
// Reject self join.
- if (self.attrib == attrib)
+ if (current_thread().attrib == attrib)
return EDEADLK;
// Do a best-effort check of concurrent/repeated join.
// This cmpxchg establishes exclusive joiner role by setting the joiner
// field iff there is no previous joiner
ThreadAttributes *expected = nullptr;
- if (!attrib->joiner.compare_exchange_strong(expected, self.attrib,
- cpp::MemoryOrder::ACQ_REL))
+ if (!attrib->joiner.compare_exchange_strong(
+ expected, current_thread().attrib, cpp::MemoryOrder::ACQ_REL))
return EINVAL;
// Reject mutual join.
- if (self.attrib->joiner.load(cpp::MemoryOrder::ACQUIRE) == attrib) {
+ if (current_thread().attrib->joiner.load(cpp::MemoryOrder::ACQUIRE) ==
+ attrib) {
attrib->joiner.store(nullptr, cpp::MemoryOrder::RELEASE);
return EDEADLK;
}
@@ -423,7 +424,7 @@ int Thread::set_name(const cpp::string_view &name) {
if (name.size() >= NAME_SIZE_MAX)
return ERANGE;
- if (*this == self) {
+ if (*this == current_thread()) {
// If we are setting the name of the current thread, then we can
// use the syscall to set the name.
int retval =
@@ -459,7 +460,7 @@ int Thread::get_name(cpp::StringStream &name) const {
char name_buffer[NAME_SIZE_MAX];
- if (*this == self) {
+ if (*this == current_thread()) {
// If we are getting the name of the current thread, then we can
// use the syscall to get the name.
int retval =
@@ -515,7 +516,7 @@ ErrorOr<SchedParameters> Thread::getschedparam() const {
}
void thread_exit(ThreadReturnValue retval, ThreadStyle style) {
- auto attrib = self.attrib;
+ auto attrib = current_thread().attrib;
// 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,
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 ae179f068b8..31c230a45b5 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
@@ -131,6 +131,7 @@ public:
atexit_unit.callback(atexit_unit.obj);
mtx.lock();
}
+ mtx.unlock();
}
};
@@ -163,8 +164,6 @@ void call_atexit_callbacks(ThreadAttributes *attrib) {
}
}
-extern "C" void __cxa_thread_finalize() { call_atexit_callbacks(self.attrib); }
-
} // namespace internal
cpp::optional<unsigned int> new_tss_key(TSSDtor *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 ac6b6ce6fb9..c42f87a1a3c 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,12 +19,11 @@
#include "src/__support/macros/attributes.h"
#include "src/__support/macros/config.h"
#include "src/__support/macros/properties/architectures.h"
+#include "src/__support/threads/thread_attributes.h"
// TODO: fix this unguarded linux dep
#include <linux/param.h> // for exec_pagesize.
-#include <stddef.h> // For size_t
-
namespace LIBC_NAMESPACE_DECL {
struct SchedParameters {
@@ -32,99 +31,6 @@ struct SchedParameters {
struct sched_param param;
};
-using ThreadRunnerPosix = void *(void *);
-using ThreadRunnerStdc = int(void *);
-
-union ThreadRunner {
- ThreadRunnerPosix *posix_runner;
- ThreadRunnerStdc *stdc_runner;
-};
-
-union ThreadReturnValue {
- void *posix_retval;
- int stdc_retval;
- constexpr ThreadReturnValue() : posix_retval(nullptr) {}
- constexpr ThreadReturnValue(int r) : stdc_retval(r) {}
- constexpr ThreadReturnValue(void *r) : posix_retval(r) {}
-};
-
-#if (defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
- defined(LIBC_TARGET_ARCH_IS_X86_64) || \
- defined(LIBC_TARGET_ARCH_IS_ANY_RISCV))
-constexpr unsigned int STACK_ALIGNMENT = 16;
-#elif defined(LIBC_TARGET_ARCH_IS_ARM)
-// See Section 6.2.1.2 Stack constraints at a public interface of AAPCS32.
-constexpr unsigned int STACK_ALIGNMENT = 8;
-#endif
-// TODO: Provide stack alignment requirements for other architectures.
-
-enum class DetachState : uint32_t {
- JOINABLE = 0x11,
- EXITING = 0x22,
- DETACHED = 0x33
-};
-
-enum class ThreadStyle : uint8_t { POSIX = 0x1, STDC = 0x2 };
-
-// Detach type is useful in testing the detach operation.
-enum class DetachType : int {
- // Indicates that the detach operation just set the detach state to DETACHED
- // and returned.
- SIMPLE = 1,
-
- // Indicates that the detach operation performed thread cleanup.
- 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
-// part of a thread's state. For example, the stack guard size.
-//
-// Thread attributes are typically stored on the stack. So, we align as required
-// for the target architecture.
-struct alignas(STACK_ALIGNMENT) ThreadAttributes {
- // We want the "detach_state" attribute to be an atomic value as it could be
- // updated by one thread while the self thread is reading it. It is a tristate
- // variable with the following state transitions:
- // 1. The a thread is created in a detached state, then user code should never
- // call a detach or join function. Calling either of them can lead to
- // undefined behavior.
- // The value of |detach_state| is expected to be DetachState::DETACHED for
- // its lifetime.
- // 2. If a thread is created in a joinable state, |detach_state| will start
- // with the value DetachState::JOINABLE. Another thread can detach this
- // thread before it exits. The state transitions will as follows:
- // (a) If the detach method sees the state as JOINABLE, then it will
- // compare exchange to a state of DETACHED. The thread will clean
- // itself up after it finishes.
- // (b) If the detach method does not see JOINABLE in (a), then it will
- // conclude that the thread is EXITING and will wait until the thread
- // exits. It will clean up the thread resources once the thread
- // exits.
- cpp::Atomic<uint32_t> detach_state;
- void *stack; // Pointer to the thread stack
- size_t stacksize; // Size of the stack
- size_t guardsize; // Guard size on stack
- uintptr_t tls; // Address to the thread TLS memory
- uintptr_t tls_size; // The size of area pointed to by |tls|.
- unsigned char owned_stack; // Indicates if the thread owns this stack memory
- 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) {}
-};
-
using TSSDtor = void(void *);
// Create a new TSS key and associate the |dtor| as the corresponding
@@ -247,8 +153,6 @@ struct Thread {
ErrorOr<SchedParameters> getschedparam() const;
};
-LIBC_INLINE_VAR LIBC_THREAD_LOCAL Thread self;
-
// Platforms should implement this function.
[[noreturn]] void thread_exit(ThreadReturnValue retval, ThreadStyle style);
@@ -266,8 +170,12 @@ ThreadAtExitCallbackMgr *get_thread_atexit_callback_mgr();
// implementing the thread_exit function.
void call_atexit_callbacks(ThreadAttributes *attrib);
+LIBC_INLINE_VAR LIBC_THREAD_LOCAL Thread self;
+
} // namespace internal
+LIBC_INLINE Thread current_thread() { return internal::self; }
+
} // namespace LIBC_NAMESPACE_DECL
#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_H
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
new file mode 100644
index 00000000000..6225837ed77
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/threads/thread_attributes.h
@@ -0,0 +1,121 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 thread attributes.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_ATTRIBUTES_H
+#define LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_ATTRIBUTES_H
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/atomic.h"
+#include "src/__support/macros/attributes.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/properties/architectures.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+using ThreadRunnerPosix = void *(void *);
+using ThreadRunnerStdc = int(void *);
+
+union ThreadRunner {
+ ThreadRunnerPosix *posix_runner;
+ ThreadRunnerStdc *stdc_runner;
+};
+
+union ThreadReturnValue {
+ void *posix_retval;
+ int stdc_retval;
+ LIBC_INLINE constexpr ThreadReturnValue() : posix_retval(nullptr) {}
+ LIBC_INLINE constexpr ThreadReturnValue(int r) : stdc_retval(r) {}
+ LIBC_INLINE constexpr ThreadReturnValue(void *r) : posix_retval(r) {}
+};
+
+#if (defined(LIBC_TARGET_ARCH_IS_AARCH64) || \
+ defined(LIBC_TARGET_ARCH_IS_X86_64) || \
+ defined(LIBC_TARGET_ARCH_IS_ANY_RISCV))
+constexpr unsigned int STACK_ALIGNMENT = 16;
+#elif defined(LIBC_TARGET_ARCH_IS_ARM)
+// See Section 6.2.1.2 Stack constraints at a public interface of AAPCS32.
+constexpr unsigned int STACK_ALIGNMENT = 8;
+#endif
+// TODO: Provide stack alignment requirements for other architectures.
+
+enum class DetachState : uint32_t {
+ JOINABLE = 0x11,
+ EXITING = 0x22,
+ DETACHED = 0x33
+};
+
+enum class ThreadStyle : uint8_t { POSIX = 0x1, STDC = 0x2 };
+
+// Detach type is useful in testing the detach operation.
+enum class DetachType : int {
+ // Indicates that the detach operation just set the detach state to DETACHED
+ // and returned.
+ SIMPLE = 1,
+
+ // Indicates that the detach operation performed thread cleanup.
+ 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
+// part of a thread's state. For example, the stack guard size.
+//
+// Thread attributes are typically stored on the stack. So, we align as required
+// for the target architecture.
+struct alignas(STACK_ALIGNMENT) ThreadAttributes {
+ // We want the "detach_state" attribute to be an atomic value as it could be
+ // updated by one thread while the self thread is reading it. It is a tristate
+ // variable with the following state transitions:
+ // 1. If a thread is created in a detached state, then user code should never
+ // call a detach or join function. Calling either of them can lead to
+ // undefined behavior.
+ // The value of |detach_state| is expected to be DetachState::DETACHED for
+ // its lifetime.
+ // 2. If a thread is created in a joinable state, |detach_state| will start
+ // with the value DetachState::JOINABLE. Another thread can detach this
+ // thread before it exits. The state transitions will as follows:
+ // (a) If the detach method sees the state as JOINABLE, then it will
+ // compare exchange to a state of DETACHED. The thread will clean
+ // itself up after it finishes.
+ // (b) If the detach method does not see JOINABLE in (a), then it will
+ // conclude that the thread is EXITING and will wait until the thread
+ // exits. It will clean up the thread resources once the thread
+ // exits.
+ cpp::Atomic<uint32_t> detach_state;
+ void *stack; // Pointer to the thread stack
+ size_t stacksize; // Size of the stack
+ size_t guardsize; // Guard size on stack
+ uintptr_t tls; // Address to the thread TLS memory
+ uintptr_t tls_size; // The size of area pointed to by |tls|.
+ unsigned char owned_stack; // Indicates if the thread owns this stack memory
+ 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) {}
+};
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_THREADS_THREAD_ATTRIBUTES_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/time/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/time/CMakeLists.txt
index f007f95bbee..00d7dba572f 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/time/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/time/CMakeLists.txt
@@ -8,7 +8,7 @@ add_header_library(
)
if(EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/${LIBC_TARGET_OS}
- AND TARGET libc.src.__support.OSUtil.osutil)
+ AND TARGET libc.src.__support.OSUtil.osutil)
add_subdirectory(${LIBC_TARGET_OS})
else()
message(STATUS "Skip libc.src.__support.time.* targets.")
@@ -31,7 +31,7 @@ add_header_library(
libc.src.__support.time.units
)
-if(TARGET libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime)
+if(TARGET libc.src.__support.time.${LIBC_TARGET_OS}.clock_settime)
add_object_library(
clock_settime
ALIAS
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
new file mode 100644
index 00000000000..a302fba15f1
--- /dev/null
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/tlsf_table.h
@@ -0,0 +1,219 @@
+//===----------------------------------------------------------------------===//
+//
+// 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 a two-level segregated fit table and mapping helper.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_LIBC_SRC___SUPPORT_TLSF_TABLE_H
+#define LLVM_LIBC_SRC___SUPPORT_TLSF_TABLE_H
+
+#include "hdr/stdint_proxy.h"
+#include "hdr/types/size_t.h"
+#include "src/__support/CPP/array.h"
+#include "src/__support/CPP/bit.h"
+#include "src/__support/CPP/limits.h"
+#include "src/__support/block.h"
+#include "src/__support/freelist.h"
+#include "src/__support/macros/config.h"
+#include "src/__support/macros/optimization.h"
+#include "src/__support/math_extras.h"
+
+namespace LIBC_NAMESPACE_DECL {
+
+/// Default configuration for TLSFFreeStore and TLSFTable.
+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 bool USE_TRIE_FOR_OVERFLOW_BIN = true;
+ static constexpr size_t LINEAR_SCAN_LIMIT = 16;
+};
+
+// A two-level segregated fit occupancy table and mapping helper.
+//
+// Rather than mapping raw block sizes directly, the table maps the size delta
+// over MIN_INNER_SIZE (delta = size - (MIN_INNER_SIZE + 1)). Small allocations
+// map directly to exact-size linear bins covering Bins 0 through EXP_BASE (33
+// linear bins total). Larger allocations are managed in a 2-D table starting at
+// Bin 33. One can think of each row containing NUM_STEPS lists. Along the row,
+// the delta grows exponentially by powers of 2; along the column, the delta
+// increases linearly by STEP_SIZE increments.
+//
+// Mathematical layout:
+// delta = size <= MIN_INNER_SIZE ? 0 : size - (MIN_INNER_SIZE + 1)
+// STEP_SIZE = 1 << STEP_SIZE_BITS
+// NUM_STEPS = 1 << NUM_STEP_BITS
+// EXP_BASE = STEP_SIZE * NUM_STEPS
+// LINEAR_BINS = EXP_BASE + 1
+// LARGE_DELTA_THRESHOLD = UNIT_SIZE * EXP_BASE
+//
+// Visual representation with realistic configuration parameters:
+// MIN_INNER_SIZE = 24 B, UNIT_SIZE = 16, STEP_SIZE = 8, NUM_STEPS = 4
+// EXP_BASE = 32, LINEAR_BINS = 33, THRESHOLD = 512 B (Size 536 B)
+//
+// 1. Small Sizes (Linear Bins on Delta over MIN_INNER_SIZE = 24 B):
+// Covers size range [0, ... 536 B] across Bins 0 to 32 (EXP_BASE = 32).
+// Assuming UNIT_SIZE matches block minimum alignment (step = unit = 16 B),
+// these linear bins hold blocks of exact inner sizes (e.g., Bin 0 = 24 B,
+// Bin 1 = 40 B, Bin 2 = 56 B). The byte ranges shown below reflect user
+// payload sizes that map directly into each exact-fit bin:
+// +-----------+-------------+-------------+-----+--------------+--------------+
+// | Bin 0 | Bin 1 | Bin 2 | ... | Bin 31 | Bin 32 |
+// | [0..24 B] | [25..40 B] | [41..56 B] | ... | [505..520 B] | [521..536 B] |
+// | (Delta 0) | (D: 0..15) | (D: 16..31) | ... | (D: 480..495)| (D: 496..511)|
+// +-----------+-------------+-------------+-----+--------------+--------------+
+//
+// 2. Large Sizes (2-D Table on Delta over MIN_INNER_SIZE for Sizes > 536 B):
+// Rows = FL (Exponential growth), Columns = SL (Linear steps)
+// Each cell shows Bin index, exact Block Size range, and Delta (D) range:
+//
+// LINEAR INCREASE ALONG COLUMN (SL) --->
+// +---------------+---------------+---------------+---------------+
+// | Col = 0 | Col = 1 | Col = 2 | Col = 3 |
+// | (Base) | (+25% Step) | (+50% Step) | (+75% Step) |
+// +---------+---------------+---------------+---------------+---------------+
+// E | Row = 0 | Bin 33 | Bin 34 | Bin 35 | Bin 36 |
+// X | Base D: | [537..664 B] | [665..792 B] | [793..920 B] | [921..1048 B] |
+// P | 512 | D:[512..639] | D:[640..767] | D:[768..895] | D:[896..1023] |
+// +---------+---------------+---------------+---------------+---------------+
+// O | Row = 1 | Bin 37 | Bin 38 | Bin 39 | Bin 40 |
+// N | Base D: |[1049..1304 B] |[1305..1560 B] |[1561..1816 B] |[1817..2072 B] |
+// E | 1024 |D:[1024..1279] |D:[1280..1535] |D:[1536..1791] |D:[1792..2047] |
+// +---------+---------------+---------------+---------------+---------------+
+// N | Row = 2 | Bin 41 | Bin 42 | Bin 43 | Bin 44 |
+// T | Base D: |[2073..2584 B] |[2585..3096 B] |[3097..3608 B] |[3609..4120 B] |
+// I | 2048 |D:[2048..2559] |D:[2560..3071] |D:[3072..3583] |D:[3584..4095] |
+// +---------+---------------+---------------+---------------+---------------+
+// A | Row = 3 | Bin 45 | Bin 46 | Bin 47 | Bin 48 |
+// L | Base D: |[4121..5144 B] |[5145..6168 B] |[6169..7192 B] |[7193..8216 B] |
+// | 4096 |D:[4096..5119] |D:[5120..6143] |D:[6144..7167] |D:[7168..8191] |
+// +---------+---------------+---------------+---------------+---------------+
+//
+// Note: For the real implementation, we don't actually store the lists in a
+// 2-D structure. Instead, we flatten the entire 2-D layout into a single
+// flat 1-D array of size TOTAL_BINS, and map sizes directly to a continuous
+// 1-D index using size_to_bin. The occupancy state is tracked compactly in
+// the lookup_table bitmask array.
+template <typename CONFIG> class TLSFTable {
+protected:
+ static_assert(cpp::has_single_bit(CONFIG::UNIT_SIZE),
+ "unit size must be a power of two");
+ static_assert(CONFIG::NUM_TABLE_ENTRIES > 0,
+ "the lookup table must have at least one entry");
+
+ static constexpr size_t STEP_SIZE = size_t(1) << CONFIG::STEP_SIZE_BITS;
+ static constexpr size_t NUM_STEPS = size_t(1) << CONFIG::NUM_STEP_BITS;
+ static constexpr size_t EXP_BASE = STEP_SIZE * NUM_STEPS;
+ static constexpr int UNIT_SIZE_LOG2 = cpp::bit_width(CONFIG::UNIT_SIZE) - 1;
+ static constexpr int EXP_BASE_LOG2 =
+ CONFIG::STEP_SIZE_BITS + CONFIG::NUM_STEP_BITS;
+ static constexpr size_t BITS_PER_ENTRY =
+ cpp::numeric_limits<uintptr_t>::digits;
+
+public:
+ static constexpr size_t TOTAL_BINS =
+ CONFIG::NUM_TABLE_ENTRIES * BITS_PER_ENTRY;
+ static constexpr size_t TOTAL_BITS = TOTAL_BINS;
+
+ static constexpr size_t MIN_OUTER_SIZE = align_up(
+ BlockRef::HEADER_SIZE + sizeof(FreeList::Node), BlockRef::MIN_ALIGN);
+ // Minimal available size for allocation.
+ static constexpr size_t MIN_INNER_SIZE =
+ MIN_OUTER_SIZE - BlockRef::HEADER_SIZE + BlockRef::PREV_FIELD_SIZE;
+ // Number of bins grows linearly.
+ static constexpr size_t LINEAR_BINS = EXP_BASE + 1;
+
+ LIBC_INLINE constexpr TLSFTable() = default;
+
+ LIBC_INLINE static constexpr size_t size_to_bin(size_t size);
+ LIBC_INLINE static constexpr size_t bin_to_min_size(size_t bin);
+
+ LIBC_INLINE void mark_occupied(size_t bin) {
+ size_t entry_index = bin / BITS_PER_ENTRY;
+ size_t bit_offset = bin % BITS_PER_ENTRY;
+ lookup_table[entry_index] |= uintptr_t(1) << bit_offset;
+ }
+
+ LIBC_INLINE void mark_vacant(size_t bin) {
+ size_t entry_index = bin / BITS_PER_ENTRY;
+ size_t bit_offset = bin % BITS_PER_ENTRY;
+ lookup_table[entry_index] &= ~(uintptr_t(1) << bit_offset);
+ }
+
+ LIBC_INLINE bool is_occupied(size_t bin) const {
+ size_t entry_index = bin / BITS_PER_ENTRY;
+ size_t bit_offset = bin % BITS_PER_ENTRY;
+ return (lookup_table[entry_index] & (uintptr_t(1) << bit_offset)) != 0;
+ }
+
+ LIBC_INLINE size_t find_first_occupied_after(size_t bin) const {
+ if (bin >= TOTAL_BINS - 1)
+ return TOTAL_BINS;
+
+ size_t target_index = bin + 1;
+ size_t start_entry = target_index / BITS_PER_ENTRY;
+ size_t bit_offset = target_index % BITS_PER_ENTRY;
+
+ uintptr_t value = lookup_table[start_entry] & (~uintptr_t(0) << bit_offset);
+ if (value != 0)
+ return start_entry * BITS_PER_ENTRY +
+ static_cast<size_t>(cpp::countr_zero(value));
+
+ for (size_t i = start_entry + 1; i < CONFIG::NUM_TABLE_ENTRIES; ++i) {
+ value = lookup_table[i];
+ if (value != 0)
+ return i * BITS_PER_ENTRY +
+ static_cast<size_t>(cpp::countr_zero(value));
+ }
+ return TOTAL_BINS;
+ }
+
+private:
+ cpp::array<uintptr_t, CONFIG::NUM_TABLE_ENTRIES> lookup_table{};
+};
+
+template <typename CONFIG>
+LIBC_INLINE constexpr size_t TLSFTable<CONFIG>::size_to_bin(size_t size) {
+ // Compute bin as delta on top of min_inner_size
+ if (sub_overflow(size, MIN_INNER_SIZE + 1, size))
+ return 0;
+
+ if (size < (EXP_BASE << UNIT_SIZE_LOG2))
+ return (size >> UNIT_SIZE_LOG2) + 1;
+
+ size_t size_ilog2 = static_cast<size_t>(cpp::bit_width(size) - 1);
+ size_t exp_offset = (size_ilog2 - UNIT_SIZE_LOG2 - EXP_BASE_LOG2 - 1)
+ << CONFIG::NUM_STEP_BITS;
+ size_t step_index = size >> (size_ilog2 - CONFIG::NUM_STEP_BITS);
+ size_t index = LINEAR_BINS + exp_offset + step_index;
+
+ return index < TOTAL_BINS ? index : TOTAL_BINS - 1;
+}
+
+template <typename CONFIG>
+LIBC_INLINE constexpr size_t TLSFTable<CONFIG>::bin_to_min_size(size_t bin) {
+ if (bin == 0)
+ return 0;
+ if (bin < LINEAR_BINS)
+ return MIN_INNER_SIZE + 1 + ((bin - 1) << UNIT_SIZE_LOG2);
+
+ size_t local_index = bin - LINEAR_BINS;
+ size_t exp_index = local_index >> CONFIG::NUM_STEP_BITS;
+ size_t linear_index = local_index & (NUM_STEPS - 1);
+
+ size_t row_base = (EXP_BASE << exp_index) << UNIT_SIZE_LOG2;
+ size_t step_size = (STEP_SIZE << exp_index) << UNIT_SIZE_LOG2;
+ return MIN_INNER_SIZE + 1 + row_base + linear_index * step_size;
+}
+
+} // namespace LIBC_NAMESPACE_DECL
+
+#endif // LLVM_LIBC_SRC___SUPPORT_TLSF_TABLE_H
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/wchar/CMakeLists.txt b/deps/v8/third_party/llvm-libc/src/src/__support/wchar/CMakeLists.txt
index ce42fc3bef2..c4e7f0dbaa1 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/wchar/CMakeLists.txt
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/wchar/CMakeLists.txt
@@ -19,7 +19,7 @@ add_header_library(
libc.src.__support.CPP.type_traits
libc.src.__support.error_or
.mbstate
- .character_converter
+ .character_converter
)
add_header_library(
@@ -35,6 +35,7 @@ add_header_library(
libc.src.__support.CPP.type_traits
libc.src.__support.error_or
libc.src.__support.macros.config
+ libc.src.__support.macros.properties.types
libc.src.__support.math_extras
.mbstate
)
diff --git a/deps/v8/third_party/llvm-libc/src/src/__support/wchar/character_converter.h b/deps/v8/third_party/llvm-libc/src/src/__support/wchar/character_converter.h
index 4da6970f08a..f754a602d2c 100644
--- a/deps/v8/third_party/llvm-libc/src/src/__support/wchar/character_converter.h
+++ b/deps/v8/third_party/llvm-libc/src/src/__support/wchar/character_converter.h
@@ -18,6 +18,7 @@
#include "src/__support/CPP/type_traits.h"
#include "src/__support/common.h"
#include "src/__support/error_or.h"
+#include "src/__support/macros/properties/types.h"
#include "src/__support/math_extras.h"
#include "src/__support/wchar/mbstate.h"
@@ -63,6 +64,12 @@ public:
ErrorOr<char8_t> pop_utf8();
ErrorOr<char32_t> pop_utf32();
+
+#if defined(LIBC_TYPES_WCHAR_T_IS_UTF32)
+ int push(wchar_t wchar);
+ ErrorOr<wchar_t> pop_wchar();
+#endif // LIBC_TYPES_WCHAR_T_IS_UTF32
+
template <typename CharType> ErrorOr<CharType> pop();
};
@@ -201,6 +208,29 @@ template <> LIBC_INLINE size_t CharacterConverter::sizeAs<char32_t>() {
return 1;
}
+#if defined(LIBC_TYPES_WCHAR_T_IS_UTF32)
+
+LIBC_INLINE int CharacterConverter::push(wchar_t wchar) {
+ return push(static_cast<char32_t>(wchar));
+}
+
+LIBC_INLINE ErrorOr<wchar_t> CharacterConverter::pop_wchar() {
+ ErrorOr<char32_t> Result = pop_utf32();
+ if (!Result)
+ return Error(Result.error());
+ return static_cast<wchar_t>(*Result);
+}
+
+template <> LIBC_INLINE ErrorOr<wchar_t> CharacterConverter::pop() {
+ return pop_wchar();
+}
+
+template <> LIBC_INLINE size_t CharacterConverter::sizeAs<wchar_t>() {
+ return sizeAs<char32_t>();
+}
+
+#endif // LIBC_TYPES_WCHAR_T_IS_UTF32
+
} // namespace internal
} // namespace LIBC_NAMESPACE_DECL
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 64708fe6a40..bb67e72d001 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
@@ -66,4 +66,3 @@ add_object_library(
.lower_to_upper
.upper_to_lower
)
-
diff --git a/deps/v8/third_party/zlib/BUILD.gn b/deps/v8/third_party/zlib/BUILD.gn
index eff72b22a29..c37b4252961 100644
--- a/deps/v8/third_party/zlib/BUILD.gn
+++ b/deps/v8/third_party/zlib/BUILD.gn
@@ -98,10 +98,6 @@ source_set("zlib_adler32_simd") {
"adler32_simd.c",
"adler32_simd.h",
]
-
- if (!is_win || is_clang) {
- cflags = [ "-mssse3" ]
- }
}
if (use_arm_neon_optimizations) {
@@ -168,6 +164,15 @@ if (use_arm_neon_optimizations) {
}
}
+# Enables 64-bit word-at-a-time compare256() in deflate's longest_match() on
+# 64-bit little-endian architectures (x64 and arm64). Follows the same pattern
+# as INFLATE_CHUNK_READ_64LE and DEFLATE_CHUNK_WRITE_64LE below.
+config("zlib_compare256_config") {
+ if (current_cpu == "x64" || current_cpu == "arm64") {
+ defines = [ "DEFLATE_COMPARE256_64LE" ]
+ }
+}
+
config("zlib_data_chunk_simd_config") {
if (use_x86_x64_optimizations) {
defines = [ "INFLATE_CHUNK_SIMD_SSE2" ]
@@ -234,13 +239,6 @@ source_set("zlib_crc32_simd") {
"crc32_simd.h",
"crc_folding.c",
]
-
- if (!is_win || is_clang) {
- cflags = [
- "-msse4.2",
- "-mpclmul",
- ]
- }
}
configs += [ ":zlib_internal_config" ]
@@ -296,6 +294,7 @@ component("zlib") {
sources = [
"adler32.c",
"chromeconf.h",
+ "compare256.h",
"compress.c",
"contrib/optimizations/insert_string.h",
"cpu_features.c",
@@ -370,6 +369,7 @@ component("zlib") {
public_configs = [ ":zlib_config" ]
configs += [
+ ":zlib_compare256_config",
":zlib_internal_config",
# Must be after no_chromium_code for warning flags to be ordered correctly.
diff --git a/deps/v8/third_party/zlib/CMakeLists.txt b/deps/v8/third_party/zlib/CMakeLists.txt
index b569804ace0..87d6613be3f 100644
--- a/deps/v8/third_party/zlib/CMakeLists.txt
+++ b/deps/v8/third_party/zlib/CMakeLists.txt
@@ -94,6 +94,7 @@ if (ENABLE_SIMD_OPTIMIZATIONS)
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -pthread")
if (CMAKE_SYSTEM_PROCESSOR STREQUAL "x86_64")
+ add_definitions(-DDEFLATE_COMPARE256_64LE)
add_definitions(-DINFLATE_CHUNK_SIMD_SSE2)
add_definitions(-DADLER32_SIMD_SSSE3)
add_definitions(-DINFLATE_CHUNK_READ_64LE)
@@ -101,9 +102,6 @@ if (ENABLE_SIMD_OPTIMIZATIONS)
add_definitions(-DCRC32_SIMD_SSE42_PCLMUL)
if (ENABLE_SIMD_AVX512)
add_definitions(-DCRC32_SIMD_AVX512_PCLMUL)
- add_compile_options(-mvpclmulqdq -msse2 -mavx512f -mpclmul)
- else()
- add_compile_options(-msse4.2 -mpclmul)
endif()
add_definitions(-DDEFLATE_SLIDE_HASH_SSE2)
# Required by CPU features detection code.
@@ -118,6 +116,7 @@ if (ENABLE_SIMD_OPTIMIZATIONS)
add_definitions(-DDEFLATE_CHUNK_WRITE_64LE)
add_definitions(-DCRC32_ARMV8_CRC32)
add_definitions(-DDEFLATE_SLIDE_HASH_NEON)
+ add_definitions(-DDEFLATE_COMPARE256_64LE)
# Required by CPU features detection code.
if (APPLE)
add_definitions(-DARMV8_OS_MACOS)
diff --git a/deps/v8/third_party/zlib/adler32_simd.c b/deps/v8/third_party/zlib/adler32_simd.c
index 08c21d3e953..ce4ce7c5755 100644
--- a/deps/v8/third_party/zlib/adler32_simd.c
+++ b/deps/v8/third_party/zlib/adler32_simd.c
@@ -53,7 +53,7 @@
#include <tmmintrin.h>
-#if defined(__GNUC__)
+#if defined(__GNUC__) || defined(__clang__)
__attribute__((__target__("ssse3")))
#endif
uint32_t ZLIB_INTERNAL adler32_simd_( /* SSSE3 */
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/third_party/zlib/compare256.h b/deps/v8/third_party/zlib/compare256.h
new file mode 100644
index 00000000000..80061c3febb
--- /dev/null
+++ b/deps/v8/third_party/zlib/compare256.h
@@ -0,0 +1,56 @@
+/* compare256.h
+ *
+ * This does 256-byte match comparison for deflate's longest_match.
+ *
+ * Copyright 2026 The Chromium Authors
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the Chromium source repository LICENSE file.
+ */
+#ifndef COMPARE256_H
+#define COMPARE256_H
+
+#include <stdint.h>
+#include <string.h>
+#if defined(_MSC_VER) && !defined(__clang__)
+#include <intrin.h>
+#endif
+
+/* Safe unaligned 16-bit load. Compilers optimize this into a single load
+ * instruction. */
+static inline uint16_t read16(const void* p) {
+ uint16_t v;
+ memcpy(&v, p, sizeof(v));
+ return v;
+}
+
+/* Finds the byte offset (0..7) of the first difference in non-zero XOR mask
+ * `x`:
+ */
+static inline int compare256_diff(uint64_t x) {
+#if defined(_MSC_VER) && !defined(__clang__)
+ unsigned long i;
+ _BitScanForward64(&i, x);
+ return (int)i / 8;
+#else
+ return __builtin_ctzll(x) / 8;
+#endif
+}
+
+/* Returns the number of matching leading bytes (0 to 256) between src0 and
+ * src1. Compares 8 bytes per iteration with early exit. */
+static inline int compare256(const unsigned char* src0,
+ const unsigned char* src1) {
+ int len = 0;
+ do {
+ uint64_t a, b, x;
+ memcpy(&a, src0 + len, sizeof(a));
+ memcpy(&b, src1 + len, sizeof(b));
+ x = a ^ b;
+ if (x)
+ return len + compare256_diff(x);
+ len += (int)sizeof(a);
+ } while (len < 256);
+ return 256;
+}
+
+#endif /* COMPARE256_H */
diff --git a/deps/v8/third_party/zlib/cpu_features.c b/deps/v8/third_party/zlib/cpu_features.c
index 34ae7b913af..6613a65e335 100644
--- a/deps/v8/third_party/zlib/cpu_features.c
+++ b/deps/v8/third_party/zlib/cpu_features.c
@@ -160,6 +160,11 @@ static void _cpu_check_features(void)
#include <immintrin.h>
#include <xsaveintrin.h>
#endif
+/* _xgetbv() below needs the xsave ISA. Annotate it here so the build does not
+ * need -mxsave. */
+#if defined(CRC32_SIMD_AVX512_PCLMUL) && (defined(__GNUC__) || defined(__clang__))
+__attribute__((__target__("xsave")))
+#endif
static void _cpu_check_features(void)
{
int x86_cpu_has_sse2;
diff --git a/deps/v8/third_party/zlib/crc32_simd.c b/deps/v8/third_party/zlib/crc32_simd.c
index 1c60ae9bd3c..f9d52a6311e 100644
--- a/deps/v8/third_party/zlib/crc32_simd.c
+++ b/deps/v8/third_party/zlib/crc32_simd.c
@@ -21,6 +21,9 @@
#include <wmmintrin.h>
#include <immintrin.h>
+#if defined(__GNUC__) || defined(__clang__)
+__attribute__((__target__("avx512f,pclmul,vpclmulqdq")))
+#endif
uint32_t ZLIB_INTERNAL crc32_avx512_simd_( /* AVX512+PCLMUL */
const unsigned char *buf,
z_size_t len,
@@ -212,6 +215,9 @@ uint32_t ZLIB_INTERNAL crc32_avx512_simd_( /* AVX512+PCLMUL */
#include <smmintrin.h>
#include <wmmintrin.h>
+#if defined(__GNUC__) || defined(__clang__)
+__attribute__((__target__("sse4.2,pclmul")))
+#endif
uint32_t ZLIB_INTERNAL crc32_sse42_simd_( /* SSE4.2+PCLMUL */
const unsigned char *buf,
z_size_t len,
diff --git a/deps/v8/third_party/zlib/crc_folding.c b/deps/v8/third_party/zlib/crc_folding.c
index 1d54ee8d48c..3e31ae4a7e4 100644
--- a/deps/v8/third_party/zlib/crc_folding.c
+++ b/deps/v8/third_party/zlib/crc_folding.c
@@ -25,6 +25,12 @@
#include <immintrin.h>
#include <wmmintrin.h>
+#if defined(__GNUC__) || defined(__clang__)
+#define TARGET_SSE42_PCLMUL __attribute__((__target__("sse4.2,pclmul")))
+#else
+#define TARGET_SSE42_PCLMUL
+#endif
+
#define CRC_LOAD(s) \
do { \
__m128i xmm_crc0 = _mm_loadu_si128((__m128i *)s->crc0 + 0);\
@@ -41,6 +47,7 @@
_mm_storeu_si128((__m128i *)s->crc0 + 4, xmm_crc_part);\
} while (0);
+TARGET_SSE42_PCLMUL
ZLIB_INTERNAL void crc_fold_init(deflate_state *const s)
{
CRC_LOAD(s)
@@ -55,6 +62,7 @@ ZLIB_INTERNAL void crc_fold_init(deflate_state *const s)
s->strm->adler = 0;
}
+TARGET_SSE42_PCLMUL
local void fold_1(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
@@ -81,6 +89,7 @@ local void fold_1(deflate_state *const s,
*xmm_crc3 = _mm_castps_si128(ps_res);
}
+TARGET_SSE42_PCLMUL
local void fold_2(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
@@ -115,6 +124,7 @@ local void fold_2(deflate_state *const s,
*xmm_crc3 = _mm_castps_si128(ps_res31);
}
+TARGET_SSE42_PCLMUL
local void fold_3(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
@@ -155,6 +165,7 @@ local void fold_3(deflate_state *const s,
*xmm_crc3 = _mm_castps_si128(ps_res32);
}
+TARGET_SSE42_PCLMUL
local void fold_4(deflate_state *const s,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3)
@@ -221,6 +232,7 @@ local const unsigned zalign(32) pshufb_shf_table[60] = {
0x0201008f,0x06050403,0x0a090807,0x0e0d0c0b /* shl 1 (16 -15)/shr15*/
};
+TARGET_SSE42_PCLMUL
local void partial_fold(deflate_state *const s, const size_t len,
__m128i *xmm_crc0, __m128i *xmm_crc1,
__m128i *xmm_crc2, __m128i *xmm_crc3,
@@ -271,6 +283,7 @@ local void partial_fold(deflate_state *const s, const size_t len,
*xmm_crc3 = _mm_castps_si128(ps_res);
}
+TARGET_SSE42_PCLMUL
ZLIB_INTERNAL void crc_fold_copy(deflate_state *const s,
unsigned char *dst, const unsigned char *src, long len)
{
@@ -427,6 +440,7 @@ local const unsigned zalign(16) crc_mask2[4] = {
0x00000000, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF
};
+TARGET_SSE42_PCLMUL
unsigned ZLIB_INTERNAL crc_fold_512to32(deflate_state *const s)
{
const __m128i xmm_mask = _mm_load_si128((__m128i *)crc_mask);
diff --git a/deps/v8/third_party/zlib/deflate.c b/deps/v8/third_party/zlib/deflate.c
index d95787f286d..b98a985e5ca 100644
--- a/deps/v8/third_party/zlib/deflate.c
+++ b/deps/v8/third_party/zlib/deflate.c
@@ -57,6 +57,8 @@
#include "slide_hash_simd.h"
#endif
+#include "compare256.h"
+
#if defined(QAT_COMPRESSION_ENABLED)
#include "contrib/qat/deflate_qat.h"
#endif
@@ -1492,7 +1494,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
Posf *prev = s->prev;
uInt wmask = s->w_mask;
-#ifdef UNALIGNED_OK
+#if defined(DEFLATE_COMPARE256_64LE)
+ /* Quickly reject non-matches with the 2-byte prefilter
+ * (scan_start/scan_end); candidates that pass are extended 8 bytes at a
+ * time with compare256(). */
+ uInt scan_start = read16(scan);
+ uInt scan_end = read16(scan + best_len - 1);
+#elif defined(UNALIGNED_OK)
/* Compare two bytes at a time. Note: this is not always beneficial.
* Try with and without -DUNALIGNED_OK to check.
*/
@@ -1534,7 +1542,13 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
* However the length of the match is limited to the lookahead, so
* the output of deflate is not affected by the uninitialized values.
*/
-#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
+#if defined(DEFLATE_COMPARE256_64LE)
+ if (read16(match + best_len - 1) != scan_end ||
+ read16(match) != scan_start) continue;
+ /* scan_start matched, so bytes 0..1 are equal; compare the remaining
+ * up to 256 bytes so the length can still reach MAX_MATCH (258). */
+ len = 2 + compare256(scan + 2, match + 2);
+#elif (defined(UNALIGNED_OK) && MAX_MATCH == 258)
/* This code assumes sizeof(unsigned short) == 2. Do not use
* UNALIGNED_OK if your compiler uses a different size.
*/
@@ -1624,7 +1638,9 @@ local uInt longest_match(deflate_state *s, IPos cur_match) {
s->match_start = cur_match;
best_len = len;
if (len >= nice_match) break;
-#ifdef UNALIGNED_OK
+#if defined(DEFLATE_COMPARE256_64LE)
+ scan_end = read16(scan + best_len - 1);
+#elif defined(UNALIGNED_OK)
scan_end = *(ushf*)(scan + best_len - 1);
#else
scan_end1 = scan[best_len - 1];
diff --git a/deps/v8/third_party/zlib/google/OWNERS b/deps/v8/third_party/zlib/google/OWNERS
index 1bd83ac482e..901c226205f 100644
--- a/deps/v8/third_party/zlib/google/OWNERS
+++ b/deps/v8/third_party/zlib/google/OWNERS
@@ -1,4 +1,4 @@
-satorux@chromium.org
+satorux@google.com
# compression_utils*
asvitkine@chromium.org
diff --git a/deps/v8/third_party/zlib/google/zip_reader_unittest.cc b/deps/v8/third_party/zlib/google/zip_reader_unittest.cc
index 578539ffbf7..6e58f7f72ee 100644
--- a/deps/v8/third_party/zlib/google/zip_reader_unittest.cc
+++ b/deps/v8/third_party/zlib/google/zip_reader_unittest.cc
@@ -35,7 +35,6 @@
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
-#include "third_party/icu/source/i18n/unicode/timezone.h"
#include "third_party/zlib/google/zip_internal.h"
using ::testing::_;
@@ -367,10 +366,8 @@ TEST_F(ZipReaderTest, RegularFile) {
EXPECT_EQ(target_path, entry->path);
EXPECT_EQ(13527, entry->original_size);
- EXPECT_EQ("2009-05-29 06:22:20.000",
- base::UnlocalizedTimeFormatWithPattern(entry->last_modified,
- "y-MM-dd HH:mm:ss.SSS",
- icu::TimeZone::getGMT()));
+ EXPECT_EQ("2009-05-29T06:22:20.000Z",
+ base::TimeFormatAsIso8601(entry->last_modified));
EXPECT_FALSE(entry->is_unsafe);
EXPECT_FALSE(entry->is_directory);
}
@@ -467,10 +464,8 @@ TEST_F(ZipReaderTest, Directory) {
EXPECT_EQ(target_path, entry->path);
// The directory size should be zero.
EXPECT_EQ(0, entry->original_size);
- EXPECT_EQ("2009-05-31 15:49:52.000",
- base::UnlocalizedTimeFormatWithPattern(entry->last_modified,
- "y-MM-dd HH:mm:ss.SSS",
- icu::TimeZone::getGMT()));
+ EXPECT_EQ("2009-05-31T15:49:52.000Z",
+ base::TimeFormatAsIso8601(entry->last_modified));
EXPECT_FALSE(entry->is_unsafe);
EXPECT_TRUE(entry->is_directory);
}
diff --git a/deps/v8/tools/.vpython3 b/deps/v8/tools/.vpython3
deleted file mode 100644
index 8153fcf6503..00000000000
--- a/deps/v8/tools/.vpython3
+++ /dev/null
@@ -1,143 +0,0 @@
-# This is a vpython "spec" file.
-#
-# It describes patterns for python wheel dependencies of the python scripts in
-# the chromium repo, particularly for dependencies that have compiled components
-# (since pure-python dependencies can be easily vendored into third_party).
-#
-# When vpython is invoked, it finds this file and builds a python VirtualEnv,
-# containing all of the dependencies described in this file, fetching them from
-# CIPD (the "Chrome Infrastructure Package Deployer" service). Unlike `pip`,
-# this never requires the end-user machine to have a working python extension
-# compilation environment. All of these packages are built using:
-# https://chromium.googlesource.com/infra/infra/+/main/infra/tools/dockerbuild/
-#
-# All python scripts in the repo share this same spec, to avoid dependency
-# fragmentation.
-#
-# If you have depot_tools installed in your $PATH, you can invoke python scripts
-# in this repo by running them as you normally would run them, except
-# substituting `vpython` instead of `python` on the command line, e.g.:
-# vpython path/to/script.py some --arguments
-#
-# Read more about `vpython` and how to modify this file here:
-# https://chromium.googlesource.com/infra/infra/+/main/doc/users/vpython.md
-
-python_version: "3.11"
-
-# The default set of platforms vpython checks does not yet include mac-arm64.
-# Setting `verify_pep425_tag` to the list of platforms we explicitly must support
-# allows us to ensure that vpython specs stay mac-arm64-friendly
-verify_pep425_tag: [
- {python: "cp38", abi: "cp38", platform: "manylinux1_x86_64"},
- {python: "cp38", abi: "cp38", platform: "linux_arm64"},
-
- {python: "cp38", abi: "cp38", platform: "macosx_10_10_intel"},
- {python: "cp38", abi: "cp38", platform: "macosx_11_0_arm64"},
-
- {python: "cp38", abi: "cp38", platform: "win32"},
- {python: "cp38", abi: "cp38", platform: "win_amd64"}
-]
-
-# TODO(https://crbug.com/898348): Add in necessary wheels as Python3 versions
-# become available.
-wheel: <
- name: "infra/python/wheels/six-py2_py3"
- version: "version:1.15.0"
->
-
-wheel: <
- name: "infra/python/wheels/coverage/${vpython_platform}"
- version: "version:7.3.1"
->
-
-wheel: <
- name: "infra/python/wheels/pbr-py2_py3"
- version: "version:3.0.0"
->
-
-wheel: <
- name: "infra/python/wheels/funcsigs-py2_py3"
- version: "version:1.0.2"
->
-
-wheel: <
- name: "infra/python/wheels/hjson-py2_py3"
- version: "version:3.1.0"
->
-
-wheel: <
- name: "infra/python/wheels/httplib2-py3"
- version: "version:0.19.1"
->
-
-wheel: <
- name: "infra/python/wheels/mock-py2_py3"
- version: "version:2.0.0"
->
-
-wheel: <
- name: "infra/python/wheels/numpy/${vpython_platform}"
- version: "version:1.23.5.chromium.4"
->
-
-wheel: <
- name: "infra/python/wheels/protobuf-py3"
- version: "version:3.19.3"
->
-
-wheel: <
- name: "infra/python/wheels/pyparsing-py3"
- version: "version:2.4.7"
->
-# requests and its dependencies.
-wheel: <
- name: "infra/python/wheels/requests-py3"
- version: "version:2.31.0"
->
-wheel: <
- name: "infra/python/wheels/urllib3-py2_py3"
- version: "version:1.26.6"
->
-wheel: <
- name: "infra/python/wheels/idna-py2_py3"
- version: "version:2.8"
->
-wheel: <
- name: "infra/python/wheels/certifi-py2_py3"
- version: "version:2020.11.8"
->
-wheel: <
- name: "infra/python/wheels/charset_normalizer-py3"
- version: "version:2.0.4"
->
-
-wheel: <
- name: "infra/python/wheels/pyyaml/${vpython_platform}"
- version: "version:5.4.1.chromium.1"
->
-
-wheel: <
- name: "infra/python/wheels/clusterfuzz-py2_py3"
- version: "version:2.5.6-5c85ed3d46137b17da04c59bcd805ee5"
->
-
-wheel: <
- name: "infra/python/wheels/packaging-py2_py3"
- version: "version:16.8"
->
-
-wheel: <
- name: "infra/python/wheels/psutil/${vpython_platform}"
- version: "version:5.8.0.chromium.3"
->
-
-wheel: <
- name: "infra/python/wheels/pyfakefs-py3"
- version: "version:5.7.3"
->
-
-# We need the markdown library:
-wheel: <
- name: "infra/python/wheels/markdown-py3"
- version: "version:3.4.1"
->
diff --git a/deps/v8/tools/BUILD.gn b/deps/v8/tools/BUILD.gn
index 430f9a2c01e..59f1550c830 100644
--- a/deps/v8/tools/BUILD.gn
+++ b/deps/v8/tools/BUILD.gn
@@ -59,7 +59,8 @@ group("v8_testrunner") {
"predictable_wrapper.py",
"run-num-fuzzer.py",
"run-tests.py",
- ".vpython3",
+ "vpython.toml",
+ "vpython.toml.uv.lock",
"testrunner/",
]
}
diff --git a/deps/v8/tools/bash-completion.sh b/deps/v8/tools/bash-completion.sh
index ab6ea9be43b..fab5c436b38 100755
--- a/deps/v8/tools/bash-completion.sh
+++ b/deps/v8/tools/bash-completion.sh
@@ -45,11 +45,10 @@ _get_v8_flags() {
| grep -v "DEFINE_NEG_IMPLICATION" \
| grep -v "DEFINE_VALUE_IMPLICATION" \
| sed -e 's/_/-/g'; \
- grep "^ V(harmony_" "$flags_file" \
- | sed -e 's/^ V/DEFINE-BOOL/' \
- | sed -e 's/_/-/g'; \
- grep "^ V(" "$v8_source/src/wasm/wasm-feature-flags.h" \
- | sed -e 's/^ V(/DEFINE-BOOL(experimental-wasm-/' \
+ sed -e 's/IF_[A-Z0-9_]*(\([A-Z_]*\), */\1(/' "$v8_source/src/flags/feature-flags.h" \
+ | sed -ne 's/.*WASM_FEATURE(/DEFINE-BOOL(wasm-/p' \
+ -ne 's/.*JS_FEATURE(/DEFINE-BOOL(/p' \
+ -ne 's/.*INTERNAL_FEATURE(/DEFINE-BOOL(/p' \
| sed -e 's/_/-/g')
sed -ne 's/^DEFINE-[^(]*(\([^,]*\).*/--\1/p' <<< "$defines"
sed -ne 's/^DEFINE-BOOL(\([^,]*\).*/--no\1/p' <<< "$defines"
diff --git a/deps/v8/tools/bigsleep/create_snapshot.py b/deps/v8/tools/bigsleep/create_snapshot.py
index 059e23906f0..33e8324f4b6 100644
--- a/deps/v8/tools/bigsleep/create_snapshot.py
+++ b/deps/v8/tools/bigsleep/create_snapshot.py
@@ -74,33 +74,6 @@ def get_recent_v8_commits(v8_dir: pathlib.Path, days: int = 30) -> list[str]:
print(f"Found {len(commit_hashes)} commits")
return commit_hashes
-def get_shared_libraries(binary_path: pathlib.Path) -> list[pathlib.Path]:
- """Determines the shared library dependencies of a binary using ldd.
-
- Args:
- binary_path: Path to the binary file.
-
- Returns:
- A list of paths to the discovered shared libraries.
- """
- try:
- env = os.environ.copy()
- env["LD_TRACE_LOADED_OBJECTS"] = "1"
- result = subprocess.run(
- ["ldd", str(binary_path)], env=env, capture_output=True, text=True
- )
- libs = []
- for line in result.stdout.splitlines():
- match = re.search(r"=>\s+(\/\S+)", line)
- if match:
- libs.append(pathlib.Path(match.group(1)))
- return libs
- except Exception as e:
- logging.warning(
- f"Failed to get shared libraries for {binary_path}: {e}"
- )
- return []
-
def format_commit(v8_dir: pathlib.Path, commit_id: str) -> GitCommit:
"""Formats commit information including message and diff.
@@ -307,11 +280,9 @@ def main():
if wasm_builder.exists():
shutil.copy(wasm_builder, artifact_dir / "wasm-module-builder.js")
- # Shared libraries and patching
- lib_path = artifact_dir / "lib"
- lib_path.mkdir(exist_ok=True)
- for lib in get_shared_libraries(artifact_dir / "d8"):
- shutil.copy(lib, lib_path / lib.name)
+ # Copy built shared libraries (e.g. libsanitizer_shared_hooks.so, component DSOs)
+ for so_path in args.build_dir.glob("*.so"):
+ shutil.copy(so_path, artifact_dir / so_path.name)
# Seeds generation
seeds = []
diff --git a/deps/v8/tools/builtins-pgo/profile_only.py b/deps/v8/tools/builtins-pgo/profile_only.py
index c7b5796dc9a..c83cf3f4b87 100755
--- a/deps/v8/tools/builtins-pgo/profile_only.py
+++ b/deps/v8/tools/builtins-pgo/profile_only.py
@@ -7,6 +7,7 @@
from pathlib import Path
import argparse
import contextlib
+import json
import subprocess
import sys
import threading
@@ -66,6 +67,17 @@ def run_benchmark(benchmark_path, d8_path, output_dir):
cmd.append("--trace-gc")
monitor_proc = True
cmd.append(benchmark_file)
+
+ # https://crbug.com/487336000: Skip babylonjs-scene-es6 on ia32 due to memory
+ # issues.
+ build_config_path = d8_path_abs.parent / "v8_build_config.json"
+ if build_config_path.exists():
+ with open(build_config_path) as f:
+ build_config = json.load(f)
+ if build_config.get("arch") == "ia32":
+ cmd.append("--")
+ cmd.append("--exclude=babylonjs-scene-es6")
+
try:
run(cmd, cwd=benchmark_dir, monitor=monitor_proc)
except:
diff --git a/deps/v8/tools/cfi/ignores.txt b/deps/v8/tools/cfi/ignores.txt
index ea9c49dbaf9..2f9d7a29da7 100644
--- a/deps/v8/tools/cfi/ignores.txt
+++ b/deps/v8/tools/cfi/ignores.txt
@@ -3,6 +3,10 @@
# a statically linked libc++.
type:std::*
+# Temporarily disable CFI unrelated/derived cast in std::shared_ptr
+# until upstream restores _LIBCPP_NO_CFI on __get_elem
+src:*third_party/libc*/*shared_ptr.h
+
# Following entries Taken from chromium's tools/cfi/blacklist.txt
[cfi-icall]
diff --git a/deps/v8/tools/clusterfuzz/foozzie/v8_fuzz_flags.json b/deps/v8/tools/clusterfuzz/foozzie/v8_fuzz_flags.json
index ec11366b4d9..048f8a835bc 100644
--- a/deps/v8/tools/clusterfuzz/foozzie/v8_fuzz_flags.json
+++ b/deps/v8/tools/clusterfuzz/foozzie/v8_fuzz_flags.json
@@ -1,6 +1,6 @@
[
[0.05, "--always-osr"],
- [0.05, "--always-osr-from-maglev"],
+ [0.05, "--osr-from-maglev=4"],
[0.05, "--always-sparkplug"],
[0.05, "--stress-compaction-random"],
[0.05, "--stress-delay-tasks"],
@@ -42,7 +42,9 @@
[0.2, "--optimize-maglev-optimizes-to-turbofan"],
[0.5, "--optimize-on-next-call-optimizes-to-maglev"],
[0.5, "--maglev-untagged-phis"],
+ [0.1, "--disable-loop-stack-checks"],
[0.1, "--no-maglev-loop-peeling"],
+ [0.1, "--maglev-disable-builtin-reducers"],
[0.0001, "--simulate-errors"],
[0.1, "--minor-ms"],
[0.1, "--shared-string-table"],
diff --git a/deps/v8/tools/clusterfuzz/trials/clusterfuzz_trials_config.json b/deps/v8/tools/clusterfuzz/trials/clusterfuzz_trials_config.json
index 5eace654f0e..b6d05d29d6b 100644
--- a/deps/v8/tools/clusterfuzz/trials/clusterfuzz_trials_config.json
+++ b/deps/v8/tools/clusterfuzz/trials/clusterfuzz_trials_config.json
@@ -1,6 +1,6 @@
[
{"app_args": "--always-osr", "app_name": "d8", "probability": 0.03},
- {"app_args": "--always-osr-from-maglev", "app_name": "d8", "probability": 0.03},
+ {"app_args": "--osr-from-maglev=4", "app_name": "d8", "probability": 0.03},
{"app_args": "--always-sparkplug", "app_name": "d8", "probability": 0.03},
{"app_args": "--assert-types", "app_name": "d8", "probability": 0.25, "contradicts": ["--stress-concurrent-inlining", "--stress-concurrent-inlining-attach-code"]},
{"app_args": "--wasm-assert-types --no-liftoff", "app_name": "d8", "probability": 0.1, "contradicts": ["--liftoff-only"]},
@@ -68,7 +68,9 @@
{"app_args": "--turboshaft-verify-reductions", "app_name": "d8", "probability": 0.1},
{"app_args": "--maglev-assert-types", "app_name": "d8", "probability": 0.1},
{"app_args": "--maglev-untagged-phis", "app_name": "d8", "probability": 0.5},
+ {"app_args": "--disable-loop-stack-checks", "app_name": "d8", "probability": 0.1},
{"app_args": "--no-maglev-loop-peeling", "app_name": "d8", "probability": 0.1},
+ {"app_args": "--maglev-disable-builtin-reducers", "app_name": "d8", "probability": 0.1},
{"app_args": "--stress-wasm-code-gc", "app_name": "d8", "probability": 0.1},
{"app_args": "--wasm-staging", "app_name": "d8", "probability": 0.25},
{"app_args": "--stress-wasm-memory-moving", "app_name": "d8", "probability": 0.1},
diff --git a/deps/v8/tools/debug_helper/BUILD.gn b/deps/v8/tools/debug_helper/BUILD.gn
index 6612537e27f..1c0265a6368 100644
--- a/deps/v8/tools/debug_helper/BUILD.gn
+++ b/deps/v8/tools/debug_helper/BUILD.gn
@@ -75,7 +75,7 @@ _debug_helper_sources = [
"$target_gen_dir/../../torque-generated/class-debug-readers.h",
"$target_gen_dir/../../torque-generated/debug-macros.cc",
"$target_gen_dir/../../torque-generated/debug-macros.h",
- "$target_gen_dir/../../torque-generated/instance-types.h",
+ "$target_gen_dir/../../torque-generated/debug-reader-classes-list.h",
"$target_gen_dir/heap-constants-gen.cc",
"../../src/common/ptr-compr.cc",
"compiler-types.cc",
@@ -98,6 +98,10 @@ _debug_helper_deps = [
"../..:v8_shared_internal_headers",
"../..:v8_tracing",
]
+if (v8_use_metagen_instance_types) {
+ _debug_helper_sources += [ "$target_gen_dir/../../metagen/instance-types.h" ]
+ _debug_helper_deps += [ "../..:metagen_instance_types_h" ]
+}
if (v8_enable_temporal_support) {
_debug_helper_deps += [ "//third_party/rust/temporal_capi" ]
}
diff --git a/deps/v8/tools/debug_helper/get-object-properties.cc b/deps/v8/tools/debug_helper/get-object-properties.cc
index dd505cbf122..e962095ab43 100644
--- a/deps/v8/tools/debug_helper/get-object-properties.cc
+++ b/deps/v8/tools/debug_helper/get-object-properties.cc
@@ -16,6 +16,7 @@
#include "src/strings/unicode-inl.h"
#include "torque-generated/class-debug-readers.h"
#include "torque-generated/debug-macros.h"
+#include "torque-generated/debug-reader-classes-list.h"
namespace i = v8::internal;
@@ -64,8 +65,8 @@ TypedObject GetTypedObjectByHint(uintptr_t address,
std::make_unique<Tq##ClassName>(address)}; \
}
- TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(TYPE_NAME_CASE)
- TORQUE_INSTANCE_CHECKERS_RANGE_FULLY_DEFINED(TYPE_NAME_CASE)
+ TORQUE_DEBUG_READER_CLASSES_SINGLE(TYPE_NAME_CASE)
+ TORQUE_DEBUG_READER_CLASSES_RANGE(TYPE_NAME_CASE)
STRING_CLASS_TYPES(TYPE_NAME_CASE)
#undef TYPE_NAME_CASE
@@ -103,8 +104,8 @@ TypedObject GetTypedObjectByInstanceType(uintptr_t address,
#define INSTANCE_TYPE_CASE(ClassName, INSTANCE_TYPE) \
case i::INSTANCE_TYPE: \
return {type_source, std::make_unique<Tq##ClassName>(address)};
- TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED(INSTANCE_TYPE_CASE)
- TORQUE_INSTANCE_CHECKERS_MULTIPLE_FULLY_DEFINED(INSTANCE_TYPE_CASE)
+ TORQUE_DEBUG_READER_CLASSES_SINGLE(INSTANCE_TYPE_CASE)
+ TORQUE_DEBUG_READER_CLASSES_MULTIPLE(INSTANCE_TYPE_CASE)
#undef INSTANCE_TYPE_CASE
default:
@@ -120,7 +121,7 @@ TypedObject GetTypedObjectByInstanceType(uintptr_t address,
if (type >= i::FIRST_TYPE && type <= i::LAST_TYPE) { \
return {type_source, std::make_unique<Tq##ClassName>(address)}; \
}
- TORQUE_INSTANCE_CHECKERS_RANGE_FULLY_DEFINED(INSTANCE_RANGE_CASE)
+ TORQUE_DEBUG_READER_CLASSES_RANGE(INSTANCE_RANGE_CASE)
#undef INSTANCE_RANGE_CASE
return {d::TypeCheckResult::kUnknownInstanceType,
diff --git a/deps/v8/tools/debug_helper/plugins/README.md b/deps/v8/tools/debug_helper/plugins/README.md
index c8b1b2dc3e4..b293853135c 100644
--- a/deps/v8/tools/debug_helper/plugins/README.md
+++ b/deps/v8/tools/debug_helper/plugins/README.md
@@ -47,6 +47,7 @@ when you print a backtrace via `bt`, and adds a `v8` command. Currently, `v8` su
```
v8 inspect <addr> [--type T] [--depth N] [--array-length N]
v8 isolate
+v8 source [frame#] [--max-lines N]
```
#### Frame annotations
@@ -110,6 +111,28 @@ isolate = 0x7f1efd3c8000
If the selected thread has not entered an isolate (e.g. an idle worker
thread), it prints `isolate = <none>`.
+#### `v8 source [frame#] [--max-lines N]`
+
+Prints the source span of the function a JS frame is running.
+`frame#` is the frame number shown by `bt` and defaults to the selected frame.
+
+```
+(gdb) v8 source 5
+#5 test_func_3 @ throw.js:15:21 (this=0x1d190100497d, argc=4)
+
+ 14
+ +---- frame 5: test_func_3 -----
+ 15 | function test_func_3(n, b, o, s) {
+ 16 | throw new Error("v8dbg bridge test: " + s);
+ 17 | }
+ +---- frame 5: test_func_3 -----
+```
+
+The span covers the whole function the frame is running, from the start of its scope
+to its last character. Long spans (e.g. for top-level frames, whose span is the
+whole script) are truncated with a `... (<K> more lines)` note after 10 lines,
+or after `--max-lines N` lines when the flag is given.
+
#### Examples
To display the JS frames on stack, and inspect the receiver, paste the address
@@ -126,6 +149,16 @@ in the frame annotation into `v8 inspect`:
.properties_or_hash=<Smi: 940196>
.elements=0x1d19000007e5 <FixedArray: EmptyFixedArray>
.cpp_heap_wrappable=0x00000000
+(gdb) frame 5
+(gdb) v8 source
+#5 test_func_3 @ throw.js:15:21 (this=0x1d190100497d, argc=4)
+
+ 14
+ +---- frame 5: test_func_3 -----
+ 15 | function test_func_3(n, b, o, s) {
+ 16 | throw new Error("v8dbg bridge test: " + s);
+ 17 | }
+ +---- frame 5: test_func_3 -----
```
## How To Test It
diff --git a/deps/v8/tools/debug_helper/plugins/gdb_plugin.py b/deps/v8/tools/debug_helper/plugins/gdb_plugin.py
index 4de27747ae8..e7fce6ec85b 100644
--- a/deps/v8/tools/debug_helper/plugins/gdb_plugin.py
+++ b/deps/v8/tools/debug_helper/plugins/gdb_plugin.py
@@ -11,8 +11,11 @@ import traceback
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
-import gdb
-from gdb.FrameDecorator import FrameDecorator
+# The gdb module only exists inside gdb's embedded Python, where typeshed
+# provides stubs but no importable source.
+import gdb # pyright: ignore[reportMissingModuleSource]
+from gdb.FrameDecorator import ( # pyright: ignore[reportMissingModuleSource]
+ FrameDecorator)
from v8dbg.commands import debug_helper_lib_warning
from v8dbg.commands import dispatch_v8_command
@@ -104,6 +107,45 @@ def _evaluate_address_in_gdb(text):
return None
+def _frame_pointer(frame):
+ """Read the frame pointer of a gdb.Frame, or 0 when unavailable."""
+ # Extend this register list as the plugin grows support for more
+ # architectures. Today the tested targets are x64 and arm64.
+ for register_name in ("rbp", "fp", "x29"):
+ try:
+ value = frame.read_register(register_name)
+ except Exception:
+ continue
+ try:
+ frame_pointer = int(value)
+ except Exception:
+ frame_pointer = 0
+ if frame_pointer:
+ return frame_pointer
+ return 0
+
+
+def _resolve_frame_fp(index):
+ """Map a frame number (None = selected frame) to (level, frame pointer)."""
+ try:
+ if index is None:
+ frame = gdb.selected_frame()
+ else:
+ frame = gdb.newest_frame()
+ while frame is not None and frame.level() != index:
+ frame = frame.older()
+ if frame is None:
+ return None
+ frame_pointer = _frame_pointer(frame)
+ if not frame_pointer:
+ return None
+ return (frame.level(), frame_pointer)
+ except Exception:
+ if _VERBOSE:
+ traceback.print_exc()
+ return None
+
+
class V8DbgFrameDecorator(FrameDecorator):
"""Appends V8 JS frame annotations to backtraces."""
@@ -134,20 +176,7 @@ class V8DbgFrameDecorator(FrameDecorator):
# if it's a genuine JS frame.
if base_name and not base_name.startswith("Builtins_"):
return base_name
- frame_pointer = 0
- # Extend this register list as the plugin grows support for more
- # architectures. Today the tested targets are x64 and arm64.
- for register_name in ("rbp", "fp", "x29"):
- try:
- value = frame.read_register(register_name)
- except Exception:
- continue
- try:
- frame_pointer = int(value)
- except Exception:
- frame_pointer = 0
- if frame_pointer:
- break
+ frame_pointer = _frame_pointer(frame)
if not frame_pointer:
return base_name
@@ -197,6 +226,16 @@ class V8Command(gdb.Command):
- isolate -- Print the current Isolate address of the selected thread.
v8 isolate
+
+ - source -- Print the source span of the function a JS frame is running.
+
+ v8 source [frame#] [--max-lines N]
+
+ * frame#: the frame to show (default: the selected frame).
+ * --max-lines N: cap the number of span lines shown (default: 10).
+
+ The span covers the whole function; the exact executing line is not
+ recovered.
"""
def __init__(self):
@@ -216,6 +255,7 @@ class V8Command(gdb.Command):
eval_address=_evaluate_address_in_gdb,
resolver=_GdbResolver(bridge.ptr_size),
verbose=_VERBOSE,
+ frame_fp=_resolve_frame_fp,
)
if not ok:
gdb.write(text + "\n", gdb.STDERR)
diff --git a/deps/v8/tools/debug_helper/plugins/lldb_plugin.py b/deps/v8/tools/debug_helper/plugins/lldb_plugin.py
index c7085150c81..81b3ec25695 100644
--- a/deps/v8/tools/debug_helper/plugins/lldb_plugin.py
+++ b/deps/v8/tools/debug_helper/plugins/lldb_plugin.py
@@ -516,6 +516,16 @@ def cmd_v8(debugger, command, result, _internal_dict):
- isolate -- Print the current Isolate address of the selected thread.
v8 isolate
+
+ - source -- Print the source span of the function a JS frame is running.
+
+ v8 source [frame#] [--max-lines N]
+
+ * frame#: the frame to show (default: the selected frame).
+ * --max-lines N: cap the number of span lines shown (default: 10).
+
+ The span covers the whole function; the exact executing line is not
+ recovered.
"""
try:
argv = shlex.split(command or "")
@@ -523,6 +533,7 @@ def cmd_v8(debugger, command, result, _internal_dict):
argv = (command or "").split()
target = debugger.GetSelectedTarget()
process = target.GetProcess() if target else None
+ thread = None
frame = None
if process:
thread = process.GetSelectedThread()
@@ -539,6 +550,22 @@ def cmd_v8(debugger, command, result, _internal_dict):
def eval_address(text):
return _evaluate_address_in_lldb(target, frame, text)
+ def frame_fp(index):
+ if not thread or not thread.IsValid():
+ return None
+ if index is None:
+ selected = thread.GetSelectedFrame()
+ elif index < thread.GetNumFrames():
+ selected = thread.GetFrameAtIndex(index)
+ else:
+ return None
+ if not selected or not selected.IsValid():
+ return None
+ fp = selected.GetFP()
+ if not fp or fp == lldb.LLDB_INVALID_ADDRESS:
+ return None
+ return (selected.GetFrameID(), fp)
+
ok, text = dispatch_v8_command(
bridge,
argv,
@@ -546,6 +573,7 @@ def cmd_v8(debugger, command, result, _internal_dict):
eval_address=eval_address,
resolver=_LldbResolver(target, process),
verbose=_VERBOSE,
+ frame_fp=frame_fp,
)
if not ok:
result.SetError(text)
diff --git a/deps/v8/tools/debug_helper/plugins/test/helpers/source.py b/deps/v8/tools/debug_helper/plugins/test/helpers/source.py
new file mode 100644
index 00000000000..0a0bf2d44d0
--- /dev/null
+++ b/deps/v8/tools/debug_helper/plugins/test/helpers/source.py
@@ -0,0 +1,121 @@
+# 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.
+"""Assertions for `v8 source` integration tests against the throw.js fixture."""
+
+import re
+
+_FUNC_FRAME_RE = re.compile(
+ r"#(?P<frame>\d+)[^\n]*\[test_func_3 @ (?P<script>[^\]]+):15:21\]"
+ r" \(this=(?P<this>0x[0-9a-f]+), argc=(?P<argc>\d+)\)")
+_TOP_LEVEL_FRAME_RE = re.compile(
+ r"#(?P<frame>\d+)[^\n]*\[<anonymous> @ (?P<script>[^\]]*throw\.js):1:1\]"
+ r" \(this=(?P<this>0x[0-9a-f]+), argc=(?P<argc>\d+)\)")
+
+
+def _match_frame(bt, frame_re):
+ """Return the bt match for the innermost frame annotated per `frame_re`."""
+ m = frame_re.search(bt)
+ if not m:
+ raise AssertionError(
+ f"no frame matching {frame_re.pattern} in backtrace:\n{bt}")
+ return m
+
+
+def _header(m, function_name, position):
+ """The `v8 source` first line, reproducing the frame's bt annotation."""
+ return (f"#{m['frame']} {function_name} @ {m['script']}:{position}"
+ f" (this={m['this']}, argc={m['argc']})\n\n")
+
+
+def _expected_func_span(m):
+ """The `v8 source` snippet for the test_func_3 frame (throw.js 15-17)."""
+ rule = f"+---- frame {m['frame']}: test_func_3 -----"
+ return (_header(m, "test_func_3", "15:21") + " 14\n"
+ f" {rule}\n"
+ " 15 | function test_func_3(n, b, o, s) {\n"
+ ' 16 | throw new Error("v8dbg bridge test: " + s);\n'
+ " 17 | }\n"
+ f" {rule}\n")
+
+
+def _expected_max_lines_span(m):
+ """The `v8 source --max-lines 2` snippet for the test_func_3 frame."""
+ rule = f"+---- frame {m['frame']}: test_func_3 -----"
+ return (_header(m, "test_func_3", "15:21") + " 14\n"
+ f" {rule}\n"
+ " 15 | function test_func_3(n, b, o, s) {\n"
+ ' 16 | throw new Error("v8dbg bridge test: " + s);\n'
+ " | ... (1 more lines)\n")
+
+
+def _expected_top_level_span(m):
+ """The `v8 source` snippet for the top-level frame, truncated at 10 lines."""
+ rule = f"+---- frame {m['frame']}: <anonymous> -----"
+ return (
+ _header(m, "<anonymous>", "1:1") + f" {rule}\n"
+ " 1 | // Copyright 2026 the V8 project authors. "
+ "All rights reserved.\n"
+ " 2 | // Use of this source code is governed by a BSD-style license "
+ "that can be\n"
+ " 3 | // found in the LICENSE file.\n"
+ " 4 |\n"
+ " 5 | function test_func_1(n, b, o, s) {\n"
+ " 6 | return test_func_2(n + 1, !b, o, s);\n"
+ " 7 | }\n"
+ " 8 |\n"
+ " 9 | function test_func_2(n, b, o, s) {\n"
+ " 10 | return (function(n, b, o, s) {\n"
+ " | ... (9 more lines)\n")
+
+
+def _assert_in_output(expected, output):
+ """Assert `expected` appears in the debugger output, modulo CRLF endings."""
+ if expected not in output.replace("\r\n", "\n"):
+ raise AssertionError(f"expected `v8 source` snippet:\n{expected}\n"
+ f"not found in output:\n{output}")
+
+
+def check_source(session):
+ """Check `v8 source` rendering, flags, and error handling end-to-end."""
+ bt = session.run_command("bt")
+ func = _match_frame(bt, _FUNC_FRAME_RE)
+ top = _match_frame(bt, _TOP_LEVEL_FRAME_RE)
+ expected = _expected_func_span(func)
+
+ # Explicit frame number.
+ _assert_in_output(expected, session.run_command(f"v8 source {func['frame']}"))
+
+ # Plain `v8 source` uses the debugger's selected frame.
+ try:
+ session.select_frame(int(func["frame"]))
+ output = session.run_command("v8 source")
+ finally:
+ session.select_frame(0)
+ _assert_in_output(expected, output)
+
+ # `--max-lines N` truncates the span after N lines, with no end rule.
+ _assert_in_output(
+ _expected_max_lines_span(func),
+ session.run_command(f"v8 source {func['frame']} --max-lines 2"))
+
+ # The top-level frame's span is the whole script, truncated at the cap.
+ _assert_in_output(
+ _expected_top_level_span(top),
+ session.run_command(f"v8 source {top['frame']}"))
+
+ # Argument validation and non-JS frame handling.
+ checks = (
+ ("v8 source 9999", "cannot resolve frame 9999"),
+ ("v8 source --context 1", "unknown flag '--context'"),
+ ("v8 source abc", "frame number must be a non-negative integer"),
+ ("v8 source --max-lines 0", "--max-lines must be a positive integer"),
+ ("v8 source --max-lines abc", "--max-lines must be a positive integer"),
+ # Frame 0 is the native abort frame, not a JS frame.
+ ("v8 source 0", "is not a JS frame"),
+ )
+ for command, expected_error in checks:
+ output = session.run_command(command)
+ if expected_error not in output:
+ raise AssertionError(
+ f"`{command}` did not report {expected_error!r}, got:\n{output}")
diff --git a/deps/v8/tools/debug_helper/plugins/test/test_gdb_core.py b/deps/v8/tools/debug_helper/plugins/test/test_gdb_core.py
index 49f2d201025..b2538628b96 100644
--- a/deps/v8/tools/debug_helper/plugins/test/test_gdb_core.py
+++ b/deps/v8/tools/debug_helper/plugins/test/test_gdb_core.py
@@ -16,6 +16,7 @@ from .helpers.inspect import check_inspect_recurses_into_map
from .helpers.isolate import check_isolate_command
from .helpers.isolate import check_isolate_none_on_idle_thread
from .helpers.session import GdbSession
+from .helpers.source import check_source
from .helpers.utils import DebuggerTestConfig
from .helpers.utils import get_gdb_core_test_config
from .helpers.utils import run_debugger_command
@@ -113,6 +114,22 @@ class GdbInspectCoreTest(unittest.TestCase):
check_isolate_none_on_idle_thread(session)
+class GdbSourceCoreTest(unittest.TestCase):
+ """Checks `v8 source` end-to-end with a core dump in GDB."""
+
+ def _session(self):
+ return GdbSession(
+ _CONFIG,
+ target_binary=_CONFIG.d8_binary,
+ core_path=os.path.join(_CORE_DIR, "throw.core"),
+ )
+
+ def test_source(self):
+ """Checks `v8 source` rendering, flags, and error handling."""
+ with self._session() as session:
+ check_source(session)
+
+
class GdbCorruptedMapCoreTest(unittest.TestCase):
"""Checks `v8 inspect` on objects with corrupted Map from a core dump in GDB."""
diff --git a/deps/v8/tools/debug_helper/plugins/test/test_gdb_live.py b/deps/v8/tools/debug_helper/plugins/test/test_gdb_live.py
index 19d3f230dfc..50dc6fbb0e1 100644
--- a/deps/v8/tools/debug_helper/plugins/test/test_gdb_live.py
+++ b/deps/v8/tools/debug_helper/plugins/test/test_gdb_live.py
@@ -16,6 +16,7 @@ from .helpers.inspect import check_inspect_recurses_into_map
from .helpers.isolate import check_isolate_command
from .helpers.isolate import check_isolate_none_on_idle_thread
from .helpers.session import GdbSession
+from .helpers.source import check_source
from .helpers.utils import DebuggerTestConfig
from .helpers.utils import FIXTURES_DIR
from .helpers.utils import get_gdb_live_test_config
@@ -119,6 +120,25 @@ class GdbInspectLiveTest(unittest.TestCase):
check_isolate_none_on_idle_thread(session)
+class GdbSourceLiveTest(unittest.TestCase):
+ """Checks `v8 source` end-to-end with a live d8 process in GDB."""
+
+ def _session(self):
+ script = os.path.join(FIXTURES_DIR, "throw.js")
+ return GdbSession(
+ _CONFIG,
+ target_binary=_CONFIG.d8_binary,
+ target_args=f'{_CONFIG.d8_args} --abort-on-uncaught-exception '
+ f'"{script}"',
+ )
+
+ def test_source(self):
+ """Checks `v8 source` rendering, flags, and error handling."""
+ with self._session() as session:
+ session.run_to_abort()
+ check_source(session)
+
+
class GdbCorruptedMapTest(unittest.TestCase):
"""Checks `v8 inspect` on objects with corrupted Map with a live d8 process in GDB."""
diff --git a/deps/v8/tools/debug_helper/plugins/test/test_lldb_core.py b/deps/v8/tools/debug_helper/plugins/test/test_lldb_core.py
index 1ba12dd9990..07d99afc33b 100644
--- a/deps/v8/tools/debug_helper/plugins/test/test_lldb_core.py
+++ b/deps/v8/tools/debug_helper/plugins/test/test_lldb_core.py
@@ -16,6 +16,7 @@ from .helpers.inspect import check_inspect_recurses_into_map
from .helpers.isolate import check_isolate_command
from .helpers.isolate import check_isolate_none_on_idle_thread
from .helpers.session import LldbSession
+from .helpers.source import check_source
from .helpers.utils import DebuggerTestConfig
from .helpers.utils import get_lldb_core_test_config
from .helpers.utils import run_debugger_command
@@ -106,6 +107,22 @@ class LldbInspectCoreTest(unittest.TestCase):
check_isolate_none_on_idle_thread(session)
+class LldbSourceCoreTest(unittest.TestCase):
+ """Checks `v8 source` end-to-end with a core dump in LLDB."""
+
+ def _session(self):
+ return LldbSession(
+ _CONFIG,
+ target_binary=_CONFIG.d8_binary,
+ core_path=os.path.join(_CORE_DIR, "throw.core"),
+ )
+
+ def test_source(self):
+ """Checks `v8 source` rendering, flags, and error handling."""
+ with self._session() as session:
+ check_source(session)
+
+
class LldbCorruptedMapCoreTest(unittest.TestCase):
"""Checks `v8 inspect` on objects with corrupted Map from a core dump in LLDB."""
diff --git a/deps/v8/tools/debug_helper/plugins/test/test_lldb_live.py b/deps/v8/tools/debug_helper/plugins/test/test_lldb_live.py
index ebe35c331ad..64c58049c9a 100644
--- a/deps/v8/tools/debug_helper/plugins/test/test_lldb_live.py
+++ b/deps/v8/tools/debug_helper/plugins/test/test_lldb_live.py
@@ -16,6 +16,7 @@ from .helpers.inspect import check_inspect_recurses_into_map
from .helpers.isolate import check_isolate_command
from .helpers.isolate import check_isolate_none_on_idle_thread
from .helpers.session import LldbSession
+from .helpers.source import check_source
from .helpers.utils import DebuggerTestConfig
from .helpers.utils import FIXTURES_DIR
from .helpers.utils import get_lldb_live_test_config
@@ -115,6 +116,25 @@ class LldbInspectLiveTest(unittest.TestCase):
check_isolate_none_on_idle_thread(session)
+class LldbSourceLiveTest(unittest.TestCase):
+ """Checks `v8 source` end-to-end with a live d8 process in LLDB."""
+
+ def _session(self):
+ script = os.path.join(FIXTURES_DIR, "throw.js")
+ return LldbSession(
+ _CONFIG,
+ target_binary=_CONFIG.d8_binary,
+ target_args=f'{_CONFIG.d8_args} --abort-on-uncaught-exception '
+ f'"{script}"',
+ )
+
+ def test_source(self):
+ """Checks `v8 source` rendering, flags, and error handling."""
+ with self._session() as session:
+ session.run_to_abort()
+ check_source(session)
+
+
class LldbCorruptedMapTest(unittest.TestCase):
"""Checks `v8 inspect` on objects with corrupted Map with a live d8 process in LLDB."""
diff --git a/deps/v8/tools/debug_helper/plugins/v8dbg/commands.py b/deps/v8/tools/debug_helper/plugins/v8dbg/commands.py
index 0c9b5d99a81..aeeea184655 100644
--- a/deps/v8/tools/debug_helper/plugins/v8dbg/commands.py
+++ b/deps/v8/tools/debug_helper/plugins/v8dbg/commands.py
@@ -11,13 +11,20 @@ import io
import os
import traceback
+from .format import (format_frame_location, format_frame_trailer,
+ render_function_span)
from .hints import resolve_current_isolate, resolve_heap_hints
-from .inspect import Formatter
+from .inspect import Formatter, read_frame_trailer
from .models import HeapHints
_V8_USAGE = ("usage: v8 <subcommand>\n"
" v8 inspect <addr> [--type T] [--depth N] [--array-length N]\n"
- " v8 isolate\n")
+ " v8 isolate\n"
+ " v8 source [frame#] [--max-lines N]\n")
+
+# Cap on the number of function span lines `v8 source` prints. Top-level
+# frames span the whole script, which can be arbitrarily large.
+_SOURCE_SPAN_MAX_LINES = 10
_LIB_PATH_ENV = "V8_DEBUG_HELPER_LIB_PATH"
@@ -31,9 +38,12 @@ def debug_helper_lib_warning():
def dispatch_v8_command(bridge, argv, *, read_memory, eval_address, resolver,
- verbose):
+ verbose, frame_fp):
"""Run one `v8 <subcommand> ...` invocation, capturing its output.
+ `frame_fp` maps a frame number (None = the selected frame) to
+ `(resolved_number, frame_pointer)`, or None when it cannot be resolved.
+
Returns `(True, output)` on success, `(False, error_message)` on failure.
"""
buffer = io.StringIO()
@@ -45,6 +55,8 @@ def dispatch_v8_command(bridge, argv, *, read_memory, eval_address, resolver,
resolver)
elif argv[0] == "isolate":
_run_isolate(argv[1:], buffer, resolver)
+ elif argv[0] == "source":
+ _run_source(bridge, argv[1:], buffer, read_memory, frame_fp)
else:
return (True, f"v8: unknown subcommand '{argv[0]}'\n{_V8_USAGE}")
except Exception:
@@ -97,6 +109,61 @@ def _run_isolate(argv, output, resolver):
output.write(f"isolate = 0x{isolate_addr:x}\n")
+def _run_source(bridge, argv, output, read_memory, frame_fp):
+ """Print the source span of the function a stack frame is running."""
+ frame_index = None
+ max_lines = _SOURCE_SPAN_MAX_LINES
+ it = iter(argv)
+ for token in it:
+ if token == "--max-lines":
+ value = next(it, "")
+ if not value.isdigit() or int(value) < 1:
+ output.write("v8 source: --max-lines must be a positive integer\n")
+ return
+ max_lines = int(value)
+ elif token.startswith("-"):
+ output.write(f"v8 source: unknown flag '{token}'\n")
+ return
+ elif frame_index is not None:
+ output.write(f"v8 source: extra positional arg '{token}'\n")
+ return
+ elif token.isdigit():
+ frame_index = int(token)
+ else:
+ output.write(f"v8 source: frame number must be a non-negative integer, "
+ f"got '{token}'\n")
+ return
+
+ frame_desc = ("the selected frame"
+ if frame_index is None else f"frame {frame_index}")
+ resolved = frame_fp(frame_index)
+ if resolved is None:
+ output.write(f"v8 source: cannot resolve {frame_desc}\n")
+ return
+ frame_number, frame_pointer = resolved
+ if frame_number is not None:
+ frame_desc = f"frame {frame_number}"
+
+ info = bridge.describe_js_frame(frame_pointer, read_memory)
+ if info is None:
+ output.write(f"v8 source: {frame_desc} is not a JS frame\n")
+ return
+ receiver, argc = read_frame_trailer(frame_pointer, bridge.ptr_size,
+ read_memory)
+
+ header = format_frame_location(info) + format_frame_trailer(receiver, argc)
+ if frame_number is not None:
+ header = f"#{frame_number} {header}"
+ output.write(header + "\n\n")
+
+ function_name = info.get("function_name") or "<anonymous>"
+ span = render_function_span(info, f"{frame_desc}: {function_name}", max_lines)
+ if span is None:
+ output.write(f"v8 source: no source available for {frame_desc}\n")
+ return
+ output.write(span)
+
+
def _run_inspect(bridge, argv, output, read_memory, eval_address, resolver):
# TODO(joyee): per-flag error messages, reject negative ints.
type_hint = None
diff --git a/deps/v8/tools/debug_helper/plugins/v8dbg/format.py b/deps/v8/tools/debug_helper/plugins/v8dbg/format.py
new file mode 100644
index 00000000000..f90ef480ebf
--- /dev/null
+++ b/deps/v8/tools/debug_helper/plugins/v8dbg/format.py
@@ -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.
+"""Pure text formatting shared by the `v8` command renderers."""
+
+
+def format_frame_location(annotation):
+ """Format "<function_name> @ <script_name>:<line>:<column>" for a JS frame.
+
+ Degrades to "<function_name> @ <script_name>" without a position and to
+ "<function_name>" without a script name.
+ """
+ function_name = annotation.get("function_name") or "<anonymous>"
+ script_name = annotation.get("script_name")
+ if not script_name:
+ return function_name
+ location = f"{function_name} @ {script_name}"
+ position = annotation.get("position")
+ if position:
+ location += f":{position[0]}:{position[1]}"
+ return location
+
+
+def format_frame_trailer(receiver, argc):
+ """Format the " (this=0x..., argc=N)" frame trailer, or "" without one."""
+ if receiver is None:
+ return ""
+ return f" (this=0x{receiver:x}, argc={argc})"
+
+
+def render_function_span(info, label, max_lines):
+ """Format a function's source span with a bracket rail in the gutter, example:
+
+ 14
+ +---- frame 5: test_func_3 -----
+ 15 | function test_func_3(n, b, o, s) {
+ 16 | throw new Error("v8dbg bridge test: " + s);
+ 17 | }
+ +---- frame 5: test_func_3 -----
+
+ If there are more than `max_lines` lines, the span is truncated with a note.
+ """
+ position = info.get("position")
+ end_position = info.get("end_position")
+ script_source = info.get("script_source") or ""
+ lines = script_source.splitlines()
+
+ start_line = position[0] if position else None
+ if not lines or start_line is None or start_line > len(lines):
+ return None
+
+ rule = f"+---- {label} -----"
+
+ end_line = end_position[0] if end_position else None
+ if end_line is not None:
+ end_line = min(max(end_line, start_line), len(lines))
+ span_last = start_line if end_line is None else end_line
+ span_last = min(span_last, start_line + max_lines - 1)
+
+ first = max(1, start_line - 1)
+ width = max(4, len(str(span_last)))
+ blank_gutter = " " * width
+
+ out = []
+ for num in range(first, span_last + 1):
+ if num == start_line:
+ out.append(f"{blank_gutter} {rule}")
+ gutter = "|" if num >= start_line else " "
+ out.append(f"{num:>{width}} {gutter} {lines[num - 1]}".rstrip())
+ if end_line is not None:
+ if end_line > span_last:
+ out.append(f"{blank_gutter} | ... ({end_line - span_last} more lines)")
+ else:
+ out.append(f"{blank_gutter} {rule}")
+ return "\n".join(out) + "\n"
diff --git a/deps/v8/tools/debug_helper/plugins/v8dbg/shared_bridge.py b/deps/v8/tools/debug_helper/plugins/v8dbg/shared_bridge.py
index 2ef41e857b2..0386e9d78c4 100644
--- a/deps/v8/tools/debug_helper/plugins/v8dbg/shared_bridge.py
+++ b/deps/v8/tools/debug_helper/plugins/v8dbg/shared_bridge.py
@@ -13,6 +13,7 @@ import re
import types
from typing import Optional
+from .format import format_frame_location, format_frame_trailer
from .inspect import (
decode_c_str,
decode_tagged_smi,
@@ -301,40 +302,56 @@ class DebuggerBridge:
char_offset + 1 if last_newline == -1 else char_offset - last_newline)
return (line, column)
- def _decode_position(self, script_source, function_name, offset_prop,
- read_memory):
- """Decode function_character_offset into a (line, column) pair."""
+ def _decode_span(self, script_source, function_name, offset_prop,
+ read_memory):
+ """Decode function_character_offset into (start, end) (line, column) pairs.
+
+ The end pair points at the last character of the function. Either pair
+ can be None when it cannot be recovered.
+ """
if (offset_prop is None or not offset_prop.address or
not offset_prop.struct_fields):
- return None
+ return (None, None)
fields = {f.name: f for f in offset_prop.struct_fields}
start_field = fields.get("start")
end_field = fields.get("end")
if start_field is None or end_field is None:
- return None
+ return (None, None)
# The debug helper reports the total struct size as 2 * kTaggedSize for the
# target build, so derive the per-field width from that build-specific size.
if start_field.offset != 0 or offset_prop.size % 2 != 0:
- return None
+ return (None, None)
field_width = offset_prop.size // 2
if field_width not in (4, 8):
- return None
- raw_start = int.from_bytes(
- read_memory(offset_prop.address + start_field.offset, field_width),
- byteorder="little",
- signed=False,
- )
- char_offset = decode_tagged_smi(raw_start, field_width)
- position = self._position_from_offset(script_source, char_offset)
- if position is not None:
- return position
+ return (None, None)
- # Top-level scripts without source can still be reported as 1:1.
- if not script_source and char_offset == 0 and function_name == "":
- return (1, 1)
- return None
+ def read_char_offset(byte_offset):
+ raw = int.from_bytes(
+ read_memory(offset_prop.address + byte_offset, field_width),
+ byteorder="little",
+ signed=False,
+ )
+ return decode_tagged_smi(raw, field_width)
+
+ start_offset = read_char_offset(0)
+ position = self._position_from_offset(script_source, start_offset)
+ if position is None:
+ # Top-level scripts without source can still be reported as 1:1.
+ if not script_source and start_offset == 0 and function_name == "":
+ return ((1, 1), None)
+ return (None, None)
+
+ # The end offset points one past the last character of the function.
+ # Like the struct size, the reported field offsets assume pointer
+ # compression (end is always at 4), so place the end field at the
+ # build-specific field width instead.
+ end_offset = read_char_offset(field_width)
+ end_position = None
+ if end_offset > start_offset:
+ end_position = self._position_from_offset(script_source, end_offset - 1)
+ return (position, end_position)
def describe_js_frame(self, frame_pointer, read_memory):
"""Return high-level JS frame metadata, or None if the frame is unusable."""
@@ -367,7 +384,7 @@ class DebuggerBridge:
read_memory,
allow_brief_fallback=False,
max_chars=None)
- position = self._decode_position(
+ position, end_position = self._decode_span(
script_source,
function_name,
props.get("function_character_offset"),
@@ -382,6 +399,8 @@ class DebuggerBridge:
"function_name": function_name,
"script_name": script_name,
"position": position,
+ "end_position": end_position,
+ "script_source": script_source,
}
finally:
library._v8_debug_helper_Free_StackFrameResult(result_ptr)
@@ -401,21 +420,10 @@ class DebuggerBridge:
annotation = self.describe_js_frame(frame_pointer, read_memory)
if not annotation:
return ""
- function_name = annotation.get("function_name") or "<anonymous>"
- script_name = annotation.get("script_name")
- position = annotation.get("position")
- location_suffix = ""
- if position:
- location_suffix = f":{position[0]}:{position[1]}"
- if script_name:
- head = f" [{function_name} @ {script_name}{location_suffix}]"
- else:
- head = f" [{function_name}]"
receiver, argc = read_frame_trailer(frame_pointer, self._ptr_size,
read_memory)
- if receiver is None:
- return head
- return f"{head} (this=0x{receiver:x}, argc={argc})"
+ location = format_frame_location(annotation)
+ return f" [{location}]{format_frame_trailer(receiver, argc)}"
_bridges = {}
diff --git a/deps/v8/tools/dev/gm.py b/deps/v8/tools/dev/gm.py
index 74abc03bccf..5444d0f29e6 100755
--- a/deps/v8/tools/dev/gm.py
+++ b/deps/v8/tools/dev/gm.py
@@ -340,6 +340,7 @@ v8_enable_backtrace = true
v8_enable_fast_mksnapshot = true
v8_enable_slow_dchecks = true
v8_optimized_debug = false
+v8_use_perfetto = false
"""
OPTDEBUG_ARGS_TEMPLATE = f"""\
diff --git a/deps/v8/tools/dev/setup_worktree_build.py b/deps/v8/tools/dev/setup_worktree_build.py
index f1fbf1c532d..419809f1ac7 100755
--- a/deps/v8/tools/dev/setup_worktree_build.py
+++ b/deps/v8/tools/dev/setup_worktree_build.py
@@ -197,6 +197,12 @@ def should_skip_worktree_deps(worktree_dir: Path) -> bool:
def sync_dependencies(main_repo: Path, worktree_dir: Path):
+ if not worktree_dir.is_dir() or not (worktree_dir / ".git").exists():
+ print(
+ f"Error: {worktree_dir} is not an initialized git worktree.",
+ file=sys.stderr)
+ sys.exit(1)
+
if main_repo.resolve() == worktree_dir.resolve():
return
diff --git a/deps/v8/tools/dev/update-compile-commands.py b/deps/v8/tools/dev/update-compile-commands.py
index 02fc6aa6509..ee1b83f5e1a 100755
--- a/deps/v8/tools/dev/update-compile-commands.py
+++ b/deps/v8/tools/dev/update-compile-commands.py
@@ -42,6 +42,14 @@ def _Call(cmd, silent=False):
print(f"# {cmd}")
return subprocess.call(cmd, shell=True)
+
+def _GetGnArg(build_dir, name):
+ """Returns the current value of a GN arg, as the string GN prints for it."""
+ out = subprocess.check_output(
+ f"gn args {build_dir} --list={name} --json", shell=True, text=True)
+ arg = json.loads(out)[0]
+ return arg.get("current", arg["default"])["value"]
+
def _Write(filename, content):
with open(filename, "w") as f:
f.write(content)
@@ -106,8 +114,13 @@ def CompileLanguageServer():
def GenerateCCFiles():
print(">>> Generating generated C++ source files...")
# This must be called after UpdateCompileCommands().
- assert os.path.exists(f"out/{DEFAULT_ARCH}.debug/build.ninja")
- _Call(f"autoninja -C out/{DEFAULT_ARCH}.debug v8_generated_cc_files")
+ build_dir = f"out/{DEFAULT_ARCH}.debug"
+ assert os.path.exists(os.path.join(build_dir, "build.ninja"))
+ targets = "v8_generated_cc_files"
+ # The metagen action only exists when v8_use_metagen_instance_types is on.
+ if _GetGnArg(build_dir, "v8_use_metagen_instance_types") == "true":
+ targets += " metagen_instance_types_h"
+ _Call(f"autoninja -C {build_dir} {targets}")
def PrepareReclient():
diff --git a/deps/v8/tools/gcmole/gcmole-tools.tar.gz.sha1 b/deps/v8/tools/gcmole/gcmole-tools.tar.gz.sha1
index 8a498d4acad..e9fcab73887 100644
--- a/deps/v8/tools/gcmole/gcmole-tools.tar.gz.sha1
+++ b/deps/v8/tools/gcmole/gcmole-tools.tar.gz.sha1
@@ -1 +1 @@
-9ca577320f9062ce2aa52d4909db761df4690e85
\ No newline at end of file
+bc810086fbc612b88056c7a1d61cd61db2f68758
\ No newline at end of file
diff --git a/deps/v8/tools/gen-postmortem-metadata.py b/deps/v8/tools/gen-postmortem-metadata.py
index d74f0140365..027e4f569c8 100644
--- a/deps/v8/tools/gen-postmortem-metadata.py
+++ b/deps/v8/tools/gen-postmortem-metadata.py
@@ -672,7 +672,7 @@ def load_objects_from_file(objfilename, checktypes):
in_torque_insttype = True
continue
- if (line.startswith('#define TORQUE_INSTANCE_CHECKERS_SINGLE_FULLY_DEFINED')):
+ if (line.startswith('#define TORQUE_DEBUG_READER_CLASSES_SINGLE')):
in_torque_fulldef = True
continue
diff --git a/deps/v8/tools/lldb_commands.py b/deps/v8/tools/lldb_commands.py
index 2ef3012cd4b..e28061e8067 100644
--- a/deps/v8/tools/lldb_commands.py
+++ b/deps/v8/tools/lldb_commands.py
@@ -282,9 +282,9 @@ def jomb(debugger, param, *args):
@lldbCommand
def bta(debugger, *args):
"""Print stack trace with assertion scopes"""
- func_name_re = re.compile("([^(<]+)(?:\(.+\))?")
+ func_name_re = re.compile(r"([^(<]+)(?:\(.+\))?")
assert_re = re.compile(
- "^v8::internal::Per\w+AssertType::(\w+)_ASSERT, (false|true)>")
+ r"^v8::internal::Per\w+AssertType::(\w+)_ASSERT, (false|true)>")
thread = current_thread(debugger)
for frame in thread:
functionSignature = frame.GetDisplayFunctionName()
diff --git a/deps/v8/tools/locs.py b/deps/v8/tools/locs.py
index f8940c05e69..2275a84ae62 100755
--- a/deps/v8/tools/locs.py
+++ b/deps/v8/tools/locs.py
@@ -32,7 +32,7 @@ except NameError:
ARGPARSE = argparse.ArgumentParser(
description=("A script that computes LoC for a build dir"),
- epilog="""Examples:
+ epilog=r"""Examples:
Count with default settings for build in out/Default:
locs.py --build-dir out/Default
Count only a custom group of files settings for build in out/Default:
diff --git a/deps/v8/tools/mb/mb_test.py b/deps/v8/tools/mb/mb_test.py
index c654fd605cd..840f2fea645 100755
--- a/deps/v8/tools/mb/mb_test.py
+++ b/deps/v8/tools/mb/mb_test.py
@@ -547,7 +547,7 @@ class UnitTest(unittest.TestCase):
" 'type': 'raw',"
" 'args': [],"
"}}\n"),
- 'c:\\fake_src\out\Default\cc_perftests.exe.runtime_deps':
+ 'c:\\fake_src\\out\\Default\\cc_perftests.exe.runtime_deps':
("cc_perftests\n"),
}
mbw = self.fake_mbw(files=files, win32=True)
diff --git a/deps/v8/tools/metagen/.gitignore b/deps/v8/tools/metagen/.gitignore
new file mode 100644
index 00000000000..27a8fcd08e6
--- /dev/null
+++ b/deps/v8/tools/metagen/.gitignore
@@ -0,0 +1,2 @@
+__pycache__/
+siso_result.json
diff --git a/deps/v8/tools/metagen/__init__.py b/deps/v8/tools/metagen/__init__.py
new file mode 100644
index 00000000000..ff92a2a465c
--- /dev/null
+++ b/deps/v8/tools/metagen/__init__.py
@@ -0,0 +1,3 @@
+# 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.
diff --git a/deps/v8/tools/metagen/clang_bootstrap.py b/deps/v8/tools/metagen/clang_bootstrap.py
new file mode 100644
index 00000000000..4afb046e113
--- /dev/null
+++ b/deps/v8/tools/metagen/clang_bootstrap.py
@@ -0,0 +1,217 @@
+# 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.
+"""Make `clang.cindex` importable and point it at a native libclang.
+
+Kept separate so the bootstrap can run before any module that uses
+`clang.cindex` is imported -- `cpp_hier.py` references
+`cindex.CursorKind.X` at module-load time (in module-level tuples), so
+its import requires `clang.cindex` to be resolvable from sys.path.
+
+Usage from the metagen entry point:
+
+ from metagen import clang_bootstrap
+ clang_bootstrap.bootstrap(libclang_dir=args.libclang_dir)
+ from metagen import cpp_hier # now safe
+
+There are three modes, and the caller must pick exactly one explicitly --
+see the mutually exclusive --libclang-dir / --libclang-from-python-env /
+--libclang-so flags in metagen.py. None is reachable by omitting an argument.
+
+`bootstrap(libclang_dir=...)` -- bundled mode, used by GN and by
+standalone Bazel. Bindings and native library both come from the
+`llvm-libclang` package extracted at `third_party/llvm-libclang` (a
+first-class GCS dep), version-matched to each other and to the V8
+compiler roll:
+
+ bindings/python/clang/{cindex,__init__}.py
+ lib/libclang.so | lib/libclang.dylib | bin/libclang.dll
+
+Sourcing both from one package (rather than the bindings from the clang
+toolchain and the .so from rust-toolchain) keeps them locked together.
+We look ONLY inside the package dir and hard-fail if it is absent.
+
+`bootstrap_from_python_env()` -- environment mode, for build systems
+whose Python dependency graph already provides a self-configuring
+`clang.cindex` (it loads its own native library at import time, so
+passing paths in would fight the wrapper). The version guarantee then
+lives in that dependency edge rather than here; see the function.
+
+Neither mode searches the system or falls back silently. A libclang
+whose API version does not match the headers' expectations yields a
+subtly wrong AST rather than a clean failure, and this generator's
+output ships in the V8 build.
+
+The clang builtin headers (stddef.h etc.) are a separate input handled
+by metagen.py's --clang-resource-dir / --clang-builtin-headers-dir.
+"""
+
+from __future__ import annotations
+
+import os
+import re
+import sys
+
+
+def _parse_clang_major(version: str) -> int | None:
+ """Pull the major version out of a `clang_getClangVersion()` string.
+
+ The string is free-form (e.g. "clang version 21.1.8 (Fedora 21.1.8-1)"),
+ so match the first dotted-number run rather than assume a fixed layout.
+ """
+ m = re.search(r"(\d+)\.\d+", version)
+ return int(m.group(1)) if m else None
+
+
+def bootstrap_from_python_env() -> None:
+ """Use a `clang.cindex` the Python environment already provides.
+
+ For build systems whose dependency graph supplies a self-configuring
+ bindings module (it calls `Config.set_library_file` itself at import
+ time). We deliberately do not touch sys.path or the Config here: the
+ module owns that, and overriding it would fight the wrapper.
+
+ A pip-installed `clang` package satisfies the import just as well and
+ would parse with a libclang nothing pins, so reject that case and log
+ the module we did accept.
+ """
+ try:
+ import clang.cindex as cindex # noqa: E402
+ except ImportError as e:
+ print(
+ f"[metagen] --libclang-from-python-env was passed but "
+ f"`import clang.cindex` failed: {e}\nThe build rule must put a "
+ f"libclang bindings module on the Python path (e.g. as a "
+ f"py_binary dep).",
+ file=sys.stderr)
+ sys.exit(1)
+
+ origin = os.path.dirname(os.path.abspath(cindex.__file__))
+ # site-packages / dist-packages means an interpreter-level install
+ # (pip, distro package), never a build-declared dependency: the trees a
+ # build stages its Python deps into do not use those directory names.
+ if any(
+ part in ("site-packages", "dist-packages")
+ for part in origin.split(os.sep)):
+ print(
+ f"[metagen] refusing a system-installed clang.cindex:\n"
+ f" {origin}\n"
+ f"--libclang-from-python-env expects the bindings to come from "
+ f"the build's dependency graph, whose libclang version is "
+ f"pinned. This path is an interpreter-level install, which "
+ f"nothing pins. Declare the bindings as a dependency of the "
+ f"metagen tool, or use --libclang-dir for the bundled package.",
+ file=sys.stderr)
+ sys.exit(1)
+
+ # cindex resolves the native library lazily, so touching the Library
+ # here surfaces a misconfigured wrapper now rather than mid-parse.
+ try:
+ cindex.Config().lib
+ except Exception as e:
+ print(
+ f"[metagen] the environment-provided clang.cindex could not load "
+ f"its native libclang: {e}\nThe bindings module is expected to "
+ f"configure this itself; metagen passes no path in this mode.",
+ file=sys.stderr)
+ sys.exit(1)
+
+ # In this mode the harvest log is the only record of which libclang
+ # parsed, so emit it unconditionally.
+ print(
+ f"[metagen] using environment-provided clang.cindex from {origin} "
+ f"(library: {cindex.Config.library_file or 'wrapper-configured'})",
+ file=sys.stderr)
+
+
+def bootstrap_native(native_so: str,
+ bindings_dir: str,
+ expect_major: int | None = None) -> None:
+ """Point cindex at an explicit system libclang and a bindings dir.
+
+ For platforms with no prebuilt llvm-libclang GCS package, the native
+ library is the distro's own libclang and the cindex bindings are
+ staged separately, so the two come from different paths rather than
+ one package.
+
+ `expect_major` is the clang toolchain major (GN's clang_version), if the
+ loaded libclang reports an older major, warn it may be out of step
+ with the builtin headers metagen parses against.
+ """
+ bindings = os.path.abspath(bindings_dir)
+ if not os.path.isfile(os.path.join(bindings, "clang", "cindex.py")):
+ print(
+ f"[metagen] clang.cindex bindings not found under\n"
+ f" {bindings}\n(expected {os.path.join(bindings, 'clang', 'cindex.py')}"
+ f"). Point --libclang-bindings-dir at the dir holding the clang/ "
+ f"package.",
+ file=sys.stderr)
+ sys.exit(1)
+ sys.path.insert(0, bindings)
+
+ import clang.cindex as cindex # noqa: E402
+
+ if not os.path.isfile(native_so):
+ print(
+ f"[metagen] libclang native library not found:\n {native_so}",
+ file=sys.stderr)
+ sys.exit(1)
+ cindex.Config.set_library_file(native_so)
+
+ # Log the libclang version and warn if it is older than the clang
+ # toolchain, so a mismatch is discoverable.
+ get_version = getattr(cindex.Config(), "get_clang_version", None)
+ version = get_version() if get_version else None
+ major = _parse_clang_major(version) if version else None
+ print(
+ f"[metagen] native libclang: {version or 'version unknown'}",
+ file=sys.stderr)
+ if major is not None and expect_major is not None and major < expect_major:
+ print(
+ f"[metagen] warning: libclang major {major} is older than the clang "
+ f"toolchain ({expect_major}); the parse may not match its builtin "
+ f"headers.",
+ file=sys.stderr)
+
+
+def bootstrap(libclang_dir: str) -> None:
+ """Add the llvm-libclang package's Python bindings to sys.path and point
+ cindex at its native libclang.
+
+ `libclang_dir` is the package root (the dir holding bindings/python/ and
+ lib/libclang.so). The GN and Bazel actions always pass it, resolved to
+ third_party/llvm-libclang, whose presence DEPS guarantees. A missing file
+ here is therefore a real error, not a layout to search around.
+ """
+ base = os.path.abspath(libclang_dir)
+
+ # Python bindings: <package>/bindings/python/clang/cindex.py.
+ bindings_dir = os.path.join(base, "bindings", "python")
+ if not os.path.isfile(os.path.join(bindings_dir, "clang", "cindex.py")):
+ print(
+ f"[metagen] llvm-libclang Python bindings not found under\n"
+ f" {bindings_dir}\nRe-run `gclient sync` to fetch the llvm-libclang "
+ f"package.",
+ file=sys.stderr)
+ sys.exit(1)
+ sys.path.insert(0, bindings_dir)
+
+ import clang.cindex as cindex # noqa: E402
+
+ # Native libclang: the package ships the loadable library next to the
+ # bindings (lib/libclang.so | lib/libclang.dylib | bin/libclang.dll).
+ if sys.platform == "darwin":
+ native_rel = os.path.join("lib", "libclang.dylib")
+ elif sys.platform == "win32":
+ native_rel = os.path.join("bin", "libclang.dll")
+ else:
+ native_rel = os.path.join("lib", "libclang.so")
+ native = os.path.join(base, native_rel)
+ if not os.path.isfile(native):
+ print(
+ f"[metagen] llvm-libclang native library not found:\n"
+ f" {native}\nRe-run `gclient sync` to fetch the llvm-libclang "
+ f"package.",
+ file=sys.stderr)
+ sys.exit(1)
+ cindex.Config.set_library_file(native)
diff --git a/deps/v8/tools/metagen/compile_flags.py b/deps/v8/tools/metagen/compile_flags.py
new file mode 100644
index 00000000000..30024b7f283
--- /dev/null
+++ b/deps/v8/tools/metagen/compile_flags.py
@@ -0,0 +1,263 @@
+# 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.
+"""Recover the libclang parse flags for the metagen harvest.
+
+One entry point per build system:
+
+ * GN (`get_compile_args_from_gn_desc`): query one representative
+ target with `gn desc <out> <target> --format=json` and reconstruct
+ its flags from the reported defines / include_dirs / cflags /
+ cflags_cc -- exactly the fields the cxx tool template expands
+ ({{defines}} {{include_dirs}} {{cflags}} {{cflags_cc}}).
+
+ * Bazel (`get_compile_args_from_file`): read the single-entry
+ compile_commands.json the rule synthesizes from the cc toolchain
+ (bazel/defs.bzl). The entry always carries an `arguments` array, so
+ the flags are read directly with no shell tokenization.
+
+Both hand the cflags to libclang VERBATIM -- no cl-vs-gcc spelling
+translation, which would need a patch per toolchain. The filter below
+drops only categories that are meaningless or harmful for
+`-fsyntax-only` (output paths, dep-info, backend options, plugin chains,
+instrumentation, warnings-as-errors) or that libclang rejects (input
+file, response files).
+
+The clang builtin headers (stddef.h etc.) are not handled here: the
+build system points metagen.py at the toolchain that holds them, via
+--clang-resource-dir or --clang-builtin-headers-dir. Probing for them
+would read paths the build never declared, which a sandboxed action
+cannot do.
+"""
+
+from __future__ import annotations
+
+import json
+import os
+import shutil
+import subprocess
+import sys
+
+# Single-token drops: compile-only and dep-info flags (these only occur
+# in the Bazel-synthesized command line; gn desc cflags never carry
+# them), plus warnings-as-errors. Warnings are meaningless for a
+# syntax-only harvest, and under /WX they would escalate to errors:
+# libclang unconditionally injects -fno-spell-checking and
+# -fallow-editor-placeholders (CIndex.cpp), which the cl-mode driver
+# does not recognize and warns about. Dropping /WX (rather than
+# suppressing individual warning groups) keeps all of that inert.
+_DROP_SINGLE = frozenset({
+ "-c",
+ "-MMD",
+ "-MD",
+ "-MP",
+ "/WX",
+})
+
+# Two-token drops: the flag plus its following argument.
+_DROP_TWO = frozenset({
+ "-Xclang", # plugin chains: -Xclang -add-plugin -Xclang blink-gc-plugin
+ "-mllvm", # backend-only options; libclang can't honor them
+ "-MF",
+ "-MT",
+ "-MQ",
+ "-MJ", # dep-info output paths
+ "-o", # output object path
+})
+
+# Single-token prefix drops: instrumentation flag families that
+# libclang can't act on in -fsyntax-only, plus per-warning escalations
+# (see _DROP_SINGLE).
+#
+# -fsanitize= stays. It reaches the preprocessor through
+# __has_feature(address_sanitizer) et al., and libc++ cross-checks that
+# against the -D_LIBCPP_INSTRUMENTED_WITH_ASAN the same build passes:
+# keep the define and drop the flag and its <__debug_utils/sanitizers.h>
+# #errors out. Only the ignore lists go, since they steer instrumentation
+# and nothing else, and a syntax-only parse has no business failing over
+# a file it would not read (see also -fno-sanitize-ignorelist in
+# metagen.py, which suppresses the implicit ones).
+#
+# Also strip modules flags. Modular headers need prebuilt .pcm files that we
+# can't produce, so the parse has to stay textual. That includes
+# -fbuiltin-module-map, which modularizes whatever -resource-dir= points at.
+_DROP_PREFIX = (
+ "-Werror", # bare and -Werror=<warning>
+ "-fcrash-diagnostics-dir=",
+ "-fprofile-",
+ "-fcoverage-",
+ "-fsanitize-ignorelist=",
+ "-fsanitize-system-ignorelist=",
+ "-fsanitize-blacklist=", # the pre-LLVM-13 spelling
+ "-fmodule", # -fmodules, -fmodule-file=, -fmodule-map-file=, ...
+ "-fimplicit-module", # -fimplicit-modules, ...-module-maps
+ "-fno-implicit-module", # -fno-implicit-modules, ...-module-maps
+ "-fbuiltin-module-map",
+)
+
+_CXX_INPUT_EXTS = (".cc", ".cpp", ".cxx", ".cppm", ".c++", ".C")
+
+
+def _find_gn(source_root: str) -> str | None:
+ """Locate the gn binary. Both trees ship it under buildtools/<plat>/,
+ except on the hosts whose DEPS entry excludes the CIPD package
+ (s390x, ppc64, z/OS); there a system gn on PATH is the only one, which
+ is what tools/mb/mb.py falls back to on the same hosts."""
+ exe = "gn.exe" if sys.platform == "win32" else "gn"
+ if sys.platform == "darwin":
+ # Both Mac arches: the arch is in the CIPD package name, not the dir.
+ plats = ("mac",)
+ elif sys.platform == "win32":
+ plats = ("win",)
+ else:
+ plats = ("linux64",)
+ for plat in plats:
+ p = os.path.join(source_root, "buildtools", plat, exe)
+ if os.path.isfile(p) and os.access(p, os.X_OK):
+ return p
+ return shutil.which("gn")
+
+
+def _is_clang_cl(arg0: str) -> bool:
+ """Detect clang-cl driver by argv[0]'s basename."""
+ name = os.path.basename(arg0).lower()
+ if name.endswith(".exe"):
+ name = name[:-4]
+ return name == "clang-cl"
+
+
+def _filter(args: list[str], input_path: str) -> list[str]:
+ out: list[str] = []
+ norm_input = os.path.normpath(input_path) if input_path else ""
+ i = 0
+ while i < len(args):
+ a = args[i]
+ if a in _DROP_TWO:
+ i += 2
+ continue
+ if a in _DROP_SINGLE:
+ i += 1
+ continue
+ if any(a.startswith(p) for p in _DROP_PREFIX):
+ i += 1
+ continue
+ if a.startswith("@"):
+ # An @-file means the compile command references an unexpanded
+ # response file; bail loudly rather than silently miss half the
+ # flags. gn desc reports expanded cflags, and the Bazel rule emits
+ # a fully-expanded `arguments` array, so this should never fire.
+ raise RuntimeError(
+ f"[metagen] unexpanded response file in compile flags: {a}.")
+ if (norm_input and a.endswith(_CXX_INPUT_EXTS) and
+ os.path.normpath(a) == norm_input):
+ i += 1
+ continue
+ out.append(a)
+ i += 1
+ return out
+
+
+def get_compile_args_from_gn_desc(
+ build_dir: str, target_label: str,
+ source_root: str) -> tuple[list[str], str, bool]:
+ """GN path: reconstruct one target's compile flags via `gn desc`.
+
+ `source_root` is the directory holding the build's `.gn` marker. The
+ caller passes it in because the build dir need not sit under it.
+
+ Returns (flags, cwd, cl_mode):
+ flags libclang args. Path-bearing flags (-I, -isystem, ...) are
+ left as-is; the caller must invoke libclang with cwd=`cwd`
+ so build-dir-relative paths resolve.
+ cwd The build dir (cflags' paths are relative to it).
+ cl_mode True iff the toolchain is clang-cl. The caller injects
+ `--driver-mode=cl` when this is set.
+
+ cflags/cflags_cc are passed through verbatim; include_dirs are
+ source-absolute `//...` and rebased against `source_root` here.
+ """
+ source_root = os.path.abspath(source_root)
+ gn = _find_gn(source_root)
+ if not gn:
+ raise RuntimeError(
+ "[metagen] gn not found under <source-root>/buildtools or on PATH.")
+ out_rel = os.path.relpath(os.path.abspath(build_dir), source_root)
+ try:
+ # -q ("don't print output on success") keeps stdout to the JSON alone.
+ # Without it gn prepends any build-file warning to the document -- an
+ # arm_float_abi that no declare_args() claims on the arm64 bots, say --
+ # and the parse below fails. A gn that actually fails still reports.
+ proc = subprocess.run(
+ [gn, "desc", "-q", out_rel, target_label, "--format=json"],
+ cwd=source_root,
+ capture_output=True,
+ text=True,
+ check=True,
+ )
+ except FileNotFoundError:
+ raise RuntimeError(f"[metagen] gn binary not found: {gn}")
+ except subprocess.CalledProcessError as e:
+ raise RuntimeError(f"[metagen] `gn desc {out_rel} {target_label}` failed "
+ f"(exit {e.returncode}). Has `gn gen` run there?\n"
+ f"{(e.stderr or '').strip()}")
+ try:
+ desc = json.loads(proc.stdout)
+ except json.JSONDecodeError as e:
+ raise RuntimeError(f"[metagen] `gn desc` output was not valid JSON: {e}")
+ if not isinstance(desc, dict) or not desc:
+ raise RuntimeError(
+ f"[metagen] `gn desc` returned no target for {target_label}.")
+ # Single-target query: the sole value maps the (toolchain-qualified)
+ # label to its resolved fields.
+ fields = next(iter(desc.values()))
+
+ flags: list[str] = [f"-D{d}" for d in fields.get("defines") or []]
+ for inc in fields.get("include_dirs") or []:
+ if inc.startswith("//"):
+ abs_inc = os.path.normpath(os.path.join(source_root, inc[2:]))
+ elif os.path.isabs(inc):
+ abs_inc = inc
+ else:
+ abs_inc = os.path.normpath(os.path.join(source_root, inc))
+ flags.append(f"-I{abs_inc}")
+ cflags = (fields.get("cflags") or []) + (fields.get("cflags_cc") or [])
+ flags += cflags
+
+ # clang-cl spells its options with a leading slash; posix clang never
+ # does. The caller injects --driver-mode=cl when this is set.
+ cl_mode = any(f.startswith("/") for f in cflags)
+
+ # Drop plugin chains (-Xclang -add-plugin ...), backend-only (-mllvm),
+ # and sanitizer/coverage/crash-dir flags libclang can't honor under
+ # -fsyntax-only. gn desc's cflags never carry -c/-o/@rsp/the input
+ # path, so the input-path arg to _filter is unused.
+ filtered = _filter(flags, "")
+ return filtered, os.path.abspath(build_dir), cl_mode
+
+
+def get_compile_args_from_file(path: str) -> tuple[list[str], str, bool]:
+ """Bazel path: read the single-entry compile_commands.json the rule
+ synthesizes (bazel/defs.bzl).
+
+ Returns (flags, cwd, cl_mode) with the same contract as
+ `get_compile_args_from_gn_desc`. The synthesized entry always carries
+ an `arguments` array (never a `command` string), so the flags are read
+ directly with no shell tokenization. argv[0] and the bogus source file
+ are dropped; `-c`/`-o` and friends go through the shared _filter.
+ """
+ with open(path) as f:
+ entries = json.load(f)
+ if not isinstance(entries, list) or len(entries) != 1:
+ n = len(entries) if isinstance(entries, list) else "n/a"
+ raise RuntimeError(f"[metagen] expected a one-entry list in {path}, got "
+ f"{type(entries).__name__} (len {n}).")
+ entry = entries[0]
+ args = entry.get("arguments")
+ if not args:
+ raise RuntimeError(
+ f"[metagen] compile-commands entry has no `arguments` array: "
+ f"{entry}. bazel/defs.bzl must emit `arguments`, not `command`.")
+ arg0, rest = args[0], args[1:]
+ cl_mode = _is_clang_cl(arg0)
+ cwd = entry.get("directory") or "."
+ return _filter(rest, entry.get("file", "")), cwd, cl_mode
diff --git a/deps/v8/tools/metagen/compile_flags_test.py b/deps/v8/tools/metagen/compile_flags_test.py
new file mode 100644
index 00000000000..928701d435f
--- /dev/null
+++ b/deps/v8/tools/metagen/compile_flags_test.py
@@ -0,0 +1,90 @@
+#!/usr/bin/env python3
+# 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.
+
+import json
+import os
+from pathlib import Path
+import subprocess
+import sys
+import tempfile
+import unittest
+from unittest import mock
+
+# Running this file as a script puts tools/metagen/ on sys.path, not its
+# parent, so the `metagen` package is not importable yet.
+_PARENT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+if _PARENT not in sys.path:
+ sys.path.insert(0, _PARENT)
+
+from metagen import compile_flags # noqa: E402
+
+
+class GnCompileFlagsTest(unittest.TestCase):
+
+ def test_external_build_directory(self):
+ with tempfile.TemporaryDirectory() as tmp:
+ source_root = Path(tmp) / 'src'
+ build_dir = Path(tmp) / 'cache' / 'Release'
+ source_root.mkdir()
+ build_dir.mkdir(parents=True)
+ (source_root / '.gn').touch()
+ target = '//v8:probe(//build/toolchain:target)'
+ desc = {
+ target: {
+ 'defines': ['PROBE=1'],
+ 'include_dirs': ['//v8/include',
+ str(build_dir / 'gen')],
+ 'cflags_cc': ['-std=c++20'],
+ }
+ }
+ with mock.patch.object(
+ compile_flags, '_find_gn',
+ return_value='gn') as find_gn, mock.patch.object(
+ compile_flags.subprocess,
+ 'run',
+ return_value=subprocess.CompletedProcess(
+ [], 0, json.dumps(desc))) as run:
+ flags, cwd, cl_mode = compile_flags.get_compile_args_from_gn_desc(
+ str(build_dir), target, str(source_root))
+ find_gn.assert_called_once_with(str(source_root))
+ # gn runs in the source root, and reaches the build dir through a
+ # relative path that leaves the checkout.
+ argv, kwargs = run.call_args
+ self.assertEqual(argv[0], [
+ 'gn', 'desc', '-q',
+ os.path.relpath(build_dir, source_root), target, '--format=json'
+ ])
+ self.assertEqual(kwargs['cwd'], str(source_root))
+ self.assertTrue(kwargs['check'])
+ self.assertEqual(flags, [
+ '-DPROBE=1', f'-I{source_root / "v8" / "include"}',
+ f'-I{build_dir / "gen"}', '-std=c++20'
+ ])
+ self.assertEqual(cwd, str(build_dir))
+ self.assertFalse(cl_mode)
+
+
+class FilterTest(unittest.TestCase):
+
+ def test_drops_clang_modules_family(self):
+ # A use_clang_modules build passes all of these. -fbuiltin-module-map
+ # is the easy one to miss: it names no path, so it does nothing until
+ # the resource dir actually has builtin headers in it.
+ modules_flags = [
+ '-fmodules',
+ '-fmodule-map-file=/x/module.modulemap',
+ '-fmodule-file=std=/x/std.pcm',
+ '-fimplicit-modules',
+ '-fimplicit-module-maps',
+ '-fno-implicit-modules',
+ '-fno-implicit-module-maps',
+ '-fbuiltin-module-map',
+ ]
+ self.assertEqual(
+ compile_flags._filter(modules_flags + ['-DKEEP'], ''), ['-DKEEP'])
+
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/deps/v8/tools/metagen/cpp_hier.py b/deps/v8/tools/metagen/cpp_hier.py
new file mode 100644
index 00000000000..9383c6d8694
--- /dev/null
+++ b/deps/v8/tools/metagen/cpp_hier.py
@@ -0,0 +1,513 @@
+# 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.
+"""Harvest the class hierarchy from C++ V8_OBJECT headers via libclang.
+
+Produces `ClassInfo` records (see instance_types.py) for every class
+that transitively inherits HeapObject in the input headers, sourced from the
+`[[clang::annotate("V8_IT_*")]]` markers carried by aliases in each class
+body. Feed the list into `instance_types.assign_instance_types` to drive IT
+generation from the C++ source-of-truth.
+
+The annotation set we surface:
+
+ V8_IT_ABSTRACT -> is_abstract
+ V8_IT_REUSE_PARENT -> has_same_instance_type_as_parent
+ V8_IT_FIXED_VALUE(N) -> constraints.value = N
+ V8_IT_FLAG_BITS(N) -> constraints.num_flags_bits = N
+ V8_IT_ORDER(FIRST) -> lowest_within_parent
+ V8_IT_ORDER(LAST) -> highest_within_parent
+ V8_IT_NO_AUTO_CHECKER -> no_auto_checker
+
+Inheritance is resolved through templates by the shared harness in
+`extract.py`.
+
+This module references `clang.cindex` at import time, so
+`clang_bootstrap.bootstrap()` must have run first -- metagen.py does
+that before importing us.
+"""
+
+from __future__ import annotations
+
+import dataclasses
+import os
+import re
+import subprocess
+import sys
+
+import clang.cindex as cindex
+
+from metagen import extract
+from metagen.instance_types import ClassInfo, InstanceTypeConstraints
+
+_V8_IT_ABSTRACT = "V8_IT_ABSTRACT"
+_V8_IT_REUSE_PARENT = "V8_IT_REUSE_PARENT"
+_V8_IT_OWN_TYPE = "V8_IT_OWN_TYPE"
+_V8_IT_NO_AUTO_CHECKER = "V8_IT_NO_AUTO_CHECKER"
+_V8_IT_NO_AUTO_DISPATCH = "V8_IT_NO_AUTO_DISPATCH"
+_V8_IT_FIXED_VALUE_RE = re.compile(r"^V8_IT_FIXED_VALUE\((.+)\)$")
+_V8_IT_FLAG_BITS_RE = re.compile(r"^V8_IT_FLAG_BITS\((.+)\)$")
+_V8_IT_ORDER_RE = re.compile(r"^V8_IT_ORDER\((FIRST|LAST)\)$")
+# Anchored, because the V8_OBJECTS_<NAME>_H_ include guards share a
+# prefix with V8_OBJECT and would otherwise match.
+_MARKER_MACRO_RE = re.compile(
+ r"^(V8_IT_[A-Z_]+|V8_ABSTRACT_OBJECT"
+ r"|V8_OBJECT(_END|_PUSH|_POP|_INNER_CLASS(_END)?)?)$")
+
+
+@dataclasses.dataclass
+class ScanResult:
+ classes: list[ClassInfo]
+ # Absolute paths of the files the harvest read a fact out of -- class
+ # declarations, the bases and templates it resolved through, and the
+ # marker definitions. Derived from the walk, not filtered from the
+ # include list, so it stays correct when a declaration moves.
+ provenance: list[str] = dataclasses.field(default_factory=list)
+
+
+def _annotations(cursor: cindex.Cursor) -> list[str]:
+ return extract.class_annotations(cursor)
+
+
+def _has_annotation(cursor: cindex.Cursor, name: str) -> bool:
+ return name in extract.class_annotations(cursor)
+
+
+def _parse_it_int(text: str, cursor: cindex.Cursor, attr: str) -> int:
+ try:
+ return int(text.strip(), 0)
+ except ValueError:
+ loc = cursor.location
+ where = f"{loc.file.name}:{loc.line}" if loc.file else "<unknown>"
+ print(
+ f"[metagen] {where}: {cursor.spelling}: malformed {attr} argument "
+ f"{text.strip()!r}; expected an integer literal.",
+ file=sys.stderr)
+ sys.exit(1)
+
+
+def _class_info_from_cursor(
+ cursor: cindex.Cursor,
+ v8_root: str,
+ base: str | None = None,
+) -> ClassInfo:
+ c = InstanceTypeConstraints()
+ is_abstract = False
+ reuse_parent = False
+ highest = False
+ lowest = False
+ no_auto_checker = False
+ no_auto_dispatch = False
+ for a in _annotations(cursor):
+ if a == _V8_IT_ABSTRACT:
+ is_abstract = True
+ elif a == _V8_IT_REUSE_PARENT:
+ reuse_parent = True
+ elif a == _V8_IT_NO_AUTO_CHECKER:
+ no_auto_checker = True
+ elif a == _V8_IT_NO_AUTO_DISPATCH:
+ no_auto_dispatch = True
+ elif m := _V8_IT_FIXED_VALUE_RE.match(a):
+ c.value = _parse_it_int(m.group(1), cursor, "V8_IT_FIXED_VALUE")
+ elif m := _V8_IT_FLAG_BITS_RE.match(a):
+ c.num_flags_bits = _parse_it_int(m.group(1), cursor, "V8_IT_FLAG_BITS")
+ elif m := _V8_IT_ORDER_RE.match(a):
+ if m.group(1) == "LAST":
+ highest = True
+ else:
+ lowest = True
+
+ if base is None:
+ base = extract.get_base_name(cursor)
+
+ # Diagnostic method detection: DECL_PRINTER(Name) / DECL_VERIFIER(Name)
+ # expand to `void Name##Print(std::ostream&)` / `void Name##Verify
+ # (Isolate*)` declarations (metagen.py parses with -DOBJECT_PRINT
+ # -DVERIFY_HEAP so they are visible in every config).
+ name = cursor.spelling
+ printer_name = name + "Print"
+ verifier_name = name + "Verify"
+ has_printer = False
+ has_verifier = False
+ for ch in cursor.get_children():
+ if ch.kind == cindex.CursorKind.CXX_METHOD:
+ if ch.spelling == printer_name:
+ has_printer = True
+ elif ch.spelling == verifier_name:
+ has_verifier = True
+
+ return ClassInfo(
+ name=name,
+ base=base,
+ position=_position(cursor, v8_root),
+ is_abstract=is_abstract,
+ has_same_instance_type_as_parent=reuse_parent,
+ highest_within_parent=highest,
+ lowest_within_parent=lowest,
+ constraints=c,
+ no_auto_checker=no_auto_checker,
+ has_printer=has_printer,
+ has_verifier=has_verifier,
+ no_auto_dispatch=no_auto_dispatch,
+ )
+
+
+def _dump_parse_failure(v8_root: str,
+ driver_path: str,
+ parse_flags: list[str],
+ reason: str,
+ parse_cwd: str | None = None) -> None:
+ """Re-run the parse through the clang binary and forward its stderr.
+
+ Covers both ways the parse fails. On an unrecoverable TU the Python
+ binding drops the diagnostics: CXTranslationUnit is NULL and
+ from_source raises, so all we have is "Error parsing translation
+ unit". On a TU that parsed with errors we have diagnostics but not the
+ `In file included from ...` stacks, which are what show a header
+ resolving to a different file than the build's compile uses. clang
+ prints both.
+
+ Best-effort: if the bundled clang is missing or won't spawn, we log
+ that and let the caller fail as it would have anyway.
+ """
+ # libclang's argv mirrors the GCC-style clang driver, not clang-cl.
+ # On Linux/Mac the Chromium toolchain ships clang directly; on
+ # Windows it ships only clang-cl.exe -- invoke that with
+ # --driver-mode=g++ to make it parse the same flag set libclang did.
+ # Probe both <v8_root>/third_party/... and <v8_root>/../third_party/...
+ # to handle Chromium subproject builds where the toolchain lives at
+ # the chromium toplevel.
+ clang_extra_args: list[str] = []
+ if sys.platform == "win32":
+ clang_rel = "third_party/llvm-build/Release+Asserts/bin/clang-cl.exe"
+ clang_extra_args = ["--driver-mode=g++"]
+ else:
+ clang_rel = "third_party/llvm-build/Release+Asserts/bin/clang"
+ clang_bin = ""
+ for root in (v8_root, os.path.abspath(os.path.join(v8_root, os.pardir))):
+ candidate = os.path.join(root, clang_rel)
+ if os.path.isfile(candidate):
+ clang_bin = candidate
+ break
+ print(
+ f"[metagen] {reason}; re-running via clang -fsyntax-only to surface "
+ "diagnostics:",
+ file=sys.stderr)
+ print(f"[metagen] clang: {clang_bin}", file=sys.stderr)
+ print(f"[metagen] driver: {driver_path}", file=sys.stderr)
+ print(
+ f"[metagen] flags ({len(parse_flags)}): "
+ f"{' '.join(parse_flags[:12])}{' ...' if len(parse_flags) > 12 else ''}",
+ file=sys.stderr)
+ if not clang_bin or not os.path.isfile(clang_bin):
+ print(
+ f"[metagen] (clang binary not found; cannot re-run)", file=sys.stderr)
+ return
+ try:
+ proc = subprocess.run(
+ [clang_bin] + clang_extra_args + ["-fsyntax-only", driver_path] +
+ parse_flags,
+ cwd=parse_cwd or v8_root,
+ capture_output=True,
+ text=True,
+ timeout=60,
+ )
+ except (OSError, subprocess.SubprocessError) as e:
+ print(f"[metagen] (subprocess failed: {e})", file=sys.stderr)
+ return
+ if proc.stderr:
+ print("[metagen] clang stderr (first 80 lines):", file=sys.stderr)
+ for line in proc.stderr.splitlines()[:80]:
+ print(f"[metagen] {line}", file=sys.stderr)
+ print(f"[metagen] clang exited with {proc.returncode}", file=sys.stderr)
+
+
+def scan_cpp(v8_root: str,
+ driver_path: str,
+ flags: list[str],
+ parse_cwd: str | None = None) -> ScanResult:
+ """Parse `driver_path` via libclang and return ClassInfo records.
+
+ The driver's active direct includes are the headers to harvest. The order of
+ returned records mirrors AST preorder, which equals (header inclusion order,
+ source-position order within each header). That order is stable for a given
+ driver + V8 tree.
+
+ `parse_cwd`, when set, is chdir'd into around the libclang parse so
+ the relative path-bearing flags from ninja's compile_commands.json
+ (-I../../v8/src, --sysroot=../../build/..., ...) resolve the same way
+ clang itself would resolve them in the build.
+ """
+ driver_path = os.path.abspath(driver_path)
+ options = (
+ cindex.TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD
+ | cindex.TranslationUnit.PARSE_SKIP_FUNCTION_BODIES)
+ index = cindex.Index.create()
+ parse_flags = list(flags)
+ # libclang resolves relative path-bearing flags (-I, --sysroot, ...)
+ # and stores file paths in source locations against the current
+ # working directory. Chdir to parse_cwd so flags from ninja's
+ # compile_commands.json (which are relative to the build dir)
+ # resolve the way clang itself resolved them in the build, and so
+ # the post-parse abspath() comparisons against `wanted` see the
+ # same absolute paths libclang recorded.
+ saved_cwd = os.getcwd() if parse_cwd else None
+ if parse_cwd:
+ os.chdir(parse_cwd)
+ try:
+ try:
+ tu = index.parse(driver_path, args=parse_flags, options=options)
+ except cindex.TranslationUnitLoadError:
+ # libclang couldn't even start the parse -- typically a sysroot
+ # / include-path / target-triple mismatch (Windows MSVC paths,
+ # missing builtin headers, ...). At this point the TU is NULL
+ # so we have no diagnostics to read via libclang. Re-run the
+ # parse via the clang binary as a subprocess; its stderr carries
+ # the actual error.
+ _dump_parse_failure(v8_root, driver_path, parse_flags,
+ "libclang refused the TU", parse_cwd)
+ raise
+ _reject_recovery_ast(tu, v8_root, driver_path, parse_flags, parse_cwd)
+ return _harvest_classes(tu, v8_root)
+ finally:
+ if saved_cwd is not None:
+ os.chdir(saved_cwd)
+
+
+def _position(cursor: cindex.Cursor, v8_root: str) -> str:
+ """`file.h:line:col`, relative to v8_root so the harvest's output and
+ its diagnostics are reproducible across checkouts."""
+ loc = cursor.location
+ fname = os.path.relpath(loc.file.name, v8_root) if loc.file else "<unknown>"
+ return f"{fname}:{loc.line}:{loc.column}"
+
+
+_SCOPE_KINDS = (cindex.CursorKind.NAMESPACE, cindex.CursorKind.CLASS_DECL,
+ cindex.CursorKind.STRUCT_DECL, cindex.CursorKind.CLASS_TEMPLATE,
+ cindex.CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION)
+
+
+def _qualified_name(cursor: cindex.Cursor) -> str:
+ """Return `cursor`'s name with its namespaces and enclosing classes,
+ e.g. "v8::internal::FixedArray::Iterator".
+
+ The enclosing classes are what separates the four v8::internal classes
+ named Iterator; the namespaces are what separates v8::Context from the
+ object.
+ """
+ parts = [cursor.spelling]
+ parent = cursor.semantic_parent
+ while parent is not None and parent.kind != cindex.CursorKind.TRANSLATION_UNIT:
+ if parent.kind in _SCOPE_KINDS:
+ parts.append(parent.spelling)
+ parent = parent.semantic_parent
+ return "::".join(reversed(parts))
+
+
+def _reject_recovery_ast(tu,
+ v8_root: str,
+ driver_path: str,
+ parse_flags: list[str],
+ parse_cwd: str | None = None) -> None:
+ """Exit unless the TU parsed cleanly.
+
+ Never consume Clang's recovery AST. A missing declaration can corrupt a
+ base edge or field type while leaving enough cursors for generation to
+ appear successful, which is especially unsafe for object layout metadata.
+ """
+ errors = [d for d in tu.diagnostics if d.severity >= cindex.Diagnostic.Error]
+ if not errors:
+ return
+ for d in errors[:30]:
+ print(
+ f"[metagen] diag {d.severity} {d.location}: {d.spelling}",
+ file=sys.stderr)
+ if len(errors) > 30:
+ print(f"[metagen] ... and {len(errors) - 30} more", file=sys.stderr)
+ _dump_parse_failure(v8_root, driver_path, parse_flags,
+ f"libclang reported {len(errors)} error diagnostic(s)",
+ parse_cwd)
+ print("[metagen] refusing to harvest a recovery AST.", file=sys.stderr)
+ sys.exit(1)
+
+
+def _harvest_classes(tu, v8_root: str) -> ScanResult:
+ # Pre-index every CLASS_TEMPLATE definition in the TU so the
+ # inheritance walk can resolve template-instantiated base types
+ # through partial specializations + parameter substitution. AND
+ # collect the candidate set (CLASS_DECL / CLASS_TEMPLATE definitions
+ # declared in input headers that reach HeapObject) in the same walk.
+ #
+ # Walking via `tu.cursor.walk_preorder()` over the full TU costs ~9s
+ # on the V8 driver TU (~750k cursors, dominated by libclang's
+ # ctypes-bound Cursor.__eq__ inside the visitor callback). Most of
+ # those cursors are inside function declarations, typedefs, etc. --
+ # places the harvest never cares about. Walk via an explicit
+ # recursion that descends only into the containers that can hold
+ # class definitions; this drops the cursor count by ~5x and the
+ # AST-walk time by ~10x.
+ _DESCEND_KINDS = frozenset((
+ cindex.CursorKind.TRANSLATION_UNIT,
+ cindex.CursorKind.NAMESPACE,
+ cindex.CursorKind.CLASS_DECL,
+ cindex.CursorKind.STRUCT_DECL,
+ cindex.CursorKind.CLASS_TEMPLATE,
+ cindex.CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+ cindex.CursorKind.LINKAGE_SPEC,
+ cindex.CursorKind.UNEXPOSED_DECL,
+ ))
+ _TEMPLATE_KINDS = (cindex.CursorKind.CLASS_TEMPLATE,
+ cindex.CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION)
+ _HARVEST_KINDS = (cindex.CursorKind.CLASS_DECL,
+ cindex.CursorKind.CLASS_TEMPLATE)
+ templates_idx: dict[str, list[cindex.Cursor]] = {}
+ raw_candidates: dict[str, cindex.Cursor] = {}
+ # Cursors that lost an unqualified-name collision, for the check below.
+ shadowed: dict[str, list[cindex.Cursor]] = {}
+
+ def _walk(cur):
+ k = cur.kind
+ if k in _TEMPLATE_KINDS and cur.is_definition():
+ templates_idx.setdefault(cur.spelling, []).append(cur)
+ if k in _HARVEST_KINDS and cur.is_definition():
+ # V8_IT_NO_AUTO_CHECKER normally excludes the class from the harvest.
+ # Combined with V8_IT_OWN_TYPE, it instead keeps the class in the IT
+ # tree while suppressing only its generated checker buckets.
+ no_auto_checker = _has_annotation(cur, _V8_IT_NO_AUTO_CHECKER)
+ own_type = _has_annotation(cur, _V8_IT_OWN_TYPE)
+ if not no_auto_checker or own_type:
+ loc = cur.location
+ # The driver reaches far more than the objects -- the public API
+ # headers among it -- and `raw_candidates` is keyed by unqualified
+ # name, so v8::Context would claim the key of the object it shares
+ # a name with and never be reconsidered. Select on the namespace:
+ # the harvest wants v8::internal and nothing else.
+ if _qualified_name(cur).startswith("v8::internal::"):
+ if raw_candidates.setdefault(cur.spelling, cur) != cur:
+ shadowed.setdefault(cur.spelling, []).append(cur)
+ if k in _DESCEND_KINDS or k in _TEMPLATE_KINDS:
+ for child in cur.get_children():
+ _walk(child)
+
+ _walk(tu.cursor)
+
+ def _reaches_heap_object(cur: cindex.Cursor) -> bool:
+ return cur.spelling == extract.HEAP_OBJECT_ROOT or (
+ extract.resolve_logical_base(cur, frozenset(),
+ templates=templates_idx) is not None)
+
+ # `raw_candidates` is keyed by unqualified name, so two v8::internal
+ # classes sharing one -- FixedArray::Iterator and BitVector::Iterator,
+ # say -- collide, and whichever the walk reached first keeps the key.
+ # That is only harmless while at most one of them is a heap object: if
+ # the loser is, it silently leaves the harvest and its class gets no
+ # instance type. Refuse to guess.
+ # TODO(jgruber): key on the qualified name instead, which removes the
+ # ambiguity rather than reporting it. That means teaching
+ # resolve_logical_base to match bases on qualified names too, where the
+ # names come from three sources at different qualification levels, so
+ # it wants its own change.
+ for name, losers in sorted(shadowed.items()):
+ winner = raw_candidates[name]
+ claimants = {}
+ for cur in [winner] + losers:
+ if _reaches_heap_object(cur):
+ claimants.setdefault(_qualified_name(cur), cur)
+ if not claimants:
+ continue
+ if len(claimants) > 1 or _qualified_name(winner) not in claimants:
+ print(
+ f"[metagen] `{name}` is claimed by more than one v8::internal "
+ f"class that reaches {extract.HEAP_OBJECT_ROOT}:",
+ file=sys.stderr)
+ for qualified, cur in sorted(claimants.items()):
+ print(
+ f"[metagen] {qualified} ({_position(cur, v8_root)})",
+ file=sys.stderr)
+ print(
+ "[metagen] The harvest identifies classes by unqualified name "
+ "and cannot tell them apart; rename one.",
+ file=sys.stderr)
+ sys.exit(1)
+
+ # Inheritance test: keep raw_candidates that are HeapObject itself or
+ # transitively reach HeapObject. `resolve_logical_base` with an
+ # empty target set returns HEAP_OBJECT_ROOT iff a chain exists.
+ # HeapObject itself has no base spec, so handle that explicitly.
+ #
+ # Collects every declaration the walks consult, including ones that
+ # ruled a candidate out: a header that keeps a class out of the
+ # harvest decides the output too.
+ visited: set[cindex.Cursor] = set()
+ candidates: dict[str, cindex.Cursor] = {
+ name: cur
+ for name, cur in raw_candidates.items()
+ if name == extract.HEAP_OBJECT_ROOT or extract.resolve_logical_base(
+ cur, frozenset(), templates=templates_idx, visited=visited)
+ is not None
+ }
+
+ # Compute the leaf set. A candidate is a leaf if no other candidate
+ # names it as the closest logical base. The base resolution here
+ # uses the full candidate set so intermediate candidates count as
+ # terminal ancestors; without that, a chain like
+ # JSDeferredModuleNamespace -> JSModuleNamespace -> ... -> HeapObject
+ # would skip past JSModuleNamespace and mark it as a leaf.
+ candidate_names = set(candidates.keys())
+ non_leaves: set[str] = set()
+ for cur in candidates.values():
+ p = extract.resolve_logical_base(
+ cur, candidate_names, templates=templates_idx, visited=visited)
+ if p is not None and p != extract.HEAP_OBJECT_ROOT:
+ non_leaves.add(p)
+
+ # Pass 2: participating = leaves OR annotated candidates. An
+ # intermediate candidate that lacks any V8_IT_* annotation is pure
+ # inheritance bookkeeping (e.g. an internal infrastructure class),
+ # not an IT participant. V8_IT_OWN_TYPE is the opt-in for concrete
+ # non-leaves that need their own _TYPE value; V8_IT_NO_AUTO_CHECKER
+ # candidates were filtered out above.
+ participating: dict[str, cindex.Cursor] = {
+ name: cur
+ for name, cur in candidates.items()
+ if name not in non_leaves or extract.has_v8_it_annotation(cur)
+ }
+
+ # Resolve each participating class's base against the *participating*
+ # set, not the candidates set: when an intermediate falls out of
+ # participation (unannotated infrastructure class), the walker must
+ # skip over it to find the closest still-participating ancestor.
+ participating_names = set(participating.keys())
+ classes: list[ClassInfo] = [
+ _class_info_from_cursor(
+ cur,
+ v8_root=v8_root,
+ base=extract.resolve_logical_base(
+ cur,
+ participating_names,
+ templates=templates_idx,
+ visited=visited),
+ ) for cur in participating.values()
+ ]
+
+ # The V8_IT_* / V8_OBJECT markers are read from class declarations, so the
+ # header defining them decides what every annotation means.
+ for cursor in tu.cursor.get_children():
+ if (cursor.kind == cindex.CursorKind.MACRO_DEFINITION and
+ _MARKER_MACRO_RE.match(cursor.spelling)):
+ visited.add(cursor)
+
+ provenance: set[str] = set()
+ # Prefix test rather than os.path.commonpath, which raises across
+ # drives on Windows -- and `visited` reaches the toolchain and sysroot
+ # declarations, which need not share the checkout's drive.
+ root = os.path.abspath(v8_root) + os.sep
+ for cursor in visited:
+ loc = cursor.location
+ if loc is None or loc.file is None:
+ continue
+ path = os.path.abspath(loc.file.name)
+ if path.startswith(root):
+ provenance.add(path)
+
+ return ScanResult(classes=classes, provenance=sorted(provenance))
diff --git a/deps/v8/tools/metagen/extract.py b/deps/v8/tools/metagen/extract.py
new file mode 100644
index 00000000000..70146416962
--- /dev/null
+++ b/deps/v8/tools/metagen/extract.py
@@ -0,0 +1,208 @@
+# 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.
+"""Shared libclang harness for the metagen pipeline.
+
+Inheritance walking through templates plus V8_IT_* annotation
+discovery. Shared between IT-mode harvesting (`cpp_hier.py`) and
+layout-mode generation (the `metagen-layout` branch); keep
+IT-emission concerns out of here.
+
+This module references `clang.cindex` at import time, so
+`clang_bootstrap.bootstrap()` must have run first -- metagen.py does
+that before importing any consumer of this module.
+"""
+
+from __future__ import annotations
+
+import clang.cindex as cindex
+
+HEAP_OBJECT_ROOT = "HeapObject"
+
+
+def class_annotations(cursor: cindex.Cursor) -> list[str]:
+ """Return the `[[clang::annotate]]` payloads on a class's members.
+
+ V8_IT_MARK expands to an artificial member alias, so the attribute
+ hangs off that member, never the class head. Annotations on real
+ members come through too (absl's inline-me, the blink GC plugin's),
+ so callers match on the V8_IT_ prefix or a full payload.
+ """
+ out: list[str] = []
+ for child in cursor.get_children():
+ for grandchild in child.get_children():
+ if grandchild.kind == cindex.CursorKind.ANNOTATE_ATTR:
+ out.append(grandchild.spelling)
+ return out
+
+
+def _strip_ns(spelling: str) -> str:
+ """Strip v8::internal:: namespace prefixes for readability."""
+ return spelling.replace("v8::internal::", "").replace("v8::", "")
+
+
+def has_v8_it_annotation(cursor: cindex.Cursor) -> bool:
+ """Class carries any `[[clang::annotate("V8_IT_*")]]` marker."""
+ return any(s.startswith("V8_IT_") for s in class_annotations(cursor))
+
+
+# Cursor kinds we'll treat as "class-like definitions" for inheritance.
+_CLASS_LIKE = (
+ cindex.CursorKind.CLASS_DECL,
+ cindex.CursorKind.STRUCT_DECL,
+ cindex.CursorKind.CLASS_TEMPLATE,
+ cindex.CursorKind.CLASS_TEMPLATE_PARTIAL_SPECIALIZATION,
+)
+
+_TEMPLATE_PARAM_KINDS = (
+ cindex.CursorKind.TEMPLATE_TYPE_PARAMETER,
+ cindex.CursorKind.TEMPLATE_NON_TYPE_PARAMETER,
+ cindex.CursorKind.TEMPLATE_TEMPLATE_PARAMETER,
+)
+
+
+def _template_params(cursor: cindex.Cursor) -> list[str]:
+ return [
+ ch.spelling
+ for ch in cursor.get_children()
+ if ch.kind in _TEMPLATE_PARAM_KINDS
+ ]
+
+
+def _resolve_type_to_class_name(t: cindex.Type) -> str | None:
+ """Best-effort: pick the class name out of a libclang Type.
+
+ Falls back to `type.spelling` when `get_declaration()` returns an
+ unnamed cursor (the bare-template-parameter case where
+ `Type.kind == UNEXPOSED`).
+ """
+ decl = t.get_declaration()
+ name = decl.spelling
+ if not name and t.kind == cindex.TypeKind.UNEXPOSED:
+ name = t.spelling
+ return name or None
+
+
+def resolve_logical_base(
+ cursor: cindex.Cursor,
+ participating: set[str],
+ templates: dict[str, list[cindex.Cursor]] | None = None,
+ args_map: dict[str, cindex.Type] | None = None,
+ seen: set | None = None,
+ visited: set[cindex.Cursor] | None = None,
+) -> str | None:
+ """Walk inheritance through templates; return the name of the closest
+ ancestor that is in `participating` (the set of classes the harvest
+ will emit) or `HeapObject`. Returns None when no chain reaches
+ HeapObject.
+
+ Doubles as a discovery predicate: with `participating` empty, the
+ result is HEAP_OBJECT_ROOT (chain exists) or None (no chain), which
+ is exactly the "transitively inherits HeapObject" test that
+ participation filtering uses.
+
+ `visited`, when given, collects every declaration the walk consults.
+ The caller turns those into the depfile: the answer depends on each
+ of them, including on the ones that ended the walk without a hit.
+
+ Algorithm sketch:
+ 1. Walk each CXX_BASE_SPECIFIER of `cursor`.
+ 2. If the base is a bare template parameter (e.g. `: public Super`)
+ bound to a concrete type via `args_map`, substitute and recurse.
+ 3. If the base is HeapObject or a `participating` class, return it.
+ 4. Otherwise, recurse into the base class/template definition with
+ a substitution map built from its template args, taken from the
+ base's canonical type so defaulted arguments are bound too.
+ """
+ if seen is None:
+ seen = set()
+ if templates is None:
+ templates = {}
+ if args_map is None:
+ args_map = {}
+
+ def _visit(c: cindex.Cursor | None) -> None:
+ if visited is not None and c is not None:
+ visited.add(c)
+
+ _visit(cursor)
+ name = cursor.spelling
+ sig = (name, frozenset((k, v.spelling) for k, v in args_map.items() if v))
+ if sig in seen:
+ return None
+ seen.add(sig)
+
+ for child in cursor.get_children():
+ if child.kind != cindex.CursorKind.CXX_BASE_SPECIFIER:
+ continue
+ bt = child.type
+ base_decl = bt.get_declaration()
+ _visit(base_decl)
+ base_decl_name = base_decl.spelling
+ if not base_decl_name and bt.kind == cindex.TypeKind.UNEXPOSED:
+ base_decl_name = bt.spelling
+
+ # (1) Bare template parameter -> substitute.
+ if base_decl_name in args_map:
+ sub = args_map[base_decl_name]
+ if sub is None:
+ continue
+ sub_name = _resolve_type_to_class_name(sub)
+ if sub_name == HEAP_OBJECT_ROOT:
+ return HEAP_OBJECT_ROOT
+ if sub_name in participating:
+ return sub_name
+ sub_def = sub.get_declaration().get_definition() or sub.get_declaration()
+ _visit(sub_def)
+ if sub_def.kind in _CLASS_LIKE:
+ result = resolve_logical_base(sub_def, participating, templates, {},
+ seen, visited)
+ if result is not None:
+ return result
+ continue
+
+ # (2) Direct hit on HeapObject.
+ if base_decl_name == HEAP_OBJECT_ROOT:
+ return HEAP_OBJECT_ROOT
+
+ # (3) Direct hit on a participating class.
+ if base_decl_name in participating:
+ return base_decl_name
+
+ # (4) Walk into the base class/template body.
+ # The canonical type, not the written one: a base spelled
+ # `PrimitiveArrayBase<ByteArray, uint8_t>` names two arguments and
+ # leaves the third, `Super`, at its FixedArrayBase default -- and
+ # that one is the instance-type parent.
+ canonical = bt.get_canonical()
+ nargs = canonical.get_num_template_arguments()
+ template_args = [
+ canonical.get_template_argument_type(i) for i in range(max(0, nargs))
+ ]
+ candidates: list[cindex.Cursor] = []
+ if nargs > 0:
+ candidates.extend(templates.get(base_decl_name, []))
+ for _t in candidates:
+ _visit(_t)
+ base_def = base_decl.get_definition() or base_decl
+ _visit(base_def)
+ if base_def.kind in _CLASS_LIKE:
+ candidates.append(base_def)
+ for cand in candidates:
+ params = _template_params(cand)
+ sub = dict(zip(params, template_args)) if params and template_args \
+ else {}
+ result = resolve_logical_base(cand, participating, templates, sub, seen,
+ visited)
+ if result is not None:
+ return result
+
+ return None
+
+
+def get_base_name(cursor: cindex.Cursor) -> str | None:
+ """Return the (namespace-stripped) name of the first direct base."""
+ for child in cursor.get_children():
+ if child.kind == cindex.CursorKind.CXX_BASE_SPECIFIER:
+ return _strip_ns(child.type.get_declaration().spelling)
+ return None
diff --git a/deps/v8/tools/metagen/harvest-driver.cc b/deps/v8/tools/metagen/harvest-driver.cc
new file mode 100644
index 00000000000..e022c1681fc
--- /dev/null
+++ b/deps/v8/tools/metagen/harvest-driver.cc
@@ -0,0 +1,14 @@
+// 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 translation unit metagen parses. Its include closure is the set of class
+// declarations the harvest can see, so it has to reach every heap object;
+// src/objects/all-objects.h is maintained to do exactly that and PRESUBMIT.py
+// checks it still does. The declaration-only aggregate avoids parsing inline
+// implementations that depend on metagen's not-yet-generated output.
+//
+// A .cc rather than parsing the header directly: clang infers the input
+// language from the extension, and a .h is a C header.
+
+#include "src/objects/all-objects.h"
diff --git a/deps/v8/tools/metagen/instance_types.py b/deps/v8/tools/metagen/instance_types.py
new file mode 100644
index 00000000000..2413dcafbfb
--- /dev/null
+++ b/deps/v8/tools/metagen/instance_types.py
@@ -0,0 +1,536 @@
+# 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.
+"""Instance-type IR, constraint solver, and macro emission.
+
+The solver is a direct port of Torque's
+`src/torque/instance-type-generator.cc`. We mirror its names, control
+flow, data layout, and tie-breaking so the emitted macros are
+comparable against Torque's reference emission (metagen.py --check;
+comment-insensitive since the two generators emit different source
+links).
+
+Takes the flat `ClassInfo` list produced by `cpp_hier`, builds and
+solves the IT tree, and emits:
+
+ - `TORQUE_ASSIGNED_INSTANCE_TYPES` -- FIRST_/LAST_/_TYPE constants
+ - `TORQUE_ASSIGNED_INSTANCE_TYPE_LIST` -- flat list of concrete _TYPEs
+ - `INSTANCE_TYPE_LIST_{SINGLE,MULTIPLE,RANGE}` -- bucket lists that
+ drive auto-emission of `IsX` predicates (instance-type-checker.h),
+ `InstanceTypeTraits` declarations (instance-type-inl.h), and heap
+ snapshot labels (heap-snapshot-generator.cc). The buckets are a
+ pure function of the solved tree; the IT enum is the source of
+ truth. There is no FULLY_DEFINED vs ONLY_DECLARED partition here --
+ that distinction is about whether Torque emits a `TqClass` debug
+ reader, a layout-availability concern owned by Torque.
+ - `HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST` -- the Print/Verify dispatch
+ cases for objects-printer.cc / objects-debug.cc, derived from
+ detected Name##Print / Name##Verify declarations (see
+ emit_dispatch_macro).
+
+Mapped pieces:
+ Torque | Python
+ --------------------------------------|---------------------------
+ InstanceTypeConstraints (constants.h) | InstanceTypeConstraints
+ ClassType (subset) | ClassInfo
+ InstanceTypeTree | InstanceTypeTree
+ BuildInstanceTypeTree | build_instance_type_tree
+ PropagateInstanceTypeConstraints | propagate_constraints
+ SolveInstanceTypeConstraints | solve_constraints
+ CompareUnconstrainedTypes | _unconstrained_sort_key
+ PrintInstanceTypes | emit_enum_macros +
+ emit_bucket_macros
+ GenerateInstanceTypes | (driven by metagen.py)
+"""
+
+from __future__ import annotations
+
+import dataclasses
+import sys
+
+INT_MAX = (1 << 31) - 1
+INT_MIN = -(1 << 31)
+
+
+@dataclasses.dataclass
+class InstanceTypeConstraints:
+ """Matches torque's InstanceTypeConstraints struct (constants.h)."""
+ value: int = -1 # @apiExposedInstanceTypeValue(N)
+ num_flags_bits: int = -1 # @reserveBitsInInstanceType(N)
+
+
+@dataclasses.dataclass
+class ClassInfo:
+ """One class participating in IT generation, with the subset of
+ metadata the solver needs. Field names track Torque's `ClassType` /
+ `InstanceTypeConstraints` so the solver can mirror the C++ logic
+ line-for-line. Populated by the libclang harvest (`cpp_hier.py`)."""
+ name: str
+ base: str | None
+ # Source position -- "file.h:line:col" (1-based). Diagnostics only;
+ # deliberately absent from the emitted output (see the note above
+ # _EnumEmission).
+ position: str
+ is_abstract: bool
+ has_same_instance_type_as_parent: bool
+ highest_within_parent: bool
+ lowest_within_parent: bool
+ constraints: InstanceTypeConstraints
+ # V8_IT_NO_AUTO_CHECKER: omit this class from the checker bucket lists.
+ # The class still participates in enum emission when combined with
+ # V8_IT_OWN_TYPE.
+ no_auto_checker: bool = False
+ # Class declares Name##Print(std::ostream&) / Name##Verify(Isolate*)
+ # (the harvest parses with -DOBJECT_PRINT -DVERIFY_HEAP so DECL_PRINTER
+ # / DECL_VERIFIER expand). Drives the diagnostic-dispatch emission.
+ has_printer: bool = False
+ has_verifier: bool = False
+ # V8_IT_NO_AUTO_DISPATCH: dispatched by a hand-written case in
+ # objects-printer.cc / objects-debug.cc instead of the generated list.
+ no_auto_dispatch: bool = False
+
+
+@dataclasses.dataclass
+class InstanceTypeTree:
+ """Matches torque's InstanceTypeTree struct."""
+ cls: ClassInfo
+ children: list["InstanceTypeTree"] = dataclasses.field(default_factory=list)
+ start: int = INT_MAX
+ end: int = INT_MIN
+ value: int = -1
+ num_values: int = 0
+ num_own_values: int = 0
+
+
+def build_instance_type_tree(
+ classes: list[ClassInfo]) -> InstanceTypeTree | None:
+ """Assemble every ClassType into a single-rooted tree.
+
+ Mirrors Torque's BuildInstanceTypeTree, which walks GlobalContext's
+ type aliases. We walk the scanned ClassInfo list instead. If the
+ scan picked up two classes with the same name we keep the first,
+ matching Torque's "already encountered" check.
+ """
+ by_name: dict[str, InstanceTypeTree] = {}
+ for c in classes:
+ if c.name in by_name:
+ continue
+ by_name[c.name] = InstanceTypeTree(cls=c)
+
+ root: InstanceTypeTree | None = None
+ for node in by_name.values():
+ parent_name = node.cls.base
+ parent = by_name.get(parent_name) if parent_name else None
+ # Torque's GetSuperClass returns nullptr for non-class parents
+ # (type aliases like StrongTagged). Treat unknown names the same
+ # way -- the node becomes a root candidate.
+ if parent is None:
+ if root is not None:
+ print(
+ f"[itypes] error: multiple roots: {root.cls.name} "
+ f"({root.cls.position}) and {node.cls.name} "
+ f"({node.cls.position}). The second class would be silently "
+ f"dropped from IT generation; check that its base class is "
+ f"reachable in the participating set.",
+ file=sys.stderr)
+ sys.exit(1)
+ root = node
+ else:
+ parent.children.append(node)
+ return root
+
+
+def propagate_constraints(root: InstanceTypeTree) -> None:
+ """Port of PropagateInstanceTypeConstraints.
+
+ Post-order walk: child ranges roll up into parent start/end/num_values,
+ then the root's own constraints are applied on top.
+ """
+ for child in root.children:
+ propagate_constraints(child)
+ if child.start < root.start:
+ root.start = child.start
+ if child.end > root.end:
+ root.end = child.end
+ root.num_values += child.num_values
+
+ constraints = root.cls.constraints
+ if not root.cls.is_abstract and not root.cls.has_same_instance_type_as_parent:
+ root.num_own_values = 1
+ root.num_values += root.num_own_values
+
+ if constraints.num_flags_bits != -1:
+ # Flag-class: subclasses share its bits, don't get their own values.
+ root.children.clear()
+ root.num_values = 1 << constraints.num_flags_bits
+ root.num_own_values = root.num_values
+ root.start = 0
+ root.end = root.num_values - 1
+
+ if constraints.value != -1:
+ if root.num_own_values != 1:
+ print(
+ f"[itypes] error: explicit instance-type value on "
+ f"abstract class {root.cls.name}",
+ file=sys.stderr)
+ sys.exit(1)
+ root.value = constraints.value
+ if constraints.value < root.start:
+ root.start = constraints.value
+ if constraints.value > root.end:
+ root.end = constraints.value
+
+
+def _select_own_values(root: InstanceTypeTree, start_value: int) -> int:
+ """Port of SelectOwnValues."""
+ if root.value == -1:
+ root.value = start_value
+ elif root.value < start_value:
+ print(
+ f"[itypes] error: failed to assign instance type "
+ f"{root.value} to {root.cls.name} (start={start_value}) "
+ f"({root.cls.position})",
+ file=sys.stderr)
+ sys.exit(1)
+ return root.value + root.num_own_values
+
+
+def _unconstrained_sort_key(node: InstanceTypeTree) -> tuple:
+ """Port of CompareUnconstrainedTypes.
+
+ Torque sorts DESCENDING by num_values, then ASCENDING by name.
+ Python's sort key is naturally ascending, so invert num_values.
+ """
+ return (-node.num_values, node.cls.name)
+
+
+def solve_constraints(
+ root: InstanceTypeTree,
+ start_value: int,
+ destination: list[InstanceTypeTree],
+) -> int:
+ """Port of SolveInstanceTypeConstraints."""
+ if root.start < start_value:
+ print(
+ f"[itypes] error: failed to assign instance type "
+ f"{root.start} to {root.cls.name} (start={start_value}) "
+ f"({root.cls.position})",
+ file=sys.stderr)
+ sys.exit(1)
+
+ # Split children into four buckets, matching Torque exactly.
+ lowest_child: InstanceTypeTree | None = None
+ highest_child: InstanceTypeTree | None = None
+ # Torque's std::multimap<int, ...> keeps insertion order among
+ # equal keys but sorts by key ascending. Python sorting is stable,
+ # so we collect then sort by start.
+ constrained_children: list[InstanceTypeTree] = []
+ # Torque's std::map<ITT*, ..., CompareUnconstrainedTypes> keeps keys
+ # in descending-num_values / ascending-name order. We sort
+ # explicitly below.
+ unconstrained_children: list[InstanceTypeTree] = []
+
+ for child in root.children:
+ if child.cls.highest_within_parent:
+ if highest_child is not None:
+ print(
+ f"[itypes] error: two highest children of "
+ f"{root.cls.name}: {highest_child.cls.name}, "
+ f"{child.cls.name}",
+ file=sys.stderr)
+ sys.exit(1)
+ if child.cls.lowest_within_parent:
+ print(
+ f"[itypes] error: class both highest and lowest: "
+ f"{child.cls.name}",
+ file=sys.stderr)
+ sys.exit(1)
+ highest_child = child
+ elif child.cls.lowest_within_parent:
+ if lowest_child is not None:
+ print(
+ f"[itypes] error: two lowest children of "
+ f"{root.cls.name}: {lowest_child.cls.name}, "
+ f"{child.cls.name}",
+ file=sys.stderr)
+ sys.exit(1)
+ lowest_child = child
+ elif child.start > child.end:
+ unconstrained_children.append(child)
+ else:
+ constrained_children.append(child)
+ root.children = []
+
+ constrained_children.sort(key=lambda n: n.start)
+ unconstrained_children.sort(key=_unconstrained_sort_key)
+
+ own_type_pending = root.num_own_values > 0
+
+ if lowest_child is not None:
+ start_value = solve_constraints(lowest_child, start_value, root.children)
+
+ for constrained in constrained_children:
+ # Try placing own type before the constrained child.
+ if own_type_pending:
+ fits_before = ((root.value != -1 and root.value < constrained.start) or
+ (root.value == -1 and
+ start_value + root.num_own_values <= constrained.start))
+ if fits_before:
+ start_value = _select_own_values(root, start_value)
+ own_type_pending = False
+
+ # Greedy: biggest unconstrained first, as long as it fits.
+ remaining: list[InstanceTypeTree] = []
+ for uc in unconstrained_children:
+ if uc.num_values + start_value <= constrained.start:
+ start_value = solve_constraints(uc, start_value, root.children)
+ else:
+ remaining.append(uc)
+ unconstrained_children = remaining
+
+ start_value = solve_constraints(constrained, start_value, root.children)
+
+ if own_type_pending:
+ start_value = _select_own_values(root, start_value)
+ own_type_pending = False
+
+ for uc in unconstrained_children:
+ start_value = solve_constraints(uc, start_value, root.children)
+
+ if highest_child is not None:
+ start_value = solve_constraints(highest_child, start_value, root.children)
+
+ root.end = start_value - 1
+ root.start = start_value if not root.children else root.children[0].start
+ if root.value != -1 and root.value < root.start:
+ root.start = root.value
+ root.num_values = root.end - root.start + 1
+
+ if root.num_values > 0:
+ destination.append(root)
+ return start_value
+
+
+def assign_instance_types(classes: list[ClassInfo]) -> InstanceTypeTree | None:
+ """Top-level entry point. Matches torque's AssignInstanceTypes."""
+ root = build_instance_type_tree(classes)
+ if root is None:
+ return None
+ propagate_constraints(root)
+ destination: list[InstanceTypeTree] = []
+ solve_constraints(root, 0, destination)
+ return destination[0] if destination else None
+
+
+# ---------------------------------------------------------------------------
+# Output emission (matches src/torque/instance-type-generator.cc
+# PrintInstanceTypes + GenerateInstanceTypes).
+# ---------------------------------------------------------------------------
+
+
+def capify_with_underscores(s: str) -> str:
+ """Port of src/torque/utils.cc CapifyStringWithUnderscores."""
+ result: list[str] = []
+ js_position = s.find("JS")
+ previous_was_lower_or_digit = False
+ for index, current in enumerate(s):
+ if ((previous_was_lower_or_digit and current.isupper()) or
+ (js_position != -1 and index == js_position + 2)):
+ result.append("_")
+ if current in (".", "-"):
+ result.append("_")
+ previous_was_lower_or_digit = False
+ continue
+ result.append(current.upper())
+ previous_was_lower_or_digit = current.islower() or current.isdigit()
+ return "".join(result)
+
+
+# Emission carries NO source-position comments (Torque's emission has
+# them): instance-types.h sits in the near-global include set, and
+# position-bearing comments would change its contents (and thus rebuild
+# the world, past the write-if-changed check) on every line shift in
+# any harvested header.
+
+
+@dataclasses.dataclass
+class _EnumEmission:
+ assigned_types: str = "" # TORQUE_ASSIGNED_INSTANCE_TYPES body
+ values_list: str = "" # TORQUE_ASSIGNED_INSTANCE_TYPE_LIST body
+
+
+def _emit_enum_walk(
+ root: InstanceTypeTree,
+ indent: str,
+ out: _EnumEmission,
+) -> None:
+ type_name = capify_with_underscores(root.cls.name) + "_TYPE"
+ inner_indent = indent
+
+ # Every type gets FIRST_/LAST_ range markers, aliasing the sole value
+ # for single-instance-type classes. Generated CSA references the range
+ # markers unconditionally (Torque's GetClassInstanceTypeRange), so the
+ # single-vs-range decision in DownCastForTorqueClass is made against
+ # this header's values at C++ compile time instead of being baked in
+ # at Torque codegen time from Torque's own (possibly divergent) tree.
+ out.assigned_types += f"{indent}V(FIRST_{type_name}, {root.start}) \\\n"
+ if root.num_values > 1:
+ inner_indent += " "
+ if root.num_own_values == 1:
+ out.assigned_types += f"{inner_indent}V({type_name}, {root.value}) \\\n"
+ out.values_list += f" V({type_name}) \\\n"
+
+ for child in root.children:
+ _emit_enum_walk(child, inner_indent, out)
+
+ # LAST_* marker is omitted for flag types (num_own_values > 1 means
+ # @reserveBitsInInstanceType(N) is active).
+ if root.num_own_values <= 1:
+ out.assigned_types += f"{indent}V(LAST_{type_name}, {root.end}) \\\n"
+
+
+def emit_enum_macros(root: InstanceTypeTree | None) -> str:
+ """Emit the IT enum macro definitions
+ (TORQUE_ASSIGNED_INSTANCE_TYPES, TORQUE_ASSIGNED_INSTANCE_TYPE_LIST)
+ as a single string ending with a trailing blank line.
+ """
+ e = _EnumEmission()
+ if root is not None:
+ _emit_enum_walk(root, " ", e)
+
+ lines: list[str] = []
+ lines.append("// Instance types for all classes except for those that use "
+ "InstanceType as flags.")
+ lines.append("#define TORQUE_ASSIGNED_INSTANCE_TYPES(V) \\")
+ lines.append(e.assigned_types.rstrip("\n"))
+ lines.append("")
+
+ lines.append("// Instance types for all classes except for those that use")
+ lines.append("// InstanceType as flags.")
+ lines.append("#define TORQUE_ASSIGNED_INSTANCE_TYPE_LIST(V) \\")
+ lines.append(e.values_list.rstrip("\n"))
+ lines.append("")
+ return "\n".join(lines) + "\n"
+
+
+# ---------------------------------------------------------------------------
+# Bucket emission for auto-generated instance-type consumers.
+#
+# Bucket placement signal: SINGLE vs MULTIPLE vs RANGE, derived from
+# the tree's `num_values` and `num_own_values`:
+# - num_own_values == 1 and num_values == 1: SINGLE
+# - num_own_values == 1 and num_values > 1: MULTIPLE
+# - num_own_values == 0 and num_values > 1: RANGE
+# ---------------------------------------------------------------------------
+
+
+@dataclasses.dataclass
+class _BucketsEmission:
+ single: str = ""
+ multiple: str = ""
+ range_: str = ""
+
+
+def _emit_buckets_walk(
+ root: InstanceTypeTree,
+ out: _BucketsEmission,
+ is_root: bool = False,
+) -> None:
+ type_name = capify_with_underscores(root.cls.name) + "_TYPE"
+
+ if root.num_own_values == 1 and not root.cls.no_auto_checker:
+ line = f" V({root.cls.name}, {type_name}) \\\n"
+ if root.num_values == 1:
+ out.single += line
+ else:
+ out.multiple += line
+
+ for child in root.children:
+ _emit_buckets_walk(child, out)
+
+ if root.num_values > 1 and not root.cls.no_auto_checker:
+ # Matches torque's check: "if root->type->GetSuperClass() != nullptr".
+ # We approximate GetSuperClass() returning non-null with "not the
+ # tree root" (the tree root's GetSuperClass is nullptr). Emitted
+ # for flag classes (num_own_values > 1) too -- the range macro
+ # gets a {FIRST,LAST}_<NAME>_TYPE pair even though the assigned-
+ # types macro omits the explicit LAST_<NAME>_TYPE in that case.
+ if not is_root:
+ out.range_ += (f" V({root.cls.name}, FIRST_{type_name}, "
+ f"LAST_{type_name}) \\\n")
+
+
+def emit_bucket_macros(root: InstanceTypeTree | None) -> str:
+ """Emit the bucket macro definitions as a single string ending
+ with a trailing blank line."""
+ e = _BucketsEmission()
+ if root is not None:
+ _emit_buckets_walk(root, e, is_root=True)
+
+ lines: list[str] = []
+
+ def block(label_comment: list[str], macro: str, body: str) -> None:
+ for lc in label_comment:
+ lines.append(lc)
+ lines.append(f"#define {macro}(V) \\")
+ lines.append(body.rstrip("\n"))
+ lines.append("")
+
+ block([
+ "// Pairs of (ClassName, INSTANCE_TYPE) for classes whose instance",
+ "// type is unique to them (no subclasses share it)."
+ ], "INSTANCE_TYPE_LIST_SINGLE", e.single)
+ block([
+ "// Pairs of (ClassName, INSTANCE_TYPE) for classes that have their",
+ "// own instance type and whose subclasses share that instance type",
+ "// (e.g. JSObject owns JS_OBJECT_TYPE; concrete leaves with the",
+ "// same IT are entered via INSTANCE_TYPE_LIST_SINGLE)."
+ ], "INSTANCE_TYPE_LIST_MULTIPLE", e.multiple)
+ block([
+ "// Triples of (ClassName, FIRST_TYPE, LAST_TYPE) for classes that",
+ "// span a contiguous range of instance types (typically abstract",
+ "// intermediates whose concrete subclasses get their own ITs)."
+ ], "INSTANCE_TYPE_LIST_RANGE", e.range_)
+
+ return "\n".join(lines) + "\n"
+
+
+def _emit_dispatch_walk(root: InstanceTypeTree, out: list[str]) -> None:
+ if (root.num_own_values == 1 and root.cls.has_printer and
+ root.cls.has_verifier and not root.cls.no_auto_dispatch):
+ type_name = capify_with_underscores(root.cls.name) + "_TYPE"
+ out.append(f" V({root.cls.name}, {type_name}) \\\n")
+ for child in root.children:
+ _emit_dispatch_walk(child, out)
+
+
+def emit_dispatch_macro(root: InstanceTypeTree | None) -> str:
+ """Emit HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST: pairs of
+ (ClassName, INSTANCE_TYPE) for the switches in
+ HeapObject::HeapObjectPrint (objects-printer.cc) and
+ HeapObject::HeapObjectVerify (objects-debug.cc).
+
+ A class is included iff it has its own instance-type value and
+ declares both Name##Print(std::ostream&) and Name##Verify(Isolate*)
+ (typically via DECL_PRINTER / DECL_VERIFIER), unless it carries
+ V8_IT_NO_AUTO_DISPATCH -- those classes are dispatched by
+ hand-written cases in the two switches, and a generated entry would
+ produce a duplicate case label.
+ """
+ entries: list[str] = []
+ if root is not None:
+ _emit_dispatch_walk(root, entries)
+
+ lines: list[str] = []
+ lines.append("// Pairs of (ClassName, INSTANCE_TYPE) for the HeapObject")
+ lines.append("// diagnostic dispatch: the switches in "
+ "HeapObject::HeapObjectPrint")
+ lines.append("// (objects-printer.cc) and HeapObject::HeapObjectVerify")
+ lines.append("// (objects-debug.cc). Included iff the class has its own")
+ lines.append("// instance-type value, declares both Name##Print and")
+ lines.append("// Name##Verify, and does not carry V8_IT_NO_AUTO_DISPATCH")
+ lines.append("// (hand-written dispatch cases).")
+ lines.append("#define HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST(V) \\")
+ lines.append("".join(entries).rstrip("\n"))
+ lines.append("")
+ return "\n".join(lines) + "\n"
diff --git a/deps/v8/tools/metagen/metagen.py b/deps/v8/tools/metagen/metagen.py
new file mode 100644
index 00000000000..bfc590af918
--- /dev/null
+++ b/deps/v8/tools/metagen/metagen.py
@@ -0,0 +1,510 @@
+#!/usr/bin/env python3
+# 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.
+"""Entry point for metagen instance-type generation.
+
+Drives a libclang harvest of V8_OBJECT / V8_IT_-annotated C++ class
+declarations and emits `instance-types.h`. One invocation per build
+dir; ninja calls us from `tools/metagen/BUILD.gn`.
+
+Layout-mode generation (`extern class Foo extends ...` Torque emission
+from the same C++ headers) is a follow-up; the prototype lives on the
+stacked `metagen-layout` branch and is not part of this CL.
+"""
+
+from __future__ import annotations
+
+import argparse
+import os
+import sys
+
+if __name__ == "__main__":
+ # Running this file as a script -- ninja runs `python3
+ # tools/metagen/metagen.py`, Bazel's launcher execs it out of the
+ # runfiles tree -- puts tools/metagen/ on sys.path, not its parent, so
+ # the `metagen` package is not importable yet.
+ _PARENT = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+ if _PARENT not in sys.path:
+ sys.path.insert(0, _PARENT)
+
+# Don't import cpp_hier yet -- it pulls in clang.cindex at module-load
+# time, which requires the bindings to be resolvable. We bootstrap that
+# in main() once the flags say where they come from.
+from metagen import compile_flags # noqa: E402
+from metagen import instance_types as it # noqa: E402
+
+
+def _write_depfile(depfile: str, output: str, deps: list[str]) -> None:
+ """Write a ninja depfile recording `deps` as inputs of `output`.
+
+ The parse's inputs are not declared as action inputs -- the build
+ file declares only the driver -- so this is what ties the output to
+ the headers it was derived from.
+
+ Paths are written relative to the process's cwd, which ninja sets to
+ the build dir -- the directory it also resolves depfile paths
+ against. Spaces are escaped; ninja's depfile parser treats an
+ unescaped one as a separator.
+ """
+
+ def rel(p: str) -> str:
+ return os.path.relpath(p).replace(" ", "\\ ")
+
+ os.makedirs(os.path.dirname(os.path.abspath(depfile)) or ".", exist_ok=True)
+ body = " \\\n ".join(rel(d) for d in deps)
+ with open(depfile, "w") as f:
+ f.write(f"{rel(output)}: \\\n {body}\n" if deps else f"{rel(output)}:\n")
+
+
+_THIS_DIR = os.path.dirname(os.path.abspath(__file__))
+_DEFAULT_V8_ROOT = os.path.abspath(
+ os.path.join(_THIS_DIR, os.pardir, os.pardir))
+
+
+def main() -> int:
+ p = argparse.ArgumentParser()
+ p.add_argument("--v8-root", default=_DEFAULT_V8_ROOT)
+ p.add_argument(
+ "--libclang-dir",
+ default=None,
+ help="Absolute or build-dir-relative path to the llvm-libclang "
+ "package root (the dir containing bindings/python/ and "
+ "lib/libclang.so -- i.e. .../third_party/llvm-libclang/). The GN "
+ "and standalone-Bazel actions resolve and pass this; DEPS "
+ "guarantees the package is present, so metagen does not search "
+ "for it. Mutually exclusive with --libclang-from-python-env.")
+ p.add_argument(
+ "--libclang-from-python-env",
+ action="store_true",
+ help="Take clang.cindex from the Python environment instead, for "
+ "build systems whose dependency graph supplies a self-configuring "
+ "bindings module (it loads its own native libclang, so there is no "
+ "path to pass). Opt-in on purpose: metagen never falls back to an "
+ "ambient module just because --libclang-dir was omitted.")
+ p.add_argument(
+ "--libclang-so",
+ default=None,
+ help="Absolute path to a native libclang shared library, for "
+ "platforms with no prebuilt llvm-libclang package.")
+ p.add_argument(
+ "--libclang-bindings-dir",
+ default=None,
+ help="Absolute path to the directory holding the clang.cindex "
+ "bindings (the dir that contains clang/cindex.py). Required with, and "
+ "only valid with, --libclang-so; the caller version-matches the two.")
+ p.add_argument(
+ "--expect-libclang-major",
+ default=None,
+ type=int,
+ help="Clang toolchain major version (GN's clang_version). Used with "
+ "--libclang-so to warn if the loaded libclang is older than the "
+ "toolchain whose builtin headers metagen parses against.")
+ p.add_argument(
+ "--clang-resource-dir",
+ default=None,
+ help="Path to the clang toolchain's resource dir (lib/clang/<N>, "
+ "the directory whose include/ holds stddef.h, stdarg.h and the arch "
+ "intrinsics). Passed to the parse as -resource-dir=, which lets the "
+ "driver order the builtin headers itself. Preferred over "
+ "--clang-builtin-headers-dir wherever the canonical layout exists. "
+ "Mutually exclusive with it.")
+ p.add_argument(
+ "--clang-builtin-headers-dir",
+ default=None,
+ help="Directory holding the clang builtin headers, for build systems "
+ "that stage them flat, with no lib/clang/<N> hierarchy for "
+ "-resource-dir= to point at (Bazel). Appended as a system-include dir "
+ "instead, which takes the path directly. Never probed for: the build "
+ "system knows where it staged them, and in a sandbox any path we "
+ "guessed would be an undeclared input. Mutually exclusive with "
+ "--clang-resource-dir.")
+ p.add_argument(
+ "--driver",
+ required=True,
+ help="Path to the checked-in C++ driver whose active direct includes "
+ "are harvested.")
+ p.add_argument(
+ "--out",
+ required=True,
+ help="Directory to write instance-types.h into. The only "
+ "directory metagen writes to.")
+ p.add_argument(
+ "--depfile",
+ default=None,
+ help="Path to write a ninja depfile recording the files the "
+ "harvest read a class declaration, base or marker definition out "
+ "of. Only the driver is a declared build input, so without this "
+ "an edit to one of them leaves the output stale.")
+ # TODO(jgruber): Remove --check once metagen is the sole IT source and the
+ # Torque reference path (v8_use_metagen_instance_types=false) is gone.
+ p.add_argument(
+ "--check",
+ action="store_true",
+ help="Diff against the reference instance-types.h under "
+ "out/x64.optdebug/gen/torque-generated/ and exit non-zero on "
+ "mismatch. Comment-insensitive: the position comments point at "
+ "C++ headers here but at .tq sources in Torque's emission.")
+ p.add_argument(
+ "--build-dir",
+ default=None,
+ help="Path to a configured V8 build dir (out/<config>). The tool "
+ "runs `gn desc` against it (see --flags-from-target) to harvest the "
+ "cflags clang uses for that target. Mutually exclusive with "
+ "--compile-commands.")
+ p.add_argument(
+ "--source-root",
+ default=None,
+ help="GN source root (the directory containing the build's .gn file). "
+ "Required with --build-dir.")
+ p.add_argument(
+ "--flags-from-target",
+ default=None,
+ help="GN label of a representative compiled target whose flags "
+ "`gn desc` reports (e.g. //v8:v8_base_without_compiler). Required "
+ "with --build-dir.")
+ p.add_argument(
+ "--flags-toolchain",
+ default=None,
+ help="GN label of the toolchain to resolve --flags-from-target in "
+ "(e.g. //build/toolchain/linux:clang_x64). Defaults to the build's "
+ "default toolchain, which is only right when the action and the "
+ "target it queries share it.")
+ p.add_argument(
+ "--flags-dependency",
+ default=None,
+ help="File materializing the GN target flags, recorded in --depfile "
+ "so a flag change reruns metagen. Required with --build-dir when "
+ "--depfile is used.")
+ p.add_argument(
+ "--extra-flag",
+ action="append",
+ default=[],
+ metavar="FLAG",
+ help="A parse flag the build system supplies outside the target's "
+ "cflags, repeatable. Windows: the SDK/UCRT include flags, which the "
+ "toolchain interpolates into its tool command template rather than "
+ "into cflags, so `gn desc` never reports them.")
+ p.add_argument(
+ "-v", "--verbose", action="store_true", help="Enable verbose logging.")
+ p.add_argument(
+ "--compile-commands",
+ default=None,
+ help="Path to a compile_commands.json the build system already "
+ "wrote (Bazel emits one synthesized via cc_common). Same shape "
+ "as compile_commands.json. Mutually exclusive with --build-dir.")
+ args = p.parse_args()
+
+ def verbose_print(msg: str) -> None:
+ if args.verbose:
+ print(msg, file=sys.stderr)
+
+ v8_root = os.path.abspath(args.v8_root)
+
+ # Deep V8 class hierarchies (js-objects.h et al.) overflow the
+ # libclang ctypes visitor's default recursion budget. Cheap and
+ # global; bump before any traversal, and before the bootstrap so it
+ # applies whichever mode supplies the bindings.
+ sys.setrecursionlimit(max(sys.getrecursionlimit(), 20000))
+
+ _modes = [
+ bool(args.libclang_dir),
+ bool(args.libclang_from_python_env),
+ bool(args.libclang_so)
+ ]
+ if sum(_modes) != 1:
+ print(
+ "error: exactly one of --libclang-dir, "
+ "--libclang-from-python-env or --libclang-so is required.",
+ file=sys.stderr)
+ return 1
+ # A matched pair: one without the other is always a misconfiguration.
+ if bool(args.libclang_so) != bool(args.libclang_bindings_dir):
+ print(
+ "error: --libclang-so and --libclang-bindings-dir must be given "
+ "together.",
+ file=sys.stderr)
+ return 1
+
+ # Bootstrap libclang *before* importing cpp_hier -- it references
+ # clang.cindex at module-load time.
+ from metagen import clang_bootstrap # noqa: E402
+ if args.libclang_from_python_env:
+ clang_bootstrap.bootstrap_from_python_env()
+ elif args.libclang_so:
+ clang_bootstrap.bootstrap_native(
+ native_so=os.path.abspath(args.libclang_so),
+ bindings_dir=os.path.abspath(args.libclang_bindings_dir),
+ expect_major=args.expect_libclang_major)
+ else:
+ # GN and Bazel rebase the path against the build root before passing
+ # it, so a relative value is relative to the current working
+ # directory (which ninja/bazel set to the build root).
+ # `os.path.abspath` honors that.
+ clang_bootstrap.bootstrap(libclang_dir=os.path.abspath(args.libclang_dir))
+ from metagen import cpp_hier # noqa: E402
+
+ if bool(args.build_dir) == bool(args.compile_commands):
+ print(
+ "error: exactly one of --build-dir or --compile-commands is "
+ "required.",
+ file=sys.stderr)
+ return 1
+ if bool(args.build_dir) != bool(args.source_root):
+ print(
+ "error: --build-dir and --source-root must be given together.",
+ file=sys.stderr)
+ return 1
+
+ driver_path = os.path.abspath(args.driver)
+
+ if args.build_dir:
+ if not args.flags_from_target:
+ print(
+ "error: --flags-from-target is required with --build-dir.",
+ file=sys.stderr)
+ return 1
+ build_dir = os.path.abspath(args.build_dir)
+ flags_target = args.flags_from_target
+ if args.flags_toolchain:
+ flags_target = f"{flags_target}({args.flags_toolchain})"
+ raw_flags, parse_cwd, cl_mode = compile_flags.get_compile_args_from_gn_desc(
+ build_dir, flags_target, os.path.abspath(args.source_root))
+ flags_source = f"build_dir={build_dir} (gn desc {flags_target})"
+ else:
+ cc_json = os.path.abspath(args.compile_commands)
+ raw_flags, parse_cwd, cl_mode = compile_flags.get_compile_args_from_file(
+ cc_json)
+ flags_source = f"compile_commands={cc_json}"
+
+ flags_dependency = None
+ if args.flags_dependency:
+ if not args.build_dir:
+ print("error: --flags-dependency requires --build-dir.", file=sys.stderr)
+ return 1
+ flags_dependency = os.path.abspath(args.flags_dependency)
+ if not os.path.isfile(flags_dependency):
+ print(
+ f"error: --flags-dependency does not exist: {flags_dependency}",
+ file=sys.stderr)
+ return 1
+ elif args.build_dir and args.depfile:
+ print(
+ "error: --flags-dependency is required with --build-dir and "
+ "--depfile.",
+ file=sys.stderr)
+ return 1
+
+ # Builtin headers (stddef.h etc.). llvm-libclang ships only the .so and
+ # bindings, so its own resource dir has no headers in it. We take them
+ # from the clang toolchain package instead, which rolls from the same
+ # LLVM revision and so always matches the parsing library.
+ if bool(args.clang_resource_dir) == bool(args.clang_builtin_headers_dir):
+ print(
+ "error: exactly one of --clang-resource-dir or "
+ "--clang-builtin-headers-dir is required.",
+ file=sys.stderr)
+ return 1
+ resource_dir = None
+ builtin_headers_dir = None
+ if args.clang_resource_dir:
+ resource_dir = os.path.abspath(args.clang_resource_dir)
+ flag = "--clang-resource-dir"
+ probe = os.path.join(resource_dir, "include", "stddef.h")
+ else:
+ builtin_headers_dir = os.path.abspath(args.clang_builtin_headers_dir)
+ flag = "--clang-builtin-headers-dir"
+ probe = os.path.join(builtin_headers_dir, "stddef.h")
+ if not os.path.isfile(probe):
+ print(
+ f"[metagen] {flag} does not hold clang's builtin headers:\n"
+ f" {probe} not found",
+ file=sys.stderr)
+ return 1
+ # -fsyntax-only, -ferror-limit=, -resource-dir= and -D carry `CLOption`
+ # visibility in clang's Options.td, so one spelling works under both
+ # drivers. -isystem does NOT: the clang-cl driver drops it with an
+ # ignorable -Wunknown-argument warning, and the parse then fails on the
+ # first intrinsics header. Its cl-mode equivalent is -imsvc.
+ sysinclude = "-imsvc" if cl_mode else "-isystem"
+
+ prefix = [
+ "-fsyntax-only",
+ # The harvest aborts on the first error either way, so this buys
+ # nothing but diagnostics: uncapped, a failure we cannot reproduce
+ # locally reports every error in one bot log rather than the first
+ # 19 and a "too many errors emitted". Note the `/clang:` forward
+ # form is silently dropped by libclang in cl-mode (the default cap
+ # still fires); the bare form works.
+ "-ferror-limit=0",
+ # A sanitizer build's -fsanitize= flags are kept, so that
+ # __has_feature() agrees with the -D_LIBCPP_INSTRUMENTED_WITH_*
+ # the same build passes. Their ignore lists are not: clang looks for
+ # the implicit ones in the resource dir, where we'd either find
+ # nothing or read files this action never declared.
+ "-fno-sanitize-ignorelist",
+ # Tell src/objects/instance-type.h to skip its file-scope
+ # references to IT symbols metagen hasn't emitted yet. See the
+ # guards there.
+ "-DV8_METAGEN_GENERATION_PASS",
+ # Make DECL_PRINTER / DECL_VERIFIER expand to declarations in
+ # every config (release builds define neither), so the harvest
+ # can detect Name##Print / Name##Verify and the emitted
+ # diagnostic-dispatch list is config-independent.
+ "-DOBJECT_PRINT",
+ "-DVERIFY_HEAP",
+ ]
+ if cl_mode:
+ prefix.insert(0, "--driver-mode=cl")
+
+ # Tracing declares nothing the harvest reads, but all-objects.h reaches
+ # src/tracing/trace-event.h, whose perfetto path pulls in generated protos
+ # (perfetto is on in Chromium builds). Taking the non-perfetto path instead
+ # of ordering the action after protoc keeps the harvest at the front of the
+ # build; the harvested set is the same either way. These have to follow the
+ # queried flags to override the -D they carry, and the SDK and JSON-export
+ # defines go with it because v8config.h requires them to imply
+ # V8_USE_PERFETTO.
+ no_perfetto = [
+ "-UV8_USE_PERFETTO",
+ "-UV8_USE_PERFETTO_JSON_EXPORT",
+ "-UV8_USE_PERFETTO_SDK",
+ ]
+
+ # --extra-flag goes ahead of the queried flags, matching where the
+ # toolchain's command template puts them.
+ flags = prefix + args.extra_flag + raw_flags + no_perfetto
+
+ # The builtin headers have to sit after libc++'s include dir and before
+ # the platform SDK's.
+ #
+ # -resource-dir= lets the driver place them, and it gets that right in
+ # both modes, so prefer it. That relies on libc++ arriving as -I, since
+ # the driver sorts -imsvc dirs after the resource dir. Only a flat
+ # staging dir needs the include-dir spelling, which we append: right for
+ # libc++, and right on Windows only while the SDK dirs arrive as
+ # /winsysroot.
+ if resource_dir:
+ flags.append(f"-resource-dir={resource_dir}")
+ else:
+ flags.append(f"{sysinclude}{builtin_headers_dir}")
+
+ verbose_print(f"Harvesting class hierarchy from "
+ f"{os.path.relpath(driver_path, v8_root)} ({flags_source})...")
+ out_dir = os.path.abspath(args.out)
+ os.makedirs(out_dir, exist_ok=True)
+ path = os.path.join(out_dir, "instance-types.h")
+
+ cpp_res = cpp_hier.scan_cpp(v8_root, driver_path, flags, parse_cwd=parse_cwd)
+ verbose_print(f" {len(cpp_res.classes)} classes, "
+ f"{len(cpp_res.provenance)} provenance files (from C++)")
+ classes = cpp_res.classes
+
+ # The files the harvest read a fact out of, not everything the parse
+ # opened. The closure is ~17x larger and mostly the inline layer and
+ # the sysroot, none of which can move a class head; depending on it
+ # would put the harvest on the critical path of edits that cannot
+ # change its output. Provenance is derived from the walk rather than
+ # filtered by hand, so it stays correct when a declaration moves --
+ # and once metagen emits object layout, field types become one more
+ # provenance source rather than a reason to widen the whole set.
+ #
+ # Written ahead of the write-if-changed check below: ninja requires
+ # the depfile to exist after the action runs, including on the run
+ # that leaves the output untouched. --check writes no output, so a
+ # depfile naming one would be meaningless.
+ if args.depfile and not args.check:
+ deps = cpp_res.provenance
+ if flags_dependency:
+ deps = deps + [flags_dependency]
+ _write_depfile(args.depfile, path, deps)
+
+ # Solve the IT tree and emit instance-types.h: the IT enum macros,
+ # the bucket lists that drive auto-emission of IsX predicates /
+ # InstanceTypeTraits / heap snapshot labels, and the Print/Verify
+ # dispatch list.
+ tree = it.assign_instance_types(classes)
+ generated = ("#ifndef V8_GEN_TORQUE_GENERATED_INSTANCE_TYPES_H_\n"
+ "#define V8_GEN_TORQUE_GENERATED_INSTANCE_TYPES_H_\n"
+ "\n" + it.emit_enum_macros(tree) + it.emit_bucket_macros(tree) +
+ it.emit_dispatch_macro(tree) +
+ "#endif // V8_GEN_TORQUE_GENERATED_INSTANCE_TYPES_H_\n")
+
+ if args.check:
+ import difflib
+ import re
+
+ def normalize(text: str) -> list[str]:
+ # Comment-insensitive comparison: /* ... */ position comments
+ # legitimately differ (C++ header links here, .tq links in
+ # Torque's emission), as do // prose comments and the include
+ # guard / V8_USE_METAGEN_INSTANCE_TYPES scaffolding around the macro
+ # blocks. The diagnostic-dispatch list is also skipped: it has no
+ # literal counterpart in Torque's emission (the torque path
+ # aliases it to the debug-reader lists, see
+ # src/objects/instance-types-gen.h). Only the remaining macro
+ # definitions must match.
+ scaffold = re.compile(r"^#(ifndef V8_GEN_TORQUE_GENERATED_"
+ r"|define V8_GEN_TORQUE_GENERATED_"
+ r"|endif|if !V8_USE_METAGEN_INSTANCE_TYPES)")
+ out: list[str] = []
+ in_dispatch = False
+ for ln in text.splitlines():
+ if ln.startswith("#define HEAP_OBJECT_DIAGNOSTIC_DISPATCH_LIST"):
+ in_dispatch = True
+ continue
+ if in_dispatch:
+ # The block is the define plus `V(...) \` continuation lines.
+ if not ln.rstrip().endswith("\\"):
+ in_dispatch = False
+ continue
+ if scaffold.match(ln) or ln.lstrip().startswith("//"):
+ continue
+ ln = re.sub(r" +", " ", re.sub(r"/\*.*?\*/", "", ln)).rstrip()
+ if ln:
+ out.append(ln + "\n")
+ return out
+
+ # The torque path splits its emission: the IT enum lands in
+ # instance-types.h, the bucket lists in
+ # instance-type-checker-lists.h. metagen emits both into one file,
+ # in the same order.
+ ref_dir = os.path.join(v8_root, "out/x64.optdebug/gen/torque-generated")
+ reference: list[str] = []
+ for ref_name in ("instance-types.h", "instance-type-checker-lists.h"):
+ ref_path = os.path.join(ref_dir, ref_name)
+ if not os.path.exists(ref_path):
+ print(f"[check] reference not found: {ref_path}", file=sys.stderr)
+ return 2
+ with open(ref_path) as f:
+ reference += normalize(f.read())
+ generated_normalized = normalize(generated)
+ if generated_normalized == reference:
+ print("[ok] instance-types.h matches reference", file=sys.stderr)
+ return 0
+ print("[diff] instance-types.h differs from reference", file=sys.stderr)
+ for line in difflib.unified_diff(
+ reference,
+ generated_normalized,
+ fromfile="reference",
+ tofile="generated"):
+ sys.stdout.write(line)
+ return 1
+
+ # Write-if-changed: the GN action rule carries restat=1, so leaving
+ # the mtime alone when the content is identical prunes the (near-
+ # global, via instance-type.h) set of dependents whenever an edit
+ # to one of the input headers doesn't change the IT assignment.
+ if os.path.exists(path):
+ with open(path) as f:
+ if f.read() == generated:
+ verbose_print(f"Unchanged {path}")
+ return 0
+ with open(path, "w") as f:
+ f.write(generated)
+ verbose_print(f"Wrote {path}")
+ return 0
+
+
+if __name__ == "__main__":
+ sys.exit(main())
diff --git a/deps/v8/tools/package-lock.json b/deps/v8/tools/package-lock.json
index 5dcc084ddeb..064cc07764a 100644
--- a/deps/v8/tools/package-lock.json
+++ b/deps/v8/tools/package-lock.json
@@ -1372,19 +1372,23 @@
}
},
"node_modules/morgan": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz",
- "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz",
+ "integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==",
"license": "MIT",
"dependencies": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
- "on-finished": "~2.3.0",
+ "on-finished": "~2.4.1",
"on-headers": "~1.1.0"
},
"engines": {
"node": ">= 0.8.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/morgan/node_modules/debug": {
@@ -1402,18 +1406,6 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"license": "MIT"
},
- "node_modules/morgan/node_modules/on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
- "license": "MIT",
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -3004,14 +2996,14 @@
}
},
"morgan": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz",
- "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz",
+ "integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==",
"requires": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
- "on-finished": "~2.3.0",
+ "on-finished": "~2.4.1",
"on-headers": "~1.1.0"
},
"dependencies": {
@@ -3027,14 +3019,6 @@
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A=="
- },
- "on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
- "requires": {
- "ee-first": "1.1.1"
- }
}
}
},
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/README.md b/deps/v8/tools/regexp/correctness_fuzzer/README.md
index 97a0ffb7f40..8a00141d6ac 100644
--- a/deps/v8/tools/regexp/correctness_fuzzer/README.md
+++ b/deps/v8/tools/regexp/correctness_fuzzer/README.md
@@ -12,8 +12,30 @@ benchmark corpus do not cover exhaustively. The two configurations are
arbitrary: a build under test against a stock reference, the interpreter against
the JIT, or two flag settings.
-The generated cases span the interesting character-width axes: ASCII, Latin-1,
-BMP two-byte, and supplementary (surrogate-pair) code points.
+Patterns come from a weighted grammar transcribed from ECMA-262 22.2.1
+(`grammar/rules.py`), one rule per grammar alternative. The spec's own parameters --
+`[UnicodeMode]`, `[UnicodeSetsMode]`, `[NamedCaptureGroups]` -- are threaded
+through the derivation, so mode-specific syntax (`\q{}`, `&&`, `\p{}`) is only
+emitted in a mode that accepts it and generated patterns are essentially always
+syntactically valid. Cases span the interesting character-width axes -- ASCII,
+Latin-1, BMP two-byte, supplementary -- and subjects are drawn from the
+characters the pattern itself mentions, so roughly half of all cases match
+rather than failing at the first character.
+
+Each case runs on two separately constructed `RegExp` objects, and both results
+are reported. The two differ in what the engine has cached by the time they
+run: a pattern is compiled by its first `exec`, and whatever that compile
+leaves on the `RegExpData` (generated code, quick-check mask, first-character
+filter) reaches the second object through the compilation cache. So the first
+`exec` runs a cold pattern and the second a warm one, along paths a
+single-shot run would never take.
+
+Reporting both also makes each case self-checking. The two objects are
+identical and start from the same `lastIndex`, so their results must agree
+whatever either configuration computes -- a mismatch is reported as
+`COLD/WARM` and is a bug in that configuration by itself. That is the one bug
+class a two-config diff cannot see, since it survives being wrong on both
+sides.
## Usage
@@ -40,6 +62,29 @@ abort (`CHECK`/`DCHECK` failure or segfault) is not, and is reported as a
crash whenever it occurs on either side, independent of any divergence. Point
both configurations at a `dcheck_always_on` build to surface those.
+Findings come in three kinds:
+
+| Kind | Meaning |
+| --- | --- |
+| `CRASH` | Either configuration aborted. A bug regardless of what the other did. |
+| `COLD/WARM` | One configuration disagreed with itself across the two execs. A bug in that configuration alone; needs no reference. |
+| `DIVERGENCE` | Both ran cleanly and the test disagreed with the reference. |
+
+Aim a campaign at a family of patterns with `--profile`, or tune one grammar
+rule directly:
+
+```sh
+tools/regexp/correctness_fuzzer/correctness_fuzzer.py --ref A --test B \
+ --profile classes --coverage
+
+tools/regexp/correctness_fuzzer/correctness_fuzzer.py --ref A --test B \
+ --weight Assertion.caret=8 --weight Atom.pattern_character=0.5
+```
+
+`--coverage` reports how often each grammar rule fired and, more usefully,
+which rules never fired -- a rule at zero means the run tested nothing about
+that construct, which case volume alone will not reveal.
+
Reproduce or minimize a single known case instead of fuzzing:
```sh
@@ -57,11 +102,44 @@ tools/regexp/correctness_fuzzer/correctness_fuzzer.py --ref A --test B \
| `--batches` | `100` | Number of batches to run. |
| `--batch-size` | `500` | Cases per batch. |
| `--max-findings` | `20` | Stop after this many divergences. |
-| `--pattern` | | Reproduce a single case (with `--flags` / `--subject`). |
+| `--progress-every` | `25` | Print a flushed progress line every N clean batches (`0` disables). |
+| `--profile` | `default` | Weight overlay: `anchored`, `classes`, `backtracking`, `loops`, `lookaround`. |
+| `--weight` | | Multiply one rule's weight, `Production.rule=N`; repeatable. |
+| `--max-depth` | `5` | Derivation depth budget. The default is the smallest that reaches every grammar rule. |
+| `--coverage` | off | Report per-rule expansion counts and unexercised rules. |
+| `--pattern` | | Reproduce a single case (with `--flags` / `--subject` / `--last-index`). |
The exit status is non-zero when any divergence is found.
+Output is flushed as it is produced, so a long run stopped with `Ctrl-C`
+keeps everything printed so far even when redirected to a file: the seed, every
+finding, and the progress trail. An interrupt during a finding's minimization
+still prints that finding unminimized before exiting.
+
+## Tests
+
+```sh
+tools/regexp/correctness_fuzzer/grammar_test.py --d8 out/x64.release/d8
+```
+
+Pins the properties that decay silently: every grammar rule stays reachable
+under every profile, mode-specific syntax stays in its mode, generated patterns
+parse, and a meaningful share of cases match. Omit `--d8` to run only the
+checks that need no build.
+
## Files
-- `correctness_fuzzer.py` -- case generation, execution, diff, and minimization.
+- `grammar/` -- the ECMA-262 pattern grammar.
+ - `registry.py` -- the `@rule` decorator, `Context`, and `expand()`.
+ - `menus.py` -- character pools and generation constants.
+ - `rules.py` -- the grammar itself, one `@rule` per spec alternative.
+ - `cases.py` -- flags, subjects, and whole cases.
+ - `profiles.py` -- weight overlays and `--weight` parsing.
+- `grammar_test.py` -- tests for the above.
+- `correctness_fuzzer.py` -- execution, diff, and minimization.
- `harness.js` -- the `d8` harness that constructs and runs each regexp.
+
+A rule never makes a weighted choice of its own: anything that would be an
+`if rng.random() < p` inside a rule body is a separate `@rule` with its own
+weight instead, since a branch is a weight that neither `--weight` nor
+`--coverage` can see. A test pins this.
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/correctness_fuzzer.py b/deps/v8/tools/regexp/correctness_fuzzer/correctness_fuzzer.py
index b6d76ff8716..5f87710baca 100755
--- a/deps/v8/tools/regexp/correctness_fuzzer/correctness_fuzzer.py
+++ b/deps/v8/tools/regexp/correctness_fuzzer/correctness_fuzzer.py
@@ -38,6 +38,7 @@ the reference is never reported as a test failure.
"""
import argparse
+import collections
import contextlib
import json
import os
@@ -47,17 +48,14 @@ import subprocess
import sys
import tempfile
+import grammar
+
# The d8 harness that actually constructs and runs each regexp, kept next to
# this script so it ships with the tool instead of being written at runtime.
# realpath so the harness is found even when the script is invoked via symlink.
HARNESS_PATH = os.path.join(
os.path.dirname(os.path.realpath(__file__)), "harness.js")
-# Character menu kept small but spanning the interesting axes: ASCII
-# letters/digits/punctuation, a Latin-1 supplement char, a BMP two-byte
-# char, and a supplementary (surrogate-pair) char.
-CHARS = list("abcxyz019:.-") + ["é", "Ω", "\U0001f0a1"]
-
def parse_config(spec):
"""'path:--flag --flag' -> (path, [flags]).
@@ -71,105 +69,6 @@ def parse_config(spec):
return path, flags
-# ---- Random regexp generation --------------------------------------------
-
-# Supplementary (surrogate-pair) code points from the playing-card block:
-# these exercise the two-code-unit text and class-lowering paths.
-_SUPP = [chr(0x1F0A1 + i) for i in range(14)
- ] + [chr(0x1F0B1 + i) for i in range(14)]
-
-# Range endpoints in ascending code-point order, so a range built from two
-# indices i <= j is always well-formed and not rejected as out-of-order.
-_CLASS_ATOMS = "0123456789abcdefxyz"
-
-
-def rand_class(r):
- if r.random() < 0.18:
- # Supplementary class: a few code points and/or a range, e.g.
- # [\u{1f0a1}-\u{1f0ae}].
- parts = []
- for _ in range(r.randint(1, 3)):
- if r.random() < 0.5:
- a = r.choice(_SUPP)
- b = chr(ord(a) + r.randint(0, 6))
- parts.append("%s-%s" % (a, b))
- else:
- parts.append(r.choice(_SUPP))
- neg = "^" if r.random() < 0.2 else ""
- return "[%s%s]" % (neg, "".join(parts))
- parts = []
- for _ in range(r.randint(1, 4)):
- if r.random() < 0.4:
- i = r.randrange(len(_CLASS_ATOMS))
- j = r.randint(i, min(i + 6, len(_CLASS_ATOMS) - 1))
- parts.append("%s-%s" % (_CLASS_ATOMS[i], _CLASS_ATOMS[j]))
- else:
- parts.append(r.choice("abcxyz019"))
- neg = "^" if r.random() < 0.2 else ""
- return "[%s%s]" % (neg, "".join(parts))
-
-
-def rand_atom(r, depth):
- roll = r.random()
- if roll < 0.35:
- return r.choice("abcxyz019:.") if r.random() < 0.8 else r.choice(CHARS)
- if roll < 0.5:
- return rand_class(r)
- if roll < 0.58:
- return r.choice([".", r"\d", r"\w", r"\s", r"\b", r"\B", "^", "$"])
- if roll < 0.64 and depth < 3:
- body = rand_re(r, depth + 1)
- return "(" + body + ")" + (r"\1" if r.random() < 0.15 else "")
- if roll < 0.74 and depth < 3:
- kind = r.choice(["(?:", "(?=", "(?!", "(?<=", "(?<!", "("])
- return kind + rand_re(r, depth + 1) + ")"
- return r.choice("abcxyz")
-
-
-def rand_piece(r, depth):
- a = rand_atom(r, depth)
- if r.random() < 0.25:
- q = r.choice(["*", "+", "?", "{0,2}", "{1,3}", "{2}", "{2,}", "{1,4}"])
- if r.random() < 0.3:
- q += "?"
- return a + q
- return a
-
-
-def rand_seq(r, depth):
- return "".join(rand_piece(r, depth) for _ in range(r.randint(1, 5)))
-
-
-def rand_re(r, depth=0):
- n = r.randint(1, 4)
- alts = [rand_seq(r, depth) for _ in range(n)]
- if r.random() < 0.15:
- alts[r.randrange(n)] = "" # empty alternative
- return "|".join(alts)
-
-
-def rand_subject(r):
- # Bias toward supplementary code points sometimes so surrogate-pair
- # texts get matching input.
- pool = CHARS + (_SUPP if r.random() < 0.5 else [])
- return "".join(r.choice(pool) for _ in range(r.randint(0, 14)))
-
-
-def gen_case(r):
- pat = rand_re(r)
- flags = "".join(r.sample(["i", "m", "s", "y"], r.randint(0, 2)))
- # 'u' and 'v' are mutually exclusive unicode modes; pick at most one,
- # biased to include one since they change surrogate handling and class
- # lowering materially. Favor 'v' (unicodeSets): it is the newer mode with
- # its own, more intricate class-lowering path.
- roll = r.random()
- if roll < 0.4:
- flags += "v"
- elif roll < 0.55:
- flags += "u"
- return [pat, flags, rand_subject(r)]
-
-
# ---- Execution + diff -----------------------------------------------------
# Sentinel return code for a timed-out run, distinct from a real process exit
@@ -219,39 +118,43 @@ class Runner:
results[int(key)] = value
return results
- def run_one(self, config, pattern, flags, subject):
- with self._cases_file([[pattern, flags, subject]]) as casefile:
+ def run_one(self, config, pattern, flags, subject, last_index=0):
+ with self._cases_file([[pattern, flags, subject, last_index]]) as casefile:
rc, out = self._run(config, casefile)
return rc, self._results(out).get(0)
- def finding(self, pattern, flags, subject):
+ def finding(self, pattern, flags, subject, last_index=0):
"""Classify a case as a finding, or return None.
'CRASH' when either configuration aborts -- a CHECK/DCHECK failure or
segfault, distinct from a syntax error, which the harness reports as a
- clean 'ERR_' result. 'DIVERGENCE' when both run cleanly but the test
- disagrees with the reference. A reference syntax error, or a timeout on
- either side, establishes no ground truth and is skipped.
+ clean 'ERR_' result. 'COLD/WARM' when one configuration disagrees with
+ itself across the two execs, which is a bug in that configuration alone.
+ 'DIVERGENCE' when both run cleanly but the test disagrees with the
+ reference. A reference syntax error, or a timeout on either side,
+ establishes no ground truth and is skipped.
"""
- rc_r, res_r = self.run_one(self.ref, pattern, flags, subject)
- rc_t, res_t = self.run_one(self.test, pattern, flags, subject)
- if rc_r == TIMEOUT_RC or rc_t == TIMEOUT_RC:
- return None
- if rc_r != 0 or rc_t != 0:
- return "CRASH" # a hard abort on either side is a bug regardless
- if res_r is None or res_r.startswith('"ERR_'):
- return None # reference doesn't establish ground truth here
- return "DIVERGENCE" if res_t != res_r else None
+ rc_r, res_r = self.run_one(self.ref, pattern, flags, subject, last_index)
+ rc_t, res_t = self.run_one(self.test, pattern, flags, subject, last_index)
+ return classify(rc_r, res_r, rc_t, res_t)
def run_batch(self, cases):
with self._cases_file(cases) as casefile:
rc_r, out_r = self._run(self.ref, casefile)
rc_t, out_t = self._run(self.test, casefile)
ref, test = self._results(out_r), self._results(out_t)
- # First case whose result differs, including one side missing it (a
- # crash or timeout that truncated that configuration's output).
for i in range(len(cases)):
- if ref.get(i) != test.get(i):
+ # Classified rather than string-compared, so the batch scan and finding()
+ # agree on what counts. A raw diff would flag every case the reference
+ # merely rejects, which finding() then declines to reproduce -- leaving
+ # an unminimizable "finding" that the ground-truth policy says to skip.
+ #
+ # Both return codes are passed as 0: they belong to the whole process,
+ # not to this case, and feeding a crashed run's code in here would
+ # classify every case from the first one onward as a CRASH and report
+ # index 0 rather than the case that actually aborted. That is what the
+ # rc check below is for.
+ if classify(0, ref.get(i), 0, test.get(i)):
return i
# Identical output but a hard exit on either side is a crash that
# truncated both runs at the same case (e.g. a shared DCHECK), which the
@@ -261,31 +164,122 @@ class Runner:
return None
+def _no_ground_truth(res):
+ """Does |res| leave the reference without an answer to compare against?
+
+ A missing line, or any error marker: a pattern the reference rejects
+ outright (ERR_CTOR) or one whose exec raised (ERR_EXEC), which a stack or
+ backtrack limit makes configuration-dependent rather than a wrong answer.
+ """
+ if res is None:
+ return True
+ try:
+ parsed = json.loads(res)
+ except json.JSONDecodeError:
+ return True
+ if isinstance(parsed, str):
+ return parsed.startswith("ERR_")
+ return any(
+ isinstance(v, str) and v.startswith("ERR_") for v in parsed.values())
+
+
+def _self_inconsistent(res):
+ """Do the two execs of one configuration disagree with each other?
+
+ Both run a freshly constructed JSRegExp over the same subject from the same
+ lastIndex, so they must agree whatever the answer is; only what the engine
+ has cached by the second one differs. This holds within a single
+ configuration, so it catches a bug the reference and the test share.
+ """
+ if res is None:
+ return False
+ try:
+ parsed = json.loads(res)
+ except json.JSONDecodeError:
+ return False
+ if not isinstance(parsed, dict):
+ return False
+ return parsed.get("cold") != parsed.get("warm")
+
+
+def classify(rc_ref, res_ref, rc_test, res_test):
+ """Classify one case's pair of results, or return None if it is clean."""
+ if rc_ref == TIMEOUT_RC or rc_test == TIMEOUT_RC:
+ return None
+ if rc_ref != 0 or rc_test != 0:
+ return "CRASH" # a hard abort on either side is a bug regardless
+ # Checked before the ground-truth filter: a configuration contradicting
+ # itself needs no external reference to be wrong.
+ if _self_inconsistent(res_ref) or _self_inconsistent(res_test):
+ return "COLD/WARM"
+ if _no_ground_truth(res_ref):
+ return None
+ return "DIVERGENCE" if res_test != res_ref else None
+
+
# ---- Minimization ---------------------------------------------------------
-def minimize(runner, pattern, flags, subject):
+def _shrink_targets(n):
+ """Candidate smaller values for a quantifier bound, best first.
+
+ 0 and 1 first because they are the shapes that usually still reproduce and
+ read best in a repro, then a halving sequence so a large bound converges in
+ log steps instead of one re-run of both configurations per unit.
+ """
+ seen = set()
+ for c in (0, 1, n // 2, n * 3 // 4, n - 1):
+ if 0 <= c < n and c not in seen:
+ seen.add(c)
+ yield c
+
+
+def _quantifier(lo, bounded, hi):
+ """Rebuild `{n}` (bounded=False) or `{n,}` / `{n,m}` (bounded=True)."""
+ if not bounded:
+ return "{%d}" % lo
+ return "{%d,%s}" % (lo, "" if hi is None else "%d" % hi)
+
+
+def minimize(runner, pattern, flags, subject, last_index=0):
def cands(p):
n = len(p)
for size in (32, 16, 8, 4, 2, 1):
for s in range(n - size + 1):
yield p[:s] + p[s + size:]
- for m in re.finditer(r"\{(\d+)(,(\d+)?)?\}", p):
- a = int(m.group(1))
- if a > 0:
- yield p[:m.start()] + m.group(0).replace(str(a), str(a - 1),
- 1) + p[m.end():]
- yield p.replace("[0-9a-f]", "[0-9]", 1)
+ # Quantifier bounds are shrunk toward zero by halving rather than by
+ # decrementing: a bound in the hundreds would otherwise need one full
+ # re-run of both configurations per step.
+ for m in re.finditer(r"\{(\d+)(,)?(\d+)?\}", p):
+ lo = int(m.group(1))
+ bounded = m.group(2) is not None
+ hi = int(m.group(3)) if m.group(3) is not None else None
+ for lo_try in _shrink_targets(lo):
+ if hi is not None and lo_try > hi:
+ continue
+ yield p[:m.start()] + _quantifier(lo_try, bounded, hi) + p[m.end():]
+ if hi is not None:
+ for hi_try in _shrink_targets(hi):
+ if hi_try >= lo:
+ yield p[:m.start()] + _quantifier(lo, bounded, hi_try) + p[m.end():]
+
+ def size(p):
+ # Length alone would reject every same-length quantifier shrink ({5} to
+ # {0}), which is most of them; the bound total breaks the tie.
+ return (len(p),
+ sum(
+ int(m.group(1)) + int(m.group(3) or 0)
+ for m in re.finditer(r"\{(\d+)(,)?(\d+)?\}", p)))
improved = True
while improved:
improved = False
for c in cands(pattern):
- if len(c) >= len(pattern):
+ if size(c) >= size(pattern):
continue
try:
- if runner.finding(c, flags, subject):
+ if runner.finding(c, flags, subject, last_index):
pattern = c
improved = True
break
@@ -295,10 +289,10 @@ def minimize(runner, pattern, flags, subject):
changed = True
while changed:
changed = False
- for size in (4, 2, 1):
- for s in range(len(subject) - size + 1):
- c = subject[:s] + subject[s + size:]
- if runner.finding(pattern, flags, c):
+ for chunk in (4, 2, 1):
+ for s in range(len(subject) - chunk + 1):
+ c = subject[:s] + subject[s + chunk:]
+ if runner.finding(pattern, flags, c, last_index):
subject = c
changed = True
break
@@ -307,23 +301,66 @@ def minimize(runner, pattern, flags, subject):
# Drop flags that aren't load-bearing.
for f in list(flags):
cand = flags.replace(f, "")
- if runner.finding(pattern, cand, subject):
+ if runner.finding(pattern, cand, subject, last_index):
flags = cand
- return pattern, flags, subject
+ # A zero lastIndex is the simpler repro; keep the nonzero one only when the
+ # finding needs it.
+ if last_index and runner.finding(pattern, flags, subject, 0):
+ last_index = 0
+ return pattern, flags, subject, last_index
-def report(runner, pattern, flags, subject, header):
- pattern, flags, subject = minimize(runner, pattern, flags, subject)
- rc_r, res_r = runner.run_one(runner.ref, pattern, flags, subject)
- rc_t, res_t = runner.run_one(runner.test, pattern, flags, subject)
+def _print_case(runner, pattern, flags, subject, last_index, header):
+ rc_r, res_r = runner.run_one(runner.ref, pattern, flags, subject, last_index)
+ rc_t, res_t = runner.run_one(runner.test, pattern, flags, subject, last_index)
print(header)
print(" pattern: /%s/%s" % (pattern, flags))
print(" subject: %r" % subject)
+ if last_index:
+ print(" lastIndex: %d" % last_index)
print(" ref : rc=%d %s" % (rc_r, res_r))
print(" test: rc=%d %s" % (rc_t, res_t))
sys.stdout.flush()
+def report(runner, pattern, flags, subject, last_index, header):
+ # Minimization can take a while on a large pattern, and a Ctrl-C during it
+ # (the usual way a long run is stopped) would otherwise discard the finding
+ # before anything is printed. On interrupt emit the un-minimized case, which
+ # is still a valid repro, before propagating.
+ try:
+ pattern, flags, subject, last_index = minimize(runner, pattern, flags,
+ subject, last_index)
+ except KeyboardInterrupt:
+ _print_case(runner, pattern, flags, subject, last_index,
+ header + " (unminimized)")
+ raise
+ _print_case(runner, pattern, flags, subject, last_index, header)
+
+
+def _print_coverage(coverage):
+ """Report per-rule expansion counts, unexercised rules last.
+
+ A rule that never fired is the actionable part: it means the run tested
+ nothing about that grammar alternative, which no amount of case volume
+ reveals on its own.
+ """
+ rules = grammar.all_rules()
+ used = [(p, n) for (p, n) in rules if coverage[(p, n)]]
+ missed = [(p, n) for (p, n) in rules if not coverage[(p, n)]]
+ total = sum(coverage.values()) or 1
+ print("\ngrammar coverage: %d/%d rules, %d expansions" %
+ (len(used), len(rules), total))
+ for prod, name in sorted(used, key=lambda k: -coverage[k]):
+ count = coverage[(prod, name)]
+ print(" %-46s %8d %5.2f%%" % ("%s.%s" %
+ (prod, name), count, 100.0 * count / total))
+ if missed:
+ print(" NOT EXERCISED:")
+ for prod, name in missed:
+ print(" %s.%s" % (prod, name))
+
+
def main():
ap = argparse.ArgumentParser(
description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter)
@@ -341,42 +378,101 @@ def main():
ap.add_argument("--batches", type=int, default=100)
ap.add_argument("--batch-size", type=int, default=500)
ap.add_argument("--max-findings", type=int, default=20)
+ ap.add_argument(
+ "--progress-every",
+ type=int,
+ default=25,
+ help="print a flushed progress line every N clean batches (0 disables); "
+ "the running trail is what survives an early Ctrl-C")
+ ap.add_argument(
+ "--profile",
+ default="default",
+ choices=sorted(grammar.PROFILES),
+ help="weight overlay aiming generation at a family of patterns")
+ ap.add_argument(
+ "--weight",
+ action="append",
+ metavar="Production.rule=N",
+ help="multiply one grammar rule's weight; repeatable")
+ ap.add_argument(
+ "--max-depth",
+ type=int,
+ default=5,
+ help="derivation depth budget; larger means bigger nested patterns. "
+ "The default is the smallest that reaches every grammar rule -- the "
+ "deepest v-mode class nesting needs 5 (verify with --coverage)")
+ ap.add_argument(
+ "--coverage",
+ action="store_true",
+ help="report which grammar rules the run exercised, and which it missed")
ap.add_argument(
"--pattern", help="reproduce a single case instead of fuzzing")
ap.add_argument("--flags", default="")
ap.add_argument("--subject", default="")
+ ap.add_argument("--last-index", type=int, default=0)
args = ap.parse_args()
+ try:
+ weights = grammar.parse_weights(args.profile, args.weight)
+ except ValueError as e:
+ ap.error(str(e))
+
runner = Runner(args.ref, args.test)
if args.pattern is not None:
- kind = runner.finding(args.pattern, args.flags, args.subject)
+ kind = runner.finding(args.pattern, args.flags, args.subject,
+ args.last_index)
if kind:
- report(runner, args.pattern, args.flags, args.subject, kind)
+ report(runner, args.pattern, args.flags, args.subject, args.last_index,
+ kind)
return 1
print("no divergence for the given case")
return 0
seed = args.seed if args.seed is not None else random.randrange(2**32)
- if args.seed is None:
- print("seed: %d (pass --seed %d to reproduce)" % (seed, seed))
+ # Print (flushed) up front so the seed survives an early abort; a long run is
+ # typically stopped with Ctrl-C, and the seed is what makes it reproducible.
+ print("seed: %d (pass --seed %d to reproduce)" % (seed, seed))
+ sys.stdout.flush()
findings = 0
- for it in range(args.batches):
- r = random.Random(seed * 1_000_003 + it)
- cases = [gen_case(r) for _ in range(args.batch_size)]
- idx = runner.run_batch(cases)
- if idx is None:
- continue
- pat, fl, sub = cases[idx]
- kind = runner.finding(pat, fl, sub) or "DIVERGENCE"
- report(runner, pat, fl, sub, "%s batch=%d case=%d" % (kind, it, idx))
- findings += 1
- if findings >= args.max_findings:
- print("reached --max-findings; stopping")
- break
- print("done: %d batches x %d cases, %d divergence(s)" %
- (args.batches, args.batch_size, findings))
+ done = 0
+ coverage = collections.Counter() if args.coverage else None
+ # A long run is usually ended by Ctrl-C or an external kill. Catch the
+ # interrupt so the summary of what completed still prints; report() has
+ # already flushed each finding as it was found.
+ try:
+ for it in range(args.batches):
+ r = random.Random(seed * 1_000_003 + it)
+ cases = [
+ grammar.gen_case(r, args.max_depth, weights, coverage)
+ for _ in range(args.batch_size)
+ ]
+ idx = runner.run_batch(cases)
+ done = it + 1
+ if idx is None:
+ # Emit a flushed heartbeat so a clean run leaves a trail (cases fuzzed,
+ # findings so far) that survives an abort instead of only the final
+ # summary.
+ if args.progress_every and done % args.progress_every == 0:
+ print("progress: %d/%d batches, %d finding(s)" %
+ (done, args.batches, findings))
+ sys.stdout.flush()
+ continue
+ pat, fl, sub, li = cases[idx]
+ kind = runner.finding(pat, fl, sub, li) or "DIVERGENCE"
+ report(runner, pat, fl, sub, li, "%s batch=%d case=%d" % (kind, it, idx))
+ findings += 1
+ if findings >= args.max_findings:
+ print("reached --max-findings; stopping")
+ break
+ except KeyboardInterrupt:
+ print("\ninterrupted after %d batch(es)" % done)
+ print("done: %d/%d batches x %d cases, %d divergence(s)" %
+ (done, args.batches, args.batch_size, findings))
+ if coverage is not None:
+ _print_coverage(coverage)
+ sys.stdout.flush()
return 1 if findings else 0
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar/__init__.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar/__init__.py
new file mode 100644
index 00000000000..5bb70aec133
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar/__init__.py
@@ -0,0 +1,60 @@
+# 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.
+"""Weighted grammar for generating ECMA-262 regexp patterns.
+
+The productions transcribe the pattern grammar of ECMA-262 22.2.1
+(Disjunction / Alternative / Term / Atom / ClassContents / ...), one
+`@rule` per grammar alternative, so a reader can check the generator
+against the spec line by line. Generation is a weighted random
+derivation: each rule carries a weight, and a rule whose `guard` is
+false for the current parameters is not eligible at all.
+
+Two properties follow from mirroring the spec rather than emitting
+strings ad hoc:
+
+ * The spec's own parameters -- [UnicodeMode], [UnicodeSetsMode],
+ [NamedCaptureGroups] -- are threaded through the derivation and
+ gate the rules the spec gates, so mode-specific syntax (`\\q{}`,
+ `&&`, `\\p{}`) is only ever emitted in a mode that accepts it.
+ Most syntax errors are structurally impossible instead of merely
+ unlikely.
+ * Coverage is measurable: every expansion records the rule it took,
+ so a run can report which grammar alternatives it never exercised.
+
+Derivation is bounded by a depth budget. Rules marked `recursive`
+re-enter the grammar; once the budget is spent they become ineligible
+and only terminal rules remain, which terminates the derivation and
+keeps the size distribution controllable via --max-depth.
+
+Weights are deliberately data, not control flow: a profile is a table
+of multipliers applied to named rules (see PROFILES), so a campaign can
+be aimed at a feature -- anchored patterns, v-mode class set algebra,
+backtracking shapes -- without touching generation logic. A rule makes
+no weighted choice of its own for the same reason: a branch inside a
+rule body would be a weight that neither --weight nor --coverage can
+see.
+
+Modules:
+ registry -- the @rule decorator, Context, and expand().
+ menus -- character pools and generation constants.
+ rules -- the grammar itself, one @rule per spec alternative.
+ cases -- flags, subjects, and whole [pattern, flags, subject, li] cases.
+ profiles -- weight overlays (--profile) and --weight parsing.
+"""
+
+from .cases import gen_case, gen_flags, gen_subject
+from .profiles import PROFILES, parse_weights
+from .registry import Context, GrammarError, all_rules, expand
+
+__all__ = [
+ "Context",
+ "GrammarError",
+ "PROFILES",
+ "all_rules",
+ "expand",
+ "gen_case",
+ "gen_flags",
+ "gen_subject",
+ "parse_weights",
+]
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar/cases.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar/cases.py
new file mode 100644
index 00000000000..a41096c8ac8
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar/cases.py
@@ -0,0 +1,72 @@
+# 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, subjects, and whole cases."""
+
+from .menus import (LAST_INDEX_SHARE, SUBJECT_LITERAL_SHARE, SUBJECT_MAX_LEN,
+ SUBJECT_NOISE)
+from .registry import Context
+from .rules import gen_pattern
+
+# Flags outside the mode pair, with the weight each is picked at. Not
+# uniform: `i` rewrites every character and class in the pattern and `g` and
+# `d` change what the result even contains, while `m` and `s` each retarget a
+# single construct and `y` only removes the search loop.
+_FLAG_WEIGHTS = {
+ "i": 0.55,
+ "g": 0.35,
+ "d": 0.25,
+ "m": 0.20,
+ "s": 0.20,
+ "y": 0.15,
+}
+
+# `u` and `v` are mutually exclusive, so they are drawn separately.
+_UNICODE_MODE_SHARE = 0.20
+_UNICODE_SETS_MODE_SHARE = 0.30
+
+
+def gen_flags(rng):
+ """Pick a flag set; `u` and `v` are mutually exclusive."""
+ flags = "".join(f for f, w in _FLAG_WEIGHTS.items() if rng.random() < w)
+ roll = rng.random()
+ if roll < _UNICODE_SETS_MODE_SHARE:
+ flags += "v"
+ elif roll < _UNICODE_SETS_MODE_SHARE + _UNICODE_MODE_SHARE:
+ flags += "u"
+ return flags
+
+
+def gen_subject(rng, literals):
+ """Build a subject biased toward characters the pattern mentions.
+
+ Drawing from the pattern's own literal pool is what makes a meaningful
+ share of cases match; a uniformly random subject almost never gets past
+ the first character, leaving the match path untested.
+ """
+ pool = [c for c in literals if c] or ["a"]
+ out = []
+ for _ in range(rng.randint(0, SUBJECT_MAX_LEN)):
+ take_literal = rng.random() < SUBJECT_LITERAL_SHARE
+ out.append(rng.choice(pool if take_literal else SUBJECT_NOISE))
+ return "".join(out)
+
+
+def gen_case(rng, max_depth=5, weights=None, coverage=None):
+ """Generate one [pattern, flags, subject, lastIndex] case."""
+ flags = gen_flags(rng)
+ ctx = Context(
+ rng,
+ unicode_mode="u" in flags or "v" in flags,
+ unicode_sets_mode="v" in flags,
+ max_depth=max_depth,
+ weights=weights,
+ coverage=coverage)
+ pattern = gen_pattern(ctx)
+ subject = gen_subject(rng, ctx.literals)
+ # lastIndex only has an observable effect for sticky/global patterns, but
+ # setting it regardless costs nothing and keeps the case shape uniform.
+ last_index = 0
+ if rng.random() < LAST_INDEX_SHARE:
+ last_index = rng.randint(0, max(0, len(subject)))
+ return [pattern, flags, subject, last_index]
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar/menus.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar/menus.py
new file mode 100644
index 00000000000..37ce043757c
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar/menus.py
@@ -0,0 +1,82 @@
+# 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.
+"""Character menus and generation constants.
+
+The pools the rules draw from, kept together so the character-width axes
+a run covers are visible in one place instead of spread across rule
+bodies.
+"""
+
+# PatternCharacter :: SourceCharacter but not SyntaxCharacter. Characters that
+# need no escaping anywhere, plus wide ones for the two-byte / surrogate paths.
+# The punctuation is load-bearing: letters and digits share their high bits, so
+# an alternation over them still admits a discriminating bitmask, while
+# punctuation spans the ASCII table and collapses one -- the shape a tokenizer's
+# operator alternation has.
+LITERAL = list("abcxyzABXY019") + list("=:;,~!@%&<>")
+LITERAL_WIDE = ["é", "Ω", "\U0001f0a1"]
+
+# `\xHH` reaches U+00FF and no further, so its pool is the Latin-1 subset:
+# LITERAL_WIDE's other members would silently truncate ("x%02x" % 0x3A9 is
+# "x3a9", which reads as `\x3a` followed by a literal `9`).
+LATIN1_ONLY = ["é", "\xa0", "\xff"]
+
+# Ordered, so a range built from two indices i <= j is well formed.
+RANGE_ALPHABET = "0123456789abcdefwxyz"
+
+# ClassSetCharacter in v mode must avoid ClassSetSyntaxCharacter and the
+# reserved double punctuators; letters and digits are unconditionally safe.
+CLASS_SET_SAFE = list("abcxyzABXY019")
+
+CONTROL_ESCAPE = list("fnrtv")
+ASCII_LETTER = list("abcxyzABXYZ")
+
+# The character each ControlEscape stands for, so the subject pool can contain
+# something the pattern can actually match.
+ESCAPE_LITERALS = {"f": "\f", "n": "\n", "r": "\r", "t": "\t", "v": "\v"}
+
+# Property names that exist in every ICU build V8 ships with.
+UNICODE_PROPERTIES = [
+ "L",
+ "Lu",
+ "Ll",
+ "N",
+ "Nd",
+ "P",
+ "S",
+ "Zs",
+ "Alphabetic",
+ "White_Space",
+ "Script=Greek",
+ "Script=Latin",
+ "General_Category=Letter",
+]
+
+# Properties of strings: v-mode only, and the one \p{} form that can match
+# more than a single character, so it runs the same string-valued machinery
+# as `\q{}`. Negating one is an early error, which is why \P{} draws from
+# UNICODE_PROPERTIES alone.
+UNICODE_PROPERTIES_OF_STRINGS = [
+ "Basic_Emoji",
+ "RGI_Emoji",
+ "RGI_Emoji_Flag_Sequence",
+ "RGI_Emoji_Modifier_Sequence",
+ "RGI_Emoji_Tag_Sequence",
+ "RGI_Emoji_ZWJ_Sequence",
+ "Emoji_Keycap_Sequence",
+]
+
+# Characters mixed into a subject on top of the pattern's own literals, so a
+# match has something to fail against and the two-byte / surrogate subject
+# representations are reached even when the pattern is pure ASCII.
+SUBJECT_NOISE = list("abcxyz019 \n") + ["é", "\U0001f0a1"]
+
+# Probability that a subject character is drawn from the pattern's literals
+# rather than SUBJECT_NOISE. High, because drawing from the pattern is what
+# makes a meaningful share of cases match at all (see gen_subject).
+SUBJECT_LITERAL_SHARE = 0.75
+SUBJECT_MAX_LEN = 10
+
+# Probability that a case sets a nonzero lastIndex.
+LAST_INDEX_SHARE = 0.3
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar/profiles.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar/profiles.py
new file mode 100644
index 00000000000..cca49749a13
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar/profiles.py
@@ -0,0 +1,80 @@
+# 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.
+"""Weight overlays that aim a campaign at a family of patterns."""
+
+from .registry import GRAMMAR
+
+# A profile is a table of multipliers keyed "Production.rule", applied on top
+# of the base weights. Aiming a campaign at a feature is a weight change, not
+# a code change.
+PROFILES = {
+ "default": {},
+ # Patterns that must match at a fixed position: what a first-character or
+ # prefix filter optimization actually sees.
+ "anchored": {
+ "Assertion.caret": 8.0,
+ "Term.assertion": 2.0,
+ "Disjunction.alternation": 2.0,
+ "Atom.character_class": 2.0,
+ },
+ # v-mode set algebra: nested classes, intersection, subtraction, strings.
+ "classes": {
+ "Atom.character_class": 4.0,
+ "ClassSetExpression.class_intersection": 3.0,
+ "ClassSetExpression.class_subtraction": 3.0,
+ "ClassSetOperand.nested_class": 3.0,
+ "ClassSetOperand.nested_negated_class": 3.0,
+ "ClassSetOperand.class_string_disjunction": 3.0,
+ "CharacterClassEscape.unicode_property_of_strings": 3.0,
+ "Atom.pattern_character": 0.3,
+ },
+ # Shapes that stress backtracking: nested quantifiers and alternations.
+ "backtracking": {
+ "Term.quantified_atom": 4.0,
+ "Disjunction.alternation": 3.0,
+ "Atom.non_capturing_group": 3.0,
+ "Atom.capturing_group": 2.0,
+ "QuantifierPrefix.star": 2.0,
+ "QuantifierPrefix.plus": 2.0,
+ },
+ # Counted quantifiers above the compiler's unroll threshold, which build a
+ # counter-based loop instead of a repeated body.
+ "loops": {
+ "Term.quantified_atom": 4.0,
+ "QuantifierPrefix.exactly_large": 6.0,
+ "QuantifierPrefix.at_least_large": 6.0,
+ "QuantifierPrefix.bounded_large": 6.0,
+ "QuantifierPrefix.star": 0.3,
+ "QuantifierPrefix.plus": 0.3,
+ "QuantifierPrefix.optional": 0.3,
+ },
+ # Lookarounds and references, which constrain without consuming.
+ "lookaround": {
+ "Assertion.lookahead": 5.0,
+ "Assertion.negative_lookahead": 5.0,
+ "Assertion.lookbehind": 5.0,
+ "Assertion.negative_lookbehind": 5.0,
+ "AtomEscape.named_backreference": 3.0,
+ "AtomEscape.decimal_escape": 3.0,
+ "Atom.named_group": 3.0,
+ },
+}
+
+
+def parse_weights(profile, overrides):
+ """Combine a named profile with explicit 'Production.rule=N' overrides."""
+ if profile not in PROFILES:
+ raise ValueError("unknown profile %r (have: %s)" %
+ (profile, ", ".join(sorted(PROFILES))))
+ weights = dict(PROFILES[profile])
+ for item in overrides or []:
+ key, _, value = item.partition("=")
+ if not _:
+ raise ValueError("expected Production.rule=N, got %r" % item)
+ weights[key] = float(value)
+ known = {"%s.%s" % (r.prod, r.name) for rs in GRAMMAR.values() for r in rs}
+ for key in weights:
+ if key not in known:
+ raise ValueError("unknown rule %r" % key)
+ return weights
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar/registry.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar/registry.py
new file mode 100644
index 00000000000..0ba3da24c79
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar/registry.py
@@ -0,0 +1,182 @@
+# 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.
+"""Rule registry and the weighted derivation itself.
+
+Each grammar alternative is a function registered with @rule; expand()
+picks among the alternatives of a production that are eligible for the
+current parameters and calls one.
+"""
+
+import collections
+import contextlib
+import re
+
+Rule = collections.namedtuple("Rule", "prod name weight recursive guard fn")
+
+# production name -> [Rule]; populated by the @rule decorator below.
+GRAMMAR = {}
+
+
+class GrammarError(Exception):
+ """A malformed grammar: unknown production, duplicate rule name, or a
+ production with no eligible alternative.
+
+ Authoring mistakes, raised with the offending name -- otherwise only
+ visible as a traceback from deep inside a derivation.
+ """
+
+
+def rule(prod, weight=1.0, recursive=False, guard=None):
+ """Register a function as one alternative of production |prod|.
+
+ weight relative selection weight among the eligible alternatives.
+ recursive the alternative re-enters the grammar, so it is dropped once
+ the depth budget is spent.
+ guard predicate on the context; a false guard makes the alternative
+ ineligible (this is how the spec's [+UnicodeMode]-style
+ parameters are expressed).
+ """
+
+ def deco(fn):
+ alternatives = GRAMMAR.setdefault(prod, [])
+ # Rules are addressed as "Production.rule" by --weight and by the coverage
+ # report, so a duplicate name would make one of the two unreachable.
+ if any(r.name == fn.__name__ for r in alternatives):
+ raise GrammarError("duplicate rule %s.%s" % (prod, fn.__name__))
+ alternatives.append(Rule(prod, fn.__name__, weight, recursive, guard, fn))
+ return fn
+
+ return deco
+
+
+# Spec parameters, as predicates over the context.
+UNICODE = lambda c: c.unicode_mode
+NOT_UNICODE = lambda c: not c.unicode_mode
+SETS = lambda c: c.unicode_sets_mode
+NOT_SETS = lambda c: not c.unicode_sets_mode
+
+
+class Context:
+ """Derivation state: parameters, budget, and the bookkeeping that keeps
+ generated references resolvable and subjects matchable (see gen_subject).
+ """
+
+ def __init__(self,
+ rng,
+ unicode_mode,
+ unicode_sets_mode,
+ max_depth,
+ weights=None,
+ coverage=None):
+ self.rng = rng
+ self.unicode_mode = unicode_mode
+ self.unicode_sets_mode = unicode_sets_mode
+ self.max_depth = max_depth
+ self.depth = 0
+ self.weights = weights or {}
+ self.coverage = coverage
+ self.capture_count = 0
+ self.group_names = []
+ self.literals = []
+ # Nonzero inside a negated class, where a string-valued operand is a
+ # static-semantics error rather than merely unusual.
+ self.no_strings = 0
+ # Nonzero inside a character class, where the `(?:)` separator
+ # _concat_terms relies on is four more class members rather than a
+ # zero-width group.
+ self.in_class = 0
+ # Set once the pattern uses `\k` as a legacy identity escape, which is
+ # only legal while the pattern has no named group at all (see
+ # legacy_k_escape).
+ self.legacy_k_escape = False
+
+ @contextlib.contextmanager
+ def inside_class(self, no_strings=False):
+ """Derive a class body: mark the subtree, optionally banning strings."""
+ self.in_class += 1
+ self.no_strings += no_strings
+ try:
+ yield
+ finally:
+ self.in_class -= 1
+ self.no_strings -= no_strings
+
+ def weight_of(self, r):
+ return r.weight * self.weights.get("%s.%s" % (r.prod, r.name), 1.0)
+
+ def note_literal(self, s):
+ self.literals.append(s)
+ return s
+
+ def describe(self):
+ """Parameter summary, for error messages."""
+ return "unicode_mode=%r unicode_sets_mode=%r in_class=%d no_strings=%d" % (
+ self.unicode_mode, self.unicode_sets_mode, self.in_class,
+ self.no_strings)
+
+
+def expand(ctx, prod):
+ """Derive |prod|, honouring guards, the depth budget, and weights."""
+ alternatives = GRAMMAR.get(prod)
+ if alternatives is None:
+ raise GrammarError("no such production %r (have: %s)" %
+ (prod, ", ".join(sorted(GRAMMAR))))
+ rules = [r for r in alternatives if r.guard is None or r.guard(ctx)]
+ if not rules:
+ raise GrammarError("every alternative of %s is guarded off for %s" %
+ (prod, ctx.describe()))
+ if ctx.depth >= ctx.max_depth:
+ terminal = [r for r in rules if not r.recursive]
+ # A production with no terminal alternative (Pattern, Disjunction) must
+ # still expand; the budget is a bias, not a hard wall, and the recursive
+ # rules below shrink their own fan-out once it is spent.
+ rules = terminal or rules
+ weights = [ctx.weight_of(r) for r in rules]
+ total = sum(weights)
+ if total <= 0:
+ weights, total = [1.0] * len(rules), float(len(rules))
+ pick = ctx.rng.random() * total
+ for r, w in zip(rules, weights):
+ pick -= w
+ if pick <= 0:
+ break
+ if ctx.coverage is not None:
+ ctx.coverage[(r.prod, r.name)] += 1
+ if not r.recursive:
+ return r.fn(ctx)
+ ctx.depth += 1
+ try:
+ return r.fn(ctx)
+ finally:
+ ctx.depth -= 1
+
+
+def concat_terms(parts):
+ """Join Terms, keeping a digit-terminated escape away from a following digit.
+
+ `\\1` and `\\0` are terminated by lookahead, not by their own syntax: put a
+ digit after either and `\\1` `9` reads as backreference 11 and `\\0` `9` as a
+ legacy octal escape. The spec expresses this as [lookahead not in
+ DecimalDigit]; concatenation is where the grammar has to honour it, since the
+ two Terms are derived independently. A non-capturing group is the neutral
+ separator -- it cannot change what either side matches.
+ """
+ out = []
+ for part in parts:
+ if (out and part[:1].isdigit() and re.search(r"\\[0-9]+$", out[-1])):
+ out.append("(?:)")
+ out.append(part)
+ return "".join(out)
+
+
+def repeat(ctx, prod, lo, hi):
+ """Concatenate |lo|..|hi| derivations of |prod|, shrinking past budget."""
+ if ctx.depth >= ctx.max_depth:
+ hi = lo
+ return concat_terms(
+ [expand(ctx, prod) for _ in range(ctx.rng.randint(lo, hi))])
+
+
+def all_rules():
+ return [(r.prod, r.name) for rs in GRAMMAR.values() for r in rs]
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar/rules.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar/rules.py
new file mode 100644
index 00000000000..0977afa7c15
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar/rules.py
@@ -0,0 +1,616 @@
+# 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 ECMA-262 22.2.1 pattern grammar, one @rule per alternative.
+
+The productions transcribe the spec's pattern grammar (Disjunction /
+Alternative / Term / Atom / ClassContents / ...) so a reader can check the
+generator against the spec line by line. Where the spec gates an
+alternative on a parameter -- [UnicodeMode], [UnicodeSetsMode] -- the rule
+carries the matching guard, so mode-specific syntax is only ever emitted in
+a mode that accepts it.
+
+Every choice a rule makes between meaningfully different outputs is a
+separate rule with its own weight, not a branch inside one. A branch would
+be a second weight system: invisible to the coverage report and unreachable
+from --weight, so a campaign could not aim at it and a run could not tell
+you it never fired.
+"""
+
+from .menus import (ASCII_LETTER, CLASS_SET_SAFE, CONTROL_ESCAPE,
+ ESCAPE_LITERALS, LATIN1_ONLY, LITERAL, LITERAL_WIDE,
+ RANGE_ALPHABET, UNICODE_PROPERTIES,
+ UNICODE_PROPERTIES_OF_STRINGS)
+from .registry import (NOT_SETS, NOT_UNICODE, SETS, UNICODE, concat_terms,
+ expand, repeat, rule)
+
+
+def _random_range(ctx):
+ """A `a-z` class range, drawn from an ordered alphabet so it is well formed."""
+ i = ctx.rng.randrange(len(RANGE_ALPHABET))
+ j = min(i + ctx.rng.randint(0, 6), len(RANGE_ALPHABET) - 1)
+ ctx.note_literal(RANGE_ALPHABET[i])
+ return "%s-%s" % (RANGE_ALPHABET[i], RANGE_ALPHABET[j])
+
+
+# ---- Pattern / Disjunction / Alternative / Term ---------------------------
+# Pattern :: Disjunction
+
+
+def gen_pattern(ctx):
+ return expand(ctx, "Disjunction")
+
+
+# Disjunction :: Alternative
+# Alternative `|` Disjunction
+
+
+@rule("Disjunction", weight=6.0)
+def single(ctx):
+ return expand(ctx, "Alternative")
+
+
+@rule("Disjunction", weight=3.0, recursive=True)
+def alternation(ctx):
+ return expand(ctx, "Alternative") + "|" + expand(ctx, "Disjunction")
+
+
+# Alternative :: [empty]
+# Alternative Term
+
+
+@rule("Alternative", weight=0.6)
+def empty(ctx):
+ return ""
+
+
+@rule("Alternative", weight=9.0, recursive=True)
+def terms(ctx):
+ return repeat(ctx, "Term", 1, 4)
+
+
+# Term :: Assertion
+# Atom
+# Atom Quantifier
+
+
+@rule("Term", weight=1.5)
+def assertion(ctx):
+ return expand(ctx, "Assertion")
+
+
+@rule("Term", weight=6.0, recursive=True)
+def atom(ctx):
+ return expand(ctx, "Atom")
+
+
+@rule("Term", weight=3.0, recursive=True)
+def quantified_atom(ctx):
+ return expand(ctx, "Atom") + expand(ctx, "Quantifier")
+
+
+# Assertion :: `^` `$` `\b` `\B`
+# `(?=` Disjunction `)` and the three other lookaround forms
+
+
+@rule("Assertion", weight=2.0)
+def caret(ctx):
+ return "^"
+
+
+@rule("Assertion", weight=1.5)
+def dollar(ctx):
+ return "$"
+
+
+@rule("Assertion", weight=1.0)
+def word_boundary(ctx):
+ return r"\b"
+
+
+@rule("Assertion", weight=0.7)
+def not_word_boundary(ctx):
+ return r"\B"
+
+
+@rule("Assertion", weight=1.0, recursive=True)
+def lookahead(ctx):
+ return "(?=" + expand(ctx, "Disjunction") + ")"
+
+
+@rule("Assertion", weight=0.8, recursive=True)
+def negative_lookahead(ctx):
+ return "(?!" + expand(ctx, "Disjunction") + ")"
+
+
+@rule("Assertion", weight=1.0, recursive=True)
+def lookbehind(ctx):
+ return "(?<=" + expand(ctx, "Disjunction") + ")"
+
+
+@rule("Assertion", weight=0.8, recursive=True)
+def negative_lookbehind(ctx):
+ return "(?<!" + expand(ctx, "Disjunction") + ")"
+
+
+# Quantifier :: QuantifierPrefix
+# QuantifierPrefix `?`
+
+
+@rule("Quantifier", weight=3.0)
+def greedy(ctx):
+ return expand(ctx, "QuantifierPrefix")
+
+
+@rule("Quantifier", weight=1.0)
+def lazy(ctx):
+ return expand(ctx, "QuantifierPrefix") + "?"
+
+
+# QuantifierPrefix :: `*` `+` `?` `{n}` `{n,}` `{n,m}`
+#
+# The compiler unrolls a quantifier whose bounds are at most
+# kMaxUnrolledMinMatches / kMaxUnrolledMaxMatches (both 3, see
+# regexp-compiler-tonode.cc). Bounds drawn only from that range would leave
+# the counter-based loop -- a different node shape with its own register
+# handling -- entirely ungenerated, so each counted form has a small and a
+# large variant. The large ones stay well under the point where compilation
+# cost is noticeable.
+
+
+@rule("QuantifierPrefix", weight=3.0)
+def star(ctx):
+ return "*"
+
+
+@rule("QuantifierPrefix", weight=3.0)
+def plus(ctx):
+ return "+"
+
+
+@rule("QuantifierPrefix", weight=3.0)
+def optional(ctx):
+ return "?"
+
+
+@rule("QuantifierPrefix", weight=1.0)
+def exactly(ctx):
+ return "{%d}" % ctx.rng.randint(0, 3)
+
+
+@rule("QuantifierPrefix", weight=0.4)
+def exactly_large(ctx):
+ return "{%d}" % ctx.rng.randint(4, 40)
+
+
+@rule("QuantifierPrefix", weight=0.7)
+def at_least(ctx):
+ return "{%d,}" % ctx.rng.randint(0, 2)
+
+
+@rule("QuantifierPrefix", weight=0.3)
+def at_least_large(ctx):
+ return "{%d,}" % ctx.rng.randint(4, 40)
+
+
+@rule("QuantifierPrefix", weight=1.0)
+def bounded(ctx):
+ lo = ctx.rng.randint(0, 2)
+ return "{%d,%d}" % (lo, lo + ctx.rng.randint(0, 3))
+
+
+@rule("QuantifierPrefix", weight=0.4)
+def bounded_large(ctx):
+ lo = ctx.rng.randint(0, 20)
+ return "{%d,%d}" % (lo, lo + ctx.rng.randint(4, 60))
+
+
+# Atom :: PatternCharacter
+# `.`
+# `\` AtomEscape
+# CharacterClass
+# `(` GroupSpecifier? Disjunction `)`
+# `(?` RegularExpressionModifiers `:` Disjunction `)`
+# `(?` Modifiers `-` Modifiers `:` Disjunction `)`
+
+
+@rule("Atom", weight=9.0)
+def pattern_character(ctx):
+ return ctx.note_literal(ctx.rng.choice(LITERAL))
+
+
+@rule("Atom", weight=1.2)
+def pattern_character_wide(ctx):
+ # A non-Latin-1 literal forces the two-byte subject representation and, for
+ # the supplementary one, the surrogate-pair path.
+ return ctx.note_literal(ctx.rng.choice(LITERAL_WIDE))
+
+
+@rule("Atom", weight=1.5)
+def dot(ctx):
+ return "."
+
+
+@rule("Atom", weight=3.0)
+def atom_escape(ctx):
+ return "\\" + expand(ctx, "AtomEscape")
+
+
+@rule("Atom", weight=4.0, recursive=True)
+def character_class(ctx):
+ return expand(ctx, "CharacterClass")
+
+
+@rule("Atom", weight=2.0, recursive=True)
+def capturing_group(ctx):
+ ctx.capture_count += 1
+ return "(" + expand(ctx, "Disjunction") + ")"
+
+
+@rule("Atom", weight=1.0, recursive=True, guard=lambda c: not c.legacy_k_escape)
+def named_group(ctx):
+ # Guarded on legacy_k_escape: a `\k` already emitted as an identity escape
+ # is only legal while the pattern has no named group at all, and adding one
+ # here would retroactively turn that `\k` into an early error.
+ ctx.capture_count += 1
+ name = "g%d" % len(ctx.group_names)
+ ctx.group_names.append(name)
+ return "(?<%s>%s)" % (name, expand(ctx, "Disjunction"))
+
+
+@rule("Atom", weight=2.0, recursive=True)
+def non_capturing_group(ctx):
+ return "(?:" + expand(ctx, "Disjunction") + ")"
+
+
+# `(?ims-ims:` ... `)`: at least one modifier, and no modifier may appear on
+# both sides of the dash. The three forms are separate rules because they
+# reach different parser paths -- adding, removing, and both at once.
+
+
+def _modifiers(ctx, n):
+ return "".join(ctx.rng.sample("ims", n))
+
+
+@rule("Atom", weight=1.0, recursive=True)
+def modifier_group_add(ctx):
+ return "(?%s:%s)" % (_modifiers(ctx, ctx.rng.randint(
+ 1, 3)), expand(ctx, "Disjunction"))
+
+
+@rule("Atom", weight=0.6, recursive=True)
+def modifier_group_remove(ctx):
+ return "(?-%s:%s)" % (_modifiers(ctx, ctx.rng.randint(
+ 1, 3)), expand(ctx, "Disjunction"))
+
+
+@rule("Atom", weight=0.6, recursive=True)
+def modifier_group_add_remove(ctx):
+ mods = _modifiers(ctx, ctx.rng.randint(2, 3))
+ cut = ctx.rng.randint(1, len(mods) - 1)
+ return "(?%s-%s:%s)" % (mods[:cut], mods[cut:], expand(ctx, "Disjunction"))
+
+
+# AtomEscape :: DecimalEscape
+# CharacterClassEscape
+# CharacterEscape
+# `k` GroupName
+
+
+@rule("AtomEscape", weight=1.5, guard=lambda c: c.capture_count > 0)
+def decimal_escape(ctx):
+ return str(ctx.rng.randint(1, ctx.capture_count))
+
+
+@rule("AtomEscape", weight=4.0)
+def character_class_escape(ctx):
+ return expand(ctx, "CharacterClassEscape")
+
+
+@rule("AtomEscape", weight=3.0)
+def character_escape(ctx):
+ return expand(ctx, "CharacterEscape")
+
+
+@rule("AtomEscape", weight=1.5, guard=lambda c: bool(c.group_names))
+def named_backreference(ctx):
+ return "k<%s>" % ctx.rng.choice(ctx.group_names)
+
+
+@rule(
+ "AtomEscape",
+ weight=0.15,
+ guard=lambda c: not c.unicode_mode and not c.group_names)
+def legacy_k_escape(ctx):
+ # `\k` with no named group anywhere in the pattern is an Annex B identity
+ # escape matching a literal `k`, and only [~UnicodeMode] admits it -- under
+ # `u`/`v`, and under any flags once a named group exists, the same source is
+ # an early error. Both guards are required for this to be a live case
+ # rather than one the reference rejects: a syntax error establishes no
+ # ground truth, so it is diffed away rather than reported. named_group is
+ # guarded off for the rest of the derivation once this fires.
+ ctx.legacy_k_escape = True
+ ctx.note_literal("k")
+ return "k"
+
+
+# CharacterEscape :: ControlEscape
+# `c` AsciiLetter
+# `0`
+# HexEscapeSequence
+# RegExpUnicodeEscapeSequence
+# IdentityEscape
+
+
+@rule("CharacterEscape", weight=2.0)
+def control_escape(ctx):
+ esc = ctx.rng.choice(CONTROL_ESCAPE)
+ ctx.note_literal(ESCAPE_LITERALS[esc])
+ return esc
+
+
+@rule("CharacterEscape", weight=1.0)
+def control_letter(ctx):
+ # `\cA` matches the control character A % 32.
+ letter = ctx.rng.choice(ASCII_LETTER)
+ ctx.note_literal(chr(ord(letter.upper()) % 32))
+ return "c" + letter
+
+
+@rule("CharacterEscape", weight=0.5)
+def null_escape(ctx):
+ ctx.note_literal("\0")
+ # `\0` carries [lookahead not in DecimalDigit], which concat_terms honours
+ # for this escape exactly as it does for a DecimalEscape -- but only between
+ # Terms. A class has no zero-width separator, so spell NUL there as `\x00`,
+ # which no following digit can extend.
+ return "x00" if ctx.in_class else "0"
+
+
+@rule("CharacterEscape", weight=1.5)
+def hex_escape(ctx):
+ # `\xHH` is two hex digits, so the pool has to stay within Latin-1.
+ c = ctx.rng.choice(LITERAL + LATIN1_ONLY)
+ ctx.note_literal(c)
+ return "x%02x" % ord(c)
+
+
+# RegExpUnicodeEscapeSequence has three spellings, and which are available
+# depends on the code point as much as on the mode: `\u{...}` needs
+# [+UnicodeMode], and a supplementary code point has no single `\uXXXX` form.
+# Each rule therefore picks its character from the pool that its own spelling
+# can express, rather than picking a character first and branching.
+
+
+@rule("CharacterEscape", weight=1.5)
+def unicode_escape(ctx):
+ c = ctx.rng.choice(LITERAL + ["é", "Ω"])
+ ctx.note_literal(c)
+ return "u%04x" % ord(c)
+
+
+@rule("CharacterEscape", weight=0.8, guard=UNICODE)
+def unicode_escape_braced(ctx):
+ c = ctx.rng.choice(LITERAL + LITERAL_WIDE)
+ ctx.note_literal(c)
+ return "u{%x}" % ord(c)
+
+
+@rule("CharacterEscape", weight=0.8, guard=NOT_UNICODE)
+def unicode_escape_surrogate_pair(ctx):
+ # Without [+UnicodeMode] `\u{...}` is unavailable, so a supplementary code
+ # point is spelled as the surrogate pair it is made of. Under `u`/`v` the
+ # pair would instead combine into the single code point, which is a
+ # different node shape and is covered by unicode_escape_braced.
+ c = ctx.rng.choice([x for x in LITERAL_WIDE if ord(x) > 0xFFFF])
+ ctx.note_literal(c)
+ cp = ord(c)
+ hi = 0xD800 + ((cp - 0x10000) >> 10)
+ lo = 0xDC00 + ((cp - 0x10000) & 0x3FF)
+ return "u%04x\\u%04x" % (hi, lo)
+
+
+@rule("CharacterEscape", weight=1.0, guard=UNICODE)
+def identity_escape(ctx):
+ # [+UnicodeMode] restricts IdentityEscape to SyntaxCharacter and `/`.
+ return ctx.rng.choice(list("^$\\.*+?()[]{}|/"))
+
+
+@rule("CharacterEscape", weight=1.0, guard=NOT_UNICODE)
+def identity_escape_extended(ctx):
+ # Only [~UnicodeMode] admits arbitrary non-ID characters.
+ return ctx.rng.choice(list("^$\\.*+?()[]{}|/-@~"))
+
+
+# CharacterClassEscape :: `d` `D` `s` `S` `w` `W`
+# [+UnicodeMode] `p{...}` `P{...}`
+
+
+@rule("CharacterClassEscape", weight=6.0)
+def perl_class(ctx):
+ return ctx.rng.choice(list("dDsSwW"))
+
+
+@rule("CharacterClassEscape", weight=2.0, guard=UNICODE)
+def unicode_property(ctx):
+ return "%s{%s}" % (ctx.rng.choice("pP"), ctx.rng.choice(UNICODE_PROPERTIES))
+
+
+@rule(
+ "CharacterClassEscape",
+ weight=1.0,
+ guard=lambda c: c.unicode_sets_mode and not c.no_strings)
+def unicode_property_of_strings(ctx):
+ # A property of strings can match more than one character, so it is
+ # v-mode-only and, like `\q{}`, forbidden inside a negated class. `\P{}` of
+ # one is an early error, hence the positive form only.
+ return "p{%s}" % ctx.rng.choice(UNICODE_PROPERTIES_OF_STRINGS)
+
+
+# CharacterClass :: `[` ClassContents `]`
+# `[^` ClassContents `]`
+
+
+@rule("CharacterClass", weight=4.0, recursive=True)
+def positive_class(ctx):
+ with ctx.inside_class():
+ return "[" + expand(ctx, "ClassContents") + "]"
+
+
+@rule("CharacterClass", weight=1.5, recursive=True)
+def negated_class(ctx):
+ # "Negated character class may contain strings": a `\q{}` whose alternatives
+ # are not all single characters makes the class string-valued, which `[^...]`
+ # rejects (MayContainStrings in the spec's static semantics). The flag
+ # suppresses the string disjunction for this subtree.
+ with ctx.inside_class(no_strings=True):
+ return "[^" + expand(ctx, "ClassContents") + "]"
+
+
+# ClassContents :: [empty]
+# [~UnicodeSetsMode] NonemptyClassRanges
+# [+UnicodeSetsMode] ClassSetExpression
+
+
+@rule("ClassContents", weight=0.4)
+def empty_class(ctx):
+ return ""
+
+
+@rule("ClassContents", weight=9.0, guard=NOT_SETS)
+def nonempty_class_ranges(ctx):
+ return repeat(ctx, "ClassRangeItem", 1, 4)
+
+
+@rule("ClassContents", weight=9.0, guard=SETS)
+def class_set_expression(ctx):
+ return expand(ctx, "ClassSetExpression")
+
+
+# NonemptyClassRanges, flattened to one item per expansion: a ClassAtom or
+# a ClassAtom `-` ClassAtom range.
+
+
+@rule("ClassRangeItem", weight=5.0)
+def class_atom(ctx):
+ return expand(ctx, "ClassAtom")
+
+
+@rule("ClassRangeItem", weight=3.0)
+def class_range(ctx):
+ return _random_range(ctx)
+
+
+# ClassAtom :: `-` | ClassAtomNoDash
+# ClassAtomNoDash :: SourceCharacter but not one of `\` or `]` or `-`
+# `\` ClassEscape
+
+
+@rule("ClassAtom", weight=6.0)
+def class_literal(ctx):
+ return ctx.note_literal(ctx.rng.choice(LITERAL))
+
+
+@rule("ClassAtom", weight=0.8)
+def class_literal_wide(ctx):
+ return ctx.note_literal(ctx.rng.choice(LITERAL_WIDE))
+
+
+@rule("ClassAtom", weight=2.0)
+def class_escape(ctx):
+ return "\\" + expand(ctx, "ClassEscape")
+
+
+# ClassEscape :: `b` | [+UnicodeMode] `-` | CharacterClassEscape
+# | CharacterEscape
+
+
+@rule("ClassEscape", weight=1.0)
+def class_backspace(ctx):
+ return "b"
+
+
+@rule("ClassEscape", weight=0.5, guard=UNICODE)
+def class_dash(ctx):
+ return "-"
+
+
+@rule("ClassEscape", weight=4.0)
+def class_perl(ctx):
+ return expand(ctx, "CharacterClassEscape")
+
+
+@rule("ClassEscape", weight=3.0)
+def class_char_escape(ctx):
+ return expand(ctx, "CharacterEscape")
+
+
+# ---- v-mode class set algebra --------------------------------------------
+# ClassSetExpression :: ClassUnion | ClassIntersection | ClassSubtraction
+
+
+@rule("ClassSetExpression", weight=6.0)
+def class_union(ctx):
+ return repeat(ctx, "ClassSetOperandOrRange", 1, 3)
+
+
+@rule("ClassSetExpression", weight=2.5, recursive=True)
+def class_intersection(ctx):
+ n = 2 if ctx.depth >= ctx.max_depth else ctx.rng.randint(2, 3)
+ return "&&".join(expand(ctx, "ClassSetOperand") for _ in range(n))
+
+
+@rule("ClassSetExpression", weight=2.5, recursive=True)
+def class_subtraction(ctx):
+ n = 2 if ctx.depth >= ctx.max_depth else ctx.rng.randint(2, 3)
+ return "--".join(expand(ctx, "ClassSetOperand") for _ in range(n))
+
+
+@rule("ClassSetOperandOrRange", weight=3.0)
+def set_range(ctx):
+ return _random_range(ctx)
+
+
+@rule("ClassSetOperandOrRange", weight=6.0)
+def set_operand(ctx):
+ return expand(ctx, "ClassSetOperand")
+
+
+# ClassSetOperand :: NestedClass | ClassStringDisjunction | ClassSetCharacter
+
+
+@rule("ClassSetOperand", weight=7.0)
+def set_character(ctx):
+ return ctx.note_literal(ctx.rng.choice(CLASS_SET_SAFE))
+
+
+@rule("ClassSetOperand", weight=2.0)
+def set_class_escape(ctx):
+ return "\\" + expand(ctx, "CharacterClassEscape")
+
+
+@rule("ClassSetOperand", weight=1.5, recursive=True)
+def nested_class(ctx):
+ with ctx.inside_class():
+ return "[" + expand(ctx, "ClassSetExpression") + "]"
+
+
+@rule("ClassSetOperand", weight=0.5, recursive=True)
+def nested_negated_class(ctx):
+ # Negation forbids string-valued contents at any nesting depth, so the ban
+ # has to hold for this whole subtree (see negated_class).
+ with ctx.inside_class(no_strings=True):
+ return "[^" + expand(ctx, "ClassSetExpression") + "]"
+
+
+@rule("ClassSetOperand", weight=1.5, guard=lambda c: not c.no_strings)
+def class_string_disjunction(ctx):
+ # `\q{a|bc|}`: a disjunction of literal strings, the one construct that
+ # lets a class match more than a single character.
+ words = []
+ for _ in range(ctx.rng.randint(1, 3)):
+ w = "".join(
+ ctx.rng.choice(CLASS_SET_SAFE) for _ in range(ctx.rng.randint(0, 3)))
+ ctx.note_literal(w)
+ words.append(w)
+ return r"\q{%s}" % "|".join(words)
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/grammar_test.py b/deps/v8/tools/regexp/correctness_fuzzer/grammar_test.py
new file mode 100755
index 00000000000..c43aa1ce6a1
--- /dev/null
+++ b/deps/v8/tools/regexp/correctness_fuzzer/grammar_test.py
@@ -0,0 +1,436 @@
+#!/usr/bin/env python3
+# 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.
+"""Tests for the regexp fuzzer's pattern grammar.
+
+The properties pinned here are the ones that decay silently: a generator
+can keep producing patterns forever while emitting mostly syntax errors,
+or while never reaching a production at all, and only a measurement
+notices. Both were true of the generator this grammar replaced.
+
+The syntax-validity and match-rate tests need a d8 to judge what parses,
+so they are skipped unless one is given:
+
+ tools/regexp/correctness_fuzzer/grammar_test.py --d8 out/x64.release/d8
+
+The rest run without a build.
+"""
+
+import argparse
+import collections
+import inspect
+import json
+import os
+import random
+import re
+import subprocess
+import sys
+import tempfile
+import unittest
+
+import correctness_fuzzer
+import grammar
+from grammar import registry
+
+HARNESS_PATH = os.path.join(
+ os.path.dirname(os.path.realpath(__file__)), "harness.js")
+
+# Set from the command line; None means the d8-dependent tests are skipped.
+D8 = None
+
+
+def run_cases(cases):
+ """Run |cases| through the harness, returning index -> result JSON string."""
+ fd, path = tempfile.mkstemp(prefix="grammar_test_", suffix=".json")
+ try:
+ with os.fdopen(fd, "w") as f:
+ json.dump(cases, f)
+ p = subprocess.run([D8, HARNESS_PATH, "--", path],
+ capture_output=True,
+ text=True,
+ timeout=300)
+ finally:
+ os.unlink(path)
+ results = {}
+ for line in p.stdout.splitlines():
+ key, tab, value = line.partition("\t")
+ if tab and key.isdigit():
+ results[int(key)] = value
+ return results
+
+
+def generate(n, seed=1, **kwargs):
+ rng = random.Random(seed)
+ return [grammar.gen_case(rng, **kwargs) for _ in range(n)]
+
+
+def _in_class(pattern, pos):
+ """Is |pos| inside a character class? Scans, since classes nest in v mode."""
+ depth = i = 0
+ while i < pos:
+ if pattern[i] == "\\":
+ i += 2
+ continue
+ if pattern[i] == "[":
+ depth += 1
+ elif pattern[i] == "]":
+ depth = max(0, depth - 1)
+ i += 1
+ return depth > 0
+
+
+class GrammarStructureTest(unittest.TestCase):
+ """Properties of the grammar itself, checkable without a d8."""
+
+ def test_every_rule_is_reachable(self):
+ # A rule that never fires tests nothing, and no amount of case volume
+ # reveals that on its own -- this is the check that caught a depth-budget
+ # bug where every generated character class came out empty.
+ coverage = collections.Counter()
+ generate(3000, coverage=coverage)
+ missing = [
+ "%s.%s" % (prod, name)
+ for prod, name in grammar.all_rules()
+ if not coverage[(prod, name)]
+ ]
+ self.assertEqual([], missing, "unreachable at the default --max-depth")
+
+ def test_every_profile_reaches_every_rule(self):
+ # A profile reweights rules; setting one to a very low weight in effect
+ # removes it, which should be a deliberate choice rather than a side
+ # effect of tuning some other rule up.
+ for profile in grammar.PROFILES:
+ with self.subTest(profile=profile):
+ coverage = collections.Counter()
+ weights = grammar.parse_weights(profile, None)
+ generate(3000, weights=weights, coverage=coverage)
+ missing = [
+ "%s.%s" % (prod, name)
+ for prod, name in grammar.all_rules()
+ if not coverage[(prod, name)]
+ ]
+ self.assertEqual([], missing)
+
+ def test_mode_specific_syntax_stays_in_its_mode(self):
+ # The spec's [+UnicodeMode] / [+UnicodeSetsMode] parameters are what make
+ # most syntax errors structurally impossible; a rule that loses its guard
+ # would still generate, just invalidly.
+ for pattern, flags, _, _ in generate(4000):
+ if "v" not in flags:
+ self.assertNotIn(r"\q{", pattern)
+ self.assertNotIn("&&", pattern)
+ self.assertNotIn("--", pattern.replace(r"\-", ""))
+ if "u" not in flags and "v" not in flags:
+ self.assertNotIn(r"\p{", pattern)
+ self.assertNotIn(r"\P{", pattern)
+ self.assertNotIn(r"\u{", pattern)
+
+ def test_digit_terminated_escapes_are_separated(self):
+ # `\1` and `\0` are terminated by lookahead, so a digit right after either
+ # silently reparses it. The `(?:)` separator that prevents this is only a
+ # separator between Terms; inside a class it would be four more members.
+ for pattern, _, _, _ in generate(4000):
+ self.assertIsNone(re.search(r"\\[0-9]+[0-9]", pattern), pattern)
+ for m in re.finditer(r"\(\?:\)", pattern):
+ self.assertFalse(_in_class(pattern, m.start()), pattern)
+
+ def test_generation_is_deterministic(self):
+ # Findings are reported as a seed; a generator that drifted would make
+ # every past finding irreproducible.
+ self.assertEqual(generate(200, seed=7), generate(200, seed=7))
+
+ def test_depth_budget_bounds_pattern_size(self):
+ small = max(len(p) for p, _, _, _ in generate(500, max_depth=2))
+ large = max(len(p) for p, _, _, _ in generate(500, max_depth=6))
+ self.assertLess(small, large)
+
+ def test_unknown_profile_and_rule_are_rejected(self):
+ with self.assertRaises(ValueError):
+ grammar.parse_weights("no-such-profile", None)
+ with self.assertRaises(ValueError):
+ grammar.parse_weights("default", ["No.Such.Rule=2"])
+ with self.assertRaises(ValueError):
+ grammar.parse_weights("default", ["missing-equals-sign"])
+
+ def test_unknown_production_is_reported(self):
+ # A mistyped production used to surface as an UnboundLocalError from
+ # inside expand(), with the offending name nowhere in the traceback.
+ ctx = grammar.Context(random.Random(1), False, False, 5)
+ with self.assertRaises(grammar.GrammarError) as e:
+ grammar.expand(ctx, "Disjuncton")
+ self.assertIn("no such production", str(e.exception))
+ self.assertIn("Disjuncton", str(e.exception))
+ # The registry was a defaultdict, so merely looking a typo up created it;
+ # a later real rule would then have joined the phantom production instead
+ # of the intended one.
+ self.assertNotIn("Disjuncton", registry.GRAMMAR)
+
+ def test_production_with_no_eligible_alternative_is_reported(self):
+ # Distinct from a typo: the production exists, but every alternative is
+ # guarded off for these parameters, which is a live derivation dead end
+ # rather than a misspelling.
+ ctx = grammar.Context(random.Random(1), False, False, 5)
+
+ @registry.rule("OnlyGuardedOff", guard=lambda c: c.unicode_mode)
+ def _unreachable(ctx):
+ return ""
+
+ try:
+ with self.assertRaises(grammar.GrammarError) as e:
+ grammar.expand(ctx, "OnlyGuardedOff")
+ self.assertIn("guarded off", str(e.exception))
+ finally:
+ del registry.GRAMMAR["OnlyGuardedOff"]
+
+ def test_duplicate_rule_names_are_rejected(self):
+ # Rules are addressed as "Production.rule" by --weight and the coverage
+ # report, so a duplicate would make one of the two unreachable.
+ @registry.rule("DuplicateProbe")
+ def probe(ctx):
+ return ""
+
+ try:
+ with self.assertRaises(grammar.GrammarError):
+
+ @registry.rule("DuplicateProbe")
+ def probe(ctx): # noqa: F811 (the point is the redefinition)
+ return ""
+ finally:
+ del registry.GRAMMAR["DuplicateProbe"]
+
+ def test_rules_make_no_hidden_weighted_choices(self):
+ # Every choice between meaningfully different outputs belongs to a rule
+ # with its own weight; an rng call inside a rule body would be a weight
+ # that neither --weight nor --coverage can reach. Drawing a character
+ # from a pool is not such a choice, so `choice` is allowed and the
+ # branching primitives are not.
+ src = inspect.getsource(sys.modules["grammar.rules"])
+ for lineno, line in enumerate(src.splitlines(), 1):
+ code = line.split("#")[0]
+ self.assertNotIn("rng.random()", code, "grammar/rules.py:%d" % lineno)
+
+ def test_quantifier_bounds_reach_past_the_unroll_threshold(self):
+ # RegExpQuantifier unrolls a body when min is in 1..kMaxUnrolledMinMatches
+ # (3, regexp-compiler-tonode.cc), recursing on the remainder -- so {2,5}
+ # unrolls entirely and "some bound exceeds 3" is not the property that
+ # matters. A min above the threshold is what forces the counter-based
+ # loop; {0,} is excluded deliberately, since it is only `*` spelled the
+ # long way and reaches no node shape the bare quantifiers miss.
+ #
+ # Counted off the QuantifierPrefix rules rather than off the pattern text,
+ # which cannot tell a quantifier from a `\q{9}` or a `{` inside a class.
+ counted = looping = 0
+ rng = random.Random(1)
+ for _ in range(3000):
+ ctx = grammar.Context(rng, False, False, 5)
+ m = re.fullmatch(r"\{(\d+),?\d*\}",
+ grammar.expand(ctx, "QuantifierPrefix"))
+ if m:
+ counted += 1
+ if int(m.group(1)) > 3:
+ looping += 1
+ self.assertTrue(counted, "no counted quantifiers generated at all")
+ self.assertGreater(
+ looping, 0, "every counted quantifier min stays "
+ "within the unroll threshold")
+
+ def test_flags_cover_the_result_shaping_ones(self):
+ # `g` drives the global lastIndex path (distinct from sticky) and `d`
+ # adds match indices, a whole output surface; neither was generated
+ # before.
+ seen = set()
+ for _, flags, _, _ in generate(2000):
+ seen.update(flags)
+ self.assertEqual(set("dgimsuvy"), seen)
+
+ def test_u_and_v_are_never_combined(self):
+ for _, flags, _, _ in generate(3000):
+ self.assertFalse("u" in flags and "v" in flags, flags)
+
+ def test_weight_override_shifts_the_distribution(self):
+
+ def caret_share(weights):
+ coverage = collections.Counter()
+ generate(1500, weights=weights, coverage=coverage)
+ return coverage[("Assertion", "caret")]
+
+ base = caret_share(None)
+ boosted = caret_share(
+ grammar.parse_weights("default", ["Assertion.caret=20"]))
+ self.assertGreater(boosted, base)
+
+
+class ClassificationTest(unittest.TestCase):
+ """How a pair of harness results is turned into a finding.
+
+ The batch scan and the single-case path share this, so a disagreement
+ between them shows up as a finding that cannot be reproduced or minimized.
+ """
+
+ OK = '{"cold":{"r":["a"],"idx":0,"li":0},"warm":{"r":["a"],"idx":0,"li":0}}'
+ OTHER = '{"cold":{"r":["z"],"idx":0,"li":0},"warm":{"r":["z"],"idx":0,"li":0}}'
+ SELF_DIFF = ('{"cold":{"r":["a"],"idx":0,"li":0},'
+ '"warm":{"r":["b"],"idx":0,"li":0}}')
+
+ def test_identical_clean_results_are_not_a_finding(self):
+ self.assertIsNone(correctness_fuzzer.classify(0, self.OK, 0, self.OK))
+
+ def test_test_disagreeing_with_reference_is_a_divergence(self):
+ self.assertEqual("DIVERGENCE",
+ correctness_fuzzer.classify(0, self.OK, 0, self.OTHER))
+
+ def test_a_configuration_disagreeing_with_itself_is_a_finding(self):
+ # Needs no reference: the two execs are the same regexp over the same
+ # subject, so whichever side does this is wrong on its own.
+ for ref, test in ((self.SELF_DIFF, self.OK), (self.OK, self.SELF_DIFF)):
+ self.assertEqual("COLD/WARM",
+ correctness_fuzzer.classify(0, ref, 0, test))
+
+ def test_a_reference_error_establishes_no_ground_truth(self):
+ # Syntax the reference rejects, and an exec that raised (a stack or
+ # backtrack limit), are both configuration-dependent rather than wrong
+ # answers -- reporting them would bury real findings.
+ for ref in (
+ '"ERR_CTOR"',
+ '{"cold":"ERR_EXEC:SyntaxError","warm":"ERR_EXEC:SyntaxError"}'):
+ self.assertIsNone(correctness_fuzzer.classify(0, ref, 0, self.OK))
+
+ def test_a_hard_abort_is_a_finding_regardless(self):
+ self.assertEqual("CRASH",
+ correctness_fuzzer.classify(0, self.OK, 1, self.OK))
+
+ def test_a_timeout_establishes_no_ground_truth(self):
+ self.assertIsNone(
+ correctness_fuzzer.classify(correctness_fuzzer.TIMEOUT_RC, None, 0,
+ self.OK))
+
+ def test_a_missing_result_line_is_a_divergence(self):
+ # One side crashed or timed out partway and never emitted this case.
+ self.assertEqual("DIVERGENCE",
+ correctness_fuzzer.classify(0, self.OK, 0, None))
+
+
+class MinimizerTest(unittest.TestCase):
+ """Shrinking, which has to keep up with the large quantifier bounds."""
+
+ def test_large_bounds_shrink_in_log_steps(self):
+ # Decrementing a bound in the hundreds costs one run of both
+ # configurations per unit, which dominates the whole minimization.
+ self.assertEqual([0, 1, 250, 375, 499],
+ list(correctness_fuzzer._shrink_targets(500)))
+ self.assertEqual([0], list(correctness_fuzzer._shrink_targets(1)))
+ self.assertEqual([], list(correctness_fuzzer._shrink_targets(0)))
+
+ def test_quantifier_forms_round_trip(self):
+ self.assertEqual("{5}", correctness_fuzzer._quantifier(5, False, None))
+ self.assertEqual("{5,}", correctness_fuzzer._quantifier(5, True, None))
+ self.assertEqual("{5,9}", correctness_fuzzer._quantifier(5, True, 9))
+
+ def test_minimization_converges_on_a_large_bound(self):
+
+ class StubRunner:
+ """Reports a finding while any quantifier min is still >= 3."""
+
+ def __init__(self):
+ self.calls = 0
+
+ def finding(self, pattern, flags, subject, last_index=0):
+ self.calls += 1
+ return any(
+ int(m.group(1)) >= 3
+ for m in re.finditer(r"\{(\d+),?\d*\}", pattern))
+
+ runner = StubRunner()
+ pattern, _, _, _ = correctness_fuzzer.minimize(runner, "a{200,900}b", "",
+ "ab")
+ # 3 is the smallest bound this stub still reproduces at, so the shrink has
+ # to reach it exactly -- stopping early would leave a repro carrying a
+ # bound that has nothing to do with the finding. The literals go too,
+ # since this stub looks at nothing else.
+ self.assertEqual("{3}", pattern)
+ # A decrementing shrink would need hundreds of runs to get here.
+ self.assertLess(runner.calls, 100)
+
+
+class GeneratedPatternTest(unittest.TestCase):
+ """Properties that only a real engine can judge."""
+
+ def setUp(self):
+ # Checked here rather than with a class decorator: D8 is set by main()
+ # after this module is imported, so a decorator would capture None.
+ if D8 is None:
+ self.skipTest("needs --d8")
+
+ def test_patterns_are_syntactically_valid(self):
+ # The generator this replaced emitted 44% syntax errors, so nearly half of
+ # every run was discarded before executing anything. Zero is the right bar
+ # rather than a small percentage: every error found so far came from a
+ # context-sensitivity the grammar has to model (a lookahead constraint, a
+ # static-semantics rule), and each showed up in well under 0.1% of cases --
+ # a tolerance wide enough to absorb one is wide enough to hide it.
+ for seed in (11, 13, 17):
+ with self.subTest(seed=seed):
+ cases = generate(4000, seed=seed)
+ results = run_cases(cases)
+ bad = [cases[i][:2] for i, r in results.items() if r == '"ERR_CTOR"']
+ self.assertEqual([], bad[:10], "syntax errors")
+
+ def test_a_meaningful_share_of_cases_match(self):
+ # Subjects are drawn from the characters the pattern mentions. Without
+ # that, cases fail at the first character and only the reject path is
+ # tested; the previous generator matched on 21% of cases, and 64% of those
+ # were empty-string matches.
+ cases = generate(4000, seed=13)
+ results = run_cases(cases)
+ matched = [
+ r for r in results.values()
+ if r != '"ERR_CTOR"' and json.loads(r).get("warm") is not None
+ ]
+ self.assertGreater(len(matched) / len(cases), 0.3)
+ nonempty = [r for r in matched if json.loads(r)["warm"]["r"][0] != ""]
+ self.assertGreater(len(nonempty) / len(matched), 0.3)
+
+ def test_the_two_execs_agree(self):
+ # The harness reports a cold and a warm exec of every case and the driver
+ # treats a mismatch as a finding, so a clean engine has to produce zero of
+ # them -- otherwise the check is noise rather than a signal.
+ cases = generate(4000, seed=19)
+ disagreed = [
+ cases[i]
+ for i, r in run_cases(cases).items()
+ if r != '"ERR_CTOR"' and json.loads(r)["cold"] != json.loads(r)["warm"]
+ ]
+ self.assertEqual([], disagreed[:10])
+
+ def test_harness_reports_lastindex(self):
+ # lastIndex selects where a sticky attempt starts; it was never varied
+ # before, which is half of sticky semantics untested.
+ results = run_cases([["a", "y", "ba", 1], ["a", "y", "ba", 0]])
+ self.assertEqual(2, json.loads(results[0])["warm"]["li"])
+ self.assertIsNone(json.loads(results[1])["warm"])
+
+ def test_harness_reports_indices_and_groups(self):
+ # `d` and `(?<name>)` add result surfaces built by their own code paths.
+ results = run_cases([["(?<g>a)(b)", "d", "ab", 0], ["a", "", "a", 0]])
+ warm = json.loads(results[0])["warm"]
+ self.assertEqual([[0, 2], [0, 1], [1, 2]], warm["di"])
+ self.assertEqual({"g": [0, 1]}, warm["dg"])
+ self.assertEqual({"g": "a"}, warm["g"])
+ # Absent without the flag or the construct, rather than reported as null.
+ self.assertNotIn("di", json.loads(results[1])["warm"])
+
+
+def main():
+ ap = argparse.ArgumentParser(description=__doc__)
+ ap.add_argument("--d8", help="d8 binary; enables the execution tests")
+ args, remaining = ap.parse_known_args()
+ global D8
+ D8 = args.d8
+ if D8 is None:
+ print("no --d8 given; skipping the tests that need one", file=sys.stderr)
+ unittest.main(argv=[sys.argv[0]] + remaining)
+
+
+if __name__ == "__main__":
+ main()
diff --git a/deps/v8/tools/regexp/correctness_fuzzer/harness.js b/deps/v8/tools/regexp/correctness_fuzzer/harness.js
index ec9b9637ac0..e1f8daf51ce 100644
--- a/deps/v8/tools/regexp/correctness_fuzzer/harness.js
+++ b/deps/v8/tools/regexp/correctness_fuzzer/harness.js
@@ -3,26 +3,61 @@
// found in the LICENSE file.
// d8 harness for the regexp correctness fuzzer. Reads a JSON array of
-// [pattern, flags, subject] triples from the file named on the command line
-// and prints one result line per case as "<index>\t<json>". The result is
+// [pattern, flags, subject, lastIndex] cases from the file named on the command
+// line and prints one result line per case as "<index>\t<json>". The result is
// null, an error marker string ("ERR_CTOR" or "ERR_EXEC:<name>"), or
// {r:[captures], idx, li}. Construction and exec errors are captured rather
// than thrown so a single bad case does not abort the batch; both markers
// share the "ERR_" prefix so the driver can treat either as "no ground
// truth" with a single check.
+//
+// lastIndex is set before exec and read back after: for a sticky or global
+// pattern it selects where the attempt starts and is updated by the result, so
+// it is part of the observable behaviour being diffed. It is optional so a
+// hand-written repro can omit it.
+//
+// Each case runs on two separately constructed JSRegExps and both results are
+// reported. The first exec compiles the pattern; what that compile leaves on
+// the RegExpData (generated code, quick-check mask, first-character filter)
+// reaches the second object through the compilation cache, so the second runs
+// warm along paths a single-shot run would never take.
+//
+// Both objects are identical and start from the same lastIndex, so their
+// results must agree whatever either configuration computes. A mismatch is a
+// bug in that configuration by itself -- the one class a two-config diff
+// cannot see, since it survives being wrong on both sides.
const cases = JSON.parse(read(arguments[0]));
for (let i = 0; i < cases.length; i++) {
- const [pat, flags, sub] = cases[i];
+ const [pat, flags, sub, lastIndex] = cases[i];
let out;
try {
- const re = new RegExp(pat, flags);
- let m;
- try { m = re.exec(sub); } catch (e) { m = "ERR_EXEC:" + e.name; }
- out = (m === null) ? null
- : (typeof m === "string") ? m
- : {r: Array.from(m, x => x === undefined ? "<u>" : x),
- idx: m.index, li: re.lastIndex};
+ const cold = execOnce(pat, flags, sub, lastIndex);
+ const warm = execOnce(pat, flags, sub, lastIndex);
+ out = {cold: cold, warm: warm};
} catch (e) { out = "ERR_CTOR"; }
print(i + "\t" + JSON.stringify(out));
}
print("DONE");
+
+// One construct-and-exec. Throws only if the constructor does, which is a
+// property of the pattern rather than of this attempt, so it fails the whole
+// case as ERR_CTOR.
+function execOnce(pat, flags, sub, lastIndex) {
+ const re = new RegExp(pat, flags);
+ if (lastIndex) re.lastIndex = lastIndex;
+ let m;
+ try { m = re.exec(sub); } catch (e) { return "ERR_EXEC:" + e.name; }
+ if (m === null) return null;
+ const r = {r: Array.from(m, x => x === undefined ? "<u>" : x),
+ idx: m.index, li: re.lastIndex};
+ // `d` adds match indices and `(?<name>)` adds the groups object; both are
+ // separately constructed result surfaces, so they are diffed too. Marked
+ // explicitly rather than left undefined, since presence is itself a
+ // difference worth catching.
+ if (m.indices !== undefined) {
+ r.di = Array.from(m.indices, x => x === undefined ? "<u>" : x);
+ r.dg = m.indices.groups === undefined ? "<u>" : m.indices.groups;
+ }
+ if (m.groups !== undefined) r.g = m.groups;
+ return r;
+}
diff --git a/deps/v8/tools/release/common_includes.py b/deps/v8/tools/release/common_includes.py
index 1bc6f96db57..492a375f22c 100644
--- a/deps/v8/tools/release/common_includes.py
+++ b/deps/v8/tools/release/common_includes.py
@@ -624,16 +624,16 @@ class Step(GitRecipesMixin):
output = ""
for line in FileToText(version_file).splitlines():
if line.startswith("#define V8_MAJOR_VERSION"):
- line = re.sub("\d+$", self[prefix + "major"], line)
+ line = re.sub(r"\d+$", self[prefix + "major"], line)
elif line.startswith("#define V8_MINOR_VERSION"):
- line = re.sub("\d+$", self[prefix + "minor"], line)
+ line = re.sub(r"\d+$", self[prefix + "minor"], line)
elif line.startswith("#define V8_BUILD_NUMBER"):
- line = re.sub("\d+$", self[prefix + "build"], line)
+ line = re.sub(r"\d+$", self[prefix + "build"], line)
elif line.startswith("#define V8_PATCH_LEVEL"):
- line = re.sub("\d+$", self[prefix + "patch"], line)
+ line = re.sub(r"\d+$", self[prefix + "patch"], line)
elif (self[prefix + "candidate"] and
line.startswith("#define V8_IS_CANDIDATE_VERSION")):
- line = re.sub("\d+$", self[prefix + "candidate"], line)
+ line = re.sub(r"\d+$", self[prefix + "candidate"], line)
output += "%s\n" % line
TextToFile(output, version_file)
diff --git a/deps/v8/tools/release/create_release.py b/deps/v8/tools/release/create_release.py
index 7d9f13bb8ba..f5f401ac779 100755
--- a/deps/v8/tools/release/create_release.py
+++ b/deps/v8/tools/release/create_release.py
@@ -118,7 +118,7 @@ class EnableMergeWatchlist(Step):
def RunStep(self):
old_watchlist_content = FileToText(os.path.join(self.default_cwd,
WATCHLISTS_FILE))
- new_watchlist_content = re.sub("(# 'v8-merges@googlegroups\.com',)",
+ new_watchlist_content = re.sub(r"(# 'v8-merges@googlegroups\.com',)",
"'v8-merges@googlegroups.com',",
old_watchlist_content)
TextToFile(new_watchlist_content, os.path.join(self.default_cwd,
diff --git a/deps/v8/tools/release/mergeinfo.py b/deps/v8/tools/release/mergeinfo.py
index 18bb486051f..b98eac5427b 100755
--- a/deps/v8/tools/release/mergeinfo.py
+++ b/deps/v8/tools/release/mergeinfo.py
@@ -88,7 +88,7 @@ def get_first_canary(branches):
return canaries[0].split('/')[-1]
def get_first_v8_version(branches):
- version_re = re.compile("remotes/origin/[0-9]+\.[0-9]+\.[0-9]+")
+ version_re = re.compile(r"remotes/origin/[0-9]+\.[0-9]+\.[0-9]+")
versions = [branch for branch in branches if version_re.match(branch)]
if len(versions) == 0:
return "--"
diff --git a/deps/v8/tools/run-clang-tidy.py b/deps/v8/tools/run-clang-tidy.py
index b5de57ac3c9..77edc09748e 100755
--- a/deps/v8/tools/run-clang-tidy.py
+++ b/deps/v8/tools/run-clang-tidy.py
@@ -18,7 +18,7 @@ import sys
CLANG_TIDY_WARNING = re.compile(r'(\/.*?)\ .*\[(.*)\]$')
CLANG_TIDY_CMDLINE_OUT = re.compile(r'^clang-tidy.*\ .*|^\./\.\*')
FILE_REGEXS = ['../src/*', '../test/*']
-HEADER_REGEX = ['\.\.\/src\/.*|\.\.\/include\/.*|\.\.\/test\/.*']
+HEADER_REGEX = [r'\.\.\/src\/.*|\.\.\/include\/.*|\.\.\/test\/.*']
THREADS = multiprocessing.cpu_count()
diff --git a/deps/v8/tools/run_perf.py b/deps/v8/tools/run_perf.py
index ca3e9405186..3e7bd8340b7 100755
--- a/deps/v8/tools/run_perf.py
+++ b/deps/v8/tools/run_perf.py
@@ -5,7 +5,7 @@
from __future__ import annotations
-"""
+r"""
Performance runner for d8.
Call e.g. with tools/run-perf.py --arch x64 some_suite.json
diff --git a/deps/v8/tools/sanitizers/sancov_formatter.py b/deps/v8/tools/sanitizers/sancov_formatter.py
index 126acbd8f89..4062c4897c6 100755
--- a/deps/v8/tools/sanitizers/sancov_formatter.py
+++ b/deps/v8/tools/sanitizers/sancov_formatter.py
@@ -168,9 +168,9 @@ def get_instrumented_lines(executable):
# We don't call the sancov tool to get more speed.
process = subprocess.Popen(
'objdump -d %s | '
- 'grep \'^\s\+[0-9a-f]\+:.*\scall\(q\|\)\s\+[0-9a-f]\+ '
- '<__sanitizer_cov\(_with_check\|\|_trace_pc_guard\)\(@plt\|\)>\' | '
- 'grep \'^\s\+[0-9a-f]\+\' -o | '
+ r"grep '^\s\+[0-9a-f]\+:.*\scall\(q\|\)\s\+[0-9a-f]\+ "
+ r"<__sanitizer_cov\(_with_check\|\|_trace_pc_guard\)\(@plt\|\)>' | "
+ r"grep '^\s\+[0-9a-f]\+' -o | "
'%s | '
'%s --obj %s -functions=none' %
(executable, SANITIZE_PCS, SYMBOLIZER, executable),
diff --git a/deps/v8/tools/testrunner/base_runner.py b/deps/v8/tools/testrunner/base_runner.py
index d561aa8ed9e..fc6f747dc75 100644
--- a/deps/v8/tools/testrunner/base_runner.py
+++ b/deps/v8/tools/testrunner/base_runner.py
@@ -122,6 +122,28 @@ TRY_RELEASE_MODE = ModeConfig(
status_mode="debug",
)
+# Environment variables set by AI coding agents. Duplicated from depot_tools'
+# gclient_utils.AI_AGENT_ENV_VARS rather than imported, because the swarming
+# isolate ships tools/testrunner/ without depot_tools (see v8_testrunner in
+# tools/BUILD.gn). Keep both lists in sync.
+AI_AGENT_ENV_VARS = (
+ "GEMINI_CLI",
+ "CLAUDECODE",
+ "ANTIGRAVITY_AGENT",
+ "CODEX_SANDBOX",
+ "CURSOR_AGENT",
+ "AI_AGENT",
+)
+
+
+def detected_ai_agent_env_vars():
+ """Returns the names of the AI agent environment variables that are set."""
+ return [
+ name for name in AI_AGENT_ENV_VARS
+ if os.environ.get(name, '').lower() not in ('', '0', 'false')
+ ]
+
+
# Set up logging. No need to log a date in timestamps as we can get that from
# test run start times.
logging.basicConfig(
@@ -194,8 +216,9 @@ class BaseTestRunner(object):
self._setup_env()
names = self._args_to_suite_names(args)
tests = self._load_testsuite_generators(ctx, names)
- print(">>> Running tests for %s.%s" % (self.build_config.arch,
- self.mode_options.label))
+ if not self.options.quiet:
+ print(">>> Running tests for %s.%s" %
+ (self.build_config.arch, self.mode_options.label))
return self._do_execute(tests, args, ctx)
except TestRunnerError:
traceback.print_exc()
@@ -262,9 +285,21 @@ class BaseTestRunner(object):
"-p",
"--progress",
choices=list(PROGRESS_INDICATORS.keys()),
- default="mono",
+ default=None,
help="The style of progress indicator (verbose, dots, "
- "color, mono, none)")
+ "color, mono, none). Defaults to mono, or to none in quiet mode.")
+ parser.add_option(
+ "--quiet",
+ default=None,
+ action="store_true",
+ help="Suppress the build, status file and progress headers, "
+ "keeping failures and the number of tests that ran. Enabled by "
+ "default when an AI agent environment variable is set.")
+ parser.add_option(
+ "--no-quiet",
+ dest="quiet",
+ action="store_false",
+ help="Print the usual output even in an AI agent environment.")
parser.add_option("--json-test-results",
help="Path to a file for storing json results.")
parser.add_option("--log-system-memory",
@@ -337,6 +372,19 @@ class BaseTestRunner(object):
options.test_root = Path(options.test_root)
options.outdir = Path(options.outdir)
+ if options.quiet is None:
+ detected = detected_ai_agent_env_vars()
+ options.quiet = bool(detected)
+ if options.quiet:
+ # Spell out what was suppressed, so that the missing output isn't
+ # mistaken for a broken run.
+ print(f"Detected AI agent env ({', '.join(detected)}). Prepending"
+ " --quiet --progress=none to suppress the status file variables"
+ " and the progress display. Failures and the number of tests"
+ " that ran are still printed. Pass --no-quiet to opt out.")
+ if options.progress is None:
+ options.progress = 'none' if options.quiet else 'mono'
+
if options.arch and ',' in options.arch: # pragma: no cover
print('Multiple architectures are deprecated')
raise TestRunnerError()
@@ -368,7 +416,8 @@ class BaseTestRunner(object):
print('Failed to load build config')
raise TestRunnerError
- print('Build found: %s' % self.outdir)
+ if not self.options.quiet:
+ print('Build found: %s' % self.outdir)
# Represents the OS where tests are run on. Same as host OS except for
# Android and iOS, which are determined by build output.
@@ -592,8 +641,9 @@ class BaseTestRunner(object):
def _load_testsuite_generators(self, ctx, names):
test_config = self._create_test_config()
variables = self._get_statusfile_variables(ctx)
- print('>>> Statusfile variables:')
- print(', '.join(f'{k}={v}' for k, v in sorted(variables.items())))
+ if not self.options.quiet:
+ print('>>> Statusfile variables:')
+ print(', '.join(f'{k}={v}' for k, v in sorted(variables.items())))
# Head generator with no elements
test_chain = testsuite.TestGenerator(0, [], [], [])
diff --git a/deps/v8/tools/testrunner/local/variants.py b/deps/v8/tools/testrunner/local/variants.py
index 1bad92e46d4..653dcf6eef0 100644
--- a/deps/v8/tools/testrunner/local/variants.py
+++ b/deps/v8/tools/testrunner/local/variants.py
@@ -207,7 +207,6 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
],
"jitless":
kIncompatibleFlagsForNoTurbofan + [
- "--no-jitless",
"--track-field-types",
"--sparkplug",
"--concurrent-sparkplug",
@@ -219,7 +218,6 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
"--script-context-cells",
],
"nooptimization": [
- "--no-disable-optimizing-compilers",
"--turbofan",
"--turboshaft",
"--wasm-in-js-inlining-body",
@@ -235,7 +233,6 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
"--additive-safe-int-feedback",
"--script-context-cells",
],
- "slow_path": ["--no-force-slow-path"],
"stress_concurrent_allocation": [
"--single-threaded", "--single-threaded-gc", "--predictable"
],
@@ -257,20 +254,16 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
kIncompatibleFlagsForNoLiftoff,
"turbofan_random_rescheduling":
kIncompatibleFlagsForNoLiftoff,
- "sparkplug": ["--jitless", "--no-sparkplug"],
+ "sparkplug": ["--jitless"],
"concurrent_sparkplug": ["--jitless"],
- "maglev": ["--jitless", "--no-maglev"],
- "maglev_future": ["--jitless", "--no-maglev", "--no-maglev-future"],
+ "maglev": ["--jitless"],
+ "maglev_future": ["--jitless"],
"maglev_no_turbofan": [
"--jitless",
- "--no-maglev",
- "--turbofan",
"--stress-concurrent-inlining",
],
"maglev_no_turbofan_regexp_from_bc": [
"--jitless",
- "--no-maglev",
- "--turbofan",
"--stress-concurrent-inlining",
"--no-regexp-tier-up",
"--regexp-interpret-all",
@@ -278,18 +271,16 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
"stress_maglev": ["--jitless"],
"stress_maglev_tracing": ["--jitless"],
"stress_maglev_non_eager_inlining": ["--jitless"],
- "stress_maglev_future": ["--jitless", "--no-maglev", "--no-maglev-future"],
+ "stress_maglev_future": ["--jitless"],
"stress_maglev_no_turbofan": [
"--jitless",
- "--no-maglev",
- "--turbofan",
"--stress-concurrent-inlining",
],
"stress_maglev_tests_with_turbofan": ["--jitless"],
"turbolev_future": ["--no-turbolev",],
"stress_turbolev_future": ["--no-turbolev",],
- "always_sparkplug": ["--jitless", "--no-sparkplug"],
- "always_sparkplug_and_stress_regexp_jit": ["--jitless", "--no-sparkplug"],
+ "always_sparkplug": ["--jitless"],
+ "always_sparkplug_and_stress_regexp_jit": ["--jitless"],
"code_serializer": [
"--cache=after-execute", "--cache=full-code-cache", "--cache=none"
],
@@ -300,8 +291,7 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
"--no-regexp-tier-up", "--regexp-interpret-all", "--jitless"
],
"assert_types": [
- "--concurrent-recompilation", "--stress_concurrent_inlining",
- "--no-assert-types"
+ "--concurrent-recompilation", "--stress_concurrent_inlining"
],
"wasm_assert_types": [
# 'wasm_assert_types' disables Liftoff, which conflicts with flags that
@@ -311,9 +301,33 @@ INCOMPATIBLE_FLAGS_PER_VARIANT = {
"--wasm-deopt",
],
"verify_turboshaft": ["--jitless"],
- "stress_wasm_stack_switching": ["--no-stress-wasm-stack-switching"],
}
+
+# Note this can get it wrong if the flag name starts with the characters "--no"
+# where "no" is part of the flag name, e.g. "--nobodys-perfect". In that case
+# the negation "--bodys-perfect" would be returned. This is a weakness we accept
+# and hope to never run into.
+def negate_flag(flag):
+ # Exclude flags with values, like --regexp-tier-up-ticks=0
+ if '=' in flag:
+ return None
+ if flag.startswith("--no-"):
+ return "--" + flag.removeprefix("--no-")
+ if flag.startswith("--no"):
+ return "--" + flag.removeprefix("--no")
+ return "--no-" + flag.removeprefix("--")
+
+
+for _variant, _flags in ALL_VARIANT_FLAGS.items():
+ # Create a new list to avoid modifying constants.
+ _incompatible = list(INCOMPATIBLE_FLAGS_PER_VARIANT.get(_variant, []))
+ for _flag in _flags:
+ _negated = negate_flag(_flag)
+ if _negated and _negated not in _incompatible:
+ _incompatible.append(_negated)
+ INCOMPATIBLE_FLAGS_PER_VARIANT[_variant] = _incompatible
+
# Flags that lead to a contradiction under certain build variables.
# This corresponds to the build variables usable in status files as generated
# in _get_statusfile_variables in base_runner.py.
diff --git a/deps/v8/tools/testrunner/objects/testcase.py b/deps/v8/tools/testrunner/objects/testcase.py
index 789d59e3ef8..675016eb8e6 100644
--- a/deps/v8/tools/testrunner/objects/testcase.py
+++ b/deps/v8/tools/testrunner/objects/testcase.py
@@ -36,6 +36,7 @@ from testrunner.local import statusfile
from testrunner.local.variants import INCOMPATIBLE_FLAGS_PER_VARIANT
from testrunner.local.variants import INCOMPATIBLE_FLAGS_PER_BUILD_VARIABLE
from testrunner.local.variants import INCOMPATIBLE_FLAGS_PER_EXTRA_FLAG
+from testrunner.local.variants import negate_flag
FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)")
@@ -222,16 +223,9 @@ class TestCase(object):
def normalize_flags(flags):
return [normalize_flag(flag) for flag in filter_flags(flags)]
- # Note this can get it wrong if the flag name starts with the characters
- # "--no" where "no" is part of the flag name, e.g. "--nobodys-perfect".
- # In that case the negation "--bodys-perfect" would be returned. This is
- # a weakness we accept and hope to never run into.
- def negate_flag(normalized_flag):
- return ("--" + normalized_flag[4:] if normalized_flag.startswith("--no")
- else "--no" + normalized_flag[2:])
-
def negate_flags(normalized_flags):
- return [negate_flag(flag) for flag in normalized_flags]
+ negated = (negate_flag(f) for f in normalized_flags)
+ return [f for f in negated if f is not None]
def find_flag(conflicting_flag, flags):
conflicting_flag = normalize_flag(conflicting_flag)
diff --git a/deps/v8/tools/testrunner/outproc/test262.py b/deps/v8/tools/testrunner/outproc/test262.py
index 2bc3c224849..8f0fb5bc572 100644
--- a/deps/v8/tools/testrunner/outproc/test262.py
+++ b/deps/v8/tools/testrunner/outproc/test262.py
@@ -38,7 +38,7 @@ class ExceptionOutProc(base.OutProc):
# somefile:somelinenumber: someerror[: sometext]
# somefile might include an optional drive letter on windows e.g. "e:".
match = re.search(
- '^(?:\w:)?[^:]*:[0-9]+: ([^: ]+?)($|: )', string, re.MULTILINE)
+ r'^(?:\w:)?[^:]*:[0-9]+: ([^: ]+?)($|: )', string, re.MULTILINE)
if match:
return match.group(1).strip()
else:
diff --git a/deps/v8/tools/testrunner/standard_runner.py b/deps/v8/tools/testrunner/standard_runner.py
index 48320dcaaec..42c921adec7 100755
--- a/deps/v8/tools/testrunner/standard_runner.py
+++ b/deps/v8/tools/testrunner/standard_runner.py
@@ -284,7 +284,8 @@ class StandardTestRunner(base_runner.BaseTestRunner):
def _do_execute(self, tests, args, ctx):
jobs = self.options.j
- print('>>> Running with test processors')
+ if not self.options.quiet:
+ print('>>> Running with test processors')
loader = LoadProc(tests, initial_batch_size=self.options.j * 2)
results = ResultsTracker.create(self.options)
outproc_factory = None
diff --git a/deps/v8/tools/testrunner/standard_runner_test.py b/deps/v8/tools/testrunner/standard_runner_test.py
index 426b1a96e51..0b2dee062c4 100644
--- a/deps/v8/tools/testrunner/standard_runner_test.py
+++ b/deps/v8/tools/testrunner/standard_runner_test.py
@@ -138,6 +138,63 @@ class StandardRunnerTest(TestRunnerTest):
result.stdout_includes('sweet/strawberries default: FAIL')
result.has_returncode(1)
+ def testQuiet(self):
+ """Test that quiet mode drops everything but failures and the counts."""
+ result = self.run_tests(
+ '--quiet',
+ '--variants=default',
+ 'sweet/bananas',
+ 'sweet/strawberries',
+ infra_staging=False,
+ )
+ result.stdout_includes('sweet/strawberries')
+ result.stdout_includes('1 tests failed')
+ result.stdout_includes('>>> 2 tests ran')
+ result.stdout_excludes('Statusfile variables')
+ result.stdout_excludes('Build found')
+ result.stdout_excludes('Running with test processors')
+ result.stdout_excludes('non-filtered tests')
+ result.has_returncode(1)
+
+ def testQuietReportsZeroTestsRan(self):
+ """Test that quiet mode doesn't report a filter matching nothing as a
+ plain success."""
+ result = self.run_tests(
+ '--quiet',
+ '--variants=default',
+ 'sweet/no-such-test',
+ infra_staging=False,
+ )
+ result.stdout_includes('>>> 0 tests ran')
+ result.has_returncode(2)
+
+ def testQuietFromAiAgentEnv(self):
+ """Test that an AI agent environment implies quiet mode."""
+ result = self.run_tests(
+ '--variants=default',
+ 'sweet/bananas',
+ infra_staging=False,
+ ai_agent_vars=['AI_AGENT'],
+ )
+ result.stdout_includes('Detected AI agent env (AI_AGENT)')
+ result.stdout_includes('>>> 1 tests ran')
+ result.stdout_excludes('Statusfile variables')
+ result.stdout_excludes('non-filtered tests')
+ result.has_returncode(0)
+
+ def testNoQuietOverridesAiAgentEnv(self):
+ """Test that --no-quiet wins over the environment."""
+ result = self.run_tests(
+ '--no-quiet',
+ '--variants=default',
+ 'sweet/bananas',
+ infra_staging=False,
+ ai_agent_vars=['AI_AGENT'],
+ )
+ result.stdout_includes('Statusfile variables')
+ result.stdout_excludes('Detected AI agent env')
+ result.has_returncode(0)
+
def testGN(self):
"""Test setup with legacy GN out dir."""
result = self.run_tests('--gn', baseroot="testroot5", outdir='out.gn')
diff --git a/deps/v8/tools/testrunner/testproc/fuzzer.py b/deps/v8/tools/testrunner/testproc/fuzzer.py
index 7bb91e84538..5380fbf552b 100644
--- a/deps/v8/tools/testrunner/testproc/fuzzer.py
+++ b/deps/v8/tools/testrunner/testproc/fuzzer.py
@@ -12,7 +12,7 @@ from . import base
# You can space-separate multiple flags in the flag string.
EXTRA_FLAGS = [
(0.05, '--always-osr'),
- (0.05, '--always-osr-from-maglev'),
+ (0.05, '--osr-from-maglev=4'),
(0.05, '--always-sparkplug'),
(0.1, '--assert-types'),
(0.1, '--cache=code'),
@@ -76,7 +76,9 @@ EXTRA_FLAGS = [
(0.1, '--turboshaft-verify-reductions'),
(0.1, '--maglev-assert-types'),
(0.5, '--maglev-untagged-phis'),
+ (0.1, '--disable-loop-stack-checks'),
(0.1, '--no-maglev-loop-peeling'),
+ (0.1, '--maglev-disable-builtin-reducers'),
(0.1, '--stress-wasm-memory-moving'),
(0.1, '--stress-scavenger-conservative-object-pinning-random'),
(0.1, '--conservative-stack-scanning'),
diff --git a/deps/v8/tools/testrunner/testproc/progress.py b/deps/v8/tools/testrunner/testproc/progress.py
index 48c959d5a05..7048bb1e76c 100644
--- a/deps/v8/tools/testrunner/testproc/progress.py
+++ b/deps/v8/tools/testrunner/testproc/progress.py
@@ -13,10 +13,11 @@ from testrunner.testproc.resultdb import rdb_sink, ResultDBIndicator
class ResultsTracker(base.TestProcObserver):
@staticmethod
def create(options):
- return ResultsTracker(options.exit_after_n_failures)
+ return ResultsTracker(options.exit_after_n_failures, options.quiet)
"""Tracks number of results and stops to run tests if max_failures reached."""
- def __init__(self, max_failures):
+
+ def __init__(self, max_failures, quiet):
super(ResultsTracker, self).__init__()
self._requirement = base.DROP_OUTPUT
@@ -24,6 +25,7 @@ class ResultsTracker(base.TestProcObserver):
self.remaining = 0
self.total = 0
self.max_failures = max_failures
+ self.quiet = quiet
def _on_next_test(self, test):
self.total += 1
@@ -39,13 +41,16 @@ class ResultsTracker(base.TestProcObserver):
self.stop()
def standard_show(self, tests):
- if tests.test_count_estimate:
- percentage = float(self.total) / tests.test_count_estimate * 100
- else:
- percentage = 0
- print(('>>> %d base tests produced %d (%d%s)'
- ' non-filtered tests') %
- (tests.test_count_estimate, self.total, percentage, '%'))
+ if not self.quiet:
+ if tests.test_count_estimate:
+ percentage = float(self.total) / tests.test_count_estimate * 100
+ else:
+ percentage = 0
+ print(('>>> %d base tests produced %d (%d%s)'
+ ' non-filtered tests') %
+ (tests.test_count_estimate, self.total, percentage, '%'))
+ # Always report how many tests ran: without it, an over-eager filter that
+ # matched nothing is indistinguishable from a successful run.
print('>>> %d tests ran' % (self.total - self.remaining))
def exit_code(self):
diff --git a/deps/v8/tools/testrunner/utils/test_utils.py b/deps/v8/tools/testrunner/utils/test_utils.py
index 7760ee96ed4..1a1f2a75abf 100644
--- a/deps/v8/tools/testrunner/utils/test_utils.py
+++ b/deps/v8/tools/testrunner/utils/test_utils.py
@@ -22,6 +22,7 @@ from testrunner.objects import output
from testrunner.local.context import DefaultOSContext
from testrunner.local.pool import SingleThreadedExecutionPool
from testrunner.local.variants import REQUIRED_BUILD_VARIABLES
+from testrunner.base_runner import AI_AGENT_ENV_VARS
TOOLS_ROOT = Path(__file__).resolve().parent.parent.parent
@@ -75,6 +76,22 @@ def capture():
sys.stderr = olderr
+@contextlib.contextmanager
+def ai_agent_env(active=None):
+ """Wrapper controlling the AI agent environment, so that the expected output
+ doesn't depend on whether an agent or a human runs the tests. All agent
+ variables are cleared, then those in `active` are set."""
+ saved = {name: os.environ.pop(name, None) for name in AI_AGENT_ENV_VARS}
+ os.environ.update({name: '1' for name in active or []})
+ try:
+ yield
+ finally:
+ for name, value in saved.items():
+ os.environ.pop(name, None)
+ if value is not None:
+ os.environ[name] = value
+
+
def with_json_output(basedir):
""" Function used as a placeholder where we need to resolve the value in the
context of a temporary test configuration"""
@@ -193,9 +210,14 @@ class TestRunnerTest(unittest.TestCase):
command.setup_testing()
pool.setup_testing()
- def run_tests(
- self, *args, baseroot='testroot1', config_overrides=None,
- with_build_config=True, outdir='out', **kwargs):
+ def run_tests(self,
+ *args,
+ baseroot='testroot1',
+ config_overrides=None,
+ with_build_config=True,
+ outdir='out',
+ ai_agent_vars=None,
+ **kwargs):
"""Executes the test runner with captured output."""
with temp_base(baseroot=baseroot) as basedir:
if with_build_config:
@@ -211,7 +233,7 @@ class TestRunnerTest(unittest.TestCase):
return json_out_path
return arg
resolved_args = [resolve_arg(arg) for arg in args]
- with capture() as (stdout, stderr):
+ with capture() as (stdout, stderr), ai_agent_env(ai_agent_vars):
sys_args = ['--command-prefix', sys.executable] + resolved_args
if kwargs.get('infra_staging', False):
sys_args.append('--infra-staging')
diff --git a/deps/v8/tools/turbolizer/package-lock.json b/deps/v8/tools/turbolizer/package-lock.json
index f726d3e9176..4925de01c3b 100644
--- a/deps/v8/tools/turbolizer/package-lock.json
+++ b/deps/v8/tools/turbolizer/package-lock.json
@@ -2708,20 +2708,24 @@
}
},
"node_modules/morgan": {
- "version": "1.10.1",
- "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.1.tgz",
- "integrity": "sha512-223dMRJtI/l25dJKWpgij2cMtywuG/WiUKXdvwfbhGKBhy1puASqXwFzmWZ7+K73vUPoR7SS2Qz2cI/g9MKw0A==",
+ "version": "1.11.0",
+ "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.11.0.tgz",
+ "integrity": "sha512-zSkVu3t18r39pw4ixfBKvfZi3y2UOqr7d4WYwcj3m8nXpEQK4rPO6GLzs/CExoRgmX3y9EjmmcXqv6jq0SK46g==",
"dev": true,
"license": "MIT",
"dependencies": {
"basic-auth": "~2.0.1",
"debug": "2.6.9",
"depd": "~2.0.0",
- "on-finished": "~2.3.0",
+ "on-finished": "~2.4.1",
"on-headers": "~1.1.0"
},
"engines": {
"node": ">= 0.8.0"
+ },
+ "funding": {
+ "type": "opencollective",
+ "url": "https://opencollective.com/express"
}
},
"node_modules/morgan/node_modules/debug": {
@@ -2739,18 +2743,6 @@
"integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==",
"dev": true
},
- "node_modules/morgan/node_modules/on-finished": {
- "version": "2.3.0",
- "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.3.0.tgz",
- "integrity": "sha512-ikqdkGAAyf/X/gPhXGvfgAytDZtDbr+bkNUJ0N9h5MI/dmdgCs3l6hoHrcUv41sRKew3jIwrp4qQDXiK99Utww==",
- "dev": true,
- "dependencies": {
- "ee-first": "1.1.1"
- },
- "engines": {
- "node": ">= 0.8"
- }
- },
"node_modules/ms": {
"version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
diff --git a/deps/v8/tools/turbolizer/src/turbo-visualizer.ts b/deps/v8/tools/turbolizer/src/turbo-visualizer.ts
index 7e9678590ca..b3935eefc9f 100644
--- a/deps/v8/tools/turbolizer/src/turbo-visualizer.ts
+++ b/deps/v8/tools/turbolizer/src/turbo-visualizer.ts
@@ -45,7 +45,7 @@ window.onload = function () {
disassemblyTabs.clearTabsAndContent();
// If the JSON isn't properly terminated, assume compiler crashed and
// add best-guess empty termination
- if (txtRes[txtRes.length - 2] === ",") {
+ if (txtRes.trimEnd().endsWith(',')) {
txtRes += '{"name":"disassembly","type":"disassembly","data":""}]}';
}
try {
diff --git a/deps/v8/tools/update-object-macros-undef.py b/deps/v8/tools/update-object-macros-undef.py
index 866fdb64680..7cef1df7f07 100755
--- a/deps/v8/tools/update-object-macros-undef.py
+++ b/deps/v8/tools/update-object-macros-undef.py
@@ -33,7 +33,7 @@ def main():
if not os.path.isfile(OUTPUT):
sys.exit("Output file {} does not exist; run this script in a v8 checkout."
.format(OUTPUT))
- regexp = re.compile('^#define (\w+)')
+ regexp = re.compile(r'^#define (\w+)')
seen = set()
with open(INPUT, 'r') as infile, open(OUTPUT, 'w') as outfile:
outfile.write(HEADER)
diff --git a/deps/v8/tools/v8_presubmit.py b/deps/v8/tools/v8_presubmit.py
index 4015d02b557..ddf23e88000 100755
--- a/deps/v8/tools/v8_presubmit.py
+++ b/deps/v8/tools/v8_presubmit.py
@@ -74,10 +74,11 @@ LINT_RULES = """
""".split()
LINT_OUTPUT_PATTERN = re.compile(r'^.+[:(]\d+[:)]')
-FLAGS_LINE = re.compile("//\s*Flags:.*--([A-z0-9-])+_[A-z0-9].*\n")
+FLAGS_LINE = re.compile(r"//\s*Flags:.*--([A-z0-9-])+_[A-z0-9].*\n")
ASSERT_OPTIMIZED_PATTERN = re.compile("assertOptimized")
-FLAGS_ENABLE_MAGLEV = re.compile("//\s*Flags:.*--maglev[^-].*\n")
-FLAGS_ENABLE_TURBOFAN = re.compile("//\s*Flags:.*--turbofan[^-].*\n")
+FLAGS_ENABLE_MAGLEV = re.compile(r"//\s*Flags:.*--maglev[^-].*\n")
+FLAGS_ENABLE_TURBOLEV = re.compile(r"//\s*Flags:.*--turbolev[^-].*\n")
+FLAGS_ENABLE_TURBOFAN = re.compile(r"//\s*Flags:.*--turbofan[^-].*\n")
ASSERT_UNOPTIMIZED_PATTERN = re.compile("assertUnoptimized")
TOOLS_PATH = dirname(abspath(__file__))
@@ -540,7 +541,7 @@ class SourceProcessor(SourceFileProcessor):
print ("Runtime functions list is suspiciously short. "
"Consider updating the presubmit script.")
sys.exit(1)
- str = '(\%\s+(' + '|'.join(runtime_functions) + '))[\s\(]'
+ str = r'(\%\s+(' + '|'.join(runtime_functions) + r'))[\s\(]'
return re.compile(str)
# Overwriting the one in the parent class.
@@ -662,9 +663,10 @@ class SourceProcessor(SourceFileProcessor):
not "mjsunit/mjsunit_numfuzz.js" in name):
if ASSERT_OPTIMIZED_PATTERN.search(contents) and \
not FLAGS_ENABLE_MAGLEV.search(contents) and \
+ not FLAGS_ENABLE_TURBOLEV.search(contents) and \
not FLAGS_ENABLE_TURBOFAN.search(contents):
- print("%s Flag --maglev or --turbofan should be set if " \
- "assertOptimized() is used" % name)
+ print("%s Flag --maglev, --turbolev, or --turbofan should be " \
+ "set if assertOptimized() is used" % name)
result = False
match = self.runtime_function_call_pattern.search(contents)
@@ -787,7 +789,7 @@ class GCMoleProcessor(SourceFileProcessor):
tools/gcmole/gcmole.py::build_file_list()
"""
gcmole_re = re.compile('### gcmole(.*)')
- arch_re = re.compile('\((.+)\) ###')
+ arch_re = re.compile(r'\((.+)\) ###')
def IsRelevant(self, name):
return True
diff --git a/deps/v8/tools/vpython.toml b/deps/v8/tools/vpython.toml
new file mode 100644
index 00000000000..1b099bfeb7c
--- /dev/null
+++ b/deps/v8/tools/vpython.toml
@@ -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.
+
+# uv-backed vpython spec for V8 tools and test runner, the modern replacement
+# for tools/.vpython3.
+#
+# The companion tools/vpython.toml.uv.lock is generated, not hand-edited. After
+# changing a dependency here, run 'vpython3' (or 'vpython3 -vpython-tool
+# upgrade') locally to resynchronize it, and commit both files together.
+
+requires-python = '>=3.11,<3.12'
+dependencies = [
+ 'six==1.15.0',
+ 'coverage==7.3.1',
+ 'pbr==3.0.0',
+ 'funcsigs==1.0.2',
+ 'hjson==3.1.0',
+ 'httplib2==0.19.1',
+ 'mock==2.0.0',
+ 'setuptools==68.0.0 ; python_version < "3.14"',
+ 'setuptools>=75.0.0 ; python_version >= "3.14"',
+ 'numpy==1.23.5+chromium.4',
+ 'protobuf==3.19.3',
+ 'pyparsing==2.4.7',
+ 'requests==2.31.0',
+ 'urllib3==1.26.6',
+ 'idna==2.8',
+ 'certifi==2020.11.8',
+ 'charset-normalizer==2.0.4',
+ 'pyyaml==5.4.1+chromium.1',
+ 'clusterfuzz==2.5.6+5c85ed3d46137b17da04c59bcd805ee5',
+ 'packaging==16.8',
+ 'psutil==5.8.0+chromium.3',
+ 'pyfakefs==5.7.3',
+ 'markdown==3.4.1',
+]
diff --git a/deps/v8/tools/vpython.toml.uv.lock b/deps/v8/tools/vpython.toml.uv.lock
new file mode 100644
index 00000000000..9567f813357
--- /dev/null
+++ b/deps/v8/tools/vpython.toml.uv.lock
@@ -0,0 +1,202 @@
+certifi==2020.11.8 \
+ --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \
+ --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \
+ --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \
+ --hash=sha256:83899d4fd2a1071acca79abb10435484cdfd9f223522fd26ac2449b2c4c52d9b \
+ --hash=sha256:e538978d4526342d7b37cfcdd503eaf48f32c7f362d7ca8cb32ee5491b872841 \
+ --hash=sha256:e538978d4526342d7b37cfcdd503eaf48f32c7f362d7ca8cb32ee5491b872841
+ # via requests
+charset-normalizer==2.0.4 \
+ --hash=sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b \
+ --hash=sha256:8290b03e2f31a4b3399e1727f0323607253bb2bd38f0cb23d4e0cc6d76a5ec72
+ # via requests
+clusterfuzz==2.5.6+5c85ed3d46137b17da04c59bcd805ee5 \
+ --hash=sha256:3775e9d2f6a13f5f3bab350c0e0ba2ee7f5e58257e9a6b07e9dbac7c2b702b6f
+coverage==7.3.1 \
+ --hash=sha256:2b7f038e155de2156bd1073068b0ba39e97ed8ca340889a680ae2d7685dd60ea \
+ --hash=sha256:37df007c1cb77d75ddf9e8753d2f69ba904d4beaec7d696fff0081a61ce81cd8 \
+ --hash=sha256:40c0f331b8bde5128d97fa3c284078958b1aab42a86697c40f65b650417ed904 \
+ --hash=sha256:412d5ef5437e9bad534e7464ea80094d195a998803146a9a856850e79083a93c \
+ --hash=sha256:4c16428216025c980a8d160c885c5225d143353f609a82537e8b957a2109330e \
+ --hash=sha256:4cf8ed834637fe317552ab068048c7202068b64706593159d67fa1936753a19b \
+ --hash=sha256:6bc0892076728c5c5d3c92a7e968ddc1c52b49e79479e9419a50431df200566d \
+ --hash=sha256:79a16c5b61a81ac581d07d74f2b257a77853d31f3e48d9f674226f4fd42a77ef \
+ --hash=sha256:7f3c398881de3a558f9fb94f232757c73d3498a420462bb232590c4ecfb9a908 \
+ --hash=sha256:85d78e23c50f3820666670e4689f1b30c0915e7db0020a22a41be4158d78e7f7 \
+ --hash=sha256:afd828ea3ffebf4851053258a3e9d52079bfd1c60d233b0d0467bba73ebd044f \
+ --hash=sha256:b81ff0d20e6da0552923e36b9b9c5c6e7dcd6192653fc9192b059137f50938c9 \
+ --hash=sha256:bdaedd684fdf5c2104be67e2c1b92f73e06b83a1cb0cab19d598a4e4894ccb56 \
+ --hash=sha256:ea1637565ebc68eca9ed5f6414c8231614c79b5f2f9d3409b8e8f1894902b7ee \
+ --hash=sha256:ec748a35bfb05af56249a15db789773644902de436f6867129eb183479f17010 \
+ --hash=sha256:fbd870567a278eddd1903e206969bb29f76288b21a5c1a61dab6e0d8260ec75f
+funcsigs==1.0.2 \
+ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
+ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
+ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
+ --hash=sha256:c75adf3fb65c5e85c480444a9182c2045f43996a805ff042207d28418e7289b8 \
+ --hash=sha256:c75adf3fb65c5e85c480444a9182c2045f43996a805ff042207d28418e7289b8 \
+ --hash=sha256:c75adf3fb65c5e85c480444a9182c2045f43996a805ff042207d28418e7289b8
+hjson==3.1.0 \
+ --hash=sha256:21632b53d5a14c505caf63f41be7191549f35e9563d3402cbc21386bf4cc40c8 \
+ --hash=sha256:6ab3778fb6c5f2796f4a13aae1def626f8000ea77e0a6e2a7a38b4d8642d9b35
+httplib2==0.19.1 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:2ad195faf9faf079723f6714926e9a9061f694d07724b846658ce08d40f522b4 \
+ --hash=sha256:b7cd9ee0a01ce4e658366e13a2047b54c84fc71f1f0ff268325a1ed5b5aa119d
+idna==2.8 \
+ --hash=sha256:6c68f10e99f5f99caff1bf6b897f7032748b7fa206d16f507c86867bc078312d \
+ --hash=sha256:6c68f10e99f5f99caff1bf6b897f7032748b7fa206d16f507c86867bc078312d \
+ --hash=sha256:6c68f10e99f5f99caff1bf6b897f7032748b7fa206d16f507c86867bc078312d \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c
+ # via requests
+markdown==3.4.1 \
+ --hash=sha256:08fb8465cffd03d10b9dd34a5c3fea908e20391a2a90b88d66362cb05beed186 \
+ --hash=sha256:64f5ec0a2ec8c0328194f54401482c34c250c33a7085e9ca5136aa79c0bcc022
+mock==2.0.0 \
+ --hash=sha256:1005a7e0d4cc802865427a9a1928d717023653e10cc7e54451981fe08ea267a1 \
+ --hash=sha256:2f61f7f5133a2fe0ba86872efbd85ff86340aa3f4b46cadf7cca961dc651b9db \
+ --hash=sha256:2f61f7f5133a2fe0ba86872efbd85ff86340aa3f4b46cadf7cca961dc651b9db \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1
+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
+packaging==16.8 \
+ --hash=sha256:12ab96d61fb0cf16023ec1d79d87e7372868c5a883d08378eb29741b1015d243 \
+ --hash=sha256:55eaf1bd3efbcc9bbfd7562abaf4b152b9b67f06da364280d04731c18eefde6e \
+ --hash=sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388 \
+ --hash=sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388 \
+ --hash=sha256:99276dc6e3a7851f32027a68f1095cd3f77c148091b092ea867a351811cfe388 \
+ --hash=sha256:cfd34b5b8bab8dd8ae8563cb2871894dd24cae16c8b3cace8b0ab5768d40f1bd
+pbr==3.0.0 \
+ --hash=sha256:86f0e548dfbdc1ad12559725a66b5e1ca0b2e0744940da1ec89991fd11a2b32b \
+ --hash=sha256:86f0e548dfbdc1ad12559725a66b5e1ca0b2e0744940da1ec89991fd11a2b32b \
+ --hash=sha256:86f0e548dfbdc1ad12559725a66b5e1ca0b2e0744940da1ec89991fd11a2b32b \
+ --hash=sha256:de776c05e4a75e4d266e03a3d82ba13894e2c51a2fa52501187361ac180d4468 \
+ --hash=sha256:de776c05e4a75e4d266e03a3d82ba13894e2c51a2fa52501187361ac180d4468 \
+ --hash=sha256:de776c05e4a75e4d266e03a3d82ba13894e2c51a2fa52501187361ac180d4468
+ # via mock
+protobuf==3.19.3 \
+ --hash=sha256:7566073ea146a7c7e90a87088d92e9f76cdad8c38b4ec528f9d08bfd94f49ca3 \
+ --hash=sha256:f6d4b5b7595a57e69eb7314c67bef4a3c745b4caf91accaf72913d8e0635111b
+psutil==5.8.0+chromium.3 \
+ --hash=sha256:0414d09ff0e351534cec610ea7abb69293c3247d85957cb8ca9079b25dcee9aa \
+ --hash=sha256:14353392ca62cfd804920a31453f4d05fa076c18bd093c2e7bcef767f14c4e9c \
+ --hash=sha256:23010beb4d80ad1c52412fbc42b22dac29075de4c251c4f59e88393556359a03 \
+ --hash=sha256:241ced5e39bf21b8262cba00e308d36e0a55b55bda72a4bc6a275e97c4bd6076 \
+ --hash=sha256:2e46f6c91650281a318edf1fa0303115316e9a18d1753331647cbe6a54992094 \
+ --hash=sha256:4775397151e9cf7ce7ba74d0c503e7ae7524647ca61b3cbb9ec074e455ae641b \
+ --hash=sha256:4c17e9d514baf04be368fabba7b7b5d939612f7918b86cbd29a69893eabc3bd7 \
+ --hash=sha256:55c5e6a6a9f224cb33780838dce6aa9ba76b417321a77e4aacec1340b42f8d4e \
+ --hash=sha256:7ab874691912e8ea195df7b205839db956eea8524f2f735017e8f441557cfd38 \
+ --hash=sha256:9e1b2514a57cfb6134e10e2292f7cc57b5268161603236b5c4d8b267d35477f7 \
+ --hash=sha256:a066d6d1ea231e91653d80c8cd12f1df1c9efa69c00ca5beda3ff91dabf32a4f \
+ --hash=sha256:ad7b79a159498273acbef1a629da7c413d7aa1485570d7e41de7124f6b59305e \
+ --hash=sha256:c8280cd87abc40fa29973d0b44c8ef89ff39d4b13ad423a02ddeebf72f10ce61 \
+ --hash=sha256:ce110dfcdd5f158c3ba9e3a7965263afcbb4b8427115f760624585ae5bd9ee49 \
+ --hash=sha256:d37cb319de52e7c194dbc6f432910105268f07f94c659d3c097b96c59c94311f \
+ --hash=sha256:d67e2c738ea14d2594a7af88730c6e48504aff57e466e41df62e15ef8b9fe0c5 \
+ --hash=sha256:e26d6129298d2aa99cf805aa81ffb76e33d9a1a12dfc0653b4c893423aeea37d
+pyfakefs==5.7.3 \
+ --hash=sha256:53702780b38b24a48a9b8481c971abf1675f5abfd7d44653c2bcdd90b9751224 \
+ --hash=sha256:ca2e283a7e47fbee6604ff2b1fbec5cb1c07800e111183f8cf07a6cf92eddeef
+pyparsing==2.4.7 \
+ --hash=sha256:e353556f0615c2246ea24b7afd6089cb096c13c2f5c26b0ad0e0a542b5db6d19 \
+ --hash=sha256:e353556f0615c2246ea24b7afd6089cb096c13c2f5c26b0ad0e0a542b5db6d19 \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:ef9d7589ef3c200abe66653d3f1ab1033c3c419ae9b9bdb1240a85b024efc88b \
+ --hash=sha256:f10f6d3fc1598d55e192fe92b58c020281a7ad211a6f8f0ca9c24b3e97ecd699
+ # via
+ # httplib2
+ # packaging
+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
+requests==2.31.0 \
+ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
+ --hash=sha256:7c024df3d83d462cc8127c6c9a2dae2e5d2bddb54c1039624ab3baf485d752ca
+setuptools==68.0.0 ; python_full_version < '3.14' \
+ --hash=sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f \
+ --hash=sha256:25c8300cbd8c41a350e4890f8340ca0bbadff88967f7b26de4c8ccfe5d851a51
+setuptools==75.6.0 ; python_full_version >= '3.14' \
+ --hash=sha256:95e7b6c4ee1eb64afe479ba9f0c89ef4fb8e0da33319d829ecb2ad1dcd131dfd \
+ --hash=sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d
+six==1.15.0 \
+ --hash=sha256:7bb413e52c2f9981580e74743d53187be17e108df9b4f9fab1964aab2e94b9d6 \
+ --hash=sha256:7bb413e52c2f9981580e74743d53187be17e108df9b4f9fab1964aab2e94b9d6 \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:c7dfbdb6d68189c1942e9405fae9eef6bdf2ddff305866df52b806c11da74323
+ # via
+ # mock
+ # packaging
+urllib3==1.26.6 \
+ --hash=sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4 \
+ --hash=sha256:fa608904f610002ec11bb0347f46ccf36c1fe0fb399c8044fce17e8fc02936db
+ # via requests
diff --git a/deps/v8/tools/wasm/update-wasm-spec-tests.sh b/deps/v8/tools/wasm/update-wasm-spec-tests.sh
index 1586e60e40d..4634314b644 100755
--- a/deps/v8/tools/wasm/update-wasm-spec-tests.sh
+++ b/deps/v8/tools/wasm/update-wasm-spec-tests.sh
@@ -140,7 +140,7 @@ log_and_run rm -rf wpt
# Generate the proposal tests.
###############################################################################
-repos='js-promise-integration threads stack-switching custom-descriptors'
+repos='js-promise-integration threads stack-switching custom-descriptors wide-arithmetic'
for repo in ${repos}; do
new_section "Process ${repo}: core tests"
diff --git a/deps/v8/vpython.toml b/deps/v8/vpython.toml
new file mode 100644
index 00000000000..69ba8f252a4
--- /dev/null
+++ b/deps/v8/vpython.toml
@@ -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.
+
+# uv-backed vpython spec for the V8 repository, the modern replacement
+# for //.vpython3.
+#
+# The companion //vpython.toml.uv.lock is generated, not hand-edited. After
+# changing a dependency here, run 'vpython3' (or 'vpython3 -vpython-tool
+# upgrade') locally to resynchronize it, and commit both files together.
+
+requires-python = '>=3.11,<3.12'
+dependencies = [
+ 'six==1.15.0',
+ 'coverage==7.3.1',
+ 'pbr==3.0.0',
+ 'filecheck==1.0.1',
+ 'funcsigs==1.0.2',
+ 'mock==2.0.0',
+ 'setuptools==68.0.0 ; python_version < "3.14"',
+ 'setuptools>=75.0.0 ; python_version >= "3.14"',
+ 'numpy==1.23.5+chromium.4',
+ 'protobuf==3.19.3',
+ 'requests==2.31.0',
+ 'urllib3==1.26.6',
+ 'idna==2.8',
+ 'certifi==2020.11.8',
+ 'charset-normalizer==2.0.4',
+ 'pyfakefs==5.7.3',
+]
diff --git a/deps/v8/vpython.toml.uv.lock b/deps/v8/vpython.toml.uv.lock
new file mode 100644
index 00000000000..6b541f92315
--- /dev/null
+++ b/deps/v8/vpython.toml.uv.lock
@@ -0,0 +1,126 @@
+certifi==2020.11.8 \
+ --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \
+ --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \
+ --hash=sha256:1f422849db327d534e3d0c5f02a263458c3955ec0aae4ff09b95f195c59f4edd \
+ --hash=sha256:83899d4fd2a1071acca79abb10435484cdfd9f223522fd26ac2449b2c4c52d9b \
+ --hash=sha256:e538978d4526342d7b37cfcdd503eaf48f32c7f362d7ca8cb32ee5491b872841 \
+ --hash=sha256:e538978d4526342d7b37cfcdd503eaf48f32c7f362d7ca8cb32ee5491b872841
+ # via requests
+charset-normalizer==2.0.4 \
+ --hash=sha256:0c8911edd15d19223366a194a513099a302055a962bca2cec0f54b8b63175d8b \
+ --hash=sha256:8290b03e2f31a4b3399e1727f0323607253bb2bd38f0cb23d4e0cc6d76a5ec72
+ # via requests
+coverage==7.3.1 \
+ --hash=sha256:2b7f038e155de2156bd1073068b0ba39e97ed8ca340889a680ae2d7685dd60ea \
+ --hash=sha256:37df007c1cb77d75ddf9e8753d2f69ba904d4beaec7d696fff0081a61ce81cd8 \
+ --hash=sha256:40c0f331b8bde5128d97fa3c284078958b1aab42a86697c40f65b650417ed904 \
+ --hash=sha256:412d5ef5437e9bad534e7464ea80094d195a998803146a9a856850e79083a93c \
+ --hash=sha256:4c16428216025c980a8d160c885c5225d143353f609a82537e8b957a2109330e \
+ --hash=sha256:4cf8ed834637fe317552ab068048c7202068b64706593159d67fa1936753a19b \
+ --hash=sha256:6bc0892076728c5c5d3c92a7e968ddc1c52b49e79479e9419a50431df200566d \
+ --hash=sha256:79a16c5b61a81ac581d07d74f2b257a77853d31f3e48d9f674226f4fd42a77ef \
+ --hash=sha256:7f3c398881de3a558f9fb94f232757c73d3498a420462bb232590c4ecfb9a908 \
+ --hash=sha256:85d78e23c50f3820666670e4689f1b30c0915e7db0020a22a41be4158d78e7f7 \
+ --hash=sha256:afd828ea3ffebf4851053258a3e9d52079bfd1c60d233b0d0467bba73ebd044f \
+ --hash=sha256:b81ff0d20e6da0552923e36b9b9c5c6e7dcd6192653fc9192b059137f50938c9 \
+ --hash=sha256:bdaedd684fdf5c2104be67e2c1b92f73e06b83a1cb0cab19d598a4e4894ccb56 \
+ --hash=sha256:ea1637565ebc68eca9ed5f6414c8231614c79b5f2f9d3409b8e8f1894902b7ee \
+ --hash=sha256:ec748a35bfb05af56249a15db789773644902de436f6867129eb183479f17010 \
+ --hash=sha256:fbd870567a278eddd1903e206969bb29f76288b21a5c1a61dab6e0d8260ec75f
+filecheck==1.0.1 \
+ --hash=sha256:3866701541a2495ac81370975c8941f0fa47c28ce27fcf4375a280e750cdeafd \
+ --hash=sha256:89c8daa52196de30813859937811f0aa63f0521c8dbef3ea585a3d9dac8bab32
+funcsigs==1.0.2 \
+ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
+ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
+ --hash=sha256:330cc27ccbf7f1e992e69fef78261dc7c6569012cf397db8d3de0234e6c937ca \
+ --hash=sha256:c75adf3fb65c5e85c480444a9182c2045f43996a805ff042207d28418e7289b8 \
+ --hash=sha256:c75adf3fb65c5e85c480444a9182c2045f43996a805ff042207d28418e7289b8 \
+ --hash=sha256:c75adf3fb65c5e85c480444a9182c2045f43996a805ff042207d28418e7289b8
+idna==2.8 \
+ --hash=sha256:6c68f10e99f5f99caff1bf6b897f7032748b7fa206d16f507c86867bc078312d \
+ --hash=sha256:6c68f10e99f5f99caff1bf6b897f7032748b7fa206d16f507c86867bc078312d \
+ --hash=sha256:6c68f10e99f5f99caff1bf6b897f7032748b7fa206d16f507c86867bc078312d \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c \
+ --hash=sha256:ea8b7f6188e6fa117537c3df7da9fc686d485087abf6ac197f9c46432f7e4a3c
+ # via requests
+mock==2.0.0 \
+ --hash=sha256:1005a7e0d4cc802865427a9a1928d717023653e10cc7e54451981fe08ea267a1 \
+ --hash=sha256:2f61f7f5133a2fe0ba86872efbd85ff86340aa3f4b46cadf7cca961dc651b9db \
+ --hash=sha256:2f61f7f5133a2fe0ba86872efbd85ff86340aa3f4b46cadf7cca961dc651b9db \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1 \
+ --hash=sha256:5ce3c71c5545b472da17b72268978914d0252980348636840bd34a00b5cc96c1
+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
+pbr==3.0.0 \
+ --hash=sha256:86f0e548dfbdc1ad12559725a66b5e1ca0b2e0744940da1ec89991fd11a2b32b \
+ --hash=sha256:86f0e548dfbdc1ad12559725a66b5e1ca0b2e0744940da1ec89991fd11a2b32b \
+ --hash=sha256:86f0e548dfbdc1ad12559725a66b5e1ca0b2e0744940da1ec89991fd11a2b32b \
+ --hash=sha256:de776c05e4a75e4d266e03a3d82ba13894e2c51a2fa52501187361ac180d4468 \
+ --hash=sha256:de776c05e4a75e4d266e03a3d82ba13894e2c51a2fa52501187361ac180d4468 \
+ --hash=sha256:de776c05e4a75e4d266e03a3d82ba13894e2c51a2fa52501187361ac180d4468
+ # via mock
+protobuf==3.19.3 \
+ --hash=sha256:7566073ea146a7c7e90a87088d92e9f76cdad8c38b4ec528f9d08bfd94f49ca3 \
+ --hash=sha256:f6d4b5b7595a57e69eb7314c67bef4a3c745b4caf91accaf72913d8e0635111b
+pyfakefs==5.7.3 \
+ --hash=sha256:53702780b38b24a48a9b8481c971abf1675f5abfd7d44653c2bcdd90b9751224 \
+ --hash=sha256:ca2e283a7e47fbee6604ff2b1fbec5cb1c07800e111183f8cf07a6cf92eddeef
+requests==2.31.0 \
+ --hash=sha256:58cd2187c01e70e6e26505bca751777aa9f2ee0b7f4300988b709f44e013003f \
+ --hash=sha256:7c024df3d83d462cc8127c6c9a2dae2e5d2bddb54c1039624ab3baf485d752ca
+setuptools==68.0.0 ; python_full_version < '3.14' \
+ --hash=sha256:11e52c67415a381d10d6b462ced9cfb97066179f0e871399e006c4ab101fc85f \
+ --hash=sha256:25c8300cbd8c41a350e4890f8340ca0bbadff88967f7b26de4c8ccfe5d851a51
+setuptools==75.6.0 ; python_full_version >= '3.14' \
+ --hash=sha256:95e7b6c4ee1eb64afe479ba9f0c89ef4fb8e0da33319d829ecb2ad1dcd131dfd \
+ --hash=sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d
+six==1.15.0 \
+ --hash=sha256:7bb413e52c2f9981580e74743d53187be17e108df9b4f9fab1964aab2e94b9d6 \
+ --hash=sha256:7bb413e52c2f9981580e74743d53187be17e108df9b4f9fab1964aab2e94b9d6 \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:8b74bedcbbbaca38ff6d7491d76f2b06b3592611af620f8426e82dddb04a5ced \
+ --hash=sha256:c7dfbdb6d68189c1942e9405fae9eef6bdf2ddff305866df52b806c11da74323
+ # via mock
+urllib3==1.26.6 \
+ --hash=sha256:39fb8672126159acb139a7718dd10806104dec1e2f0f6c88aab05d17df10c8d4 \
+ --hash=sha256:fa608904f610002ec11bb0347f46ccf36c1fe0fb399c8044fce17e8fc02936db
+ # via requests